summaryrefslogtreecommitdiff
path: root/docs/html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html')
-rwxr-xr-xdocs/html/index.htm33
-rwxr-xr-xdocs/html/xbase.jpgbin0 -> 6421 bytes
-rwxr-xr-xdocs/html/xbbib.htm63
-rwxr-xr-xdocs/html/xbc1.htm185
-rwxr-xr-xdocs/html/xbc10.htm12
-rwxr-xr-xdocs/html/xbc11.htm12
-rwxr-xr-xdocs/html/xbc12.htm72
-rwxr-xr-xdocs/html/xbc13.htm46
-rwxr-xr-xdocs/html/xbc14.htm12
-rwxr-xr-xdocs/html/xbc15.htm34
-rwxr-xr-xdocs/html/xbc2.htm267
-rwxr-xr-xdocs/html/xbc3.htm73
-rwxr-xr-xdocs/html/xbc4.htm80
-rwxr-xr-xdocs/html/xbc5.htm205
-rwxr-xr-xdocs/html/xbc6.htm137
-rwxr-xr-xdocs/html/xbc7.htm153
-rwxr-xr-xdocs/html/xbc8.htm79
-rwxr-xr-xdocs/html/xbc9.htm179
18 files changed, 1642 insertions, 0 deletions
diff --git a/docs/html/index.htm b/docs/html/index.htm
new file mode 100755
index 0000000..3c992f5
--- /dev/null
+++ b/docs/html/index.htm
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML><TITLE>Xbase DBMS Documentation Table of Contents</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H1><p align="center">Xbase DBMS<br>
+Last Updated 11/21/22<br>Version 4.x.x</p></H1>
+<h2>Documentation Table Of Contents</h2>
+<h3>Section 1 - Xbase Concepts</h3>
+<h4>
+<A HREF="xbc1.htm">Chapter 1 - Getting Started</A><br>
+<A HREF="xbc2.htm">Chapter 2 - Database Overview</A><br>
+<A HREF="xbc3.htm">Chapter 3 - Fields and Strings</A><br>
+<A HREF="xbc4.htm">Chapter 4 - Date Processing</A><br>
+<A HREF="xbc5.htm">Chapter 5 - Expression Handling</A><br>
+<A HREF="xbc6.htm">Chapter 6 - Index Overview</A><br>
+<A HREF="xbc7.htm">Chapter 7 - NDX (DBase) Indices</A><br>
+<A HREF="xbc8.htm">Chapter 8 - MDX (DBase) Indices</A><br>
+<A HREF="xbc9.htm">Chapter 9 - NTX (Clipper) Indices</A><br>
+<A HREF="xbc10.htm">Chapter 10 - CDX (FoxPro) Indices</A><br>
+<A HREF="xbc11.htm">Chapter 11 - IDX (FoxPro) Indices</A><br>
+<A HREF="xbc12.htm">Chapter 12 - Record and File Locking</A><br>
+<A HREF="xbc13.htm">Chapter 13 - Logfile Support</A><br>
+<A HREF="xbc14.htm">Chapter 14 - SQL Support</A><br>
+<A HREF="xbc15.htm">Chapter 15 - Utility programs</A><br>
+
+</h4>
+<h3>Section 3 - Appendices</h3>
+<h4>
+<A HREF="copying.lib">Appendix C - GPL Library License</A><br>
+<A HREF="xbbib.htm">Appendix D - Bibliography</A><br>
+</h4>
+<p><img src="xbase.jpg"><br><hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbase.jpg b/docs/html/xbase.jpg
new file mode 100755
index 0000000..5070fcb
--- /dev/null
+++ b/docs/html/xbase.jpg
Binary files differ
diff --git a/docs/html/xbbib.htm b/docs/html/xbbib.htm
new file mode 100755
index 0000000..70e4e82
--- /dev/null
+++ b/docs/html/xbbib.htm
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Bibliography</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H1><p align="center">Xbase DBMS Bibliography</p></H1>
+<p align="center">Page Updated 2/1/99</p><hr>
+
+Bachman, Erik<br>
+Xbase File Format Description / Erik Bachman, Roskilde, Denmark: Clickety
+Click Software, 1996-1998, 44 pages<br><br>
+
+Loomis, Mary:<br>
+The Database Book, Macmillan Publishing Company, 1987, New York, New York:
+ISBN 0-02-371760-2<br><br>
+
+Dorfman, Len:<br>
+Building C Libraries, Windcrest, 1990, Blue Ridge Summit, PA:
+ISBN 0-8306-3418-5<br><br>
+
+Eckel, Bruce:<br>
+Using C++, Osborne, McGraw-Hill, 1990, Berkeley, CA:
+ISBN 0-07-881522-3<br><br>
+
+Aho, Alfred: Hopcroft, John: Ullman, Jeffrey:<br>
+Data Structures and Algorithms, Addison-Wesley Publishing, 1983,
+Reading Massachusetts: ISBN 0-201-00023-7<br><br>
+
+Stevens, Al:<br>
+C Database Development, MIS Press, 1991, Portland Oregon:
+ISBN 1-55828-136-3<br><br>
+
+Pressman, Roger:<br>
+Software Engineering: A Practitioner's Approach, McGraw-Hill, 1982,
+New York ISBN 0-07-050781-3<br><br>
+
+Chou, George Tsu-der:<br>
+2nd Edition dBase III Plus Handbook: Que Corporation, 1986,
+Indianapolis, Indiana ISBN 0-88022-269-7<br><br>
+
+Krumm, Rob:<br>
+Understanding and Using dBase II & III, Brady Communications Company, Inc,
+1985, Bowie MD ISBN 0-89303-917-9<br><br>
+
+Hursch, Jack: Hursch, Carulyn:<br>
+dBase IV Essentials, Windcrest, 1988, Blue Ridge Summit, PA
+ISBN 0-8306-9616-4<br><br>
+
+Borland:<br>
+Turbo C++, Programmer's Guide, Borland International, 1990,
+Scotts Valley CA<br><br>
+
+Borland:<br>
+Turbo C++, Library Reference, Borland International 1990,
+Scotts Valley CA<br><br>
+
+The Draft Standard C++ Library by P.J. Plauger, Prentice Hall, New Jersey,
+1995.<br><br>
+
+H.M Dietel/P.J. Deitel: C++ How To Program, Prentice Hall, Englewod Cliffs,
+New Jersey 07632<br><br>
+
+</BODY>
+</HTML>
diff --git a/docs/html/xbc1.htm b/docs/html/xbc1.htm
new file mode 100755
index 0000000..bb04aec
--- /dev/null
+++ b/docs/html/xbc1.htm
@@ -0,0 +1,185 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 1</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+
+<h1><p align="center">Getting Started</p></h1>
+<p align="center">Chapter Updated 11/21/22</p>
+
+<hr><h2>Overview</h2>
+
+Welcome to Xbase64 DBMS, a collection of specifications, programs,
+utilities and a C++ class library for manipulating legacy Xbase (DBF) type
+data files and indices.
+<br><br>
+
+The term Xbase is often used used to describe the format of the original
+DBase, Clipper and Foxbase (.DBF) files. The XBase file format is well
+documented and has stood the test of time. Various popular programs
+still create and read xbase formatted files.<br><br>
+
+The purpose of the Xbase64 library is to provide reliable and usable
+programming tools for reading, writing and updating DBF databases,
+indices and memo fields. Version 4.x.x has been tested for compatability
+with DBase III (TM) and DBase IV (TM) version data files and indices
+*.DBF (data), *.NDX (single tag index), *.MDX (multi tag index) and
+*.DBT (memo).<br><br>
+
+Version 4.x.x is a major rewrite of the library to strenghen error
+processing and bring consistency across modules. It includes updates
+to the locking process and also includes a module to support MDX multi
+tag indices.<br><br>
+
+Earlier versions of the library have included NTX and CDX index formats
+and that code will be re-incorporated into the latest version in the
+future.
+
+
+
+<br><br><br>
+
+<hr><h2>System Requirements</h2>
+
+To build the Xbase64 library, the following items are needed:<br><br>
+
+A computer, a C/C++ compiler and CMAKE.<br><br>
+
+The original source code was developed on a Linux platform with the GCC
+public domain C/C++ compiler.
+<br><br>
+
+Xbase64 DBMS has been successfully ported and runs on Linux, Mac and and Windows.
+<br><br>
+
+<hr><h2>Classes and User Interface</h2>
+
+<a href="..\doxygen\html\index.html">Classes and User Interface Documentation via Doxygen</a>
+
+<br><br>
+<hr><h2>Portability, Type Defs and Structures</h2>
+
+To make the Xbase64 library as portable as possible, the following things occurred:
+<br><br>
+<li>The software was developed to compile and run on either 32 or 64 bit architectures.
+<li>The software was developed to compile and run on either big endian or little endian archtectures.
+<li>All numeric data is stored in little endian format.
+<li>The library is built using <a href="https://cmake.org">Cmake</a> to provide support on a wide variety of platforms.
+<li>Field types were defined to be consistent across various OS and CPU configurations.
+Xbase64 defines the following field types:<br><br><br>
+<CENTER>
+<TABLE BORDER>
+<CAPTION ALIGN=TOP><h3>Field Types</h3></CAPTION>
+<TR ALIGN=BASELINE>
+<TR><TH ALIGN=LEFT>Type<TD>Description
+<TR><TH ALIGN=LEFT>xbInt16<TD>16 bit int
+<TR><TH ALIGN=LEFT>xbUInt16<TD>16 bit unsigned int
+<TR><TH ALIGN=LEFT>xbInt32<TD>32 bit int
+<TR><TH ALIGN=LEFT>xbUInt32<TD>32 bit unsigned int
+<TR><TH ALIGN=LEFT>xbInt64<TD>64 bit int
+<TR><TH ALIGN=LEFT>xbUInt64<TD>64 bit unsigned int
+<TR><TH ALIGN=LEFT>xbDouble<TD>double
+<TR><TH ALIGN=LEFT>char<TD>char
+<TR><TH ALIGN=LEFT>void<TD>void
+<TR><TH ALIGN=LEFT>struct SCHEMA<TD>Used for defining record structures
+</TABLE></CENTER>
+<br><br>
+
+Xbase64 was designed for portability utilizing standard ANSI-C/C++ compliant
+code. If you decide to write updates to the Xbase64 project, please try
+to keep your work to standard C/C++ generic calls and use the above predefined field types.<br><br>
+
+<hr><h2>Compilation Overview</h2>
+To build the xbase64 library, verify you have:<br>
+<li>Xbase64 source code
+<li>cmake 2.6 or LATER
+<li>Compiler and linker
+
+<br><br>
+Verify you have access rights to the target location of the library
+
+<br><br>
+For Linux:
+<br><br>
+<li>cd xbase/Linux
+<li>cmake .
+<li>make
+<li>make test
+<li>sudo make install
+<li>Verify the ld.so.conf file has the library target directory. For example
+update file /etc/ld.so.conf to include /usr/local/lib and run ldconfig.
+<br><br>
+
+For Mac:
+<br><br>
+<li>Verify you have xcode installed and operational.
+<li>cd xbase/Mac
+<li>cmake . -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk
+<li>make
+<li>make test
+<br><br>
+
+For Windows 64 bit with Visual Studio:
+<br><br>
+<li>Open a Visual Studio 64 bit Shell
+<li>cd xbase\Win64VS
+<li>buildwin.bat
+<li>nmake test
+<li>From a VS Studio 64 bit shell in admin mode: nmake install
+<br><br>
+
+For Windows 32 bit with Visual Studio:
+<br><br>
+<li>Open a Visual Studio 32 bit Shell
+<li>cd xbase\Win32VS
+<li>buildwin.bat
+<li>nmake test
+<li>From a VS Studio 32 bit shell in admin mode: nmake install
+<br><br>
+
+For Windows 32 bit with Borland 5.5 free compiler
+<br><br>
+<li>cd xbase\Win32Borland
+<li>BuildBorland.bat
+<li>make test
+<br><br>
+
+For other platforms:
+<br><br>
+Here is something to start with...
+<li>cd xbase
+<li>md MyPlatform
+<li>cd MyPlatform
+<li>cp ../Cmake/CmakeLists.txt.
+<li>Enter the appropriate make command for your environment. Check the cmake web site for help.<br>
+ On Linux, it is .cmake, then make
+ your mileage may vary
+
+ Send your results to the library maintainer so it can be added to this library
+
+
+
+To use the Xbase classes, include the following header file in the program:
+<br><br>
+
+#include &lt;xbase.h&gt;<br><br>
+
+For more information on getting started, check out the sample programs in the src/examples folder.
+<br><br>
+
+<hr><br>
+<h2>System Limitations</h2>
+<br>
+Maximum size of a database file is the size of LONG - 2,147,483,647 bytes<br>
+Total number of fields in a database - 255 <br>
+Total number of characters in all fields - 32767<br>
+Maximum number of characters in a field - 254<br>
+Total number of records in a file - 1 billion<br>
+Maximum index key length - 100 bytes<br>
+Maximum .DBT file memo block size - 32256<br>
+Maximum expression result length - 100 bytes<br>
+Maximum NDX index key length - 100 bytes<br><br>
+<hr><br><br>
+
+<p><img src=xbase.jpg><br><hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc10.htm b/docs/html/xbc10.htm
new file mode 100755
index 0000000..04f5158
--- /dev/null
+++ b/docs/html/xbc10.htm
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 10</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H2><p align="center">CDX Indices</p></H2>
+<p align="center">Chapter Updated 11/28/22</p><hr>
+
+<h3>Pending CDX index module development.</h3>
+
+<hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc11.htm b/docs/html/xbc11.htm
new file mode 100755
index 0000000..4230f3f
--- /dev/null
+++ b/docs/html/xbc11.htm
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 10</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H2><p align="center">CDX Indices</p></H2>
+<p align="center">Chapter Updated 11/28/22</p><hr>
+
+<h3>Pending IDX index module development.</h3>
+
+<hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc12.htm b/docs/html/xbc12.htm
new file mode 100755
index 0000000..f9fe114
--- /dev/null
+++ b/docs/html/xbc12.htm
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 8</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H1><p align="center">Record and File Locking</p></H1>
+<p align="center">Chapter Updated 11/29/22</p><hr>
+
+<h3>Locking Overview</h3>
+
+Xbase64 supports multi-user processing through file and record locks.
+Record locking restricts multiple cooperating programs from simultaneously
+accessing the same data and corrupting it. Without record and file locking
+in a multi-user environment, simultaneous access to the data and index files
+can cause the files to become inaccurate and unusable.<br><br>
+
+Automatic record locking is on by default in the Xbase64 library. To disable it,
+use method xbXBase::DisableDefaultAutoLock() and to enable it, use method xbXBase::EnableDefaultAutoLock().
+
+Locking can also be enabled / disabled at the table level with with xbDbf::SetAutoLock().
+
+
+<br><br>
+The current Xbase64 record locking logic is modeled after DBase (tm) V7 locking.
+<br><br>
+
+The locking methods return either XB_LOCK_FAILED or XB_NO_ERROR. If they return
+XB_LOCK_FAILED the actual reason can be found in the global variable
+<em>errno</em> or function <em>perror()</em> can be executed to view the
+results.
+<br><br>
+
+The errno field may contain one of the following values if the lock was not
+successful.<br><br>
+<TABLE BORDER>
+<TR VALIGN="BASELINE">
+<TR><TH ALIGN="LEFT">Error Code<TD>Description
+<TR><TH ALIGN="LEFT">EBADF<TD>Invalid file descriptor
+<TR><TH ALIGN="LEFT">EINVAL<TD>Invalid lock information or file does not support locks
+<TR><TH ALIGN="LEFT">EACCESS<BR>EAGAIN<TD>Lock can not be set because it is blocked by an existing lock on the file.
+<TR><TH ALIGN="LEFT">ENOLCK<TD>The system is out of lock resources, too many file locks in place.
+<TR><TH ALIGN="LEFT">EDEADLK<TD>Deadlock condition
+<TR><TH ALIGN="LEFT">EINTR<TD>Process was interrupted by a signal while it was waiting
+</TABLE>
+<br><br>
+
+<h3>Linux/Windows File Locking Compatibility Issue</h3>
+
+There is a compatibility locking issue to be aware of. Windows environments allow for the exclusive
+opening of file handles and Linux/Unix platforms do not. If you are writing an application that will be
+using a tool like Dbase on a Windows machine, accessing a file on a Linux/Samba configure machine,
+be aware that the file could be opened in exclusive mode by DBase on the Windows system, and the same file could
+be simultaneously opened with a program on the Unix box. That could cause some issues.
+
+<br><br>
+In Unix, a program can not lock a file so another process can not access it.<br>
+In Windows, a program can lock a file so another process can not access it.<br>
+DBase(tm) supports routines to open files exclusively, preventing other users from opening a file.<br>
+
+<br><h3>Samba settings</h3>
+
+If you will be using Samba on Linux/Unix and sharing files between Linux and Windows machines,
+you will need to disable oplocks. In the smb.conf file, set:<br>
+<h4>oplocks = no</h4>
+
+
+
+
+<br>
+<hr><br>
+<p><img src="xbase.jpg"><br><hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc13.htm b/docs/html/xbc13.htm
new file mode 100755
index 0000000..9f51a85
--- /dev/null
+++ b/docs/html/xbc13.htm
@@ -0,0 +1,46 @@
+
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 13</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H2><p align="center">Logfiles</p></H2>
+<p align="center">Chapter Updated 11/29/22</p><hr>
+
+
+<h3>Logging</h3>
+
+The Xbase library includes a logging module that can be turned on or off for auditing purposes.
+
+See example code below for how to use the logging routines.
+
+<hr>
+
+#include "xbase.h"<br>
+using namespace xb;<br>
+<br>
+int main( int argCnt, char **av ){<br>
+
+ #ifdef XB_LOGGING_SUPPORT<br>
+ xbString sMsg;<br>
+ xbString sLogFileName;<br>
+ xbXBase x;<br>
+ sLogFileName = "/home/xbase/logfiles/LogFile.txt";<br>
+ x.SetLogFileName( sLogFileName );<br>
+ x.EnableMsgLogging(); <br><br>
+
+
+ std::cout << "Logfile is [" << x.GetLogFqFileName().Str() << "]" << std::endl;<br>
+ sMsg.Sprintf( "Program [%s] initializing...", av[0] );<br>
+ x.WriteLogMessage( sMsg );<br>
+ std::cout << "Logging status is " << x.GetLogStatus() << std::endl;<br>
+ sMsg = "A logfile message";<br>
+ x.WriteLogMessage( sMsg );<br>
+ x.DisableMsgLogging();<br>
+ #endif /* XB_LOGGING_SUPPORT */<br>
+ return 0;<br>
+}<br>
+
+<hr>
+<p><img src="xbase.jpg"><hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc14.htm b/docs/html/xbc14.htm
new file mode 100755
index 0000000..fdcf949
--- /dev/null
+++ b/docs/html/xbc14.htm
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 14</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H2><p align="center">CDX Indices</p></H2>
+<p align="center">Chapter Updated 11/30/22</p><hr>
+
+<h3>Pending SQL module development.</h3>
+
+<hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc15.htm b/docs/html/xbc15.htm
new file mode 100755
index 0000000..89bab09
--- /dev/null
+++ b/docs/html/xbc15.htm
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 15</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H1><p align=center>Sample Programs</p></H1>
+<p align=center>Page Updated 11/30/22</p><hr><br><br>
+Sample Xbase DBMS programs include in the library.<br><br>
+<CENTER>
+<TABLE BORDER>
+<CAPTION ALIGN=TOP><H3>XBase Sample Programs</H3></CAPTION>
+<TR ALIGN=BASELINE>
+<TR><TH ALIGN=LEFT>Program<TD>Program Description
+<TR><TH ALIGN=LEFT>xb_cfg_check<TD>This program prints the compile settings and options in use
+<TR><TH ALIGN=LEFT>xb_copydbf<TD>This program copies a DBF file structure
+<TR><TH ALIGN=LEFT>xb_dbfutil1<TD>Menu program for executing Xbase functions
+<TR><TH ALIGN=LEFT>xb_deletall<TD>This program marks all records in a DBF file for deletion
+<TR><TH ALIGN=LEFT>xb_dumpdbt<TD>Debug memo files
+<TR><TH ALIGN=LEFT>xb_dumphdr<TD>This program opens an Xbase file and prints its header
+<TR><TH ALIGN=LEFT>xb_dumprecs<TD>This program dumps records for an X-Base file
+<TR><TH ALIGN=LEFT>xb_ex_string<TD>Example string program
+<TR><TH ALIGN=LEFT>xb_ex_v3_create_dbf<TD>Example program to create V3 DBF file
+<TR><TH ALIGN=LEFT>xb_ex_v3_upd_dbf<TD>Example program to update V3 DBF file
+<TR><TH ALIGN=LEFT>xb_ex_v4_create_dbf<TD>Example Program to create V4 DBF file
+<TR><TH ALIGN=LEFT>xb_ex_v4_upd_dbf<TD>Example program to update V4 DBF file
+<TR><TH ALIGN=LEFT>xb_execsql<TD>This program executes SQL statements
+<TR><TH ALIGN=LEFT>xb_pack<TD>This program packs (removes deleted records) from a DBF database file
+<TR><TH ALIGN=LEFT>xb_undelall<TD>This program undeletes all deleted records in a dbf file
+<TR><TH ALIGN=LEFT>xb_zap<TD>This program removes all records from a DBF file
+</TABLE></CENTER>
+<br><br>
+<hr>
+<p><img src="xbase.jpg"><br><hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc2.htm b/docs/html/xbc2.htm
new file mode 100755
index 0000000..72a6009
--- /dev/null
+++ b/docs/html/xbc2.htm
@@ -0,0 +1,267 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 2</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H2><p align="center">Database Overview</p></H2>
+<p align="center">Chapter Updated 11/21/22</p><hr>
+
+The objective of this chapter is to provide information regarding how
+the database files are utilized and document the various record structures.
+With the exception of the brief section on the record buffer, the
+information presented in this chapter is not required to use the
+Xbase library. It is mainly information describing internal file
+structures utilized by the Xbase routines.<br><br>
+
+Xbase DBF files are comprised of a variable length header record which stores
+information about the file and describes
+the fixed length record format, followed by a series of fixed length
+data records.
+<br><br>
+
+Each fixed length data record is preceded by a one byte indicator
+which identifiies if the record has been deleted. If the record is
+not deleted, the indicator is a space (0x20). If deleted, the
+indicator contains an asterisk (0x2A). Data fields are stored in records
+without field separators or record terminators.<br><br>
+
+In earlier releases of dBASE, there is an ASCII NULL character
+between the $0D end of header indicator and the start of the data.
+This NULL was removed starting with dBASE III Plus, making a Plus
+header one byte shorter than an identically structured III file.
+The methods documented in the Xbase software and documentation follow
+the more recent version where the NULL character is not included.
+<br><br>
+
+Each database file is comprised of zero, one or many records. A record is
+comprised of fields. Only one record is accessed at a time.<br><br>
+
+Zero, one or many database files can be open simultaneously.<br><br>
+
+<hr>
+
+<h3>The Record Buffer</h3>
+
+When using the Xbase routines, each open data file has a record buffer
+which is manipulated by calling the database, index and field routines.
+<br><br>
+
+If <i>AutoCommit</i> is turned on (Default), updates are committed from
+the record buffer to the database when a write, or append is performed.
+The library automatically writes updates to the database if the buffer has
+been updated and the record is repositioned or the database is closed.
+<br><br>
+
+If <i>AutoCommit</i> is turned off, updates will need to be explicity
+committed to the database file with one of <i>dbf->Put(), dbf->Append()
+or dbf->Commit()</i> command depending on context..
+Updates can be cancelled with the <i>Abort()</i> command.
+<br><br>
+The record buffer is not used for handling the actual data portion of
+memo fields. When working with memo fields, the application program must
+allocate enough buffer space for reading and writing memo fields or use
+the xbString class for handling memo data.<br><br>
+
+Internal to the library, there is an additional record buffer which
+stores the original value of the data record before any changes are made.
+This is used by the index routines for finding and deleting original key
+values from any open indices before adding the new keys. If the key values
+are not changed, no index updates occur. Additionally, calling the Abort()
+method will back out any updates to the record buffer.
+
+
+<br><br>
+
+<hr>
+<br>
+<h3>Xbase Database File Header - DBF Version III and Version IV</h3>
+
+The Xbase file header, located at the beginning of the database, describes
+the .DBF database. Knowledge of this structure is not necessary to
+effectively utilize the Xbase64 libraries.<br><br><br>
+
+<TABLE BORDER>
+<TR valign="BASELINE">
+<TR><TH ALIGN="LEFT">Position<TD>Length<TD>Description
+<TR><TH ALIGN="LEFT">0<TD>1 byte<TD>file version number<br>
+ (03H without a .DBT file)<br>
+ (83H with a .DBT file)
+<TR><TH ALIGN="LEFT">1-3<TD>3 bytes<TD>date of last update<br>
+ (YY MM DD) in binary format
+<TR><TH ALIGN="LEFT">4-7<TD>32 bit number<TD>number of records in data file
+<TR><TH ALIGN="LEFT">8-9<TD>16 bit number<TD>length of header structure
+<TR><TH ALIGN="LEFT">10-11<TD>16 bit number<TD>length of the record
+<TR><TH ALIGN="LEFT">12-31<TD>20 bytes<TD>reserved
+<TR><TH ALIGN="LEFT">32-n<TD>32 bytes each<TD>field descriptor record (see below)
+<TR><TH ALIGN="LEFT">n+1<TD>1 byte<TD>0DH as the field terminator
+</TABLE>
+<BR><BR>
+
+<hr>
+<br>
+<h3>Xbase Field Descriptor Record</h3>
+The Xbase field descriptor record stores information about each field in the
+database. Each database has from 1 to 1024 fields.
+Knowledge of this structure is not necessary to
+effectively utilize the Xbase libraries.<br><br><br>
+
+<TABLE BORDER>
+<TR VALIGN="BASELIGN">
+<TR><TH ALIGN="LEFT">Position<TD>Length<TD>Description
+<TR><TH ALIGN="LEFT">0-10<TD>11 bytes<TD>field name in ASCII zero-filled
+<TR><TH ALIGN="LEFT">11<TD>1 byte<TD>field type in ASCII (C N L D or M)
+<TR><TH ALIGN="LEFT">12-15<TD>32 bit number<TD>field data address
+<TR><TH ALIGN="LEFT">16<TD>1 byte<TD>field length in binary
+<TR><TH ALIGN="LEFT">17<TD>1 byte<TD>field decimal count in binary
+<TR><TH ALIGN="LEFT">18-31<TD>14 bytes<TD>reserved bytes (version 1.00)
+</TABLE>
+<BR><BR>
+<hr>
+<br>
+<h3>Field Data Format</h3>
+Data are stored in ASCII format in the database as follows:<br><br>
+<TABLE BORDER>
+<TR VALIGN="BASELIGN">
+<TR><TH ALIGN="LEFT">DATA TYPE<TD>DATA RECORD STORAGE
+<TR><TH ALIGN="LEFT">Character<TD>ASCII characters, left justified, right blank filled
+<TR><TH ALIGN="LEFT">Date<TD>(8 digits in YYYYMMDD format, such as<BR>
+ 19601007 for October 7, 1960)
+<TR><TH ALIGN="LEFT">Logical<TD>? Y y N n T t F f (? when not initialized)
+<TR><TH ALIGN="LEFT">Memo<TD>10 digits representing a .DBT block number
+<TR><TH ALIGN="LEFT">Numeric<TD>. 0 1 2 3 4 5 6 7 8 9 + -, right justified, left blank filled
+<TR><TH ALIGN="LEFT">Float (Version IV only)<TD>. 0 1 2 3 4 5 6 7 8 9 + -, right justified, left blank filled
+</TABLE>
+<BR><BR>
+
+<hr>
+<h3>Memo Fields</h3>
+
+Memo fields store variable length data elements in a seperate .DBT file.
+The main .DBF file maintains a ten byte field which is used by the Xbase
+routines for determining the location of the data in the .DBT file.
+<br><br>
+
+Xbase DBMS supports both dBASE III+ and dBASE IV version memo files.
+The version IV files are somewhat more efficient in that they reuse
+unused memo space when data are deleted or freed from use. With version
+III files, all new updates are appended to the end of the file and the
+unused space is not reclaimed until the datafiles are packed.
+<br><br>
+
+Memo fields can be used for storing a variety of date type. However,
+type 3 files are limited to storing textual data because most internal
+memo field processing in a type 3 file relies on two contiguous 0x1a
+charaters. <br><br>
+
+Type 4 memo fields can be used for storing BLOB (binary large object)
+data reliably, as the internal file structure does not rely on any
+special characters embedded in the data.<br><br>
+
+A special note on storing string data in a memo field. For those users
+that are new to C/C++ programming, string fields typically end with
+a null (0x00) terminator character. As a general rule of thumb when using
+the library, add one to the length of any string when
+specifying the length of the data. This stores the null terminating byte
+with the data. For example, when storing string "This is a string"
+specified size should be 17, not 16.
+
+
+<h4>Technical memo file information</h4>
+
+The following info on memo fields is for the curious.
+It is not required
+reading if you don't need to know the internals.<br><br>
+
+<li>Memo files are made up of one or more blocks
+<li>For version III files, the block size is 512
+<li>For version IV files, the block size is a multiple of 512
+<li>The minimum amout of space necessary to store one memo field is
+one block or 512 bytes.
+<li>The default block size can be adjusted by manipulating the
+XB_DBT_BLOCK_SIZE macro in the options.h file.
+
+
+<li>The main .DBF file maintains a ten byte numeric field which is blank if
+no memo data exists for a given field. Otherwise it contains a number, which
+when multiplied by the block size, points to the offset in the file of the head
+block in the file/
+<br><br>
+
+For version 3 memo field files, there are two fields in the head block of
+the file, <em>NextBlockNo</em> and <em>Version</em>. Depending on the
+Xbase software, some vendors products update these two fields, some do not.
+The Xbase library keeps the fields updated, but does not rely on them to
+be valued with correct data. This helps to support maximum compatibility
+amoungst all Xbase tools available.<br><br>
+
+For version 4 memo field files,
+the first block in the .DBT file is a header block which is comprised of
+8 bytes of data which maintain the file's block size and the next free
+block available in the file. Blocks two through n contain the actual
+memo data. A chain of empty blocks is maintained within the file for
+potential future use. When an add or update routine executes, it first
+attempts to find a spot in a set of blocks which were earlier allocated,
+but not currently in use for the data. If no free spot is found, data are
+appended to the end of the file.
+
+The free block chain is sorted in block number order. When blocks of
+data are freed and added to the free block chain, the routines will attempt
+to concatonate free block chains togethor where possible. When a delete
+occurs, or an update which requires less space occurs, the new free space
+is added to the free block chain.
+
+<br><br>
+
+<h3>Various Memo File Block Types</h3>
+
+<TABLE BORDER>
+<TR VALIGN="BASELIGN">
+<TR><TH ALIGN="LEFT">Valid Block Types
+<TR><TH ALIGN="LEFT">Head Block
+<TR><TH ALIGN="LEFT">Only data block for memo field
+<TR><TH ALIGN="LEFT">First of several contiguous data block set
+<TR><TH ALIGN="LEFT">2-n of contiguous data block set
+<TR><TH ALIGN="LEFT">Only data block in free chain (version IV only)
+<TR><TH ALIGN="LEFT">First of several contiguous free block set (version IV only)
+<TR><TH ALIGN="LEFT">2-n of contiguous free block set (type 4 only)
+</TABLE>
+<BR><BR>
+
+<h3>Head Block Structure</h3>
+<TABLE BORDER>
+<TR VALIGN="BASELIGN">
+<TR><TH ALIGN="LEFT">1-4<TD>LONG<TD>Next Block ID
+<TR><TH ALIGN="LEFT">5-8<TD>LONG<TD>Not used all 0x00's
+<TR><TH ALIGN="LEFT">9-16<TD>CHAR(8)<TD>Filename (Version IV Only)
+<TR><TH ALIGN="LEFT">17<TD>CHAR<TD>Version (0x03 = Version III, 0x00 = Version IV)
+<TR><TH ALIGN="LEFT">18-20<TD>CHAR(3)<TD>Not used all 0x00's
+<TR><TH ALIGN="LEFT">21-22<TD>SHORT<TD>Block Size (Version IV only )
+<TR><TH ALIGN="LEFT">23-Remainder of block<TD>CHAR<TD>Not used
+</TABLE>
+<BR><BR>
+
+
+<h3>Version IV Head Data Block Structure</h3>
+<TABLE BORDER>
+<TR VALIGN="BASELIGN">
+<TR><TH ALIGN="LEFT">xbShort<TD>0-1<TD>-1
+<TR><TH ALIGN="LEFT">xbShort<TD>2-3<TD>Starting position of data (always 8 ?)
+<TR><TH ALIGN="LEFT">xbLong<TD>4-7<TD>Length of data includes first 8 bytes
+<TR><TH ALIGN="LEFT">char (9) - Blocksize<TD>8-15<TD>Data
+</TABLE>
+<BR><BR>
+
+<h3>Version IV Head Free Block Structure</h3>
+<TABLE BORDER>
+<TR VALIGN="BASELIGN">
+<TR><TH ALIGN="LEFT">xbLong<TD>0-3<TD>Next free block in the free block chain
+<TR><TH ALIGN="LEFT">xbLong<TD>4-7<TD>Number of free blocks in this contiguous free
+ block set
+</table>
+<br><br>
+Version 3 and 4 memo fields are terminated with two contiguous 0x1A bytes of data.
+<br><br>
+<hr>
+<p><img src="xbase.jpg"><hr>
+</BODY>
+</HTML>
+
diff --git a/docs/html/xbc3.htm b/docs/html/xbc3.htm
new file mode 100755
index 0000000..f2f4a1d
--- /dev/null
+++ b/docs/html/xbc3.htm
@@ -0,0 +1,73 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 3</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H1><p align="center">Fields and Strings</p></H1>
+<p align="center">Chapter Updated 11/21/22</p><hr>
+
+<br><br>
+The main objective of this chapter is to provide basic information regarding
+various field types supported by the library.<br><br>
+
+Field names can be up to ten bytes in length and can contain characters, numbers
+or special characters in the name. The field methods are used to manipulate
+the data in a record of a data file. There are several types of fields.<br><br>
+
+
+<TABLE BORDER>
+<CAPTION ALIGN="TOP"><h3>Field Types</H3></CAPTION>
+<TR VALIGN="BASELINE">
+<TR><TH ALIGN="LEFT">Type<TD>Size<TD>Allowable Values<TD>Schema Value
+<TR><TH ALIGN="LEFT">Numeric<TD>0 - 17(include sign and decimal point<TD>+ - . 0 through 9<TD>XB_NUMERIC_FLD
+<TR><TH ALIGN="LEFT">Character<TD>0 - 254<TD>Anything<TD>XB_CHAR_FLD
+<TR><TH ALIGN="LEFT">Date<TD>8<TD>CCYYMMDD<TD>XB_DATE_FLD
+<TR><TH ALIGN="LEFT">Floating Point<TD>0 - 17 (includes sign and decimal point<TD>+ - . 0 through 9<TD>XB_FLOAT_FLD
+<TR><TH ALIGN="LEFT">Logical<TD>1<TD>? Y y N n T t F f (? - uninitialized)<TD>XB_LOGICAL_FLD
+<TR><TH ALIGN="LEFT">Memo<TD>Fixed length portion - 10<br>Variable length 0 - 32760
+<TD>Type III - Text<br>Type IV - Anything<TD>XB_MEMO_FLD
+</TABLE>
+
+<br><br>
+Field names, types and lengths are defined when a data file is created.
+After the file is created, the field characteristics can not be changed. To
+change field characteristics, a new database table must be defined with the new
+field requirements.<br><br>
+
+<h2>Memo Fields</h2>
+
+Memo fields are variable length data fields which are stored in two parts.
+This first part is a ten byte field which is stored
+in the fixed length record of the .DBF file. The variable data is stored in
+a seperate .DBT file in 512 byte blocks. The ten byte field in the fixed
+length portion of the record points to a .DBT block number.<br><br>
+
+There are two versions of memo data files type III and type IV. Type IV
+is more advanced in that released space can be reused and it also
+supports BLOB data. The type III file is older technology, does not
+support dynamic space reclamation and only supports string data.
+See method xbDbf::SetVersion for controlling which version type you are
+using.
+
+<br><br>
+To utilize memo fields, the application program must allocate a buffer
+which is large enough to handle the memo data.<br><br>
+
+<h2>Fields and Field Numbers</h2>
+
+The Xbase routines can access field data via using field names or field
+numbers. Field numbers are numbered 0-n where the first field in a datafile
+is field 0 going through the last field n. Accessing fields by number is
+slightly more efficient than accessing by name.<br><br>
+
+<h2>Strings</h2>
+
+Xbase64 includes support for a string class <em>xbString</em>.
+The xbString class interface was originally derived from the
+<em>Draft Standard C++ Library by P.J. Plauger</em> and modified.
+If you are familiar with other string classes, this one should be similar.
+Strings can be used to manage strings of character data.
+<br><br>
+<hr>
+<p><img src="xbase.jpg"><hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc4.htm b/docs/html/xbc4.htm
new file mode 100755
index 0000000..f494629
--- /dev/null
+++ b/docs/html/xbc4.htm
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 4</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H1><p align="center">Date Processing</p></H1>
+<p align="center">Chapter Updated 2/12/99</p><hr>
+
+The objective of this chapter is to provide information regarding
+the basic concepts of date arithmetic and supply generic
+C/C++ date methods.<br><br>
+
+<h2>Leap Years</h2>
+
+Due to the fact that it actually takes about 365 1/4 days for
+the earth to circle the sun, every fourth year and every fourth
+century have an extra day added to the end of February and the year
+is called a leap year. Leap years have 366 days, non leap years
+have 365 days. The following code segment describes how to
+determine if a given year is a leap year.
+
+A leap year is a year having 366 days, which can be evenly
+divisible by 4 and not by 100 or divisible by 400.
+
+There are also leap centuries. Leap centuries are years which
+are evenly divisible by 400.
+
+To calculate a leap year, the following code segment can be used
+
+<xmp>
+ int year;
+
+ if(( year % 4 == 0 && year % 100 != 0 ) || year % 400 = 0 )
+ LEAP_YEAR = TRUE;
+ else
+ LEAP_YEAR = FALSE
+</xmp>
+
+
+<h2>Julian Dates</h2>
+
+Around the time of Jesus Christ, a fellow with the name of Julias Ceasar
+established the Julian calendar. The Julian calendar established every
+fourth year as a leap year with 366 days and all other years having 365 days.
+The months were set up the same as they are with a Gregorian calendar, which
+is what we use today. A Julian date is defined as as the number of days from the
+first day of the year; February 1 would have a Julian day of 32.<br><br>
+
+From a programmer's perspective, Julian dates are useful for doing date
+arithmetic, determining the difference between two dates or calculating
+a future or past date.<br><br>
+
+To determine the difference between two dates, convert both dates to a
+Julian date and subtract one from the other.<br><br>
+
+To calculate a future or past date, convert the base date to a Julian date,
+add (or subtract) the number of days necessary to (from) it and convert the
+julian date back to a Gregorian date.<br><br>
+
+The Julian date routines use a base date of 01/01/0001.<br><br>
+
+<h2>Gregorian Dates</h2>
+
+In 1582, Pope Gregor XIII introduced a corrected form of the Julian calendar.
+Every 4th year still has 366 days except for century years. Century years
+were added as leap years if evenly divisible by 400. The year 2000 is a leap century.
+<br><br>
+
+The methods supplied with this software are based on gregorian dates with
+the format of CCYYMMDD for century, year, month and day.<br><br>
+
+
+<h2>Date Formats</h2>
+
+All dates are stored in the .DBF files with format CCYYMMDD.<br><br>
+All date routines work with dates formated with the same CCYYMMDD format.<br><br>
+
+<hr>
+<p><img src="xbase.jpg"><br><hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc5.htm b/docs/html/xbc5.htm
new file mode 100755
index 0000000..f798125
--- /dev/null
+++ b/docs/html/xbc5.htm
@@ -0,0 +1,205 @@
+<!DOCTYPE HTML PUBLIC>
+<html>
+<title>Xbase DBMS Chapter 5</title>
+<body bgcolor=#FFFFFF>
+<h1><p align="center">Expression Handling<br></h1>
+<p align="center">Chapter Updated 11/27/22</p><hr>
+
+<h3>Overview</h3>
+
+The main objective of this chapter is to provide information regarding the
+basic concepts of using the Xbase64 Expression module.<br><br>
+
+The Xbase64 library includes an expression parsing routine which assists
+application programmers by providing a high level data manipulation tool and
+also allows for building complex index keys.
+
+The functions included were derived from dBASE III Plus, dBASE IV and Clipper.
+<br><br>
+Expressions are primarily used for index key definitions and filter criteria, but
+can also be used for other tasks as well.
+<br><br>
+
+<h3>Internal fuctioning</h3>
+The expression module works in two phases. Firstly, method
+<em>ParseExpression</em> is called and builds an expression tree from
+all the components of the expression. The tree is made up of individual
+nodes. The expression is checked for valid field names, literals,
+operands and functions. Any field references are resolved. If fields
+are used in an expression and the database name for the field is not
+included in the name with the -> operand, the routines assume the
+associated database has been successfully opened.
+<br><br>
+Secondly, method <em>ProcessExpression</em> is called to process the
+expression tree created by ParseExpression(). The routine parses each
+node in the expression tree, executing functions, processing operands
+and manipulating data to produce the desired result.<br><br>
+
+If an expression will be processed repeatedly, it is best to pre-parse the
+tree using <em>ParseExpression</em>, then for each new call to the expression,
+execute method <em>ProcessExpression</em> which processes the tree.
+
+
+<h3>Expression Return Types</h3>
+Expressions will return a type of CHAR, NUMERIC, DATE or LOGICAL.<br><br>
+
+An expression return type can be determined with method <em>
+GetExpressionResultType</em> after parsing it.<br><br>
+
+Expressions returning a return type of CHAR are limited to a 200 byte internal
+buffer. There is also a 100 byte limit for NDX and MDX index key support. If
+the 200 byte limit is not large enough for your application, adjust field
+<em>enum { WorkBufMaxLen = 200 };</em> in file <em>exp.h</em>.
+
+<br><br>
+<table border=1>
+<tr><th>Return Type</th><th>XBase Type</th></tr>
+<tr><td>CHAR</td><td>xbString</td></tr>
+<tr><td>NUMERIC</td><td>xbDouble</td></tr>
+<tr><td>DATE</td><td>xbDate</td></tr>
+<tr><td>LOGICAL</td><td>xbBool</td></tr>
+</table>
+
+<br><br>
+Date routines return an xbDate result. In addition, the date value can be
+extracted using GetStringResult() which returns YYYYMMDD or GetDoubleResult()
+which returns a julian value.
+
+<br><br>
+<h3>Expression Functions</h3>
+Each expression function also has a corresponding C++ function. It is
+slightly more efficient to call the C++ functions directly, rather than
+execute the expression parsing routines.<br><br>
+
+To add a new function, find a function that is similar to what you need, copy
+the code and modify xbxbase.h, xbfuncs.cpp, xbexp.cpp and xb_test_expression.cpp.
+
+
+<table border=1>
+<tr><th>Function Name</th><th>Return Type</th><th>Description</th></tr>
+<tr><td>ABS</td><td>N</td><td>Calculate absolute value of numeric expression</td></tr>
+<tr><td>ALLTRIM</td><td>C</td><td>Trim leading andtrailing whitespace from a string</td></tr>
+<tr><td>ASC</td><td>N</td><td>Return ASCII code for first character in a string</td></tr>
+<tr><td>AT</td><td>N</td><td>Return starting position of a string within a string</td></tr>
+<tr><td>CDOW</td><td>C</td><td>Retun character weekday name for a date</td></tr>
+<tr><td>CHR</td><td>C</td><td>Convert numeric expression to a character</td></tr>
+<tr><td>CMONTH</td><td>C</td><td>Return month name for a date</td></tr>
+<tr><td>CTOD</td><td>D</td><td>Return date from a character date input</td></tr>
+<tr><td>DATE</td><td>D</td><td>Return system date</td></tr>
+<tr><td>DAY</td><td>N</td><td>Return the day of the month from a date</td></tr>
+<tr><td>DEL</td><td>C</td><td>Return record deletion status for a record</td></tr>
+<tr><td>DELETED</td><td>L</td><td>Return record deletion status for a record<</td></tr>
+<tr><td>DESCEND</td><td>1</td><td>Clipper DESCEND function</td></tr>
+<tr><td>DOW</td><td>N</td><td>Return number of day of week</td></tr>
+<tr><td>DTOC</td><td>C</td><td>Return character date from input date</td></tr>
+<tr><td>DTOS</td><td>C</td><td>Return character CCYYMMDD date from input date</td></tr>
+<tr><td>EXP</td><td>N</td><td>Return exponent value</td></tr>
+<tr><td>IIF</td><td>C</td><td>Immediate If</td></tr>
+<tr><td>INT</td><td>N</td><td>Convert number to integer, truncate any decimals</td></tr>
+<tr><td>ISALPHA</td><td>L</td><td>Check if string begins with alpha character</td></tr>
+<tr><td>ISLOWER</td><td>L</td><td>Check if string begins with lower case alpha character</td></tr>
+<tr><td>ISUPPER</td><td>L</td><td>Check if string begins with upper case character</td></tr>
+<tr><td>LEFT</td><td>C</td><td>Return left characters from a string</td></tr>
+<tr><td>LEN</td><td>N</td><td>Return lenght of string</td></tr>
+<tr><td>LOG</td><td>N</td><td>Calculate logarithm</td></tr>
+<tr><td>LOWER</td><td>C</td><td>Convert upper case to lower case</td></tr>
+<tr><td>LTRIM</td><td>C</td><td>Trim left side of a string</td></tr>
+<tr><td>MAX</td><td>N</td><td>Return higher of two values</td></tr>
+<tr><td>MIN</td><td>N</td><td>Return lesser of two values</td></tr>
+<tr><td>MONTH</td><td>N</td><td>Return number of month for a given date</td></tr>
+<tr><td>RECNO</td><td>N</td><td>Return current rec number for a given table</td></tr>
+<tr><td>RECCOUNT</td><td>N</td><td>Return number of records in a given table</td></tr>
+<tr><td>REPLICATE</td><td>C</td><td>Repeat character expression N times</td></tr>
+<tr><td>RIGHT</td><td>C</td><td>Return right characters from as tring</td></tr>
+<tr><td>RTRIM</td><td>C</td><td>Trim right side of string</td></tr>
+<tr><td>SPACE</td><td>C</td><td>Generate a string of N spaces</td></tr>
+<tr><td>SQRT</td><td>N</td><td>Calculate square root</td></tr>
+<tr><td>STOD</td><td>D</td><td>Convert 8 byte CCYYMMDD date to date</td></tr>
+<tr><td>STR</td><td>C</td><td>Convert number to character string</td></tr>
+<tr><td>STRZERO</td><td>C</td><td>Convert number to character string with leading zeroes</td></tr>
+<tr><td>SUBSTR</td><td>C</td><td>Extract portion oif one string from another string</td></tr>
+<tr><td>TRIM</td><td>C</td><td>Trim left and right sides of a string</td></tr>
+<tr><td>UPPER</td><td>C</td><td>Conver lower case to upper case</td></tr>
+<tr><td>VAL</td><td>N</td><td>Convert numeric characters to number</td></tr>
+<tr><td>YEAR</td><td>N</td><td>Return year for a given date</td></tr>
+</table>
+
+<br><br>
+<h3>Expression Components</h3>
+Expressions are made up of one or more tokens. A token is one of literal,
+database field, operand or function. Literals are either numeric or character.
+Character literals are enclosed in 'single' or "double" quotes. numeric
+literals are a series of one or more contiguous numerals, ".", "+" or "-'".
+<br><br>
+A field is simply a field name in the default database, or is in the form
+of database->fieldname.
+
+
+<br><br>
+<h3>Expression Literals</h3>
+
+<table border=1>
+<tr><th>Type</th><th>Example</th></tr>
+<tr><td>CHAR</td><td>"literal" or 'literal'</td></tr>
+<tr><td>NUMERIC</td><td>+99999.99</td></tr>
+<tr><td>DATE</td><td>{10/07/60} or {02/09/1989}</td></tr>
+</table>
+
+
+
+<br><br>
+<h3>Expression Operators</h3>
+<table border=1>
+<tr><th>Type</th><th>Operator</th><th>Precedence</th><th>Result</th><th>Notes</th></tr>
+<tr><td>Parens</td><td>()</td><td>12</td></tr>
+<tr><td>Numeric Operator</td><td>+ (unary)</td><td>11</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>- (unary)</td><td>11</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>--X</td><td>10</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>++X</td><td>10</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>**</td><td>9</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>^</td><td>9</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>%</td><td>8</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>*</td><td>8</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>/</td><td>8</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>+ Addition</td><td>7</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>- Subtraction</td><td>7</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>X--</td><td>6</td><td>N</td></tr>
+<tr><td>Numeric Operator</td><td>X++</td><td>6</td><td>N</td></tr>
+<tr></tr>
+<tr><td>String Operator</td><td>+</td><td>5</td><td>C</td><td>Concatonate 1</td></tr>
+<tr><td>String Operator</td><td>-</td><td>5</td><td>C</td><td>Concatonate 2</td></tr>
+<tr></tr>
+<tr><td>Relational Operator</td><td>=</td><td>4</td><td>L</td><td>N,C,D</td></tr>
+<tr><td>Relational Operator</td><td>#, <>, !=</td><td>4</td><td?L</td><td>N,C,D</td></tr>
+<tr><td>Relational Operator</td><td><</td><td>4</td><td>L</td><td>N,C,D</td></tr>
+<tr><td>Relational Operator</td><td>></td><td>4</td><td>L</td><td>N,C,D</td></tr>
+<tr><td>Relational Operator</td><td><=</td><td>4</td><td>L</td><td>N,C,D</td></tr>
+<tr><td>Relational Operator</td><td>>=</td><td>4</td><td>L</td><td>N,C,D</td></tr>
+<tr><td>Relational Operator</td><td>$</td><td>4</td><td>L</td><td>N,C,D</td></tr>
+<tr><td>Relational Operator</td><td>==</td><td></td><td></td><td>Clipper operator, not implemented yet</td></tr>
+<tr></tr>
+<tr><td>Logical Operator</td><td>NOT</td><td>3</td><td>L</td><td>Evaluated after all math and relational operators</td></tr>
+<tr><td>Logical Operator</td><td>.NOT.</td><td>3</td><td>L</td><td>Evaluated after all math and relational operators</td></tr>
+<tr><td>Logical Operator</td><td>AND</td><td>2</td><td>L</td><td>Evaluated after all math and relational operators</td></tr>
+<tr><td>Logical Operator</td><td>.AND.</td><td>2</td><td>L</td><td>Evaluated after all math and relational operators</td></tr>
+<tr><td>Logical Operator</td><td>OR</td><td>1</td><td>L</td><td>Evaluated after all math and relational operators</td></tr>
+<tr><td>Logical Operator</td><td>.OR.</td><td>1</td><td>L</td><td>Evaluated after all math and relational operators</td></tr>
+</table>
+
+<br><br>
+<h3>Examples</h3>
+<li>CUSTOMERS->LNAME + ", " + CUSTOMERS->FNAME
+<li>LNAME + ", " + FNAME
+<li>STARTDT + 90
+<li>YEAR( TODAY() )
+<li>IIF( "A" = "N", "true result", "false result" )
+<li>IIF( "A" = "N" .OR. 2 > 1 , "true result", "false result" )
+<li>IIF( .NOT. "A" = "N", "true result", "false result" )
+<li>.NOT. DELETED()
+<br><br>
+
+
+<hr>
+<p><img src="xbase.jpg"><br><hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc6.htm b/docs/html/xbc6.htm
new file mode 100755
index 0000000..a7e1746
--- /dev/null
+++ b/docs/html/xbc6.htm
@@ -0,0 +1,137 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 6</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H1><p align="center">Index Overview</p></H1>
+<p align="center">Chapter Updated 11/27/222</p><hr>
+
+The objective of this chapter is to provide information regarding
+the basic concepts of index processing for the Xbase library.<br><br>
+
+
+<h2>Overview</h2>
+
+The Xbase library is designed to support multiple index types simultaneously.
+Dbase, Clipper and Foxbase each had their own index formats and ultimately the
+goal is to provide support for all the legacy index file formats.
+
+<br><br>
+The 4.0.x rewrite includes the NDX and MDX formats. Earlier versions of the
+library included NTX and CDX formats which will be brought forward into the
+library rewrite at some point in the future.
+
+
+<h2>Tags</h2>
+
+Each index file contains one or more tags depending on the file type. Each tag is a sort order
+and has characteristics: Sort order (ASC or DESC), unique or not unique and some formats support filtering.
+Each open table (dbf file) has an "active tag" for database operations.
+
+
+<h2>Index updates</h2>
+
+The library automatically updates all tags in all open index files.
+
+
+<br><br>
+<h2>Index File Types</h2>
+
+<table border=1>
+<tr><th>File<br>Type</th><th>Source</th><th>Max Tags<br>Per File</th><th>Auto Opened</th><th>Sort Order</th><th>Unique Keys</th>
+ <th>Reclaimed Nodes</th><th>Filter Support</th><th>Status</th></tr>
+<tr>
+ <td>NDX</td><td>dBase</td>
+ <td><center>1</center></td>
+ <td><center>Optional</center></td>
+ <td>ASC only</td>
+ <td><center>Y</center></td>
+ <td><center>N</center></td>
+ <td><center>N</center></td>
+ <td><center>Available in 4.0.1</center></td>
+</tr>
+<tr>
+ <td>MDX</td><td>dBase</td>
+ <td><center>47</center></td>
+ <td><center>Yes</center></td>
+ <td><center>ASC or DESC</center></td>
+ <td><center>Y</center></td>
+ <td><center>Y</center></td>
+ <td><center>Y</center></td>
+ <td><center>Available in 4.0.1</center></td>
+</tr>
+<tr>
+ <td>NTX</td>
+ <td>Clipper</td>
+ <td><center>1</center></td>
+ <td><center>Optional</center></td>
+ <td><center>?</center></td>
+ <td><center>?</center></td>
+ <td><center>?</center></td>
+ <td><center>?</center></td>
+ <td><center>Pending upgrades</center></td>
+</tr>
+<tr>
+ <td>CDX</td>
+ <td>Fox Pro</td>
+ <td><center>?</center></td>
+ <td><center>?</center></td>
+ <td><center>?</center></td>
+ <td><center>?</center></td>
+ <td><center>?</center></td>
+ <td><center>?</center></td>
+ <td><center>Pending upgrades</center></td>
+<tr>
+<tr>
+ <td>IDX</td><td>Fox Pro</td><td></td><td></td><td></td><td></td><td></td><td></td><td>Undeveloped</td>
+<tr>
+
+</table>
+
+<br><br>
+<h2>Index/Tag Methods</h2>
+<table border=1>
+<tr><th>Method</th><th>Description</th></tr>
+
+<tr>
+ <td>xbDbf::CheckTagIntegrity</td><td>Checks a tag for missing or duplicate entries. Available if XB_DEBUG_SUPPORT is on.</td>
+</tr>
+<tr>
+ <td>xbDbf::CreateTag</td><td>Create a new tag.</td>
+</tr>
+<tr>
+ <td>xbDbf::DeleteTag</td><td>Delete existing tag.</td>
+</tr>
+<tr>
+ <td>xbDbf::Find</td><td>Find key value for the active tag.</td>
+</tr>
+<tr>
+ <td>xbDbf::GetFirsKey</td><td>Retrieve the first key for the active tag.</td>
+</tr>
+<tr>
+ <td>xbDbf::GetLastKey</td><td>Retrieve the last key for the active tag.</td>
+</tr>
+<tr>
+ <td>xbDbf::GetNextKey</td><td>Retrieve the next key for the active tag.</td>
+</tr>
+<tr>
+ <td>xbDbf::GetPrevKey</td><td>Retrieve the previous key for the active tag.</td>
+</tr>
+<tr>
+ <td>xbDbf::GetCurTag</td><td>Retrieve the tag name key for the active tag.</td>
+</tr>
+<tr>
+ <td>xbDbf::OpenIndex</td><td>Open an index file. Only used for index files that aren't automatically opened.</td>
+</tr>
+<tr>
+ <td>xbDbf::Reindex</td><td>Rebuild a tag. Available if XB_DEBUG_SUPPORT is on.</td>
+</tr>
+<tr>
+ <td>xbDbf::SetCurTag</td><td>Set current tag.</td>
+</tr>
+</table>
+
+<br><br>
+<hr>
+<p><img src="xbase.jpg"><br><hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc7.htm b/docs/html/xbc7.htm
new file mode 100755
index 0000000..20a60de
--- /dev/null
+++ b/docs/html/xbc7.htm
@@ -0,0 +1,153 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 7</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H2><p align="center">NDX Indices</p></H2>
+<p align="center">Chapter Updated 11/27/22</p><hr>
+
+The objective of this chapter is to provide information regarding the
+basic concepts of how .NDX index files work in the Xbase environment.<br><br>
+
+The information in this chapter has been gathered by searching the internet
+and by examining the structure of known good NDX indexes.<br><br>
+
+<h4>NDX Index File Characteristics</h4>
+
+<li>NDX indices maintain keys in ascending sort order only.<br><br>
+<li>NDX indices support <em>unique</em> or <em>non unique</em> keys.<br><br>
+
+<em>Unique</em> keys must be unique if the UniqueKeyOption is not set to XB_EMULATE_DBASE.
+If the UniqueKeyOption is set to XB_EMULATE_DBASE, then the database update routines will
+add a record to the table, but not add a corresponding duplicate key to the index tag.
+The UniqueKeyOption is off (don't allow duplicates) by default.
+<br><br>
+
+<em>Non-unique</em> Keys are not required to be unique, duplicate
+keys are allowed if the index is created with the XB_NOT_UNIQUE
+setting. Duplicate keys are stored in record number order.<br><br>
+
+<li>NDX indexes are automatically updated by the Xbase library after the
+indices are opened.<br><br>
+
+<li>Character keys are left justified and padded on the right with spaces.<br><br>
+
+<li>Numeric keys are stored as eight byte double values.<br><br>
+
+<h4>NDX File Internals</h4>
+
+NDX files are comprised of two or more 512 byte blocks or nodes of
+information. There are three types of nodes: Head Nodes, Interior
+Nodes and Leaf Nodes.<br><br>
+
+<li>The <em>Head Node</em> is the first node in the file starting at
+position zero (0) and contains information about the NDX file. There
+is only one Head Node in each index and it always starts at the
+beginning of the file.<br><br>
+
+
+<TABLE BORDER>
+<CAPTION ALIGN="TOP"><h3>NDX Header Node</H3></CAPTION>
+<TR VALIGN="BASELINE">
+<TR><TH ALIGN="LEFT">Type<TD>Size<TD>Field Name<TD>Description
+<TR><TH ALIGN="LEFT">xbLong<TD>4<TD>StartNode<TD>This identifies the root node of
+ the index. The Header node is node 0.
+<TR><TH ALIGN="LEFT">xbLong<TD>4<TD>Total Nodes<TD>This is the count of the total
+ nodes in the index. The count includes the header node.
+<TR><TH ALIGN="LEFT">xbLong<TD>4<TD>NoOfKeys<TD>Total number of keys in the index +1
+<TR><TH ALIGN="LEFT">xbUShort<TD>2<TD>KeyLen<TD>The index key length
+<TR><TH ALIGN="LEFT">xbUShort<TD>2<TD>KeysPerNode<TD>The maximum number of keys per node
+<TR><TH ALIGN="LEFT">xbUShort<TD>2<TD>KeyType<TD>Type of key<br>
+00 - Character<br>01 - Numeric
+<TR><TH ALIGN="LEFT">xbLong<TD>4<TD>Keysize<TD>Key record size + 8
+<TR><TH ALIGN="LEFT">char<TD>1<TD>Unknown<TD>Reserved
+<TR><TH ALIGN="LEFT">char<TD>1<TD>Unique<TD>Unique indicator<br>
+00 - Not Unique - XB_NON_UNIQUE<br>01 - Unique - XB_UNIQUE
+<TR><TH ALIGN="LEFT">char<TD>488<TD>KeyExpression<TD>Key expression string
+<TR><TH ALIGN="LEFT"><TD>512<TD><TD>Total bytes in node
+</TABLE>
+<br><br>
+The following structure is used by the Xbase NDX routines:
+<xmp>
+ struct NdxHeadNode{
+ xbLong StartNode; /* header node is node 0 */
+ xbLong TotalNodes; /* includes header node */
+ xbLong NoOfKeys; /* actual count + 1 */
+ xbUShort KeyLen; /* length of key data */
+ xbUShort KeysPerNode; /* max number of keys per node */
+ xbUShort KeyType; /* 00 = Char, 01 = Numeric */
+ xbLong KeySize; /* KeyLen + 8 */
+ char Reserved1; /* Not sure about this one */
+ char Unique; /* 00 = not unique, 01 = unique*/
+ char KeyExpression[488]; /* key definition */
+ }
+</xmp>
+<br><br>
+
+<h4>Interior and Leaf Nodes</h4>
+
+Interior Nodes and Leaf Nodes share the same structure in an NDX file.
+The difference between the two types is that interior nodes point to
+other interior nodes or leaf nodes and leaf nodes point to records in
+a DBF file. Interior nodes are optional nodes in an NDX file,
+however if there are more than a few keys in the index there will
+certainly be one or more interior nodes in the file. There will
+always be at least one leaf node in the file. Leaf nodes contain DBF
+record numbers which point to the location of the record in the
+DBF file.<br><br>
+
+Interior nodes have field LeftNodeNo valued which points to the node
+which points to the keys which are less than the key value in the KeyVal
+field. There is one more LeftNodeNo value in the node than there are keys.
+The Last LeftNodeNo points to the node which is greater than the highest
+key value in the node. Interior nodes have 0 in the value for the
+DbfRecNo field.<br><br>
+
+Leaf nodes have 0 in the LeftNodeNo field but do have a value in the
+DbfRecNo field which points to a DFB record.<br><br>
+
+
+<TABLE BORDER>
+<CAPTION ALIGN="TOP"><h3>NDX Interior Node and Leaf Node Structure</H3></CAPTION>
+<TR VALIGN="BASELINE">
+<TR><TH ALIGN="LEFT">Type<TD>Size<TD>Field Name<TD>Description
+<TR><TH ALIGN="LEFT">xbLong<TD>4<TD>NoOfKeysThisNode<TD>The number of key values in this node.
+<TR><TH ALIGN="LEFT">char<TD>508<TD>KeyRec<TD>A repeating structure of
+ pointers and keys. See the next table for the KeyRec structure.
+</TABLE>
+<br><br>
+<TABLE BORDER>
+<CAPTION ALIGN="TOP"><h3>KeyRec Structure</H3></CAPTION>
+<TR VALIGN="BASELINE">
+<TR><TH ALIGN="LEFT">Type<TD>Size<TD>Field Name<TD>Description
+<TR><TH ALIGN="LEFT">xbLong<TD>4<TD>LeftNodeNo<TD>The node number of the lower node
+ for this key. 0 in Leaf Nodes.
+<TR><TH ALIGN="LEFT">xbLong<TD>4<TD>DbfRecNo<TD>The DBF record number for this key.
+ 0 in Interior Nodes.
+<TR><TH ALIGN="LEFT">char<TD>KeyLen<TD>KeyValue<TD>The key value.
+</TABLE>
+
+<br><br>
+For those interested in knowing how the Xbase DBMS manipulates and
+navigates index files, the following discussion may be helpfull.<br><br>
+
+Xbase DBMS navigates through NDX files by using an in-memory chain
+of nodes of the current location / key in use. It starts by reading the
+Head Node of the index, which points to the first node of the file. The
+first node of the file will be a leaf node if the index is small or will
+be an interior node if the index has more than one leaf node. The first
+interior node is loaded into memory, added to the node chain and points
+to the next node to read. The node is made up of one or more keys. If
+it is a leaf node, the logic looks for a matching key on the node.
+Otherwise, if it is an interior node, the logic looks at the keys until the
+search key is greater than or equal to the key in the node and then
+traverses down the tree to the next node. It continues down the tree,
+adding the nodes to the in-memory node chain until it reaches the correct
+leaf node. If it finds a matching key in the leaf node, it returns a
+XB_FOUND condition. If it doesn't find an exact match in the leaf node, it
+returns a XB_NOT_FOUND condition and stops on the key which is greater than
+the search key given.
+
+<hr>
+<p><img src="xbase.jpg"><br><hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc8.htm b/docs/html/xbc8.htm
new file mode 100755
index 0000000..cb47657
--- /dev/null
+++ b/docs/html/xbc8.htm
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 8</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H2><p align="center">MDX Indices</p></H2>
+<p align="center">Chapter Updated 11/28/22</p><hr>
+
+The objective of this chapter is to provide information regarding the
+basic concepts of how .MDX index files work in the Xbase environment.<br><br>
+
+The information in this chapter has been gathered by searching the internet
+and by examining the structure of known good <DX indexes.<br><br>
+
+<h4>MDX Index File Characteristics</h4>
+
+<li>MDX files are the same name as the corresponding DBF file with an MDX extension.
+<li>MDX files are automatically opened by the library when the DBF file is opened.
+<li>MDX index files (aka prod indices) contain from one to 47 tags, where each tag has it's own key characteristics.
+<li>MDX indices maintain keys in either ascending or descending sort order.
+<li>MDX indices support filtered keys. For example, a filter of <b>.NOT. DELETED()</b> will keep deleted records out
+of the index tag.
+<li>MDX indices are automatically updated by the Xbase library after the
+indices are opened.
+
+<li>MDX indices support <em>unique</em> or <em>non unique</em> keys.<br><br>
+
+<em>Unique</em> keys must be unique if the UniqueKeyOption is not set to XB_EMULATE_DBASE.
+If the UniqueKeyOption is set to XB_EMULATE_DBASE, then the database update routines will
+add a record to the table, but not add a corresponding duplicate key to the index tag.
+The UniqueKeyOption is off (don't allow duplicates) by default.
+<br><br>
+
+<em>Non-unique</em> Keys are not required to be unique, duplicate
+keys are allowed if the index is created with the XB_NOT_UNIQUE
+setting. Duplicate keys are stored in record number order.<br><br>
+
+
+<li>Character keys are left justified and padded on the right with spaces.
+<li>Numeric keys are stored as twelve byte BCD values.
+<li>Date keys are stored as eight byte double julian values.
+
+<h4>MDX File Internals</h4>
+
+The following information is not needed to use the library, it is just included
+for general information.<br><br>
+
+MDX files are comprised of 512 pages where multiple pages make a block. The default
+setting is 1024 blocks, each block containing two pages.<br><br>
+
+The first four pages contain:
+<li>Bytes 0 - 543 contain general file information.
+<li>Bytes 544 - 2047 is a 47 item table containing specific tag information.
+<br><br>
+
+Pages five and beyound:
+<li>Bytes 2048 and beyond contain tag header blocks, interior nodes and leaf nodes.
+
+<br><br>
+
+<h4>Interior and Leaf Nodes</h4>
+
+Interior Nodes and Leaf Nodes share the same structure in an NDX file with
+the exception that interior nodes have a non zero number immediately
+after the rightmost key on the node.
+
+Interior nodes point to other interior nodes or leaf nodes and leaf nodes point
+to records in a DBF file. Interior nodes are optional nodes in an MDX file,
+however if there are more than a few keys in the index there will
+certainly be one or more interior nodes in the file. There will
+always be at least one leaf node per tag in the file. Leaf nodes
+contain DBF record numbers which point to the location of the record
+in the DBF file.<br><br>
+
+<br><br>
+
+<hr>
+<p><img src="xbase.jpg"><br><hr>
+</BODY>
+</HTML>
diff --git a/docs/html/xbc9.htm b/docs/html/xbc9.htm
new file mode 100755
index 0000000..297a702
--- /dev/null
+++ b/docs/html/xbc9.htm
@@ -0,0 +1,179 @@
+<!DOCTYPE HTML PUBLIC>
+<HTML>
+<TITLE>Xbase DBMS Chapter 9</TITLE>
+<BODY BGCOLOR=#FFFFFF>
+<H2><p align="center">NTX Indices</p></H2>
+<p align="center">Chapter Updated 11/28/22</p><hr>
+
+
+<h3>This chapter might be out of date. The NTX module is pending review and updates for release 4.x.x</h3>
+
+The objective of this chapter is to provide information regarding the
+basic concepts of how .NTX index files work in the Xbase environment.<br><br>
+
+The information in this chapter has been gathered by searching the internet
+and by examining the structure of known good NTX indexes.<br><br>
+
+<h4>NTX Index File Characteristics</h4>
+
+<ul><li>NTX indices maintain keys in ascending sort order only.<br><br>
+<li>NTX indices support <em>unique</em> or <em>non unique</em> keys.<br><br>
+
+<em>Unique</em> keys must be unique. The database update routines will
+fail if an attempt to add a non-unique key is performed.<br><br>
+
+<em>Non-unique</em> Keys are not required to be unique, duplicate
+keys are allowed if the index is created with the XB_NOT_UNIQUE
+setting. Duplicate keys are stored in record number order.<br><br>
+
+<li>NTX indexes are automatically updated by the Xbase library after the
+indices are opened.<br><br>
+
+<li>Character keys are left justified and padded on the right with spaces.<br><br>
+
+<li>Numeric keys are stored as eight byte double values.<br><br>
+
+The numeric key processing logic performs floating point numeric
+calculations on eight byte double values. This logic may be compute intensive
+and slow on older machines, especially the older intel processors without a
+math coprocessor chip.
+
+</ul>
+
+
+<h4>NTX File Internals</h4>
+
+NTX files are comprised of two or more 1024 byte blocks or nodes of
+information. There are three types of nodes: Head Nodes, Interior
+Nodes and Leaf Nodes.<br><br>
+
+The <em>Head Node</em> is the first node in the file starting at
+position zero (0) and contains information about the NTX file. There
+is only one Head Node in each index and it always starts at the
+beginning of the file.<br><br>
+
+
+<TABLE BORDER>
+<CAPTION ALIGN="TOP"><h3>NTX Header Node</H3></CAPTION>
+<TR VALIGN="BASELINE">
+<TR><TH ALIGN="LEFT">Type<TD>Size<TD>Field Name<TD>Description
+<TR><TH ALIGN="LEFT">xbShort<TD>2<TD>Signature Byte<TD>The Clipper signature byte. 0x003h indicates Clipper 87. 0x006h indicates Clipper 5.x
+<TR><TH ALIGN="LEFT">xbShort<TD>2<TD>Indexing Version Number<TD>Documented as the "Compiler Version" but I have observed an increasing number. Incremented whenever the index is changed.
+<TR><TH ALIGN="LEFT">xbLong<TD>4<TD>First Node Offset<TD>The offset to the first node.
+<TR><TH ALIGN="LEFT">xbLong<TD>4<TD>First Unused Page Offset<TD>The offset to the first unused node.
+<TR><TH ALIGN="LEFT">xbShort<TD>2<TD>Key Size + 8<TD>The Key Size plus 8 bytes.
+<TR><TH ALIGN="LEFT">xbShort<TD>2<TD>Key Size<TD>The size (length) of the key.
+<TR><TH ALIGN="LEFT">xbShort<TD>2<TD>Number of Decimals<TD>Number of decimal places in key.
+<TR><TH ALIGN="LEFT">xbShort<TD>2<TD>Max Items Per Node<TD>The maximum number of key per node.
+<TR><TH ALIGN="LEFT">xbShort<TD>2<TD>1/2 The Max Items Per Node<TD>Half the maximum number of key per node. Important in a B-tree system, as this is the minimum number of keys that must be on a page.
+<TR><TH ALIGN="LEFT">char<TD>256<TD>KeyExpression<TD>Key expression string
+<TR><TH ALIGN="LEFT">char<TD>1<TD>Unique<TD>Unique indicator<br>
+ 00 - Not Unique - XB_NON_UNIQUE<br>
+ 01 - Unique - XB_UNIQUE
+<TR><TH ALIGN="LEFT">char<TD>745<TD>Unused<TD>Unused
+
+
+<TR><TH ALIGN="LEFT"><TD>1024<TD><TD>Total bytes in node
+</TABLE>
+<br><br>
+The following structure is used by the Xbase NTX routines:
+<xmp>
+
+struct NtxHeadNode { /* ntx header on disk */
+ xbUShort Signature; /* Clipper 5.x or Clipper 87 */
+ xbUShort Version; /* Compiler Version */
+ /* Also turns out to be */
+ /* a last modified counter */
+ xbULong StartNode; /* Offset in file for first node */
+ xbULong UnusedOffset; /* First free node offset */
+ xbUShort KeySize; /* Size of items (KeyLen + 8) */
+ xbUShort KeyLen; /* Size of the Key */
+ xbUShort DecimalCount; /* Number of decimal positions */
+ xbUShort KeysPerNode; /* Max number of keys per node */
+ xbUShort HalfKeysPerNode; /* Min number of keys per node */
+ char KeyExpression[256]; /* Null terminated key expression */
+ unsigned Unique; /* Unique Flag */
+ char NotUsed[745];
+};
+
+</xmp>
+
+<br><br>
+
+<h4>Interior and Leaf Nodes</h4>
+
+NTX files use a B-tree system to store keys. A B-tree is a balanced,
+on disk tree who's design minimizes disk access. Interior Nodes and
+Leaf Nodes share the same structure in an NTX file. The difference is
+that interior nodes point to other nodes. Leaf nodes point to
+nothing. Keys in both interior nodes and leaf nodes point to records
+in a DBF file.
+
+Interior nodes have field LeftNodeNo valued which points to the node
+which points to the keys which are less than the key value in the KeyVal
+field. There is one more LeftNodeNo value in the node than there are keys. The
+Last LeftNodeNo points to the node which is greater than the highest
+key value in the node. <br><br>
+
+Leaf nodes have 0 in the LeftNodeNo field.<br><br>
+
+
+<TABLE BORDER>
+<CAPTION ALIGN="TOP"><h3>NTX Interior Node and Leaf Node Structure</H3></CAPTION>
+<TR VALIGN="BASELINE">
+<TR><TH ALIGN="LEFT">Type<TD>Size<TD>Field Name<TD>Description
+<TR><TH ALIGN="LEFT">xbShort<TD>2<TD>NoOfKeysThisNode<TD>The number of key values in this node. (N)
+<TR><TH ALIGN="LEFT">Array of xbUShort<TD>2<TD>offsets[]<TD>Array of
+ <pre>HeadNode.KeysPerNode +1</pre> unsigned longs.
+ These values are the offsets (in bytes) of each key
+ in this node, from the beginning of the node.
+<TR><TH ALIGN="LEFT">char<TD>variable<TD>KeyRecs<TD>A repeating structure of
+ pointers and keys. See the next table for the KeyRec structure.
+</TABLE>
+<br><br>
+
+One primary difference between NDX files and NTX files is that NTX
+files uses an array of offsets on all interior and leaf nodes. Each
+offset is the byte count from the beginning of the node where each
+KeyRec will be found. The order of the array of offsets determines
+the order of keys on a given node. When keys are added or deleted,
+thus changing the order of the keys on a node, only the order of the
+offset array is changed. All other key data is not moved. This results
+in slightly better index performance.
+
+<BR>
+<TABLE BORDER>
+<CAPTION ALIGN="TOP"><h3>KeyRec Structure</H3></CAPTION>
+<TR VALIGN="BASELINE">
+<TR><TH ALIGN="LEFT">Type<TD>Size<TD>Field Name<TD>Description
+<TR><TH ALIGN="LEFT">xbLong<TD>4<TD>LeftNodeNo<TD>The node number (offset from beginning of file) of the lower node
+ for this key. 0 in Leaf Nodes.
+<TR><TH ALIGN="LEFT">xbLong<TD>4<TD>DbfRecNo<TD>The DBF record number for this key.
+ 0 in Interior Nodes.
+<TR><TH ALIGN="LEFT">char<TD>KeyLen<TD>KeyValue<TD>The key value.
+</TABLE>
+
+<br><br>
+For those interested in knowing how the Xbase DBMS manipulates and
+navigates index files, the following discussion may be helpfull.<br><br>
+
+Xbase DBMS navigates through NTX files by using an in-memory chain of
+nodes of the current location / key in use. It starts by reading the
+Head Node of the index, which points to the first node of the
+file. The first node of the file will be a leaf node if the index is
+small or will be an interior node if the index has more than one leaf
+node. The first interior node is loaded into memory, added to the
+node chain and points to the next node to read. The node is made up
+of one or more keys. If it is a leaf node, the logic looks for a
+matching key on the node. It continues down the tree, adding the
+nodes to the in-memory node chain until it reaches the correct
+node. If it finds a matching key in the leaf node, it returns a XB_FOUND
+condition. If it doesn't find an exact match in the leaf node, it
+returns a XB_NOT_FOUND condition and stops on the key which is greater
+than the search key given.
+
+<hr>
+<A HREF="mailto:bob@#synxis.com">
+Author: Bob Cotton - bob@synxis.com</A><br>
+</BODY>
+</HTML>