summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2023-08-14 21:07:46 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2023-08-14 21:07:46 +0200
commitc894a7cdd8686ea695602a23a511a3f1b0d047be (patch)
tree1fb4e9f4781af3221982a5831173ea14e6585306 /src/include
parentbfa452a375ea0a0a3f95304a69186936567e5263 (diff)
New upstream version 4.1.4upstream
Diffstat (limited to 'src/include')
-rwxr-xr-xsrc/include/xbase.h100
-rwxr-xr-xsrc/include/xbbcd.h93
-rwxr-xr-xsrc/include/xbblkread.h70
-rwxr-xr-xsrc/include/xbconfig.h.in128
-rwxr-xr-xsrc/include/xbcrix.cpp292
-rwxr-xr-xsrc/include/xbdate.h125
-rwxr-xr-xsrc/include/xbdbf.h568
-rwxr-xr-xsrc/include/xbexp.h216
-rwxr-xr-xsrc/include/xbexpnode.h120
-rwxr-xr-xsrc/include/xbfile.h198
-rwxr-xr-xsrc/include/xbfilter.h78
-rwxr-xr-xsrc/include/xbindex.h613
-rwxr-xr-xsrc/include/xbindex.h.nope605
-rwxr-xr-xsrc/include/xblnklst.h257
-rwxr-xr-xsrc/include/xblnklstord.h367
-rwxr-xr-xsrc/include/xblnknod.h94
-rwxr-xr-xsrc/include/xblog.h67
-rwxr-xr-xsrc/include/xbmemo.h224
-rwxr-xr-xsrc/include/xbretcod.h98
-rwxr-xr-xsrc/include/xbsql.h161
-rwxr-xr-xsrc/include/xbssv.h194
-rwxr-xr-xsrc/include/xbstring.h188
-rwxr-xr-xsrc/include/xbtag.h74
-rwxr-xr-xsrc/include/xbtblmgr.h63
-rwxr-xr-xsrc/include/xbtypes.h55
-rwxr-xr-xsrc/include/xbuda.h52
-rwxr-xr-xsrc/include/xbxbase.h235
27 files changed, 5335 insertions, 0 deletions
diff --git a/src/include/xbase.h b/src/include/xbase.h
new file mode 100755
index 0000000..4ab8892
--- /dev/null
+++ b/src/include/xbase.h
@@ -0,0 +1,100 @@
+/* xbase.h
+
+
+Xbase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022,2023 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+#include <xbconfig.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+#include <math.h>
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+// #ifdef STDC_HEADERS
+#ifdef HAVE_STDARGS_H
+#include <stdargs.h>
+#endif
+
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+
+#ifdef HAVE_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_VARARGS_H
+#ifndef HAVE_STDARG_H
+#include <varargs.h>
+#endif
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#include <io.h>
+#endif
+
+#include <iomanip>
+
+#include <xbretcod.h>
+#include <xbtypes.h>
+#include <xbstring.h>
+#include <xbssv.h>
+#include <xbdate.h>
+#include <xbtblmgr.h>
+#include <xbxbase.h>
+#include <xblnknod.h>
+#include <xblnklst.h>
+#include <xblnklstord.h>
+#include <xbfile.h>
+#include <xblog.h>
+#include <xbmemo.h>
+#include <xbbcd.h>
+#include <xbuda.h>
+#include <xbexpnode.h>
+#include <xbexp.h>
+
+#include <xbtag.h>
+#include <xbblkread.h>
+#include <xbdbf.h> /* dbf base class */
+#include <xbindex.h> /* index base class */
+#include <xbfilter.h>
+#include <xbsql.h>
diff --git a/src/include/xbbcd.h b/src/include/xbbcd.h
new file mode 100755
index 0000000..8c931d3
--- /dev/null
+++ b/src/include/xbbcd.h
@@ -0,0 +1,93 @@
+/* xbbcd.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014, 2018, 2019, 2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+#ifndef __XB_BCD_H__
+#define __XB_BCD_H__
+#ifdef XB_INDEX_SUPPORT
+
+///@cond DOXYOFF
+
+namespace xb{
+
+// structure for bcd value
+// next structure superceeded. Different compilers allocate different
+// sizes to structures with bit fields, can't count on the size
+
+/*
+struct XBDLLEXPORT xbBcdStrucOld {
+ unsigned SigDigits : 8; // significant digit count
+ unsigned Filler : 2; // always set to 1
+ unsigned EncDigits : 5; // encoded digit count
+ unsigned Sign : 1; // +/- sign
+ unsigned char Data[10];
+};
+*/
+
+struct XBDLLEXPORT xbBcdStruct {
+ unsigned char cSigDigits; // significant digit count
+ unsigned char cEncDigits; // encoded digit count
+ unsigned char cData[10]; // data
+};
+
+struct XBDLLEXPORT xbByteSplit {
+ unsigned c1 : 4;
+ unsigned c2 : 4;
+};
+
+class XBDLLEXPORT xbBcd {
+ public:
+
+ xbBcd( const xbString &sIn );
+ xbBcd( xbDouble dIn );
+ xbBcd( const void *vBcd12In );
+ void Set( xbDouble dIn );
+ void Set( const void *cBcd12In );
+ void Set( const xbString &sIn );
+
+
+ void ToString( xbString &sOut );
+ void ToDouble( xbDouble &dOut );
+ void ToBcd( xbBcdStruct &bcdOut );
+ void ToChar( char *cOut );
+
+ // const unsigned char * GetBcd() const;
+ void StringToBcd( const xbString &sStringIn );
+
+ xbInt16 Compare( const xbBcd &bcdIn );
+ xbInt16 Compare( xbDouble d );
+
+ const unsigned char *GetData() const;
+ const void * GetBcd() const;
+
+
+ private:
+ void ctor();
+ unsigned char GetEncDigitsNoSign() const;
+ unsigned GetSign() const;
+ unsigned GetSigDigits() const;
+ unsigned GetActualSigDigits() const;
+
+
+// xbBcdStruc bcdOld;
+ xbBcdStruct bcd;
+};
+
+} /* namespace xb */
+
+
+///@endcond DOXYOFF
+
+#endif /* XB_INDEX_SUPPORT */
+#endif /* __XB_BCD_H__ */
diff --git a/src/include/xbblkread.h b/src/include/xbblkread.h
new file mode 100755
index 0000000..353c618
--- /dev/null
+++ b/src/include/xbblkread.h
@@ -0,0 +1,70 @@
+/* xbblkread.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+#ifndef __XB_BLKREAD_H__
+#define __XB_BLKREAD_H__
+
+namespace xb{
+#ifdef XB_BLOCKREAD_SUPPORT
+
+
+
+//! @brief xbBlockRead class.
+/*!
+The xbBlockRead class can be used to read blocks of records at one time
+rather than one record at a time for perfomance improvements when reading a DBF file sequentially.<br>
+
+*/
+
+
+class XBDLLEXPORT xbBlockRead {
+
+ public:
+ xbBlockRead( xbDbf * d );
+ ~xbBlockRead();
+
+ #ifdef XB_DEBUG_SUPPORT
+ void DumpReadBlockInternals();
+ #endif
+
+ xbInt16 Init( xbUInt32 ulBlkSize = 0 );
+
+ xbUInt32 GetBlockFirstRecNo() const;
+ xbUInt32 GetBlockRecCnt() const;
+ xbUInt32 GetBlockSize() const;
+
+ xbInt16 GetRecord( xbUInt32 ulRecNo ); // retrieve a data record from a block to RecBuf
+ xbInt16 SetBlockSize( xbUInt32 ulBlkSize );
+
+
+ private:
+
+ xbInt16 GetBlockForRecNo( xbUInt32 ulRecNo ); // retrieve block from disk for a given record number
+
+ char *pBlock; // block pointer
+ xbUInt32 ulBlkSize; // block size in bytes
+ xbUInt32 ulFirstBlkRec; // first recod number in the block
+ xbUInt32 ulRecCnt; // number of records in block
+ xbUInt32 ulMaxRecs; // max number of records block can handle
+ xbBool bEof; // EOF flag
+ xbDbf *dbf; // reference to associated dbf file
+// xbXBase *xbase; // reference to main xbXBase structure
+ time_t tFmTime; // file modify time at time of block read
+
+};
+
+#endif // XB_BLOCKREAD
+} /* namespace */
+#endif /* __XB_BLOCKREAD_H__ */
diff --git a/src/include/xbconfig.h.in b/src/include/xbconfig.h.in
new file mode 100755
index 0000000..f084038
--- /dev/null
+++ b/src/include/xbconfig.h.in
@@ -0,0 +1,128 @@
+// the configured options and settings for xbase
+
+#define xbase_VERSION_MAJOR @xbase_VERSION_MAJOR@
+#define xbase_VERSION_MINOR @xbase_VERSION_MINOR@
+#define xbase_VERSION_PATCH @xbase_VERSION_PATCH@
+
+#define PROJECT_PARENT_DIR "@PROJECT_PARENT_DIR@"
+#define PROJECT_BINARY_DIR "@PROJECT_BINARY_DIR@"
+
+#define PROJECT_SOURCE_DIR "@PROJECT_SOURCE_DIR@"
+#define PROJECT_RUNTIME_DIR "@PROJECT_RUNTIME_DIR@"
+#define PROJECT_DATA_DIR "@PROJECT_DATA_DIR@"
+#define PROJECT_LOG_DIR "@PROJECT_LOG_DIR@"
+#define PROJECT_TEMP_DIR "@PROJECT_TEMP_DIR@"
+#define PROJECT_DFLT_LOGFILE "@CMAKE_SYSTEM_NAME@_@XB_PLATFORM@.xbLog.txt"
+#define EXTRA_LIBS "@EXTRA_LIBS@"
+#define CMAKE_RUNTIME_OUTPUT_DIRECTORY "@CMAKE_RUNTIME_OUTPUT_DIRECTORY@"
+
+
+#define CMAKE_HOME_DIRECTORY "@CMAKE_HOME_DIRECTORY@"
+#define CMAKE_PROJECT_NAME "@CMAKE_PROJECT_NAME@"
+#define BUILD_SHARED_LIBS "@BUILD_SHARED_LIBS@"
+#define CMAKE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@"
+#define CMAKE_SYSTEM_PROCESSOR "@CMAKE_SYSTEM_PROCESSOR@"
+#define CMAKE_SYSTEM_VERSION "@CMAKE_SYSTEM_VERSION@"
+#define CMAKE_BUILD_TYPE "@CMAKE_BUILD_TYPE@"
+#define CMAKE_C_FLAGS "@CMAKE_C_FLAGS@"
+#define CMAKE_C_FLAGS_DEBUG "@CMAKE_C_FLAGS_DEBUG@"
+#define CMAKE_C_FLAGS_RELEASE "@CMAKE_C_FLAGS_RELEASE@"
+
+
+#define XB_PLATFORM "@XB_PLATFORM@"
+#define Mylibrary_Exports "@Mylibrary_Exports@"
+#define MYLIB_EXPORT "@MYLIB_EXPORT@"
+#define CMAKE_SIZEOF_VOID_P "@CMAKE_SIZEOF_VOID_P@"
+
+#define CMAKE_COMPILER "@CMAKE_CXX_COMPILER_ID@"
+
+// integer definitions
+#define xbInt16 @xbInt16@
+#define xbUInt16 @xbUInt16@
+#define xbInt32 @xbInt32@
+#define xbUInt32 @xbUInt32@
+#define xbInt64 @xbInt64@
+#define xbUInt64 @xbUInt64@
+
+#cmakedefine UNIX
+
+#cmakedefine CMAKE_COMPILER_IS_GNUCC
+#cmakedefine HAVE_CTYPE_H
+#cmakedefine HAVE_DIRENT_H
+#cmakedefine HAVE_DOS_H
+#cmakedefine HAVE_FCNTL_H
+#cmakedefine HAVE_INTTYPES_H
+#cmakedefine HAVE_PWD_H
+#cmakedefine HAVE_STDARG_H
+#cmakedefine HAVE_STDARGS_H
+#cmakedefine HAVE_STRING_H
+#cmakedefine HAVE_STRINGS_H
+#cmakedefine HAVE_STAT_H
+#cmakedefine HAVE_UNISTD_H
+#cmakedefine HAVE_VARARGS_H
+#cmakedefine HAVE_WINDOWS_H
+
+#cmakedefine HAVE__CLOSE_F
+#cmakedefine HAVE_CREATEPROCESSW_F
+#cmakedefine HAVE_CREATEPROCESSW_F2
+#cmakedefine HAVE_FCNTL_F
+#cmakedefine HAVE__FDOPEN_F
+#cmakedefine HAVE__FILENO_F
+#cmakedefine HAVE_FOPEN_S_F
+#cmakedefine HAVE__FSOPEN_F
+#cmakedefine HAVE_FORK_F
+#cmakedefine HAVE__FSEEKI64_F
+#cmakedefine HAVE_FSEEKO_F
+#cmakedefine HAVE_FTRUNCATE_F
+
+#cmakedefine HAVE_GETENV_S_F
+#cmakedefine HAVE__LOCALTIME64_S_F
+#cmakedefine HAVE_LOCKFILE_F
+#cmakedefine HAVE_LOCKING_F
+#cmakedefine HAVE__LOCKING_F
+#cmakedefine HAVE__OPEN_F
+#cmakedefine HAVE_SETENDOFFILE_F
+#cmakedefine HAVE_VSNPRINTF_F
+#cmakedefine HAVE__VSNPRINTF_S_F
+#cmakedefine HAVE_VSPRINTF_S_F
+
+
+#cmakedefine XB_PLATFORM_32
+#cmakedefine XB_PLATFORM_64
+#cmakedefine XB_DEBUG_SUPPORT
+#cmakedefine XB_LINKLIST_SUPPORT
+#cmakedefine XB_MEMO_SUPPORT
+#cmakedefine XB_LOGGING_SUPPORT
+#cmakedefine XB_DBF3_SUPPORT
+#cmakedefine XB_DBF4_SUPPORT
+#cmakedefine XB_LOCKING_SUPPORT
+#cmakedefine XB_FUNCTION_SUPPORT
+#cmakedefine XB_EXPRESSION_SUPPORT
+#cmakedefine XB_INDEX_SUPPORT
+#cmakedefine XB_NDX_SUPPORT
+#cmakedefine XB_MDX_SUPPORT
+#cmakedefine XB_TDX_SUPPORT
+#cmakedefine XB_SQL_SUPPORT
+#cmakedefine XB_INF_SUPPORT
+#cmakedefine XB_FILTER_SUPPORT
+#cmakedefine XB_BLOCKREAD_SUPPORT
+
+#cmakedefine XB_UTILS_SUPPORT
+#cmakedefine XB_EXAMPLES_SUPPORT
+
+#cmakedefine HAVE_LONG_LONG
+
+#if defined (WIN32)
+ #if defined ( Mylibrary_Exports )
+ #define XBDLLEXPORT __declspec(dllexport)
+ #else
+ #define XBDLLEXPORT __declspec(dllimport)
+ #endif
+#else
+ #define XBDLLEXPORT
+#endif
+
+#if defined (UNIX) && defined (XB_PLATFORM_32)
+ #define _FILE_OFFSET_BITS 64
+#endif
+
diff --git a/src/include/xbcrix.cpp b/src/include/xbcrix.cpp
new file mode 100755
index 0000000..b89baaa
--- /dev/null
+++ b/src/include/xbcrix.cpp
@@ -0,0 +1,292 @@
+/* xbcrix.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+#include "xbase.h"
+
+#ifdef XB_SQL_SUPPORT
+
+namespace xb{
+
+
+/***********************************************************************/
+#ifdef XB_INDEX_SUPPORT
+xbInt16 xbSql::SqlCreateIndex( const xbString &sCmdLine ){
+
+ // std::cout << "CREATE INDEX " << sCmdLine << std::endl;
+
+ // expected format to create an Dbase 3, NDX index:
+ // CREATE INDEX ixname.ndx ON tablename.dbf ( EXPRESSION ) [ASSOCIATE]
+
+ // expected format to create an Dbase 4, tag on an MDX index:
+ // CREATE [UNIQUE] INDEX tagname ON tablename.dbf ( EXPRESSION ) [DESC] [FILTER .NOT. DELETED()]
+
+ // The ASSOCIATE parameter is specific to Xbase64 library, it is used to associate
+ // a non production (NDX) index file to a dbf file so it will be automatically
+ // opened with the dbf file whenever the dbf file is opened by the xbase64 routines.
+
+ // The [ASSOCIATE] parameter is not used with MDX production indices
+
+ // This method first looks for ".NDX" in the file name to determine if an NDX
+ // index should be created.
+ // if .NDX is not in the filename, it looks in the uda for "IXTYPE" for either
+ // NDX or MDX to detmermine the index type to create
+ // if IXTYPE not found, create an MDX tag
+
+ // The optional DESC parameter defines an entire index key as descending. This is
+ // different than other SQL implementations where specific fields can be descending.
+
+ // The optional FILTER parameter is specific to the XBASE64 library, is it used to
+ // assign a filter to a tag in an MDX style index. Everything to the right of
+ // the keyword FILTER is considered part of the filter.
+
+ // The original DBASE indices used to '+' to create an index on more than one field
+ // ie: FIELD1+FIELD2+FIELD3
+ // SQL uses commas: ie: FIELD1, FIELD2, FIELD3
+ // The Xbase library supports either '+' or ',' when creating mutli field indices.
+
+ xbInt16 iRc = 0;
+ xbInt16 iErrorStop = 0;
+ xbString sTableName;
+ xbString sIxName;
+ xbString sIxType;
+ xbUInt32 ulPos;
+ xbString sCmd = sCmdLine;
+ xbString sNode;
+ xbBool bUnique = xbFalse;
+ xbDbf * dbf = NULL;
+ xbBool bTableLocked = xbFalse;
+
+ try{
+
+ // drop off the first node
+ ulPos = sCmd.Pos( ' ' );
+ sCmd.Ltrunc( ulPos );
+ sCmd.Ltrim();
+
+ sNode.ExtractElement( sCmd, ' ', 1, 0 );
+ sNode.ToUpperCase();
+
+ if( sNode == "UNIQUE" ){
+ //std::cout << "unique ix\n";
+ bUnique = xbTrue;
+ ulPos = sCmd.Pos( ' ' );
+ sCmd.Ltrunc( ulPos );
+ sCmd.Ltrim();
+ }
+
+ // go past the index keyword
+ ulPos = sCmd.Pos( ' ' );
+ sCmd.Ltrunc( ulPos );
+ sCmd.Ltrim();
+
+ // pull the index name off the cmd line
+ sIxName.ExtractElement( sCmd, ' ', 1, 0 );
+
+ #ifdef XB_NDX_SUPPORT
+ xbString sTemp = sIxName;
+ sTemp.ToUpperCase();
+ ulPos = sTemp.Pos( ".NDX" );
+ if(ulPos == (sTemp.Len() - 3) )
+ sIxType = "NDX";
+ #endif // XB_NDX_SUPPORT
+
+ if( sIxType == "" ){
+ if(( iRc = uda.GetTokenForKey( "IXTYPE", sIxType )) != XB_NO_ERROR ){
+ iErrorStop = 100;
+ throw iRc;
+ }
+ }
+
+ #ifdef XB_NDX_SUPPORT
+ if( sIxType == "NDX" ){
+ xbFile f( xbase );
+ f.SetFileName( sIxName );
+ if( f.FileExists()){
+
+ iErrorStop = 110;
+ iRc = XB_FILE_EXISTS;
+ throw iRc;
+ }
+ }
+ #endif // XB_NDX_SUPPORT
+
+ // skip past index name
+ ulPos = sCmd.Pos( ' ' );
+ sCmd.Ltrunc( ulPos );
+ sCmd.Ltrim();
+
+ // skip past "ON"
+ ulPos = sCmd.Pos( ' ' );
+ sCmd.Ltrunc( ulPos );
+ sCmd.Ltrim();
+
+ // get the table name
+ ulPos = sCmd.Pos( '(' );
+ sTableName.ExtractElement( sCmd, '(', 1, 0 );
+ sTableName.Trim();
+
+ xbFile fDbf( xbase );
+ fDbf.SetFileName( sTableName );
+
+ // if not open, attempt to open it
+ dbf = xbase->GetDbfPtr( fDbf.GetFqFileName());
+
+ if( !dbf ){
+ if(( iRc = xbase->OpenHighestVersion( sTableName, "", &dbf )) != XB_NO_ERROR ){
+ iErrorStop = 120;
+ throw iRc;
+ }
+ }
+
+ if( dbf == NULL ){
+ iErrorStop = 130;
+ iRc = XB_FILE_NOT_FOUND;
+ throw iRc;
+ }
+ sCmd.Ltrunc( ulPos );
+
+ //ulPos = sCmd.GetLastPos( ')' );
+ xbString sKeyExpression;
+ xbBool bDone = xbFalse;
+ xbUInt32 lPos = 1;
+ xbInt16 iParenCtr = 0;
+
+ while( !bDone && lPos < sCmd.Len()){
+ if( sCmd[lPos] == '(' ){
+ iParenCtr++;
+ sKeyExpression.Append( sCmd[lPos] );
+ } else if( sCmd[lPos] == ')' ){
+ if( iParenCtr > 0 ){
+ iParenCtr--;
+ sKeyExpression.Append( sCmd[lPos] );
+ } else {
+ bDone = xbTrue;
+ }
+ } else if( sCmd[lPos] == ',' && iParenCtr == 0 ){
+ sKeyExpression.Append( '+' );
+ } else if( sCmd[lPos] != ' ' ){
+ sKeyExpression.Append( sCmd[lPos] );
+ }
+ lPos++;
+ }
+
+ // std::cout << "Key Expression =[" << sKeyExpression << "]\n";
+ sCmd.Ltrunc( lPos );
+ sCmd.Trim();
+
+ xbBool bDesc = xbFalse;
+ // std::cout << "sCmd - looking for DESC [" << sCmd << "]\n";
+ if( sCmd.Len() > 4 ){
+ sNode = sCmd;
+ sNode.ToUpperCase();
+ ulPos = sNode.Pos( "DESC" );
+ if( ulPos > 0 ){
+ bDesc = xbTrue;
+ sCmd.Ltrunc( 4 );
+ sCmd.Trim();
+ std::cout << "Descending\n";
+ }
+ }
+
+ // std::cout << "sCmd - looking for FILTER stuff [" << sCmd << "]\n";
+ xbString sFilter;
+ if( sCmd.Len() > 6 ){
+ sNode = sCmd;
+ sNode.ToUpperCase();
+ ulPos = sNode.Pos( "FILTER" );
+ if( ulPos > 0 ){
+ sFilter = sCmd;
+ sFilter.Ltrunc( ulPos + 6 );
+ sFilter.Trim();
+ }
+ }
+ // std::cout << "sCmd - FILTER = [" << sFilter << "]\n";
+
+ #ifdef XB_LOCKING_SUPPORT
+ if(( iRc = dbf->LockTable( XB_LOCK )) != XB_NO_ERROR ){
+ iErrorStop = 140;
+ throw iRc;
+ } else {
+ bTableLocked = xbTrue;
+ }
+ #endif // XB_LOCKING_SUPPORT
+
+ xbIx *pIx;
+ void *vpTag;
+
+ if(( iRc = dbf->CreateTag( sIxType, sIxName, sKeyExpression, sFilter, bDesc, bUnique, xbFalse, &pIx, &vpTag )) != XB_NO_ERROR ){
+ iErrorStop = 150;
+ throw iRc;
+ }
+
+ #ifdef XB_NDX_SUPPORT
+ if( sIxType == "NDX"){
+ sCmd.Ltrunc( ulPos );
+ sCmd.Trim();
+ if( sCmd.Len() > 0 ){
+ sCmd.ToUpperCase();
+ if( sCmd.Pos( "ASSOCIATE" )){
+ if(( iRc = dbf->AssociateIndex( "NDX", sIxName, 0 )) != XB_NO_ERROR ){
+ iErrorStop = 160;
+ throw iRc;
+ }
+ }
+ }
+ }
+ #endif // XB_NDX_SUPPORT
+
+ if(( iRc = pIx->Reindex( &vpTag )) != XB_NO_ERROR ){
+
+// if(( iRc = dbf->Reindex( 2, &vpTag )) != XB_NO_ERROR ){
+ iErrorStop = 170;
+ throw iRc;
+ }
+
+
+ //std::cout << "Tag count = " << pIx->GetTagCount() << "\n";
+ // s = pIx->GetTagName( &vpTag );
+ // std::cout << "tagname = [" << s.Str() << "]\n";
+
+
+ #ifdef XB_LOCKING_SUPPORT
+ if( bTableLocked ){
+ if(( iRc = dbf->LockTable( XB_UNLOCK )) != XB_NO_ERROR ){
+ iErrorStop = 180;
+ throw iRc;
+ } else {
+ bTableLocked = xbFalse;
+ }
+ }
+ #endif // XB_LOCKING_SUPPORT
+
+ }
+ catch (xbInt16 iRc ){
+ xbString sMsg;
+ sMsg.Sprintf( "xbSql::SqlCreateIndex() Exception Caught. Error Stop = [%d] rc = [%d] table = [%s]", iErrorStop, iRc, sTableName.Str() );
+ xbase->WriteLogMessage( sMsg.Str() );
+ xbase->WriteLogMessage( GetErrorMessage( iRc ));
+ }
+ #ifdef XB_LOCKING_SUPPORT
+ if( bTableLocked && dbf )
+ dbf->LockTable( XB_UNLOCK );
+ #endif // XB_LOCKING_SUPPORT
+
+ return iRc;
+}
+#endif // XB_INDEX_SUPPORT
+/***********************************************************************/
+} /* namespace */
+#endif /* XB_SQL_SUPPORT */
+
diff --git a/src/include/xbdate.h b/src/include/xbdate.h
new file mode 100755
index 0000000..e914d65
--- /dev/null
+++ b/src/include/xbdate.h
@@ -0,0 +1,125 @@
+/* xbdate.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_XBDATE_H__
+#define __XB_XBDATE_H__
+
+#ifdef CMAKE_COMPILER_IS_GNUCC
+#pragma interface
+#endif
+
+
+namespace xb{
+
+#define XB_FMT_WEEK 1
+#define XB_FMT_MONTH 2
+#define XB_FMT_YEAR 3
+
+// next value is added to the date calculation to match dbase calculation
+// first valid dbase date is 01/01/0001
+#define JUL_OFFSET 1721425L
+
+
+//! @brief xbDate class.
+/*!
+This xbDate class handles two type of date values:<br>
+
+1) Gregorian dates with a format of CCYYMMDD. This is how dates are stored in dbf files.<br>
+2) Julian dates calculated as the number of days since 1901-01-01 + 1721425.<br>
+
+Leap Years: The routines in the class support both leap years (one every four
+years) and leap centuries (one every four hundred years.)
+
+A leap year is a year having 366 days, which can be evenly
+divisible by 4 and not by 100.<br>
+Leap centuries are years which are evenly divisible by 400.<br>
+
+From a programming perspective, Julian dates are useful for date
+arithmetic, determining the difference between two dates or calculating
+a future or past date.<br>
+
+To determine the difference between two dates, convert both dates to a
+Julian date and subtract one from the other.<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.
+*/
+
+class XBDLLEXPORT xbDate : public xbSsv {
+ public:
+
+ xbDate();
+ xbDate( const char * Date8 );
+ xbDate( const xbString &Date8 );
+ xbDate( xbInt32 lJulDate );
+ xbDate( xbUInt16 iInit ); // Constructor used to set the static variables, also defaults to sysdate
+ ~xbDate();
+
+ void operator=( const xbDate &d );
+ void operator+=( xbInt32 i );
+ void operator-=( xbInt32 i );
+ void operator++( xbInt32 i );
+ void operator--( xbInt32 i );
+
+ xbInt32 operator-( const xbDate & ) const;
+ const char * operator-( xbInt32 i );
+ const char * operator+( xbInt32 i );
+
+ xbBool operator==( const xbDate & ) const;
+ xbBool operator!=( const xbDate & ) const;
+ xbBool operator< ( const xbDate & ) const;
+ xbBool operator> ( const xbDate & ) const;
+ xbBool operator<=( const xbDate & ) const;
+ xbBool operator>=( const xbDate & ) const;
+
+ xbInt16 CalcRollingCenturyForYear( xbInt16 year ) const;
+ xbInt16 CenturyOf() const;
+ xbInt16 CharDayOf( xbString &sOutCharDay );
+ xbInt16 CharMonthOf( xbString &sOutCharMonth );
+ xbBool DateIsValid ( const xbString &sDate8 ) const;
+ xbInt16 DayOf( xbInt16 iFormat ) const;
+ xbInt16 CTOD( const xbString &sCtodInDate );
+ xbInt16 FormatDate( const xbString &sFmtIn, xbString &sFmtOut );
+ const char *Str() const;
+ xbBool IsLeapYear( xbInt16 iYear ) const;
+ xbBool IsLeapYear() const;
+ xbBool IsNull() const;
+ xbInt32 JulianDays() const;
+ xbInt16 JulToDate8( xbInt32 lJulDate );
+ xbInt16 LastDayOfMonth();
+ xbInt16 MonthOf() const;
+ xbInt16 Set( const xbString &Date8 );
+ xbInt16 Sysdate();
+ xbInt16 YearOf() const;
+
+#ifdef XB_DEBUG_SUPPORT
+ void Dump( const char * title );
+ void DumpDateTables();
+#endif
+
+ private:
+ void SetDateTables();
+ xbString sDate8; // CCYYMMDD date format ie; 20140718
+ // Null date is identified by sDate.Len() < 8
+
+ static int iAggregatedDaysInMonths[2][13];
+ static int iDaysInMonths[2][13];
+};
+
+} /* namespace */
+#endif /*__XB_XBDATE_H__ */
+
diff --git a/src/include/xbdbf.h b/src/include/xbdbf.h
new file mode 100755
index 0000000..fe24e72
--- /dev/null
+++ b/src/include/xbdbf.h
@@ -0,0 +1,568 @@
+/* xbdbf.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022,2023 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_XBDBF_H__
+#define __XB_XBDBF_H__
+
+//#ifdef CMAKE_COMPILER_IS_GNUCC
+//#pragma interface
+//#endif
+
+namespace xb{
+
+/*****************************/
+/* Field Types */
+
+#define XB_CHAR_FLD 'C'
+#define XB_LOGICAL_FLD 'L'
+#define XB_NUMERIC_FLD 'N'
+#define XB_DATE_FLD 'D'
+#define XB_MEMO_FLD 'M'
+#define XB_FLOAT_FLD 'F'
+
+/*****************************/
+/* File Status Codes */
+
+#define XB_CLOSED 0
+#define XB_OPEN 1
+#define XB_UPDATED 2
+
+
+/*****************************/
+/* File Access Modes */
+// #define XB_SINGLE_USER 0 // file buffering on
+// #define XB_MULTI_USER 1 // file buffering off
+
+/*****************************/
+/* File Lock Functions */
+#define XB_LOCK 0
+#define XB_UNLOCK 1
+
+#define LK_DBASE 1
+#define LK_CLIPPER 2 // future
+#define LK_FOX 3 // future
+#define LK_XBASE64 9 // future
+
+/*****************************/
+/* Record retrieve options */
+#define XB_ALL_RECS 0
+#define XB_ACTIVE_RECS 1
+#define XB_DELETED_RECS 2
+
+
+/*****************************/
+/* Other defines */
+
+#define XB_OVERLAY 1
+#define XB_DONTOVERLAY 0
+#define XB_CHAREOF '\x1A' /* end of DBF */
+#define XB_CHARHDR '\x0D' /* header terminator */
+
+
+//! @brief Schema used for defining tables with CreateTable methods.
+/*!
+ See program xb_ex_v3_create_dbf.cpp or xb_ex_v4_create_dbf.cpp
+ as examples on how to use.
+
+\code
+xbSchema MyRecord[] = {
+// FieldName, Type, Len, Dec
+ { "FIRSTNAME", XB_CHAR_FLD, 15, 0 },
+ { "LASTNAME", XB_CHAR_FLD, 20, 0 },
+ { "BIRTHDATE", XB_DATE_FLD, 8, 0 },
+ { "AMOUNT", XB_NUMERIC_FLD, 9, 2 },
+ { "RETIRED?", XB_LOGICAL_FLD, 1, 0 },
+ { "ZIPCODE", XB_NUMERIC_FLD, 5, 0 },
+ { "NUMFLD1", XB_FLOAT_FLD, 12, 2 },
+ { "NUMFLD2", XB_FLOAT_FLD, 14, 2 },
+ { "MEMO1", XB_MEMO_FLD, 10, 0 },
+ { "",0,0,0 }};
+\endcode
+*/
+struct XBDLLEXPORT xbSchema {
+ char cFieldName[11];
+ char cType;
+ xbInt16 iFieldLen; /* fields are stored as one byte on record*/
+ xbInt16 iNoOfDecs;
+};
+
+///@cond DOXYOFF
+struct XBDLLEXPORT xbSchemaRec {
+ char cFieldName[11]; /* ASCIIZ field name */
+ char cType; /* field type */
+ char *pAddress; /* pointer to field in record buffer 1 */
+ unsigned char cFieldLen; /* fields are stored as one byte on record */
+ unsigned char cNoOfDecs;
+ char *pAddress2; /* pointer to field in record buffer 2 */
+ xbInt16 iLongFieldLen; /* to handle long field lengths */
+ unsigned char cIxFlag; /* DBase IV Index field flag */
+};
+///@endcond DOXYOFF
+
+
+
+///@cond DOXYOFF
+#ifdef XB_INDEX_SUPPORT
+class XBDLLEXPORT xbIx;
+// structure for file list, each open DBF file can have one or more index files
+struct XBDLLEXPORT xbIxList {
+ xbIxList *next;
+ xbIx *ix;
+ xbString *sFmt;
+};
+#endif // XB_INDEX_SUPPORT
+///@endcond DOXYOFF
+
+
+//! @brief Base class for handling dbf files/tables.
+/*!
+The xbDbf class is used as a base class for accessing dbf files.
+In line with relational theory, a each dbf file can be considered as a table.
+The documentation uses the terms dbf and table interchangeably.<br>
+
+This module handles methods for accessing and updating dbf files.
+
+<br>
+The class is designed to support additional file layouts with a minimal amount of effort.
+If you are wanting to update the library to support a new dbf file type not currently supported
+by the library, create a derived class using xbDbf as a base class and modify methods needed
+to support the new dbf file version.<br>
+See the following for examples on how to start on this:<br>
+xbDbf3 is a derived class from xbDbf and supports the original Dbase III+ file version.<br>
+xbDbf4 is a derived class from xbDbf and supports the original Dbase IV file version.<br>
+
+*/
+
+
+class XBDLLEXPORT xbDbf : public xbFile {
+
+ public:
+ xbDbf( xbXBase *x );
+ virtual ~xbDbf();
+
+ virtual xbInt16 Abort();
+ virtual xbInt16 AppendRecord();
+ virtual xbInt16 BlankRecord();
+ virtual xbInt16 Commit();
+ virtual xbInt16 Close();
+ virtual xbInt16 CopyDbfStructure( xbDbf *dNewTable, const xbString &sTableName, const xbString &sTableAlias, xbInt16 iOverlay, xbInt16 iShareMode );
+ virtual xbInt16 CreateTable ( const xbString &sTableName, const xbString &sAlias, xbSchema *pSchema, xbInt16 iOverlay, xbInt16 iShareMode ) = 0;
+ virtual xbInt16 DeleteTable ();
+ virtual xbInt16 DeleteAll ( xbInt16 iOption );
+ virtual xbInt16 DeleteAllRecords ();
+ virtual xbInt16 DeleteRecord ();
+ virtual xbInt16 DumpHeader ( xbInt16 iOption );
+ virtual xbInt16 DumpRecord ( xbUInt32 ulRecNo, xbInt16 iOutputDest = 0, xbInt16 iOutputFmt = 0 );
+ virtual xbInt16 GetAutoCommit () const;
+ virtual xbInt16 GetAutoCommit ( xbInt16 iOption ) const;
+ virtual xbBool GetBof ();
+ virtual xbUInt32 GetCurRecNo () const;
+ virtual xbInt16 GetDbfStatus () const;
+ virtual xbBool GetEof ();
+ virtual xbInt32 GetFieldCnt () const;
+ virtual xbInt16 GetFirstRecord ();
+ virtual xbInt16 GetFirstRecord ( xbInt16 iOption );
+ virtual xbUInt16 GetHeaderLen () const;
+ virtual xbInt16 GetLastRecord ();
+ virtual xbInt16 GetLastRecord ( xbInt16 iOption );
+
+ virtual xbInt16 GetNextRecord ();
+ virtual xbInt16 GetNextRecord ( xbInt16 iOption );
+ virtual xbInt16 GetNextRecord ( xbInt16 iOption, xbUInt32 ulStartRec );
+ virtual xbInt16 GetPrevRecord ();
+ virtual xbInt16 GetPrevRecord ( xbInt16 iOption );
+ virtual xbInt16 GetRecord ( xbUInt32 ulRecNo );
+
+ // virtual xbUInt32 GetRecordCount ();
+ virtual xbInt16 GetRecordCnt ( xbUInt32 & ulRecCnt );
+
+ virtual char * GetRecordBuf ( xbInt16 iOpt = 0 ) const;
+ virtual xbUInt16 GetRecordLen () const;
+ virtual const xbString &GetTblAlias() const;
+ virtual xbInt16 GetVersion () const = 0;
+ virtual xbXBase *GetXbasePtr () const; // return xbase pointer
+
+
+ virtual xbBool MemoFieldsExist () const;
+
+ virtual xbInt16 Open ( const xbString &sTableName );
+ virtual xbInt16 Open ( const xbString &sTableName, const xbString &sAlias );
+ virtual xbInt16 Open ( const xbString &sTableName, const xbString &sAlias, xbInt16 iOpenMode, xbInt16 iShareMode ) = 0;
+ virtual xbInt16 Pack ();
+ virtual xbInt16 Pack ( xbUInt32 &ulDeletedRecCnt );
+
+
+ virtual xbInt16 PutRecord (); // Put record to current location
+ virtual xbInt16 PutRecord ( xbUInt32 ulRecNo );
+// virtual xbInt16 ReadHeader ( xbInt16 iFilePositionOption, xbInt16 iReadOption );
+ virtual xbInt16 RecordDeleted ( xbInt16 iOpt = 0 ) const;
+ virtual xbInt16 Rename ( const xbString sNewName ) = 0;
+
+ virtual xbInt16 SetAutoCommit ( xbInt16 iAutoCommit );
+
+ virtual xbInt16 UndeleteAllRecords();
+ virtual xbInt16 UndeleteRecord ();
+ virtual xbInt16 Zap ();
+
+
+ /* field methods */
+ //virtual xbInt16 GetRawField( xbInt16 iFieldNo, char *Buf, xbUInt32 BufSize, xbInt16 iRecBufSw ) const;
+ virtual xbInt16 GetField(xbInt16 iFieldNo, xbString &sFieldValue, xbInt16 iRecBufSw ) const;
+ virtual xbInt16 GetField(xbInt16 iFieldNo, xbString &sFieldValue) const;
+ virtual xbInt16 GetField(const xbString &sFieldName, xbString &sFieldValue) const;
+ virtual xbInt16 GetFieldDecimal( xbInt16 iFieldNo, xbInt16 &iFieldDecimal ) const;
+ virtual xbInt16 GetFieldDecimal( const xbString &sFieldName, xbInt16 &iFieldDecimal ) const;
+ virtual xbInt16 GetFieldLen( xbInt16 iFieldNo, xbInt16 &iFieldLen ) const;
+ virtual xbInt16 GetFieldLen( const xbString &sFieldName, xbInt16 &iFieldLen ) const;
+ virtual xbInt16 GetFieldName( xbInt16 iFieldNo, xbString &sFieldName ) const;
+
+ virtual xbInt16 GetFieldNo( const xbString &sFieldName, xbInt16 &iFieldNo ) const;
+ virtual xbInt16 GetFieldNo( const xbString &sFieldName ) const;
+
+ virtual xbInt16 GetFieldType( xbInt16 iFieldNo, char &cFieldType ) const;
+ virtual xbInt16 GetFieldType( const xbString &sFieldName, char &cFieldType ) const;
+ virtual xbInt16 PutField( const xbString &sFieldName, const xbString &sFieldData );
+ virtual xbInt16 PutField( xbInt16 iFieldNo, const xbString &sFieldData );
+
+ virtual xbInt16 PutLogicalField( xbInt16 iFieldNo, const xbString &sFieldData );
+ virtual xbInt16 PutLogicalField( const xbString &sFieldName, const xbString &sFieldData );
+ virtual xbInt16 GetLogicalField( xbInt16 iFieldNo, xbString &sFieldData ) const;
+ virtual xbInt16 GetLogicalField( const xbString &sFieldName, xbString &sFieldData) const;
+
+ virtual xbInt16 PutLogicalField( xbInt16 iFieldNo, xbBool bFieldData );
+ virtual xbInt16 PutLogicalField( const xbString &sFieldName, xbBool bFieldData );
+ virtual xbInt16 GetLogicalField( xbInt16 iFieldNo, xbBool &bFieldData ) const;
+ virtual xbInt16 GetLogicalField( xbInt16 iFieldNo, xbBool &bFieldData, xbInt16 iRecBufSw ) const;
+ virtual xbInt16 GetLogicalField( const xbString &sFieldName, xbBool &bFieldData) const;
+
+ virtual xbInt16 GetLongField( xbInt16 iFieldNo, xbInt32 &lFieldValue ) const;
+ virtual xbInt16 GetLongField( const xbString &sFieldName, xbInt32 &lFieldValue ) const;
+ virtual xbInt16 PutLongField( xbInt16 iFieldNo, xbInt32 lFieldValue );
+ virtual xbInt16 PutLongField( const xbString &sFieldName, xbInt32 lFieldValue );
+
+ virtual xbInt16 GetULongField( xbInt16 iFieldNo, xbUInt32 &lFieldValue ) const;
+ virtual xbInt16 GetULongField( const xbString &sFieldName, xbUInt32 &lFieldValue ) const;
+ virtual xbInt16 PutULongField( xbInt16 iFieldNo, xbUInt32 lFieldValue );
+ virtual xbInt16 PutULongField( const xbString &sFieldNo, xbUInt32 lFieldValue );
+
+ virtual xbInt16 GetDoubleField( xbInt16 FieldNo, xbDouble &dFieldValue ) const;
+ virtual xbInt16 GetDoubleField( xbInt16 FieldNo, xbDouble &dFieldValue, xbInt16 iRecBufSw ) const;
+ virtual xbInt16 GetDoubleField( const xbString &sFieldName, xbDouble &dFieldValue ) const;
+ virtual xbInt16 PutDoubleField( xbInt16 FieldNo, xbDouble dFieldValue );
+ virtual xbInt16 PutDoubleField( const xbString &FieldName, xbDouble dFieldValue );
+
+ virtual xbInt16 GetFloatField( xbInt16 iFieldNo, xbFloat &fFieldValue ) const;
+ virtual xbInt16 GetFloatField( const xbString &sFieldName, xbFloat &fFieldValue ) const;
+ virtual xbInt16 PutFloatField( xbInt16 iFieldNo, xbFloat fFieldValue );
+ virtual xbInt16 PutFloatField( const xbString &sFieldName, xbFloat fFieldValue );
+
+ virtual xbInt16 GetDateField( xbInt16 iFieldNo, xbDate &dt ) const;
+ virtual xbInt16 GetDateField( const xbString &sFieldName, xbDate &dt ) const;
+ virtual xbInt16 PutDateField( xbInt16 iFieldNo, const xbDate &dt );
+ virtual xbInt16 PutDateField( const xbString &sFieldName, const xbDate &dt );
+
+ virtual xbInt16 GetNullSts( xbInt16 iFieldNo, xbBool &bIsNull ) const;
+ virtual xbInt16 GetNullSts( const xbString &sFieldName, xbBool &bIsNull ) const;
+ virtual xbInt16 GetNullSts( xbInt16 iFieldNo, xbBool &bIsNull, xbInt16 iRecBufSw ) const;
+
+
+
+ #ifdef XB_MEMO_SUPPORT
+ virtual xbInt16 GetMemoFieldCnt () const;
+ virtual xbMemo *GetMemoPtr ();
+ virtual xbUInt32 GetCreateMemoBlockSize() const;
+ virtual xbInt16 GetMemoField ( xbInt16 iFldNo, xbString &sMemoData );
+ virtual xbInt16 GetMemoField ( const xbString & sFldName, xbString &sMemoData );
+ virtual xbInt16 GetMemoFieldLen ( xbInt16 iFldNo, xbUInt32 &ulMemoFieldLen );
+ virtual xbInt16 GetMemoFieldLen ( const xbString & sFldName, xbUInt32 &ulMemoFieldLen );
+ virtual xbBool MemoFieldExists ( xbInt16 iFieldNo ) const;
+ virtual xbBool MemoFieldExists ( const xbString &sFieldName ) const;
+ virtual xbInt16 SetCreateMemoBlockSize( xbUInt32 ulBlockSize ) = 0;
+ virtual xbInt16 UpdateMemoField ( xbInt16 iFldNo, const xbString &sMemoData );
+ virtual xbInt16 UpdateMemoField ( const xbString & sFldName, const xbString &sMemoData );
+ #endif // XB_MEMO_SUPPORT
+
+
+ #ifdef XB_LOCKING_SUPPORT
+ virtual xbInt16 LockTable ( xbInt16 iLockFunction );
+ virtual xbInt16 LockRecord ( xbInt16 iLockFunction, xbUInt32 ulRecNo );
+ virtual xbInt16 LockAppend ( xbInt16 iLockFunction );
+ virtual xbInt16 LockHeader ( xbInt16 iLockFunction );
+
+ #ifdef XB_MEMO_SUPPORT
+ virtual xbInt16 LockMemo ( xbInt16 iLockFunction );
+ virtual xbBool GetMemoLocked () const;
+ #endif // XB_MEMO_LOCK
+
+ #ifdef XB_INDEX_SUPPORT
+ virtual xbInt16 LockIndices ( xbInt16 iLockFunction );
+ #endif // XB_INDEX_SUPPORT
+
+ xbInt16 GetAutoLock () const;
+ void SetAutoLock ( xbInt16 iAutoLock );
+ xbInt16 GetLockFlavor () const;
+ void SetLockFlavor ( xbInt16 iLockFlavor );
+ xbBool GetTableLocked () const;
+ xbBool GetHeaderLocked () const;
+ xbUInt32 GetAppendLocked () const;
+ xbLinkListNode<xbUInt32> * GetFirstRecLock () const;
+
+ #ifdef XB_DEBUG_SUPPORT
+ void DumpTableLockStatus() const;
+ #endif // XB_DEBUG_SUPPORT
+ #endif // XB_LOCKING_SUPPORT
+
+
+ #ifdef XB_INDEX_SUPPORT
+ virtual xbInt16 CheckTagIntegrity( xbInt16 iTagOpt, xbInt16 iOutputOpt );
+ virtual xbInt16 CloseIndexFile( xbIx *pIx );
+ virtual xbInt16 CreateTag( const xbString &sIxType, const xbString &sName, const xbString &sKey, const xbString &sFilter,
+ xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverLay, xbIx **xbIxOut, void **vpTagOut );
+ virtual xbInt16 DeleteTag( const xbString &sIxType, const xbString &sName );
+ virtual xbInt16 DeleteAllIndexFiles();
+ virtual xbInt16 Find( xbString &sKey );
+ virtual xbInt16 Find( xbDate &dtKey );
+ virtual xbInt16 Find( xbDouble &dKey );
+ virtual xbIx *GetCurIx() const;
+ virtual void *GetCurTag() const;
+
+ virtual xbInt16 GetFirstKey();
+ virtual xbInt16 GetNextKey();
+ virtual xbInt16 GetPrevKey();
+ virtual xbInt16 GetLastKey();
+
+ virtual const xbString &GetCurIxType() const;
+ virtual const xbString &GetCurTagName() const;
+ virtual xbIxList *GetIxList() const;
+ virtual xbInt32 GetPhysicalIxCnt () const;
+ xbLinkListNode<xbTag *> *GetTagList () const;
+
+ virtual xbInt16 OpenIndex( const xbString &sIxType, const xbString &sIndexName );
+ virtual xbInt16 Reindex( xbInt16 iTagOpt = 0, xbInt16 iErrorOpt = 1, xbIx **pIx = NULL, void **vpTag = NULL );
+ virtual xbInt16 SetCurTag( const xbString &sTagName );
+ virtual void SetCurTag( const xbString &sIxType, xbIx *pIx, void *vpTag );
+
+ #endif // XB_INDEX_SUPPORT
+
+ #ifdef XB_INF_SUPPORT
+ virtual xbInt16 AssociateIndex( const xbString &sType, const xbString &sName, xbInt16 iOption );
+ xbLinkListNode<xbString> *GetInfList() const;
+ #endif // XB_INF_SUPPORT
+
+ //#ifdef XB_MDX_SUPPORT
+ //virtual xbInt16 GetCreateMdxBlockSize() const;
+ //virtual xbInt16 SetCreateMdxBlockSize( xbInt16 ulBlockSize );
+ //#endif
+
+ #ifdef XB_BLOCKREAD_SUPPORT
+ xbInt16 DisableBlockReadProcessing();
+ xbInt16 EnableBlockReadProcessing();
+ xbBool GetBlockReadStatus() const;
+ #endif // XB_BLOCKREAD_SUPPORT
+
+ protected:
+ #ifdef XB_INDEX_SUPPORT
+ friend class xbIx;
+ friend class xbIxMdx;
+ friend class xbIxTdx;
+
+ xbInt16 AddIndex( xbIx *ix, const xbString &sFmt );
+ void ClearTagList();
+ xbInt16 RemoveIndex( xbIx * ix );
+ void UpdateSchemaIxFlag( xbInt16 iFldNo, unsigned char cVal );
+
+
+ virtual xbInt16 UpdateTagList ();
+ #endif // XB_INDEX_SUPPORT
+
+ virtual xbInt16 ReadHeader ( xbInt16 iFilePositionOption, xbInt16 iReadOption );
+
+
+ #ifdef XB_INF_SUPPORT
+ virtual xbInt16 GetInfFileName( xbString &sNdxIdxFileName );
+ #endif // XB_INF_SUPPORT
+
+ #ifdef XB_BLOCKREAD_SUPPORT
+ friend class xbBlockRead;
+ #endif // XB_BLOCKREAD_SUPPORT
+
+
+ #ifdef XB_LOCKING_SUPPORT
+ void SetHeaderLocked ( xbBool bTableLocked );
+ void SetTableLocked ( xbBool bTableLocked );
+ #endif // XB_LOCKING_SUPORT
+
+ #ifdef XB_MEMO_SUPPORT
+ xbInt16 iMemoFieldCnt; // Memo field cnt in the table
+ xbMemo *Memo; // Pointer to memo class
+ xbUInt32 ulCreateMemoBlockSize; // blocksize to use when creating dbt file
+ #endif
+
+ #ifdef XB_INF_SUPPORT
+ virtual xbInt16 DeleteInfData();
+ virtual xbInt16 LoadInfData();
+ virtual xbInt16 SaveInfData();
+ #endif // XB_INF_SUPPORT
+
+/*
+ #ifdef XB_MDX_SUPPORT
+ xbInt16 iCreateMdxBlockSize;
+ #endif // XB_MDX_SUPPORT
+*/
+
+ virtual xbInt16 GetRawField( xbInt16 iFieldNo, char *Buf, xbUInt32 BufSize, xbInt16 iRecBufSw ) const;
+ virtual void InitVars();
+ virtual xbInt16 SetVersion() = 0;
+ virtual xbInt16 ValidateSchema( xbSchema * s ) = 0;
+ xbInt16 WriteHeader( xbInt16 iPositionOption, xbInt16 iWriteOption );
+
+
+ xbUInt32 ulCurRec; // Current record or zero
+ xbInt16 iAutoCommit; // Auto commit updates if not explicitly performed before moving off record?
+ // -1 --> Use DBMS default
+ // 0 --> No auto update on this table, regardless of DBMS setting
+ // 1 --> Auto update on this table, regardless of DBMS setting
+
+ xbInt16 iFileVersion; // xBase file version - which class is in play
+
+
+ xbString sAlias; // table alias
+ xbInt16 iNoOfFields;
+ xbInt16 iDbfStatus; // 0 = closed
+ // 1 = open
+ // 2 = updates pending
+
+ xbSchemaRec *SchemaPtr; // Pointer to field data
+ char *RecBuf; // Pointer to record buffer
+ char *RecBuf2; // Pointer to original rec buf allocation
+
+
+/* Next several variables are database header fields, up through dbase V */
+ unsigned char cVersion;
+ char cUpdateYY;
+ char cUpdateMM;
+ char cUpdateDD;
+ xbUInt32 ulNoOfRecs;
+ xbUInt16 uiHeaderLen;
+ xbUInt16 uiRecordLen;
+ char cTransactionFlag;
+ char cEncryptionFlag;
+ char cIndexFlag;
+ char cLangDriver; // dbase 7 sets to 1B
+
+
+
+ private:
+ void ResetNoOfRecords();
+
+
+ #ifdef XB_LOCKING_SUPPORT
+ xbInt16 iAutoLock; // 0 - autolock off, 1 - autolock on
+ xbInt16 iLockFlavor;
+ xbBool bTableLocked; // is the table locked
+ xbBool bHeaderLocked; // is the header locked
+ xbUInt32 ulAppendLocked; // record number of the new record for the append lock operation
+ xbLinkListOrd<xbUInt32> lloRecLocks; // ordered link list of locked records
+ #endif
+
+ #ifdef XB_INDEX_SUPPORT
+ xbIxList *ixList; // pointer to a list of indices associated with the table
+ xbIx *pCurIx; // Pointer to current index class
+ void *vpCurIxTag; // Pointer to current tag
+ xbString sCurIxType; // Current index type
+ xbLinkList<xbTag *> llTags; // linked list of open tags
+ #endif // XB_INDEX_SUPPORT
+
+ #ifdef XB_INF_SUPPORT
+ xbLinkList<xbString> llInfData; // linked list of strings containing ndx file entries
+ #endif // XB_INF_SUPPORT
+
+ #ifdef XB_BLOCKREAD_SUPPORT
+ xbBlockRead *pRb;
+ xbBool bBlockReadEnabled; // if true, then block read mode is on
+ #endif
+
+
+
+};
+
+
+#ifdef XB_DBF3_SUPPORT
+//! @brief Derived class for handling dbf version III files/tables.
+/*!
+The xbDbf class is used as a base class for accessing dbf files.
+The xbDbf3 class is derived from the xbDbf class and is designed to handle the
+orginal version 3 type files.
+*/
+
+class XBDLLEXPORT xbDbf3 : public xbDbf {
+ public:
+ xbDbf3(xbXBase *x);
+ ~xbDbf3();
+ virtual xbInt16 CreateTable ( const xbString &sTableName, const xbString &sAlias, xbSchema *, xbInt16 iOverlay, xbInt16 iShareMode );
+ virtual xbInt16 GetVersion () const;
+ virtual xbInt16 Open ( const xbString &sTableName, const xbString &sAlias, xbInt16 iOpenMode, xbInt16 iShareMode );
+ virtual xbInt16 Rename ( const xbString sNewName );
+
+ #ifdef XB_MEMO_SUPPORT
+ virtual xbInt16 SetCreateMemoBlockSize( xbUInt32 iBlockSize );
+ #endif
+
+ protected:
+ xbInt16 SetVersion ();
+ virtual xbInt16 ValidateSchema( xbSchema *s );
+
+ private:
+
+};
+#endif /* XB_DBF3_SUPPORT */
+
+
+#ifdef XB_DBF4_SUPPORT
+//! @brief Derived class for handling dbf version IV files/tables.
+/*!
+The xbDbf class is used as a base class for accessing dbf files.
+The xbDbf4 class is derived from the xbDbf class and is designed to handle the
+orginal version 4 type files.
+*/
+class XBDLLEXPORT xbDbf4 : public xbDbf {
+ public:
+ xbDbf4( xbXBase *x );
+
+ ~xbDbf4();
+
+ virtual xbInt16 CreateTable ( const xbString &sTableName, const xbString &sAlias, xbSchema *, xbInt16 iOverlay, xbInt16 iShareMode );
+ virtual xbInt16 GetVersion () const;
+ virtual xbInt16 Open ( const xbString &sTableName, const xbString &sAlias, xbInt16 iOpenMode, xbInt16 iShareMode );
+ virtual xbInt16 Rename ( const xbString sNewName );
+
+ #ifdef XB_MEMO_SUPPORT
+ virtual xbInt16 SetCreateMemoBlockSize( xbUInt32 iBlockSize );
+ #endif
+
+ protected:
+ // void InitVars ();
+ xbInt16 SetVersion();
+ virtual xbInt16 ValidateSchema ( xbSchema *s );
+
+ private:
+
+};
+
+#endif /* XB_DBF4_SUPPORT */
+
+} /* namespace xb */
+#endif /* __XB_DBF_H__ */
diff --git a/src/include/xbexp.h b/src/include/xbexp.h
new file mode 100755
index 0000000..4792b0e
--- /dev/null
+++ b/src/include/xbexp.h
@@ -0,0 +1,216 @@
+/* xbexp.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_EXP_H__
+#define __XB_EXP_H__
+
+
+// #ifdef CMAKE_COMPILER_IS_GNUCC
+// #pragma interface
+// #endif
+
+#define XB_NULL_DATE 21474835648
+
+
+#ifdef XB_FUNCTION_SUPPORT
+#define XB_EXP_CHAR 'C'
+#define XB_EXP_DATE 'D'
+#define XB_EXP_LOGICAL 'L'
+#define XB_EXP_NUMERIC 'N'
+#define XB_EXP_UNKNOWN 'U'
+#endif
+
+#ifdef XB_EXPRESSION_SUPPORT
+
+#define XB_EXP_CONSTANT 'C'
+#define XB_EXP_FUNCTION 'F'
+#define XB_EXP_FIELD 'D'
+#define XB_EXP_OPERATOR 'O'
+#define XB_EXP_NOTROOT 'N' // not root node, needs further parsing
+#define XB_EXP_PRE_OPERATOR 'B' // (B)efore) pre increment, pre decrement
+#define XB_EXP_POST_OPERATOR 'A' // (A)fter) post increment, pre decrement
+
+#define XB_END_OF_EXPRESSION -100
+
+// #define XB_UNBALANCED_PARENS -101
+// #define XB_UNBALANCED_QUOTES -102
+
+
+namespace xb{
+
+///@cond DOXYOFF
+struct XBDLLEXPORT xbExpToken {
+ xbString sExpression; // in - expression to pull next token from
+ // out - remainder of the expression after token removed
+ xbString sToken; // next token pulled from the expression
+ char cNodeType; // one of XB_EXP_CONSTANT, XB_EXP_FUNCTION, XB_EXP_FIELD, XB_EXP_OPERATOR, XB_EXP_NOTROOT
+ char cReturnType; // one of XB_EXP_CHAR, XB_EXP_DATE, XB_EXP_LOGICAL, XB_EXP_NUMERIC, XB_EXP_UNKNOWN
+ xbInt16 iSts; // return status after retrieving or attempting next token from expression
+ // 0 = no error
+ // XB_END_OF_EXPRESSION
+ // XB_UNBALANCED_PARENS
+ // XB_UNBALANCED_QUOTES
+ char cPrevNodeType; // previous node type
+ char cPrevReturnType; // previous return type
+
+ // constructor
+ xbExpToken() { cNodeType = 0; cReturnType = 0; iSts = 0; cPrevNodeType = 0; cPrevReturnType = 0; }
+};
+///@endcond DOXYOFF
+
+
+/************************************************************************/
+
+//! @brief Class for handling expressions.
+/*!
+The xbExp class is used for parsing and evaluating expression.
+
+The Xbase64 library includes an expression parsing module 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>
+
+<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>
+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>
+
+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.<br><br>
+
+<h3>Expression Return Types</h3>
+Expressions will return a type of CHAR, NUMERIC, DATE or LOGICAL.<br>
+
+An expression return type can be determined with method <em>
+GetExpressionResultType</em> after parsing it.<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 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>
+
+<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>
+
+<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.
+
+*/
+
+class XBDLLEXPORT xbExp{
+
+ public:
+ xbExp( xbXBase * );
+ xbExp( xbXBase *, xbDbf * );
+ virtual ~xbExp();
+ void ClearTreeHandle();
+
+
+ #ifdef XB_DEBUG_SUPPORT
+ void DumpTree( xbInt16 iOption );
+ void DumpToken( xbExpToken &t, xbInt16 iOption = 0 );
+ #endif
+
+ xbInt16 GetResultLen() const;
+ char GetReturnType() const;
+ xbInt16 GetBoolResult( xbBool &bResult );
+ xbInt16 GetDateResult( xbDate &dtResult );
+ xbInt16 GetNumericResult( xbDouble &dResult );
+ xbInt16 GetStringResult( xbString &sResult );
+ xbInt16 GetStringResult( char * vpResult, xbUInt32 ulLen );
+ xbExpNode *GetTreeHandle();
+ xbInt16 ParseExpression( const xbString &sExpression );
+ xbInt16 ParseExpression( xbDbf *dbf, const xbString &sExpression );
+ xbInt16 ProcessExpression();
+ xbInt16 ProcessExpression( xbInt16 iRecBufSw );
+
+
+ protected:
+ xbInt16 GetNextToken( xbExpToken &t );
+ xbInt16 OperatorWeight( const xbString &sOperator );
+ xbExpNode *GetNextNode( xbExpNode * n ) const; // traverses the tree from bottom left node, right, then up
+
+ private: // methods
+
+ // xbInt16 CalcExpressionResultLen();
+ xbInt16 CalcFunctionResultLen( xbExpNode *n ) const;
+ xbInt16 CalcCharNodeLen( xbExpNode *n );
+ xbInt16 CheckParensAndQuotes( const xbString &sExpression );
+ xbInt16 GetExpressionResultLen() const;
+
+ xbInt16 GetTokenCharConstant ( xbExpToken &t );
+ xbInt16 GetTokenDatabaseField ( xbExpToken &t );
+ xbInt16 GetTokenDateConstant ( xbExpToken &t );
+ xbInt16 GetTokenFunction ( xbExpToken &t );
+ xbInt16 GetTokenLogicalConstant( xbExpToken &t );
+ xbInt16 GetTokenNumericConstant( xbExpToken &t );
+ xbInt16 GetTokenOperator ( xbExpToken &t );
+ xbInt16 GetTokenParen ( xbExpToken &t );
+
+ xbBool IsFunction ( const xbString &sExp, char &cReturnType );
+ xbBool IsLogicalConstant ( const xbString &sExp );
+ xbBool IsNumericConstant ( const xbString &sExp, char cPrevNodeType );
+ xbBool IsOperator ( const xbString &sExp );
+ char IsTokenSeparator ( char c );
+ xbBool IsWhiteSpace ( char c );
+
+ xbInt16 ParseExpression ( const xbString &sExpression, xbInt16 iWeight );
+ xbInt16 ParseExpressionConstant( xbExpToken &t, xbExpNode *n );
+ xbInt16 ParseExpressionFunction( xbExpToken &t, xbExpNode *n, xbInt16 iWeight );
+ xbInt16 ParseExpressionFunctionParms( const xbString &sParms, xbLinkList<xbString> &llParms );
+ xbInt16 ParseExpressionField ( xbExpToken &t, xbExpNode *n );
+ xbInt16 ParseExpressionOperator( xbExpToken &t, xbExpNode *n, xbInt16 iWeight );
+
+ xbInt16 ProcessExpressionFunction( xbExpNode *n, xbInt16 iRecBufSw = 0 );
+ xbInt16 ProcessExpressionOperator( xbExpNode *n );
+
+ private: // fields
+ xbXBase *xbase;
+ xbDbf *dbf;
+ xbExpNode *nTree; // pointer to tree of expNodes
+ // xbInt16 iExpLen; // size of expression result
+
+
+};
+
+/* Expression handler */
+
+
+};
+#endif // XB_EXPRESSION_SUPPORT
+#endif // __XB_EXP_H__
+
+
diff --git a/src/include/xbexpnode.h b/src/include/xbexpnode.h
new file mode 100755
index 0000000..51efa9b
--- /dev/null
+++ b/src/include/xbexpnode.h
@@ -0,0 +1,120 @@
+/* xbexpnode.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_EXPNODE_H__
+#define __XB_EXPNODE_H__
+
+// #ifdef CMAKE_COMPILER_IS_GNUCC
+// #pragma interface
+// #endif
+
+#ifdef XB_EXPRESSION_SUPPORT
+
+
+namespace xb{
+
+//class XBDLLEXPORT xbDbf;
+
+/************************************************************************/
+//! @brief Expression node class for handling expression nodes.
+/*!
+The xbExpNode class is used by the expression logic for handling specific
+nodes within a tree of nodes.<br>
+
+Expressions are parsed into nodes and a logical tree of nodes is created
+out of all the individual components within the expression.<br>
+
+This class is used for handling a specific node within a tree.<br>
+
+An application program will typically not need to be concerned with
+this class.<br>
+
+*/
+class XBDLLEXPORT xbExpNode {
+ public:
+ xbExpNode();
+ xbExpNode( xbString &sNodeText, char cReturnType, char cNodeType );
+ xbExpNode( xbString &sNodeText, char cNodeType );
+ xbExpNode( char cNodeType );
+
+ virtual ~xbExpNode();
+ xbInt16 AddChild( xbExpNode *n );
+ xbExpNode *GetChild( xbUInt32 ulChildNo ) const;
+ xbUInt32 GetChildCnt() const;
+ xbUInt32 GetChildNo() const;
+ xbDbf *GetDbf() const;
+ xbInt16 GetFieldNo() const;
+ xbExpNode *GetFirstNode();
+ xbExpNode *GetNextNode() const;
+ void GetNodeText( xbString &sNodeText ) const;
+ char GetNodeType() const;
+ xbExpNode *GetParent() const;
+ xbString &GetStringResult();
+ xbBool GetBoolResult() const;
+ xbDouble GetNumericResult() const;
+ xbUInt32 GetResultLen() const;
+ xbExpNode *GetRightSibling() const;
+ char GetReturnType() const;
+ xbInt16 GetWeight() const;
+ xbBool HasRightSibling() const;
+ xbBool IsOperator() const;
+ xbBool IsUnaryOperator() const;
+ void RemoveLastChild();
+ void SetResultLen( xbUInt32 ulResultLen );
+ void SetDbfInfo( xbDbf *dbf );
+ void SetDbfInfo( xbDbf *dbf, xbInt16 iFieldNo );
+ void SetNodeText( xbString &sNodeText );
+ void SetNodeType( char cNodeType );
+ void SetParent( xbExpNode *n );
+ void SetResult( xbString &sResult );
+ void SetResult( xbDate &dtResult );
+ void SetResult( xbBool bResult );
+ void SetResult( xbDouble dResult );
+ void SetReturnType( char cReturnType );
+ void SetWeight( xbInt16 iWeight );
+
+ #ifdef XB_DEBUG_SUPPORT
+ void DumpNode( xbInt16 iOption ) const; // 0 = no children, 1 = and children
+ #endif
+
+ private:
+ xbString sNodeText; // expression text
+ char cReturnType; // one of: XB_EXP_CHAR, XB_EXP_DATE, XB_EXP_LOGICAL, XB_EXP_NUMERIC
+ char cNodeType; // one of: XB_EXP_CONSTANT, XB_EXP_FUNCTION, XB_EXP_FIELD, XB_EXP_OPERATOR
+ xbString sResult; // char result, and operator
+ xbDouble dResult; // numeric and bool results
+ xbExpNode * nParent; // pointer to parent
+ xbLinkList<xbExpNode *> llChildren; // linked list of descendent nodes
+ xbDbf *dbf; // pointer to dbf, used for field, RECNO() and RECCOUNT()
+ xbInt16 iFieldNo; // field no if DBF field
+ xbUInt32 ulResultLen; // for string results, accumulated length of character operations
+ // includes the sum of all nodes under this + this
+ // date = 8, numeric = 4, logical = 1
+ xbInt16 iWeight; // used for building the tree of nodes, assigned to operators
+ // the higher the number, the lower it goes on the tree
+
+};
+
+/************************************************************************/
+
+/* Expression handler */
+
+
+};
+#endif // XB_EXPRESSION_SUPPORT
+#endif // __XB_EXP_H__
+
+
diff --git a/src/include/xbfile.h b/src/include/xbfile.h
new file mode 100755
index 0000000..e346a75
--- /dev/null
+++ b/src/include/xbfile.h
@@ -0,0 +1,198 @@
+/* xbfile.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+#ifndef __XB_FILE_H__
+#define __XB_FILE_H__
+
+#ifdef CMAKE_COMPILER_IS_GNUCC
+#pragma interface
+#endif
+
+/*****************************/
+/* File Open Modes */
+#define XB_READ 0
+#define XB_READ_WRITE 1
+#define XB_WRITE 2
+
+/*****************************/
+/* File Access Modes */
+#define XB_SINGLE_USER 0 // file buffering on
+#define XB_MULTI_USER 1 // file buffering off
+
+namespace xb{
+
+/*! @brief Class for handling low level file I/O.
+*/
+
+/*!
+The xbFile class is used as an abstraction layer to isolate the library from the nuances
+of different operating systems and machine architectures.
+
+This module handles low level file I/O and is a base class
+for the (dbf) table, (dbt) memo and (ndx,mdx) index classes.
+Files are opened and manipulated via methods in the xbFile class.<br>
+This class handles:<br>
+1) Big and little endian reads/writes<br>
+2) 32 or 64 bit system calls, depending on OS<br>
+3) Various different c/c++ calls to open/close/read/write based on OS and compiler version<br>
+<br>
+If you are wanting to port this library to a new platform, start with this class.
+This class could be used if you want to write a platform independent program that needs R/W file access.
+*/
+
+
+class XBDLLEXPORT xbFile : public xbSsv {
+
+ public:
+ xbFile( xbXBase * x );
+ ~xbFile();
+
+ const xbString& GetDirectory() const;
+ const xbString& GetFileName() const;
+ const xbString& GetFqFileName() const;
+
+
+ xbInt16 CreateUniqueFileName( const xbString &sDirIn, const xbString &sExtIn, xbString &sFqnOut, xbInt16 iOption = 0 );
+
+ xbInt16 DetermineXbaseTableVersion( unsigned char cFileTypeByte ) const;
+ xbInt16 DetermineXbaseMemoVersion( unsigned char cFileTypeByte ) const;
+
+ xbDouble eGetDouble ( const char *p ) const;
+ xbInt32 eGetInt32 ( const char *p ) const;
+ xbUInt32 eGetUInt32 ( const char *p ) const;
+ xbInt16 eGetInt16 ( const char *p ) const;
+ xbUInt16 eGetUInt16 ( const char *p ) const;
+ void ePutDouble ( char *p, xbDouble d );
+ void ePutInt32 ( char *p, xbInt32 l );
+ void ePutUInt32 ( char *p, xbUInt32 ul );
+ void ePutInt16 ( char *p, xbInt16 s );
+ void ePutUInt16 ( char *p, xbUInt16 s );
+
+ xbBool FileExists () const;
+ xbBool FileExists ( xbInt16 iOption ) const;
+ xbBool FileExists ( const xbString &sFileName ) const;
+ xbBool FileExists ( const xbString &sFileName, xbInt16 iOption ) const;
+ xbBool FileIsOpen () const;
+
+ xbUInt32 GetBlockSize () const;
+
+ xbInt16 GetFileDirPart ( xbString &sFileDirPartOut ) const;
+ xbInt16 GetFileDirPart ( const xbString &sCompleteFileNameIn, xbString &sFileDirPartOut ) const;
+ xbInt16 GetFileExtPart ( xbString &sFileExtPartOut ) const;
+ xbInt16 GetFileExtPart ( const xbString &sCompleteFileNameIn, xbString &sFileExtPartOut ) const;
+ xbInt16 GetFileMtime ( time_t &mtime );
+ xbInt16 GetFileNamePart( xbString &sFileNamePartOut ) const;
+ xbInt16 GetFileNamePart( const xbString &sCompleteFileNameIn, xbString &sFileNamePartOut ) const;
+ xbInt16 GetFileSize ( xbUInt64 &ullFileSize );
+ xbInt16 GetFileType ( xbString &sFileType ) const;
+
+
+ xbInt16 GetOpenMode () const;
+ xbInt16 GetShareMode () const;
+
+
+ xbInt16 GetXbaseFileTypeByte( const xbString &sFileName, xbInt16 &iVersion );
+ xbInt16 GetXbaseFileTypeByte( const xbString &sFileName, unsigned char &cFileTypeByte );
+ xbInt16 GetXbaseFileTypeByte( const xbString &sFileName, unsigned char &cFileTypeByte, xbInt16 &iVersion );
+
+ xbInt16 NameSuffixMissing( const xbString &sFileName, xbInt16 iOption ) const;
+
+ xbInt16 ReadBlock ( xbUInt32 ulBlockNo, size_t readSize, void *buf );
+ xbInt16 ReadBlock ( xbUInt32 ulBlockNo, xbUInt32 ulBlockSize, size_t readSize, void *buf );
+
+ xbInt16 SetBlockSize ( xbUInt32 ulBlockSize );
+ void SetDirectory ( const xbString &sDirectory);
+ void SetFileName ( const xbString &sFileName );
+ void SetFqFileName ( const xbString &sFqName );
+ xbInt16 SetHomeFolders();
+
+ xbInt16 WriteBlock ( xbUInt32 ulBlockNo, size_t writeSize, void *buf );
+
+ xbInt16 xbFclose ();
+ xbInt16 xbFeof ();
+ xbInt16 xbFflush ();
+ xbInt16 xbFgetc ( xbInt32 &c );
+ xbInt16 xbFgetc ( char &c );
+ xbInt16 xbFgets ( size_t lSize, xbString &sLine );
+
+
+ xbInt16 xbFopen ( xbInt16 iOpenMode );
+ xbInt16 xbFopen ( const xbString &sOpenMode, xbInt16 iShareMode );
+ xbInt16 xbFopen ( xbInt16 iOpenMode, xbInt16 iShareMode );
+ xbInt16 xbFopen ( const xbString &sMode, const xbString &sFileName, xbInt16 iShareMode );
+
+ xbInt16 xbFputc ( xbInt32 c );
+ xbInt16 xbFputc ( xbInt32 c, xbInt32 iNoTimes );
+ xbInt16 xbFputs ( const xbString &s );
+ xbInt16 xbFread ( void *ptr, size_t size, size_t nmemb );
+ xbInt16 xbFseek ( xbInt64 llOffset, xbInt32 whence );
+ size_t xbFtell ();
+ void xbFTurnOffFileBuffering();
+
+ xbInt16 xbReadUntil ( const char cDelim, xbString &sOut );
+ xbInt16 xbRemove ( const xbString &sFileName, xbInt16 iOption );
+ xbInt16 xbRemove ( const xbString &sFileName );
+ xbInt16 xbRemove ();
+
+ xbInt16 xbRename ( const xbString &sOldName, const xbString &sNewName );
+ void xbRewind ();
+
+ xbInt16 xbFwrite ( const void *ptr, size_t lSize, size_t lNmemb );
+
+ xbInt16 xbTruncate ( xbInt64 llSize );
+
+
+ #ifdef XB_LOCKING_SUPPORT
+ xbInt16 xbLock ( xbInt16 iFunction, xbInt64 llOffset, size_t stLen );
+ xbInt16 GetLockRetryCount() const;
+ void SetLockRetryCount( xbInt16 iLockRetries );
+ #endif
+
+ #ifdef XB_DEBUG_SUPPORT
+ xbInt16 DumpBlockToDisk( xbUInt32 ulBlockNo, size_t lBlockSize );
+ xbInt16 DumpMemToDisk ( char *p, size_t lBlockSize );
+ #endif
+
+
+ protected:
+
+ xbXBase *xbase; /* pointer to the main structures */
+
+ private:
+ FILE *fp;
+ xbString sFqFileName; /* fully qualified file name */
+ xbString sFileName; /* file name */
+ xbString sDirectory; /* directory, ends with / or \ */
+ xbBool bFileOpen; /* true if file is open */
+ xbUInt32 ulBlockSize; /* used for memo and index files */
+
+ xbInt16 iOpenMode; /* XB_READ || XB_READ_WRITE || XB_WRITE */
+ xbInt16 iShareMode; /* XB_SINGLE_USER || XB_MULTI_USER - set file buffering */
+ xbInt32 iFileNo; /* Library File No */
+
+ #ifdef XB_LOCKING_SUPPORT
+ xbInt16 iLockRetries; /* file override number of lock attempts */
+ #endif
+
+ #ifdef HAVE_SETENDOFFILE_F
+ HANDLE fHandle;
+ #endif
+
+
+};
+
+} /* namespace */
+#endif /* __XBFILE_H__ */
+
diff --git a/src/include/xbfilter.h b/src/include/xbfilter.h
new file mode 100755
index 0000000..635d117
--- /dev/null
+++ b/src/include/xbfilter.h
@@ -0,0 +1,78 @@
+/* xbfilter.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+This class manages the user data area (UDA)
+
+*/
+
+
+#ifndef __XB_XBFILTER_H__
+#define __XB_XBFILTER_H__
+
+#ifdef CMAKE_COMPILER_IS_GNUCC
+#pragma interface
+#endif
+
+
+#ifdef XB_FILTER_SUPPORT
+
+
+namespace xb{
+
+//#ifdef XB_INDEX_SUPPORT
+//class XBDLLEXPORT xbIx;
+//#endif // XB_INDEX_SUPPORT
+
+
+class XBDLLEXPORT xbFilter {
+
+ public:
+ xbFilter( xbDbf *dbf );
+ ~xbFilter();
+ xbInt16 Set( xbString &sFilterExpression );
+ xbInt16 Set( const char *sFilterExpression );
+ xbInt16 GetFirstRecord( xbInt16 iOpt = 1 );
+ xbInt16 GetNextRecord ( xbInt16 iOpt = 1 );
+ xbInt16 GetPrevRecord ( xbInt16 iOpt = 1 );
+ xbInt16 GetLastRecord ( xbInt16 iOpt = 1 );
+ void SetLimit( xbInt32 ulLimit );
+ xbInt32 GetLimit() const;
+ void ResetQryCnt();
+ xbInt32 GetQryCnt() const;
+
+ #ifdef XB_INDEX_SUPPORT
+ xbInt16 GetFirstRecordIx( xbInt16 iOpt = 1 );
+ xbInt16 GetNextRecordIx ( xbInt16 iOpt = 1 );
+ xbInt16 GetPrevRecordIx ( xbInt16 iOpt = 1 );
+ xbInt16 GetLastRecordIx ( xbInt16 iOpt = 1 );
+ #endif // XB_INDEX_SUPPORT
+
+
+ private:
+// xbXBase *xbase;
+ xbDbf *dbf;
+ xbExp *exp;
+
+ xbInt32 lLimit; // max number rows returned
+ xbInt32 lCurQryCnt; // current count of rows returned, neg# is moving from bottom to top
+ // pos# is moving from top to bottom
+ #ifdef XB_INDEX_SUPPORT
+ xbIx *pIx; // if index is set, the class uses the index tag, otherwise table
+ void *vpTag;
+ #endif // XB_INDEX_SUPPORT
+
+
+};
+} /* namespace */
+#endif /* XB_FILTER_SUPPORT */
+#endif /* __XBFILTER_H__ */ \ No newline at end of file
diff --git a/src/include/xbindex.h b/src/include/xbindex.h
new file mode 100755
index 0000000..959562c
--- /dev/null
+++ b/src/include/xbindex.h
@@ -0,0 +1,613 @@
+/* xbindex.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014, 2018, 2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_INDEX_H__
+#define __XB_INDEX_H__
+
+#ifdef XB_INDEX_SUPPORT
+
+
+#define XB_ADD_KEY 1
+#define XB_UPD_KEY 2
+#define XB_DEL_KEY 3
+
+namespace xb{
+
+
+
+///@cond DOXYOFF
+// structure for index nodes, each node contains information regarding one block
+struct XBDLLEXPORT xbIxNode {
+ xbIxNode *npPrev; // pointer to previous node in chain
+ xbIxNode *npNext; // pointer to next node in chain
+ xbUInt32 iCurKeyNo; // current key number in the node, 0 offset
+ xbUInt32 ulBlockNo; // this block number
+ xbUInt32 ulBufSize; // size of cpBlockData
+ char *cpBlockData; // pointer to memory version of block data stored in file
+};
+///@endcond DOXYOFF
+
+
+//! @brief Base class for handling dbf indices.
+/*!
+
+The xbIx class is used as a base class for accessing index files.
+Each index file can have one or more tags.
+
+Calls to the index routines to perform index updates are handled automatically by the dbf class.
+The application program does not need to be concerned with index updates.
+
+If there is a production MDX index, it is opened automatically when the dbf file is opened.
+If there is an ndx file, that has been associated with the dbf file with the metadata routines,
+it will be opened automatically when the dbf file is opened.
+If there are non prod ndx indices that are not associated with the dbf file, the application
+program will need to open as appropriate.
+The meta data association logic is specific to the Xbase64 library and is not applicable to
+other available tools that handle ndx indices.
+All index files are automatically closed when the dbf file is closed.
+
+
+<br>
+The class is designed to support the addition of additional indices with a minimal amount of effort
+needed to integrate into the library.
+If you are looking at adding an new index type to the library, create a derived class using xbIx as a
+base class and modify methods needed to support the new index file version.
+The xbDbf class (and derived classes) perform the needed calls to the index routines for updates.<br>
+See the following for examples on how to start on this:<br>
+xbIxNdx is a derived class and supports a single tag.<br>
+xbIxMdx is a derived class and supports multiple tags.<br>
+
+
+
+<br>
+How data fields are stored in index files:
+<table>
+<tr><th>Field Type<th>Stored in DBF as<th>Stored in NDX as<th>Stored in MDX as</tr>
+<tr><td>C<td>char<td>char<td>char
+<tr><td>F<td>text numbers<td>xbDouble<td>xbBcd
+<tr><td>N<td>text numbers<td>xbDouble<td>xbBcd
+<tr><td>D<td>text CCYYMMDD<td>xbDouble - julian<td>xbDouble - julian
+</table>
+
+
+<br>
+Pages Vs Blocks
+<br>
+For purposes of the Xbase index classes, a page is considered to be 512 bytes of data
+and a block is made up of one or more 512 byte pages.
+<br>Default block sixe of NDX indices is one 512 byte page.
+<br>Default block size of MDX indices is two 512 byte pages or 1024 bytes.
+
+<br>The WriteBlock and GetBlock functions calculate the physical position in the
+file based on a combination of Block Number and Block Size. Block size is set at
+time of index file creation, default is 1024 or two pages.
+
+<br>Page numbers are stored in the physical file, but block reads and writes
+are performed.
+
+<br>
+Duplicate Keys
+<br>
+With the original DBase unique indexing option, if a table has multiple records with the
+same key value, DBase would allow multiple records in the table, but only the first
+record would be found in the index.
+<br>
+XBase64 can be configured to support the original DBase duplicate key implementation,
+or can be configured to halt with a DUPLICATE_KEY error on the insertion of a record
+with a duplicate key.
+<br>
+<table>
+<tr><th>Option<th>Description</tr>
+<tr><td>XB_HALT_ON_DUPKEY</td><td>Return error XB_KEY_NOT_UNIQUE when attempting to append record with duplicate key</td></tr>
+<tr><td>XB_EMULATE_DBASE</td><td>Emulate DBase, allow duplicate records with the same key, only the first record is indexed</td></tr>
+</table>
+*/
+
+
+class XBDLLEXPORT xbIx : public xbFile {
+ public:
+ xbIx( xbDbf * d );
+ virtual ~xbIx();
+
+ virtual xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt ) = 0;
+ virtual xbInt16 Close();
+ virtual xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag ) = 0;
+ virtual xbInt16 FindKey( void *vpTag, const xbString &sKey, xbInt16 iRetrieveSw );
+ virtual xbInt16 FindKey( void *vpTag, const char * cKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw );
+ virtual xbInt16 FindKey( void *vpTag, const xbBcd &bcd, xbInt16 iRetrieveSw );
+ virtual xbInt16 FindKey( void *vpTag, const xbDate &dtKey, xbInt16 iRetrieveSw );
+ virtual xbInt16 FindKey( void *vpTag, xbDouble dKey, xbInt16 iRetrieveSw );
+ virtual xbInt16 FindKey( void *vpTag, const void *vKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw ) = 0;
+ virtual void *GetCurTag() const;
+ virtual xbDbf *GetDbf() const;
+
+ virtual xbString &GetKeyExpression( const void *vpTag ) const = 0;
+ virtual xbString &GetKeyFilter( const void *vpTag ) const = 0;
+ virtual char GetKeyType( const void *vpTag ) const = 0;
+ virtual xbBool GetLocked() const;
+
+ virtual xbInt16 GetFirstKey( void *vpTag, xbInt16 iRetrieveSw ) = 0;
+ virtual xbInt16 GetFirstKey( void *vpTag );
+ virtual xbInt16 GetFirstKey();
+
+ virtual xbInt16 GetLastKey( void *vpTag, xbInt16 lRetrieveSw ) = 0;
+ virtual xbInt16 GetLastKey( void *vpTag );
+ virtual xbInt16 GetLastKey();
+
+ virtual xbInt16 GetNextKey( void *vpTag, xbInt16 iRetrieveSw ) = 0;
+ virtual xbInt16 GetNextKey( void *vpTag );
+ virtual xbInt16 GetNextKey();
+
+ virtual xbInt16 GetPrevKey( void *vpTag, xbInt16 iRetrieveSw ) = 0;
+ virtual xbInt16 GetPrevKey( void *vpTag );
+ virtual xbInt16 GetPrevKey();
+
+ virtual void *GetTag( xbInt16 iTagNo ) const = 0;
+ virtual void *GetTag( xbString &sTagName ) const = 0;
+ virtual xbInt16 GetTagCount() const = 0;
+
+ virtual xbString &GetTagName( void *vpTag ) const = 0;
+ virtual const char * GetTagName( void *vpTag, xbInt16 iOpt ) const = 0;
+ virtual void GetTagName( void *vpTag, xbString &sTagName ) {};
+
+ virtual xbBool GetUnique( void *vpTag ) const = 0;
+ virtual xbBool GetSortOrder( void *vpTag ) const = 0;
+
+ virtual xbInt16 Open( const xbString &sFileName );
+ virtual xbInt16 SetCurTag( xbInt16 iTagNo ) = 0;
+ virtual xbInt16 SetCurTag( xbString &sTagName ) = 0;
+ virtual void SetCurTag( void * vpCurTag );
+ virtual void SetLocked( xbBool bLocked );
+
+ virtual void TestStub( char *s, void *vpTag ) {};
+
+
+
+ virtual xbInt16 Reindex( void **vpTag ) = 0;
+
+
+ #ifdef XB_DEBUG_SUPPORT
+ virtual xbInt16 DumpFreeBlocks( xbInt16 iOpt = 0 ) { return XB_NO_ERROR; }
+ virtual xbInt16 DumpHeader( xbInt16 iDestOpt = 0, xbInt16 iFmtOpt = 0 ) = 0;
+ virtual xbInt16 DumpIxForTag( void *vpTag, xbInt16 iOutputOpt ) = 0;
+ virtual void DumpIxNodeChain( void *vpTag, xbInt16 iOutputOpt ) const = 0;
+ virtual xbInt16 DumpNode( void * vpTag, xbIxNode * pNode, xbInt16 iOption ) const;
+ virtual xbInt16 DumpTagBlocks( xbInt16 iOpt = 1, void *vpTag = NULL ) = 0;
+
+ #endif
+
+ protected:
+ friend class xbDbf;
+
+ virtual xbInt16 AddKey( void *vpTag, xbUInt32 ulRecNo ) = 0;
+ virtual xbInt16 AddKeys( xbUInt32 ulRecNo );
+ virtual xbIxNode *AllocateIxNode( xbUInt32 ulBufSize = 0, xbInt16 iOption = 0 );
+ virtual xbInt16 BSearchBlock( char cKeyType, xbIxNode *npNode, xbInt32 lKeyLen, const void *vpKey, xbInt32 lSearchKeyLen, xbInt16 &iCompRc, xbBool bDescending = xbFalse ) const;
+ virtual xbInt16 CheckForDupKeys();
+ virtual xbInt16 CheckForDupKey( void *vpTag ) = 0;
+ virtual xbInt16 CompareKey( char cKeyType, const void *v1, const void *v2, size_t lKeyLen ) const;
+ virtual xbInt16 CreateKeys( xbInt16 iOpt );
+ virtual xbInt16 CreateKey( void * vpTag, xbInt16 iOpt ) = 0;
+ virtual xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo ) = 0;
+ virtual xbInt16 DeleteKeys();
+ virtual xbInt16 DeleteKey( void *vpTag ) = 0;
+ virtual xbInt16 DeleteTag( void *vpTag ) = 0;
+
+ virtual xbInt16 FindKeyForCurRec( void *vpTag ) = 0;
+ virtual xbIxNode *FreeNodeChain( xbIxNode *np );
+ virtual xbInt16 GetBlock( void *vpTag, xbUInt32 ulBlockNo, xbInt16 iOpt, xbUInt32 ulAddlBuf = 0 );
+ virtual xbInt32 GetKeyCount( xbIxNode *npNode ) const;
+ virtual char *GetKeyData( xbIxNode *npNode, xbInt16 iKeyNo, xbInt16 iKeyItemLen ) const;
+ virtual xbInt16 GetKeySts( void *vpTag ) const = 0;
+ virtual xbInt16 GetLastKey( xbUInt32 ulNodeNo, void *vpTag, xbInt16 lRetrieveSw ) = 0;
+ virtual xbInt16 InsertNodeL( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, char * cpKeyBuf, xbUInt32 uiPtr ) = 0;
+ virtual xbInt16 InsertNodeI( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, xbUInt32 uiPtr ) = 0;
+ virtual xbInt16 KeyExists( void * ) = 0;
+ virtual void NodeFree( xbIxNode * ixNode );
+ virtual xbInt16 ReadHeadBlock( xbInt16 iOpt = 0 ) = 0;
+ // virtual xbInt16 Reindex( void **vpTag ) = 0;
+ virtual void SetDbf( xbDbf *dbf );
+ virtual xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr ) = 0;
+ virtual xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr ) = 0;
+ virtual xbInt16 UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo = 0 ) = 0;
+ virtual xbInt16 WriteHeadBlock( xbInt16 iOption ) = 0;
+
+ xbDbf *dbf;
+ char *cNodeBuf; // pointer to memory for processing in a block of index data
+ void *vpCurTag; // pointer to active tag. Single index files have only one tag
+
+ private:
+ virtual void AppendNodeChain( void *vpTag, xbIxNode *npNode ) = 0;
+ virtual xbInt16 GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulKeyPtr ) const = 0;
+ virtual xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const = 0;
+ // virtual void SetCurNode( void *vpTag, xbIxNode *npNode ) = 0;
+
+ xbBool bLocked; // index file locked?
+};
+
+#ifdef XB_NDX_SUPPORT
+
+#define XB_NDX_BLOCK_SIZE 512
+
+
+///@cond DOXYOFF
+struct XBDLLEXPORT xbNdxTag {
+
+ // NDX File Header Fields
+ xbUInt32 ulRootBlock; // header node is 0
+ xbUInt32 ulTotalBlocks; // includes header node
+ char cKeyType; // C = Char, F = Numeric, D = Date
+ xbInt16 iKeyLen; // length of key data
+ xbInt16 iKeysPerBlock; // max number keys per block <=100
+ xbInt16 iKeyType; // 00 = Char, 01 = Numeric
+ xbInt16 iKeyItemLen; // KeyLen + 8 bytes
+ char cSerNo; // rolling incrementing serial number +1 on each index update
+ xbInt16 iUnique; // True if unique
+ xbString sKeyExpression; // index expression
+ // end of NDX Header field
+
+ xbExp *exp; // pointer to expression for expression keys
+ time_t tNodeChainTs; // node chain time stamp
+ xbIxNode *npNodeChain;
+ xbIxNode *npCurNode;
+ char *cpKeyBuf; // key buffer, for searches and adds
+ char *cpKeyBuf2; // key buffer, for deletes
+ xbString sTagName; // tag name - is the file name without the extension
+ xbBool bFoundSts; // key found? used to determine if new key should be added in XB_EMULATE_DBASE mode in AddKey
+
+
+ xbInt16 iKeySts; // key updated? set in method CreateKey, checked in AddKey and DeleteKey routines
+ // old key filtered new key filtered iKeySts
+ // Y Y XB_UPD_KEY 2 - update key if changed (delete and add)
+ // Y N XB_DEL_KEY 3 - delete key
+ // N Y XB_ADD_KEY 1 - add key
+ // N N 0 - no update
+
+};
+///@endcond DOXYOFF
+
+//! @brief Class for handling NDX single tag indices.
+/*!
+
+The xbIxNdx class is derived from the xbIx base class and is specific to handling NDX single tag index files.
+Each NDX index file can have only one tag, but the methods are set up to take an argument for a specific tag.
+This was done in order to provide a consistant interface across index types.
+
+Calls to the ndx index routines to perform index updates are handled automatically be the dbf class after
+the ndx file has been opened.
+
+Xbase64 provides a mechanism to automatically open ndx files when a dbf file is opened.
+If the ndx file has been associated with the dbf file with the metadata routines,
+it will be opened automatically when the dbf file is opened.
+If there are non prod ndx indices that are not associated with the dbf file, the application
+program will need to open as appropriate.
+The meta data association logic is specific to the Xbase64 library and is not applicable to
+other available tools that handle ndx indices.
+
+*/
+
+class XBDLLEXPORT xbIxNdx : public xbIx {
+ public:
+ xbIxNdx( xbDbf * d );
+ ~xbIxNdx();
+ xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt );
+ xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag );
+ xbInt16 FindKey( void *vpTag, const void *vpKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw );
+ xbInt16 GetFirstKey( void *vpTag, xbInt16 iRetrieveSw );
+
+ xbInt16 GetLastKey( void *vpTag, xbInt16 iRetrieveSw = 1 );
+ xbInt16 GetNextKey( void *vpTag, xbInt16 iRetrieveSw = 1 );
+ xbInt16 GetPrevKey( void *vpTag, xbInt16 iRetrieveSw = 1 );
+ xbInt32 GetKeyLen ( const void *vpTag ) const;
+ char GetKeyType ( const void *vpTag ) const;
+ xbString &GetKeyExpression( const void *vpTag ) const;
+ xbString &GetKeyFilter( const void *vpTag ) const;
+ void *GetTag( xbInt16 iTagNo ) const;
+ void *GetTag( xbString &sTagName ) const;
+ xbString &GetTagName( void *vpTag ) const;
+ const char * GetTagName( void *vpTag, xbInt16 iOpt ) const;
+
+ xbInt16 GetTagCount() const;
+ xbBool GetUnique( void *vpTag = NULL ) const;
+ xbBool GetSortOrder( void *vpTag ) const;
+ xbInt16 SetCurTag( xbInt16 iTagNo );
+ xbInt16 SetCurTag( xbString &sTagName );
+
+ #ifdef XB_DEBUG_SUPPORT
+ xbInt16 DumpTagBlocks( xbInt16 iOpt = 1, void *vpTag = NULL );
+ xbInt16 DumpHeader( xbInt16 iOpt = 0, xbInt16 iFmt = 0 );
+ xbInt16 DumpIxForTag( void *vpTag, xbInt16 iOutputOpt );
+ void DumpIxNodeChain( void *vpTag, xbInt16 iOutputOpt ) const;
+ xbInt16 DumpNode( void * vpTag, xbIxNode * pNode, xbInt16 iOption ) const;
+ #endif
+
+ xbInt16 Reindex( void **vpTag );
+
+
+ protected:
+ friend class xbDbf;
+ xbInt16 AddKey( void *vpTag, xbUInt32 ulRecNo );
+ xbIxNode *AllocateIxNode( xbUInt32 ulBufSize = 0, xbInt16 iOption = 0 );
+ xbInt16 CheckForDupKey( void *vpTag );
+ xbIxNode *CreateIxNode( xbUInt32 ulBufSize );
+ xbInt16 CreateKey( void * vpTag, xbInt16 iOpt );
+ xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo );
+ xbInt16 DeleteKey( void *vpTag );
+ xbInt16 DeleteTag( void *vpTag );
+ xbInt16 FindKeyForCurRec( void *vpTag );
+ xbInt16 GetKeyTypeN( const void *vpTag ) const;
+ xbInt16 GetKeySts( void *vpTag ) const;
+ xbInt16 GetLastKey( xbUInt32 ulNodeNo, void *vpTag, xbInt16 iRetrieveSw = 1 );
+ xbInt16 InsertNodeI( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, xbUInt32 uiPtr );
+ xbInt16 InsertNodeL( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, char * cpKeyBuf, xbUInt32 uiPtr );
+ xbInt16 KeyExists( void *vpTag = NULL );
+ xbInt16 ReadHeadBlock(xbInt16 iOpt); // read the header node of the disk NDX file
+// xbInt16 Reindex( void **vpTag );
+ xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr );
+ xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr );
+ xbInt16 UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo = 0 );
+ xbInt16 WriteHeadBlock( xbInt16 iOption );
+
+ private:
+ xbInt16 AddKeyNewRoot( xbNdxTag *npTag, xbIxNode *npLeft, xbIxNode *npRight );
+ void AppendNodeChain( void *vpTag, xbIxNode *npNode );
+ xbInt16 GetDbfPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulDbfPtr ) const;
+ xbInt16 GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulKeyPtr ) const;
+ xbInt16 GetLastKeyForBlockNo( void *vpTag, xbUInt32 ulBlockNo, char *cpKeyBuf );
+ xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const;
+ xbInt16 KeySetPosAdd( xbNdxTag *npTag, xbUInt32 ulAddKeyRecNo );
+ xbInt16 KeySetPosDel( xbNdxTag *npTag );
+ xbNdxTag *ndxTag;
+};
+
+#endif /* XB_NDX_SUPPORT */
+
+
+#ifdef XB_MDX_SUPPORT
+//#define XB_MDX_BLOCK_SIZE 1024
+
+struct XBDLLEXPORT xbMdxTag {
+
+ // next 7 fields comprise the tag table entry
+ xbUInt32 ulTagHdrPageNo; // 512 byte page number, NOT block number
+ char cTagName[11];
+ char cKeyFmt; // always 0x10 w/ DBase V7
+ char cLeftChild; // cFwdTagThread
+ char cRightChild; // cFwdTagThread2
+ char cParent; // cBwdTagThread
+ char c2;
+ char cKeyType; // C,D,N
+
+ xbUInt32 ulRootPage; // 512 byte page number, NOT block number
+ xbUInt32 ulTagSize; // Number of 512 byte pages allocated to the tag. Tag size of two is a single 1024 block
+
+ char cKeyFmt2; // 0x10 - base
+ // 0x08 - descending
+ // 0x40 - unique
+ char cKeyType2;
+ // one unused byte fits here
+
+ char cTag11; // dbase sets to 0x1B
+ xbInt16 iKeyLen;
+ xbInt16 iKeysPerBlock;
+ xbInt16 iSecKeyType;
+ xbInt16 iKeyItemLen; // iKeyLen + 4
+
+ char cSerialNo; // Increments +1 for each tag update
+ char cUnique;
+ xbString *sKeyExp; // Key expression
+ char cHasFilter; // 0x00 or 0x01
+ char cHasKeys; // 0x00 or 0x01
+ xbUInt32 ulLeftChild; // dbase 7 sets this to the root page on tag creation
+ xbUInt32 ulRightChild; // dbase 7 sets this to the root page on tag creation
+
+ char cTagYY;
+ char cTagMM;
+ char cTagDD;
+
+ char cKeyFmt3; // dbase 7 sets this 0x01 if discreet field or 0x00 if calculated or combination field key expression on tag creation
+
+ xbString *sFiltExp; // Filter expression
+
+ time_t tNodeChainTs;
+ xbIxNode *npNodeChain;
+ xbIxNode *npCurNode;
+ xbExp *exp; // pointer to expression for expression based tags
+ xbExp *filter; // pointer to expression for index filter
+
+ char *cpKeyBuf; // key buffer
+ char *cpKeyBuf2; // key buffer
+ xbString *sTagName; // string tag name
+
+
+ xbMdxTag *next;
+ xbBool bFoundSts; // key found? used to determine if new key should be added in XB_EMULATE_DBASE mode in AddKey
+
+
+ xbInt16 iKeySts; // key updated? set in method CreateKey, checked in AddKey and DeleteKey routines
+ // old key filtered new key filtered iKeySts
+ // Y Y XB_UPD_KEY 2 - update key if changed (delete and add)
+ // Y N XB_DEL_KEY 3 - delete key
+ // N Y XB_ADD_KEY 1 - add key
+ // N N 0 - no update
+
+
+};
+
+
+class XBDLLEXPORT xbIxMdx : public xbIx {
+ public:
+ xbIxMdx( xbDbf * d );
+ ~xbIxMdx();
+ virtual xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt );
+ virtual xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag );
+ virtual xbInt16 FindKey( void *vpTag, const void *vKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw );
+ virtual xbInt16 FindKey( void *vpTag, xbDouble dKey, xbInt16 iRetrieveSw );
+ virtual xbInt16 GetFirstKey( void *vpTag, xbInt16 lRetrieveSw );
+ virtual xbString &GetKeyExpression( const void *vpTag ) const;
+ virtual xbString &GetKeyFilter( const void *vpTag ) const;
+ virtual char GetKeyType( const void *vpTag ) const;
+ virtual xbInt16 GetLastKey( void *vpTag, xbInt16 lRetrieveSw );
+ virtual xbInt16 GetNextKey( void *vpTag, xbInt16 lRetrieveSw );
+ virtual xbInt16 GetPrevKey( void *vpTag, xbInt16 lRetrieveSw );
+ virtual xbBool GetReuseEmptyNodesSw() const;
+ virtual xbBool GetSortOrder( void *vpTag ) const;
+ virtual void *GetTag( xbInt16 iTagNo ) const;
+ virtual void *GetTag( xbString &sTagName ) const;
+ virtual xbInt16 GetTagCount() const;
+
+ virtual xbString &GetTagName( void *vpTag ) const;
+ virtual const char * GetTagName( void *vpTag, xbInt16 iOpt ) const;
+ virtual void GetTagName( void *vpTag, xbString &sTagName );
+
+ virtual xbInt16 GetUnique( void *vpTag ) const;
+ virtual xbInt16 SetCurTag( xbInt16 iTagNo );
+ virtual xbInt16 SetCurTag( xbString &sTagName );
+ void SetReuseEmptyNodesSw( xbBool bReuse );
+
+ void TestStub( char *s, void *vpTag );
+
+
+ virtual xbInt16 Reindex( void **vpTag );
+
+
+ protected:
+ friend class xbDbf;
+
+ xbInt16 AddKey( void *vpTag, xbUInt32 ulRecNo );
+ xbIxNode *AllocateIxNode( xbMdxTag * mpTag, xbUInt32 ulBufSize, xbUInt32 ulBlock2 );
+ void CalcBtreePointers();
+ char CalcTagKeyFmt( xbExp &exp );
+
+ xbInt16 CheckForDupKey( void *vpTag );
+ virtual xbInt16 Close();
+ xbInt16 CreateKey( void * vpTag, xbInt16 iOpt );
+ xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo );
+ xbInt16 DeleteKey( void *vpTag );
+
+ virtual xbInt16 DeleteTag( void *vpTag );
+
+ xbInt16 FindKeyForCurRec( void *vpTag );
+ xbInt16 GetKeySts( void *vpTag ) const;
+ xbInt16 GetLastKey( xbUInt32 ulBlockNo, void *vpTag, xbInt16 lRetrieveSw );
+ void *GetTagTblPtr() const;
+
+ xbInt16 HarvestTagNodes( xbMdxTag *mpTag, xbBool bRecycleRoot = xbFalse );
+ void Init( xbInt16 iOpt = 0 );
+ xbInt16 InsertNodeI( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo, xbUInt32 uiPtr );
+ xbInt16 InsertNodeL( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr );
+ xbInt16 KeyExists( void * );
+ xbInt16 LoadTagTable();
+ xbInt16 ReadHeadBlock(xbInt16 iOpt); // read the header node of the disk file
+ //virtual xbInt16 Reindex( void **vpTag );
+ xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr );
+ xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr );
+ xbInt16 UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo = 0 );
+ xbInt16 WriteHeadBlock( xbInt16 iOption );
+
+ #ifdef XB_DEBUG_SUPPORT
+ xbInt16 DumpTagBlocks( xbInt16 iOpt = 1, void *vpTag = NULL );
+ xbInt16 DumpFreeBlocks( xbInt16 iOpt = 0 );
+ xbInt16 DumpHeader( xbInt16 iOpt = 0, xbInt16 iFmtOpt = 0 );
+ xbInt16 DumpIxForTag( void *vpTag, xbInt16 iOutputOpt );
+ void DumpIxNodeChain( void *vpTag, xbInt16 iOutputOpt ) const;
+ #endif
+
+
+ xbMdxTag *mdxTagTbl;
+
+// MDX File Header Fields
+ char cVersion;
+ char cCreateYY;
+ char cCreateMM;
+ char cCreateDD;
+ xbString sFileName;
+ xbInt16 iBlockFactor; // 1-32 #of 512 byte segments in a block
+
+ // use file version
+ // xbInt16 iBlockSize; // Stored at the xbFile level
+
+ char cProdIxFlag;
+ char cTagEntryCnt;
+ xbInt16 iTagLen;
+ xbInt16 iTagUseCnt;
+ char cNextTag; // byte 28 +1
+ char c1B; // always 0x1B
+ xbUInt32 ulPageCnt; // number of 512 byte pages in the mdx file
+ xbUInt32 ulFirstFreePage; // page number corresponding to the next free block
+ xbUInt32 ulNoOfBlockAvail; // might be improperly named?? not sure how it is used
+ char cUpdateYY;
+ char cUpdateMM;
+ char cUpdateDD;
+ // end of MDX Header fields
+
+
+ xbBool bReuseEmptyNodes; // Reuese empty MDX nodes when all keys deleted?
+ // DBase 7.x and MS ODBC drivers do not reuse empty nodes, leaves them stranded in the file
+ // Codebase 6.x reuses empty nodes.
+ // Setting this to True will reuse empty nodes in the same manner Codebase 6.x reuses them.
+
+
+ private:
+ xbInt16 AddKeyNewRoot( xbMdxTag *npTag, xbIxNode *npLeft, xbIxNode *npRight );
+ void AppendNodeChain( void *vpTag, xbIxNode *npNode );
+ xbUInt32 BlockToPage( xbUInt32 ulBlockNo );
+ xbMdxTag *ClearTagTable();
+ xbInt16 DumpBlock( xbInt16 iOpt, xbUInt32 ulBlockNo, xbMdxTag * mpTag );
+ xbInt16 GetDbfPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulDbfPtr ) const;
+ xbInt16 GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulKeyPtr ) const;
+ xbInt16 GetLastKeyForBlockNo( void *vpTag, xbUInt32 ulBlockNo, char *cpKeyBuf );
+ xbInt16 HarvestEmptyNode( xbMdxTag *mpTag, xbIxNode *npNode, xbInt16 iOpt, xbBool bHarvestRoot = xbFalse );
+ xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const;
+ xbInt16 KeySetPosAdd( xbMdxTag *mpTag, xbUInt32 ulAddKeyRecNo );
+ xbInt16 KeySetPosDel( xbMdxTag *mpTag );
+ xbInt16 LoadTagDetail( xbInt16 iOption, xbMdxTag *tte );
+ xbUInt32 PageToBlock( xbUInt32 ulPageNo );
+ xbInt16 TagSerialNo( xbInt16 iOption, xbMdxTag *mpTag );
+ xbInt16 UpdateTagSize( xbMdxTag *mpTag, xbUInt32 ulTagSz );
+
+ #ifdef XB_DEBUG_SUPPORT
+ xbInt16 PrintKey( void *vpTag, xbIxNode *npNode, xbInt16 iKeyNo, xbInt16 iDepth, char cType, xbInt16 iOutputOpt );
+ #endif
+
+
+ };
+ #endif /* XB_MDX_SUPPORT */
+
+
+#ifdef XB_TDX_SUPPORT
+
+class XBDLLEXPORT xbIxTdx : public xbIxMdx {
+ public:
+ xbIxTdx( xbDbf * d );
+ ~xbIxTdx();
+
+ xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag );
+
+ protected:
+ friend class xbDbf;
+ xbInt16 Close();
+ xbInt16 DeleteTag( void *vpTag );
+
+ private:
+};
+
+#endif /* XB_TDX_SUPPORT */
+
+
+ } /* namespace xb */
+ #endif /* XB_INDEX_SUPPORT */
+#endif /* __XB_INDEX_H__ */
diff --git a/src/include/xbindex.h.nope b/src/include/xbindex.h.nope
new file mode 100755
index 0000000..b42f76e
--- /dev/null
+++ b/src/include/xbindex.h.nope
@@ -0,0 +1,605 @@
+/* xbindex.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014, 2018, 2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_INDEX_H__
+#define __XB_INDEX_H__
+
+#ifdef XB_INDEX_SUPPORT
+
+
+#define XB_ADD_KEY 1
+#define XB_UPD_KEY 2
+#define XB_DEL_KEY 3
+
+namespace xb{
+
+
+
+///@cond DOXYOFF
+// structure for index nodes, each node contains information regarding one block
+struct XBDLLEXPORT xbIxNode {
+ xbIxNode *npPrev; // pointer to previous node in chain
+ xbIxNode *npNext; // pointer to next node in chain
+ xbUInt32 iCurKeyNo; // current key number in the node, 0 offset
+ xbUInt32 ulBlockNo; // this block number
+ xbUInt32 ulBufSize; // size of cpBlockData
+ char *cpBlockData; // pointer to memory version of block data stored in file
+};
+///@endcond DOXYOFF
+
+
+//! @brief Base class for handling dbf indices.
+/*!
+
+The xbIx class is used as a base class for accessing index files.
+Each index file can have one or more tags.
+
+Calls to the index routines to perform index updates are handled automatically by the dbf class.
+The application program does not need to be concerned with index updates.
+
+If there is a production MDX index, it is opened automatically when the dbf file is opened.
+If there is an ndx file, that has been associated with the dbf file with the metadata routines,
+it will be opened automatically when the dbf file is opened.
+If there are non prod ndx indices that are not associated with the dbf file, the application
+program will need to open as appropriate.
+The meta data association logic is specific to the Xbase64 library and is not applicable to
+other available tools that handle ndx indices.
+All index files are automatically closed when the dbf file is closed.
+
+
+<br>
+The class is designed to support the addition of additional indices with a minimal amount of effort
+needed to integrate into the library.
+If you are looking at adding an new index type to the library, create a derived class using xbIx as a
+base class and modify methods needed to support the new index file version.
+The xbDbf class (and derived classes) perform the needed calls to the index routines for updates.<br>
+See the following for examples on how to start on this:<br>
+xbIxNdx is a derived class and supports a single tag.<br>
+xbIxMdx is a derived class and supports multiple tags.<br>
+
+
+
+<br>
+How data fields are stored in index files:
+<table>
+<tr><th>Field Type<th>Stored in DBF as<th>Stored in NDX as<th>Stored in MDX as</tr>
+<tr><td>C<td>char<td>char<td>char
+<tr><td>F<td>text numbers<td>xbDouble<td>xbBcd
+<tr><td>N<td>text numbers<td>xbDouble<td>xbBcd
+<tr><td>D<td>text CCYYMMDD<td>xbDouble - julian<td>xbDouble - julian
+</table>
+
+
+<br>
+Pages Vs Blocks
+<br>
+For purposes of the Xbase index classes, a page is considered to be 512 bytes of data
+and a block is made up of one or more 512 byte pages.
+<br>Default block sixe of NDX indices is one 512 byte page.
+<br>Default block size of MDX indices is two 512 byte pages or 1024 bytes.
+
+<br>The WriteBlock and GetBlock functions calculate the physical position in the
+file based on a combination of Block Number and Block Size. Block size is set at
+time of index file creation, default is 1024 or two pages.
+
+<br>Page numbers are stored in the physical file, but block reads and writes
+are performed.
+
+<br>
+Duplicate Keys
+<br>
+With the original DBase unique indexing option, if a table has multiple records with the
+same key value, DBase would allow multiple records in the table, but only the first
+record would be found in the index.
+<br>
+XBase64 can be configured to support the original DBase duplicate key implementation,
+or can be configured to halt with a DUPLICATE_KEY error on the insertion of a record
+with a duplicate key.
+<br>
+<table>
+<tr><th>Option<th>Description</tr>
+<tr><td>XB_HALT_ON_DUPKEY</td><td>Return error XB_KEY_NOT_UNIQUE when attempting to append record with duplicate key</td></tr>
+<tr><td>XB_EMULATE_DBASE</td><td>Emulate DBase, allow duplicate records with the same key, only the first record is indexed</td></tr>
+</table>
+*/
+
+
+class XBDLLEXPORT xbIx : public xbFile {
+ public:
+ xbIx( xbDbf * d );
+ virtual ~xbIx();
+
+ virtual xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt ) = 0;
+ virtual xbInt16 Close();
+ virtual xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag ) = 0;
+ virtual xbInt16 FindKey( void *vpTag, const xbString &sKey, xbInt16 iRetrieveSw );
+ virtual xbInt16 FindKey( void *vpTag, const char * cKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw );
+ virtual xbInt16 FindKey( void *vpTag, const xbBcd &bcd, xbInt16 iRetrieveSw );
+ virtual xbInt16 FindKey( void *vpTag, const xbDate &dtKey, xbInt16 iRetrieveSw );
+ virtual xbInt16 FindKey( void *vpTag, xbDouble dKey, xbInt16 iRetrieveSw );
+ virtual xbInt16 FindKey( void *vpTag, const void *vKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw ) = 0;
+ virtual void *GetCurTag() const;
+ virtual xbDbf *GetDbf() const;
+
+ virtual xbString &GetKeyExpression( const void *vpTag ) const = 0;
+ virtual xbString &GetKeyFilter( const void *vpTag ) const = 0;
+ virtual char GetKeyType( const void *vpTag ) const = 0;
+ virtual xbBool GetLocked() const;
+
+ virtual xbInt16 GetFirstKey( void *vpTag, xbInt16 iRetrieveSw ) = 0;
+ virtual xbInt16 GetFirstKey( void *vpTag );
+ virtual xbInt16 GetFirstKey();
+
+ virtual xbInt16 GetLastKey( void *vpTag, xbInt16 lRetrieveSw ) = 0;
+ virtual xbInt16 GetLastKey( void *vpTag );
+ virtual xbInt16 GetLastKey();
+
+ virtual xbInt16 GetNextKey( void *vpTag, xbInt16 iRetrieveSw ) = 0;
+ virtual xbInt16 GetNextKey( void *vpTag );
+ virtual xbInt16 GetNextKey();
+
+ virtual xbInt16 GetPrevKey( void *vpTag, xbInt16 iRetrieveSw ) = 0;
+ virtual xbInt16 GetPrevKey( void *vpTag );
+ virtual xbInt16 GetPrevKey();
+
+ virtual void *GetTag( xbInt16 iTagNo ) const = 0;
+ virtual void *GetTag( xbString &sTagName ) const = 0;
+ virtual xbInt16 GetTagCount() const = 0;
+
+ virtual xbString &GetTagName( void *vpTag ) const = 0;
+ virtual const char * GetTagName( void *vpTag, xbInt16 iOpt ) const = 0;
+ virtual void GetTagName( void *vpTag, xbString &sTagName ) {};
+
+ virtual xbBool GetUnique( void *vpTag ) const = 0;
+ virtual xbBool GetSortOrder( void *vpTag ) const = 0;
+
+ virtual xbInt16 Open( const xbString &sFileName );
+ virtual xbInt16 Reindex( void **vpTag ) = 0;
+ virtual xbInt16 SetCurTag( xbInt16 iTagNo ) = 0;
+ virtual xbInt16 SetCurTag( xbString &sTagName ) = 0;
+ virtual void SetCurTag( void * vpCurTag );
+ virtual void SetLocked( xbBool bLocked );
+
+ virtual void TestStub( char *s, void *vpTag ) {};
+
+
+ #ifdef XB_DEBUG_SUPPORT
+ virtual xbInt16 DumpFreeBlocks( xbInt16 iOpt = 0 ) { return XB_NO_ERROR; }
+ virtual xbInt16 DumpHeader( xbInt16 iDestOpt = 0, xbInt16 iFmtOpt = 0 ) = 0;
+ virtual xbInt16 DumpIxForTag( void *vpTag, xbInt16 iOutputOpt ) = 0;
+ virtual void DumpIxNodeChain( void *vpTag, xbInt16 iOutputOpt ) const = 0;
+ virtual xbInt16 DumpNode( void * vpTag, xbIxNode * pNode, xbInt16 iOption ) const;
+ virtual xbInt16 DumpTagBlocks( xbInt16 iOpt = 1, void *vpTag = NULL ) = 0;
+
+ #endif
+
+ protected:
+ friend class xbDbf;
+
+ virtual xbInt16 AddKey( void *vpTag, xbUInt32 ulRecNo ) = 0;
+ virtual xbInt16 AddKeys( xbUInt32 ulRecNo );
+ virtual xbIxNode *AllocateIxNode( xbUInt32 ulBufSize = 0, xbInt16 iOption = 0 );
+ virtual xbInt16 BSearchBlock( char cKeyType, xbIxNode *npNode, xbInt32 lKeyLen, const void *vpKey, xbInt32 lSearchKeyLen, xbInt16 &iCompRc, xbBool bDescending = xbFalse ) const;
+ virtual xbInt16 CheckForDupKeys();
+ virtual xbInt16 CheckForDupKey( void *vpTag ) = 0;
+ virtual xbInt16 CompareKey( char cKeyType, const void *v1, const void *v2, size_t lKeyLen ) const;
+ virtual xbInt16 CreateKeys( xbInt16 iOpt );
+ virtual xbInt16 CreateKey( void * vpTag, xbInt16 iOpt ) = 0;
+ virtual xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo ) = 0;
+// virtual xbInt16 DeleteKeys( xbUInt32 ulRecNo );
+ virtual xbInt16 DeleteKeys();
+ virtual xbInt16 DeleteKey( void *vpTag ) = 0;
+
+ virtual xbInt16 DeleteTag( void *vpTag ) = 0;
+
+
+ virtual xbInt16 FindKeyForCurRec( void *vpTag ) = 0;
+ virtual xbIxNode *FreeNodeChain( xbIxNode *np );
+ virtual xbInt16 GetBlock( void *vpTag, xbUInt32 ulBlockNo, xbInt16 iOpt, xbUInt32 ulAddlBuf = 0 );
+// virtual xbBool GetIndexUpdated() const = 0;
+ virtual xbInt32 GetKeyCount( xbIxNode *npNode ) const;
+ virtual char *GetKeyData( xbIxNode *npNode, xbInt16 iKeyNo, xbInt16 iKeyItemLen ) const;
+ virtual xbInt16 GetKeySts( void *vpTag ) const = 0;
+ virtual xbInt16 GetLastKey( xbUInt32 ulNodeNo, void *vpTag, xbInt16 lRetrieveSw ) = 0;
+ virtual xbInt16 InsertNodeL( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, char * cpKeyBuf, xbUInt32 uiPtr ) = 0;
+ virtual xbInt16 InsertNodeI( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, xbUInt32 uiPtr ) = 0;
+ virtual xbInt16 KeyExists( void * ) = 0;
+// virtual xbInt16 KeyUpdated( void *vpTag ) const = 0;
+ virtual void NodeFree( xbIxNode * ixNode );
+ virtual xbInt16 ReadHeadBlock( xbInt16 iOpt = 0 ) = 0;
+ virtual void SetDbf( xbDbf *dbf );
+ virtual xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr ) = 0;
+ virtual xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr ) = 0;
+ virtual xbInt16 UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo = 0 ) = 0;
+ virtual xbInt16 WriteHeadBlock( xbInt16 iOption ) = 0;
+
+ xbDbf *dbf;
+ char *cNodeBuf; // pointer to memory for processing in a block of index data
+ void *vpCurTag; // pointer to active tag. Single index files have only one tag
+
+ private:
+ virtual void AppendNodeChain( void *vpTag, xbIxNode *npNode ) = 0;
+ virtual xbInt16 GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulKeyPtr ) const = 0;
+ virtual xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const = 0;
+ // virtual void SetCurNode( void *vpTag, xbIxNode *npNode ) = 0;
+
+ xbBool bLocked; // index file locked?
+};
+
+#ifdef XB_NDX_SUPPORT
+
+#define XB_NDX_BLOCK_SIZE 512
+
+
+///@cond DOXYOFF
+struct XBDLLEXPORT xbNdxTag {
+
+ // NDX File Header Fields
+ xbUInt32 ulRootBlock; // header node is 0
+ xbUInt32 ulTotalBlocks; // includes header node
+ char cKeyType; // C = Char, F = Numeric, D = Date
+ xbInt16 iKeyLen; // length of key data
+ xbInt16 iKeysPerBlock; // max number keys per block <=100
+ xbInt16 iKeyType; // 00 = Char, 01 = Numeric
+ xbInt16 iKeyItemLen; // KeyLen + 8 bytes
+ char cSerNo; // rolling incrementing serial number +1 on each index update
+ xbInt16 iUnique; // True if unique
+ xbString sKeyExpression; // index expression
+ // end of NDX Header field
+
+ xbExp *exp; // pointer to expression for expression keys
+ time_t tNodeChainTs; // node chain time stamp
+ xbIxNode *npNodeChain;
+ xbIxNode *npCurNode;
+ char *cpKeyBuf; // key buffer, for searches and adds
+ char *cpKeyBuf2; // key buffer, for deletes
+ xbString sTagName; // tag name - is the file name without the extension
+// xbInt16 iKeyUpdated; // key updated? set in method KeyUpdated, checked in AddKey and DeleteKey routines
+ xbBool bFoundSts; // key found? used to determine if new key should be added in XB_EMULATE_DBASE mode in AddKey
+
+
+ xbInt16 iKeySts; // key updated? set in method CreateKey, checked in AddKey and DeleteKey routines
+ // old key filtered new key filtered iKeySts
+ // Y Y XB_UPD_KEY 2 - update key if changed (delete and add)
+ // Y N XB_DEL_KEY 3 - delete key
+ // N Y XB_ADD_KEY 1 - add key
+ // N N 0 - no update
+
+};
+///@endcond DOXYOFF
+
+//! @brief Class for handling NDX single tag indices.
+/*!
+
+The xbIxNdx class is derived from the xbIx base class and is specific to handling NDX single tag index files.
+Each NDX index file can have only one tag, but the methods are set up to take an argument for a specific tag.
+This was done in order to provide a consistant interface across index types.
+
+Calls to the ndx index routines to perform index updates are handled automatically be the dbf class after
+the ndx file has been opened.
+
+Xbase64 provides a mechanism to automatically open ndx files when a dbf file is opened.
+If the ndx file has been associated with the dbf file with the metadata routines,
+it will be opened automatically when the dbf file is opened.
+If there are non prod ndx indices that are not associated with the dbf file, the application
+program will need to open as appropriate.
+The meta data association logic is specific to the Xbase64 library and is not applicable to
+other available tools that handle ndx indices.
+
+*/
+
+class XBDLLEXPORT xbIxNdx : public xbIx {
+ public:
+ xbIxNdx( xbDbf * d );
+ ~xbIxNdx();
+ xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt );
+ xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag );
+// xbInt16 DeleteTag( void *vpTag );
+ xbInt16 FindKey( void *vpTag, const void *vpKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw );
+ xbInt16 GetFirstKey( void *vpTag, xbInt16 iRetrieveSw );
+
+ xbInt16 GetLastKey( void *vpTag, xbInt16 iRetrieveSw = 1 );
+ xbInt16 GetNextKey( void *vpTag, xbInt16 iRetrieveSw = 1 );
+ xbInt16 GetPrevKey( void *vpTag, xbInt16 iRetrieveSw = 1 );
+ xbInt32 GetKeyLen ( const void *vpTag ) const;
+ char GetKeyType ( const void *vpTag ) const;
+ xbString &GetKeyExpression( const void *vpTag ) const;
+ xbString &GetKeyFilter( const void *vpTag ) const;
+ void *GetTag( xbInt16 iTagNo ) const;
+ void *GetTag( xbString &sTagName ) const;
+ xbString &GetTagName( void *vpTag ) const;
+ const char * GetTagName( void *vpTag, xbInt16 iOpt ) const;
+
+ xbInt16 GetTagCount() const;
+ xbBool GetUnique( void *vpTag = NULL ) const;
+ xbBool GetSortOrder( void *vpTag ) const;
+ xbInt16 Reindex( void **vpTag );
+ xbInt16 SetCurTag( xbInt16 iTagNo );
+ xbInt16 SetCurTag( xbString &sTagName );
+
+
+
+ #ifdef XB_DEBUG_SUPPORT
+ xbInt16 DumpTagBlocks( xbInt16 iOpt = 1, void *vpTag = NULL );
+ xbInt16 DumpHeader( xbInt16 iOpt = 0, xbInt16 iFmt = 0 );
+ xbInt16 DumpIxForTag( void *vpTag, xbInt16 iOutputOpt );
+ void DumpIxNodeChain( void *vpTag, xbInt16 iOutputOpt ) const;
+ xbInt16 DumpNode( void * vpTag, xbIxNode * pNode, xbInt16 iOption ) const;
+ #endif
+
+ protected:
+ friend class xbDbf;
+ xbInt16 AddKey( void *vpTag, xbUInt32 ulRecNo );
+ xbIxNode *AllocateIxNode( xbUInt32 ulBufSize = 0, xbInt16 iOption = 0 );
+ xbInt16 CheckForDupKey( void *vpTag );
+ xbIxNode *CreateIxNode( xbUInt32 ulBufSize );
+ xbInt16 CreateKey( void * vpTag, xbInt16 iOpt );
+ xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo );
+ xbInt16 DeleteKey( void *vpTag );
+
+ xbInt16 DeleteTag( void *vpTag );
+
+ xbInt16 FindKeyForCurRec( void *vpTag );
+// xbBool GetIndexUpdated() const;
+ xbInt16 GetKeyTypeN( const void *vpTag ) const;
+ xbInt16 GetKeySts( void *vpTag ) const;
+ xbInt16 GetLastKey( xbUInt32 ulNodeNo, void *vpTag, xbInt16 iRetrieveSw = 1 );
+ xbInt16 InsertNodeI( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, xbUInt32 uiPtr );
+ xbInt16 InsertNodeL( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, char * cpKeyBuf, xbUInt32 uiPtr );
+ xbInt16 KeyExists( void *vpTag = NULL );
+// xbBool KeyFiltered( void *vpTag ) const;
+// xbInt16 KeyUpdated( void *vpTag ) const;
+ xbInt16 ReadHeadBlock(xbInt16 iOpt); // read the header node of the disk NDX file
+ xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr );
+ xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr );
+ xbInt16 UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo = 0 );
+ xbInt16 WriteHeadBlock( xbInt16 iOption );
+
+ private:
+ xbInt16 AddKeyNewRoot( xbNdxTag *npTag, xbIxNode *npLeft, xbIxNode *npRight );
+ void AppendNodeChain( void *vpTag, xbIxNode *npNode );
+ xbInt16 GetDbfPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulDbfPtr ) const;
+ xbInt16 GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulKeyPtr ) const;
+ xbInt16 GetLastKeyForBlockNo( void *vpTag, xbUInt32 ulBlockNo, char *cpKeyBuf );
+ xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const;
+ xbInt16 KeySetPosAdd( xbNdxTag *npTag, xbUInt32 ulAddKeyRecNo );
+ xbInt16 KeySetPosDel( xbNdxTag *npTag );
+ // void SetCurNode( void *vpTag, xbIxNode *np );
+ xbNdxTag *ndxTag;
+};
+
+#endif /* XB_NDX_SUPPORT */
+
+
+#ifdef XB_MDX_SUPPORT
+//#define XB_MDX_BLOCK_SIZE 1024
+
+struct XBDLLEXPORT xbMdxTag {
+
+ // next 7 fields comprise the tag table entry
+ xbUInt32 ulTagHdrPageNo; // 512 byte page number, NOT block number
+ char cTagName[11];
+ char cKeyFmt; // always 0x10 w/ DBase V7
+ char cLeftChild; // cFwdTagThread
+ char cRightChild; // cFwdTagThread2
+ char cParent; // cBwdTagThread
+ char c2;
+ char cKeyType; // C,D,N
+
+ xbUInt32 ulRootPage; // 512 byte page number, NOT block number
+ xbUInt32 ulTagSize; // Number of 512 byte pages allocated to the tag. Tag size of two is a single 1024 block
+
+ char cKeyFmt2; // 0x10 - base
+ // 0x08 - descending
+ // 0x40 - unique
+ char cKeyType2;
+ // one unused byte fits here
+
+ char cTag11; // dbase sets to 0x1B
+
+ xbInt16 iKeyLen;
+ xbInt16 iKeysPerBlock;
+ xbInt16 iSecKeyType;
+ xbInt16 iKeyItemLen; // iKeyLen + 4
+
+ char cSerialNo; // Increments +1 for each tag update
+ char cUnique;
+ xbString *sKeyExp; // Key expression
+
+ char cHasFilter; // 0x00 or 0x01
+ char cHasKeys; // 0x00 or 0x01
+
+ xbUInt32 ulLeftChild; // dbase 7 sets this to the root page on tag creation
+ xbUInt32 ulRightChild; // dbase 7 sets this to the root page on tag creation
+
+ char cTagYY;
+ char cTagMM;
+ char cTagDD;
+
+ char cKeyFmt3; // dbase 7 sets this 0x01 if discreet field or 0x00 if calculated or combination field key expression on tag creation
+
+ xbString *sFiltExp; // Filter expression
+
+ time_t tNodeChainTs;
+ xbIxNode *npNodeChain;
+ xbIxNode *npCurNode;
+ xbExp *exp; // pointer to expression for expression based tags
+ xbExp *filter; // pointer to expression for index filter
+
+ char *cpKeyBuf; // key buffer
+ char *cpKeyBuf2; // key buffer
+// xbBool iKeyUpdated; // key updated? set in method CreateKey, checked in AddKey and DeleteKey routines
+ // 0 - no update
+ // 1 - Add
+ // 2 - Update
+ // 3 - Delete
+// xbBool bKeyFiltered; // key filtered? True if included key, False if excluded key. Set in method CreateKey, checked in AddKey and DeleteKey routines
+ xbString *sTagName; // string tag name
+
+
+ xbMdxTag *next;
+ xbBool bFoundSts; // key found? used to determine if new key should be added in XB_EMULATE_DBASE mode in AddKey
+
+
+ xbInt16 iKeySts; // key updated? set in method CreateKey, checked in AddKey and DeleteKey routines
+ // old key filtered new key filtered iKeySts
+ // Y Y XB_UPD_KEY 2 - update key if changed (delete and add)
+ // Y N XB_DEL_KEY 3 - delete key
+ // N Y XB_ADD_KEY 1 - add key
+ // N N 0 - no update
+
+
+};
+
+
+class XBDLLEXPORT xbIxMdx : public xbIx {
+ public:
+ xbIxMdx( xbDbf * d );
+ ~xbIxMdx();
+ xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt );
+ xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag );
+// xbInt16 DeleteTag( void *vpTag );
+ xbInt16 FindKey( void *vpTag, const void *vKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw );
+ xbInt16 FindKey( void *vpTag, xbDouble dKey, xbInt16 iRetrieveSw );
+ xbInt16 GetFirstKey( void *vpTag, xbInt16 lRetrieveSw );
+ xbString &GetKeyExpression( const void *vpTag ) const;
+ xbString &GetKeyFilter( const void *vpTag ) const;
+ char GetKeyType( const void *vpTag ) const;
+ xbInt16 GetLastKey( void *vpTag, xbInt16 lRetrieveSw );
+ xbInt16 GetNextKey( void *vpTag, xbInt16 lRetrieveSw );
+ xbInt16 GetPrevKey( void *vpTag, xbInt16 lRetrieveSw );
+ xbBool GetReuseEmptyNodesSw() const;
+ xbBool GetSortOrder( void *vpTag ) const;
+ void *GetTag( xbInt16 iTagNo ) const;
+ void *GetTag( xbString &sTagName ) const;
+ xbInt16 GetTagCount() const;
+
+ xbString &GetTagName( void *vpTag ) const;
+ const char * GetTagName( void *vpTag, xbInt16 iOpt ) const;
+ void GetTagName( void *vpTag, xbString &sTagName );
+
+ xbInt16 GetUnique( void *vpTag ) const;
+ xbInt16 Reindex( void **vpTag );
+ xbInt16 SetCurTag( xbInt16 iTagNo );
+ xbInt16 SetCurTag( xbString &sTagName );
+ void SetReuseEmptyNodesSw( xbBool bReuse );
+
+ void TestStub( char *s, void *vpTag );
+
+ protected:
+ friend class xbDbf;
+
+ xbInt16 AddKey( void *vpTag, xbUInt32 ulRecNo );
+ xbIxNode *AllocateIxNode( xbMdxTag * mpTag, xbUInt32 ulBufSize, xbUInt32 ulBlock2 );
+ xbInt16 CheckForDupKey( void *vpTag );
+ xbInt16 Close();
+ xbInt16 CreateKey( void * vpTag, xbInt16 iOpt );
+ xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo );
+ xbInt16 DeleteKey( void *vpTag );
+
+ xbInt16 DeleteTag( void *vpTag );
+
+ xbInt16 FindKeyForCurRec( void *vpTag );
+ xbInt16 GetKeySts( void *vpTag ) const;
+ xbInt16 GetLastKey( xbUInt32 ulBlockNo, void *vpTag, xbInt16 lRetrieveSw );
+ void *GetTagTblPtr() const;
+ void Init( xbInt16 iOpt = 0 );
+ xbInt16 InsertNodeI( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo, xbUInt32 uiPtr );
+ xbInt16 InsertNodeL( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr );
+ xbInt16 KeyExists( void * );
+ xbInt16 LoadTagTable();
+ xbInt16 ReadHeadBlock(xbInt16 iOpt); // read the header node of the disk file
+ xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr );
+ xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr );
+ xbInt16 UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo = 0 );
+ xbInt16 WriteHeadBlock( xbInt16 iOption );
+
+ #ifdef XB_DEBUG_SUPPORT
+ xbInt16 DumpTagBlocks( xbInt16 iOpt = 1, void *vpTag = NULL );
+ xbInt16 DumpFreeBlocks( xbInt16 iOpt = 0 );
+ xbInt16 DumpHeader( xbInt16 iOpt = 0, xbInt16 iFmtOpt = 0 );
+ xbInt16 DumpIxForTag( void *vpTag, xbInt16 iOutputOpt );
+ void DumpIxNodeChain( void *vpTag, xbInt16 iOutputOpt ) const;
+ #endif
+
+ private:
+ xbInt16 AddKeyNewRoot( xbMdxTag *npTag, xbIxNode *npLeft, xbIxNode *npRight );
+ void AppendNodeChain( void *vpTag, xbIxNode *npNode );
+ xbUInt32 BlockToPage( xbUInt32 ulBlockNo );
+ void CalcBtreePointers();
+ char CalcTagKeyFmt( xbExp &exp );
+ char CalcTagFwdThread1();
+ char CalcTagFwdThread2();
+ xbMdxTag *ClearTagTable();
+ xbInt16 DumpBlock( xbInt16 iOpt, xbUInt32 ulBlockNo, xbMdxTag * mpTag );
+ xbInt16 GetDbfPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulDbfPtr ) const;
+ xbInt16 GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulKeyPtr ) const;
+ xbInt16 GetLastKeyForBlockNo( void *vpTag, xbUInt32 ulBlockNo, char *cpKeyBuf );
+ xbInt16 HarvestEmptyNode( xbMdxTag *mpTag, xbIxNode *npNode, xbInt16 iOpt, xbBool bHarvestRoot = xbFalse );
+ xbInt16 HarvestTagNodes( xbMdxTag *mpTag, xbBool bRecycleRoot = xbFalse );
+ xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const;
+ xbInt16 KeySetPosAdd( xbMdxTag *mpTag, xbUInt32 ulAddKeyRecNo );
+ xbInt16 KeySetPosDel( xbMdxTag *mpTag );
+ xbInt16 LoadTagDetail( xbInt16 iOption, xbMdxTag *tte );
+ xbUInt32 PageToBlock( xbUInt32 ulPageNo );
+ xbInt16 TagSerialNo( xbInt16 iOption, xbMdxTag *mpTag );
+ xbInt16 UpdateTagSize( xbMdxTag *mpTag, xbUInt32 ulTagSz );
+
+ #ifdef XB_DEBUG_SUPPORT
+ xbInt16 PrintKey( void *vpTag, xbIxNode *npNode, xbInt16 iKeyNo, xbInt16 iDepth, char cType, xbInt16 iOutputOpt );
+ #endif
+
+ // MDX File Header Fields
+ char cVersion;
+ char cCreateYY;
+ char cCreateMM;
+ char cCreateDD;
+ xbString sFileName;
+ xbInt16 iBlockFactor; // 1-32 #of 512 byte segments in a block
+
+ // use file version
+ // xbInt16 iBlockSize; // Stored at the xbFile level
+
+ char cProdIxFlag;
+ char cTagEntryCnt;
+ xbInt16 iTagLen;
+ xbInt16 iTagUseCnt;
+ char cNextTag; // byte 28 +1
+ char c1B; // always 0x1B
+ xbUInt32 ulPageCnt; // number of 512 byte pages in the mdx file
+ xbUInt32 ulFirstFreePage; // page number corresponding to the next free block
+ xbUInt32 ulNoOfBlockAvail; // might be improperly named?? not sure how it is used
+ char cUpdateYY;
+ char cUpdateMM;
+ char cUpdateDD;
+ // end of MDX Header fields
+
+
+
+ xbMdxTag *mdxTagTbl;
+
+ xbBool bReuseEmptyNodes; // Reuese empty MDX nodes when all keys deleted?
+ // DBase 7.x and MS ODBC drivers do not reuse empty nodes, leaves them stranded in the file
+ // Codebase 6.x reuses empty nodes.
+ // Setting this to True will reuse empty nodes in the same manner Codebase 6.x reuses them.
+
+};
+#endif /* XB_MDX_SUPPORT */
+
+
+} /* namespace xb */
+#endif /* XB_INDEX_SUPPORT */
+#endif /* __XB_INDEX_H__ */
diff --git a/src/include/xblnklst.h b/src/include/xblnklst.h
new file mode 100755
index 0000000..eaec587
--- /dev/null
+++ b/src/include/xblnklst.h
@@ -0,0 +1,257 @@
+/* xblnklst.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_XBLNKLST_H__
+#define __XB_XBLNKLST_H__
+
+#ifdef XB_LINKLIST_SUPPORT
+
+namespace xb{
+
+
+template<class xbNodeType>
+class XBDLLEXPORT xbLinkList {
+ public:
+ xbLinkList();
+ ~xbLinkList();
+
+ xbLinkListNode<xbNodeType> *GetHeadNode() const;
+ xbLinkListNode<xbNodeType> *GetEndNode() const;
+ xbLinkListNode<xbNodeType> *GetNodeForNo( xbUInt32 ulNodeNo ) const;
+
+ void Clear();
+ xbUInt32 GetNodeCnt () const;
+ xbInt16 InsertAtEnd ( const xbNodeType &xbLLN );
+ xbInt16 InsertAtFront ( const xbNodeType &xbLLN );
+ xbInt16 RemoveByVal ( const xbNodeType &xbLLN );
+ xbInt16 RemoveFromEnd ();
+ xbInt16 RemoveFromEnd ( xbNodeType &xbLLN );
+ xbInt16 RemoveFromFront( xbNodeType &xbLLN );
+ xbInt16 SearchFor ( const xbNodeType &xbLLN );
+
+ private:
+ xbUInt32 ulNodeCnt;
+ xbLinkListNode<xbNodeType> *llStartPtr;
+ xbLinkListNode<xbNodeType> *llEndPtr;
+};
+
+template<class xbNodeType>
+xbLinkList<xbNodeType>::xbLinkList(){
+ ulNodeCnt = 0;
+ llStartPtr = NULL;
+ llEndPtr = NULL;
+}
+
+template<class xbNodeType>
+xbLinkList<xbNodeType>::~xbLinkList(){
+ Clear();
+}
+
+template<class xbNodeType>
+void xbLinkList<xbNodeType>::Clear(){
+ xbLinkListNode<xbNodeType> *cPtr = llStartPtr, *tPtr;
+ for( xbUInt32 i = 0; i < ulNodeCnt; i++ ){
+ tPtr = cPtr;
+ cPtr = cPtr->GetNextNode();
+ delete tPtr;
+ }
+ ulNodeCnt = 0;
+ llStartPtr = NULL;
+ llEndPtr = NULL;
+}
+
+
+template<class xbNodeType>
+xbLinkListNode<xbNodeType> *xbLinkList<xbNodeType>::GetHeadNode() const{
+ return llStartPtr;
+}
+
+template<class xbNodeType>
+xbLinkListNode<xbNodeType> *xbLinkList<xbNodeType>::GetEndNode() const{
+ return llEndPtr;
+}
+
+
+template<class xbNodeType>
+xbLinkListNode<xbNodeType> *xbLinkList<xbNodeType>::GetNodeForNo( xbUInt32 ulNo ) const{
+
+ xbLinkListNode<xbNodeType> *cPtr = llStartPtr;
+ xbUInt32 i;
+ for( i = 0; i < ulNo && i < ulNodeCnt; i++ )
+ cPtr = cPtr->GetNextNode();
+
+ if( i == ulNo )
+ return cPtr;
+ else
+ return 0;
+}
+
+
+
+template<class xbNodeType>
+xbUInt32 xbLinkList<xbNodeType>::GetNodeCnt() const{
+ return ulNodeCnt;
+}
+
+template<class xbNodeType>
+xbInt16 xbLinkList<xbNodeType>::InsertAtFront( const xbNodeType & ntKey ){
+
+ xbLinkListNode<xbNodeType> *p = new xbLinkListNode<xbNodeType>( ntKey );
+ if( p == 0 )
+ return XB_NO_MEMORY;
+
+ if( ulNodeCnt > 0 ){
+ llStartPtr->SetPrevNode( p );
+ p->SetNextNode( llStartPtr );
+ } else {
+ llEndPtr = p;
+ }
+
+ llStartPtr = p;
+ ulNodeCnt++;
+ return XB_NO_ERROR;
+}
+
+template<class xbNodeType>
+xbInt16 xbLinkList<xbNodeType>::InsertAtEnd( const xbNodeType & ntKey ){
+
+ xbLinkListNode<xbNodeType> *p = new xbLinkListNode<xbNodeType>( ntKey );
+ if( p == 0 )
+ return XB_NO_MEMORY;
+
+ if( ulNodeCnt > 0 ){
+ llEndPtr->SetNextNode( p );
+ p->SetPrevNode( llEndPtr );
+ llEndPtr = p;
+ } else {
+ llStartPtr = p;
+ }
+
+ llEndPtr = p;
+ ulNodeCnt++;
+ return XB_NO_ERROR;
+}
+
+
+
+template<class xbNodeType>
+xbInt16 xbLinkList<xbNodeType>::RemoveByVal( const xbNodeType & ntKey ){
+ // Remove the first instance of ntKey from the node chain
+ xbLinkListNode<xbNodeType> *currPtr = llStartPtr;
+ xbLinkListNode<xbNodeType> *prevPtr = NULL;
+
+ for( xbUInt32 i = 0; i < ulNodeCnt; i++ ){
+ if( currPtr->GetKey() == ntKey ){
+ if( prevPtr == NULL ){ //then this is the first node
+ llStartPtr = currPtr->GetNextNode();
+ if( llStartPtr ) // if more than one link in the linked list
+ llStartPtr->SetPrevNode( NULL );
+ delete currPtr;
+ ulNodeCnt--;
+ return i + 1;
+ }
+ else {
+ prevPtr->SetNextNode( currPtr->GetNextNode());
+ if( currPtr->GetNextNode())
+ currPtr->GetNextNode()->SetPrevNode( prevPtr );
+ delete currPtr;
+ ulNodeCnt--;
+ return i + 1;
+ }
+ }
+ prevPtr = currPtr;
+ currPtr = currPtr->GetNextNode();
+ }
+ return XB_NOT_FOUND;
+}
+
+
+template<class xbNodeType>
+xbInt16 xbLinkList<xbNodeType>::RemoveFromFront( xbNodeType & ntKey ){
+
+ if( ulNodeCnt <= 0 )
+ return XB_INVALID_NODELINK;
+ xbLinkListNode<xbNodeType> *p = llStartPtr;
+ llStartPtr = p->GetNextNode();
+ if( llStartPtr )
+ llStartPtr->SetPrevNode( NULL );
+ ntKey = p->GetKey();
+ delete p;
+ ulNodeCnt--;
+ return XB_NO_ERROR;
+}
+
+
+template<class xbNodeType>
+xbInt16 xbLinkList<xbNodeType>::RemoveFromEnd( xbNodeType & ntKey ){
+
+ if( ulNodeCnt <= 0 )
+ return XB_INVALID_NODELINK;
+ xbLinkListNode<xbNodeType> *p = llEndPtr;
+ if( p->GetPrevNode()){
+ llEndPtr = p->GetPrevNode();
+ llEndPtr->SetNextNode( NULL );
+ } else {
+ // there are no more nodes
+ llStartPtr = NULL;
+ llEndPtr = NULL;
+ }
+ ntKey = p->GetKey();
+ delete p;
+ ulNodeCnt--;
+ return XB_NO_ERROR;
+}
+
+
+template<class xbNodeType>
+xbInt16 xbLinkList<xbNodeType>::RemoveFromEnd(){
+
+ if( ulNodeCnt <= 0 )
+ return XB_INVALID_NODELINK;
+ xbLinkListNode<xbNodeType> *p = llEndPtr;
+ if( p->GetPrevNode()){
+ llEndPtr = p->GetPrevNode();
+ llEndPtr->SetNextNode( NULL );
+ } else {
+ // there are no more nodes
+ llStartPtr = NULL;
+ llEndPtr = NULL;
+ }
+ delete p->GetKey();
+ delete p;
+ ulNodeCnt--;
+ return XB_NO_ERROR;
+}
+
+
+template<class xbNodeType>
+xbInt16 xbLinkList<xbNodeType>::SearchFor( const xbNodeType & ntKey ){
+
+ xbLinkListNode<xbNodeType> *cPtr = llStartPtr;
+ for( xbUInt32 i = 0; i < ulNodeCnt; i++ ){
+ if( cPtr->GetKey() == ntKey )
+ return i+1;
+ cPtr = cPtr->GetNextNode();
+ }
+ return XB_NO_ERROR;
+
+}
+} // namespace
+
+#endif // XB_LINKLIST_SUPPORT
+#endif // XB_XBLNKLST_H__
+
+
diff --git a/src/include/xblnklstord.h b/src/include/xblnklstord.h
new file mode 100755
index 0000000..d319c31
--- /dev/null
+++ b/src/include/xblnklstord.h
@@ -0,0 +1,367 @@
+/* xblnklstord.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2019,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+// Ordered link list
+
+
+
+#ifndef __XB_XBLNKLSTORD_H__
+#define __XB_XBLNKLSTORD_H__
+
+#ifdef XB_LINKLIST_SUPPORT
+
+
+namespace xb{
+
+
+template<class xbNodeType>
+class XBDLLEXPORT xbLinkListOrd {
+ public:
+ xbLinkListOrd();
+ ~xbLinkListOrd();
+
+ void Clear();
+ xbLinkListNode<xbNodeType> *GetHeadNode() const;
+ xbLinkListNode<xbNodeType> *GetEndNode() const;
+ xbLinkListNode<xbNodeType> *GetNodeForKey( const xbString &sKey ) const;
+
+ xbInt16 GetDataForKey ( const xbNodeType &ntKey, xbString &sData );
+
+ xbBool GetDupKeys ();
+
+ xbUInt32 GetNodeCnt () const;
+ xbUInt32 GetNodeCnt ( const xbString &sNodeKey ) const;
+ xbInt16 InsertKey ( const xbNodeType &ntKey );
+ xbInt16 InsertKey ( const xbNodeType &ntKey, const xbString &sData );
+ xbInt16 InsertKey ( const xbNodeType &ntKey, xbUInt32 ulData );
+
+ xbBool KeyExists ( const xbNodeType &ntKey ) const;
+ xbInt16 RemoveKey ( const xbNodeType &ntKey );
+ xbInt16 RemoveFromEnd ( xbNodeType &ntKey );
+ xbInt16 RemoveFromFront( xbNodeType &ntKey );
+ xbInt16 RemoveFromFront();
+ void SetDupKeys ( xbBool bAllowDupKeys );
+ xbInt16 UpdateForKey ( const xbNodeType &ntKey, const xbString &sData );
+
+
+ private:
+ xbUInt32 ulNodeCnt;
+ xbBool bAllowDupKeys;
+ xbLinkListNode<xbNodeType> *llStartPtr;
+ xbLinkListNode<xbNodeType> *llEndPtr;
+
+};
+
+
+template<class xbNodeType>
+xbLinkListOrd<xbNodeType>::xbLinkListOrd(){
+ bAllowDupKeys = xbTrue; // default setting - allow duplicate keys
+ ulNodeCnt = 0;
+ llStartPtr = NULL;
+ llEndPtr = NULL;
+}
+
+template<class xbNodeType>
+xbLinkListOrd<xbNodeType>::~xbLinkListOrd(){
+ Clear();
+}
+
+template<class xbNodeType>
+void xbLinkListOrd<xbNodeType>::Clear(){
+ xbLinkListNode<xbNodeType> *cPtr = llStartPtr, *tPtr;
+ for( xbUInt32 i = 0; i < ulNodeCnt; i++ ){
+ tPtr = cPtr;
+ cPtr = cPtr->GetNextNode();
+
+ // next line might cause seg faults
+ // delete tPtr->GetData();
+
+ delete tPtr;
+ }
+ ulNodeCnt = 0;
+ llStartPtr = NULL;
+ llEndPtr = NULL;
+}
+
+template<class xbNodeType>
+xbLinkListNode<xbNodeType> * xbLinkListOrd<xbNodeType>::GetHeadNode() const{
+ return llStartPtr;
+}
+
+template<class xbNodeType>
+xbLinkListNode<xbNodeType> * xbLinkListOrd<xbNodeType>::GetEndNode() const{
+ return llEndPtr;
+}
+
+template<class xbNodeType>
+xbUInt32 xbLinkListOrd<xbNodeType>::GetNodeCnt() const{
+ return ulNodeCnt;
+}
+
+template<class xbNodeType>
+xbUInt32 xbLinkListOrd<xbNodeType>::GetNodeCnt( const xbString &sNodeKey ) const{
+
+ // won't work if nodekey is not a string
+ xbLinkListNode<xbNodeType> *currPtr = llStartPtr;
+ // skip to sNodeKey
+ while( currPtr && ( sNodeKey > currPtr->GetKey())) {
+ currPtr = currPtr->GetNextNode();
+ }
+ // count entries for sNodeKey
+ xbInt16 iKeyCnt = 0;
+ while( currPtr && ( sNodeKey == currPtr->GetKey())) {
+ iKeyCnt++;
+ currPtr = currPtr->GetNextNode();
+ }
+ return iKeyCnt;
+}
+
+
+template<class xbNodeType>
+xbInt16 xbLinkListOrd<xbNodeType>::InsertKey( const xbNodeType &ntKey ){
+ xbString s;
+ return InsertKey( ntKey, s );
+}
+
+
+
+
+template<class xbNodeType>
+xbInt16 xbLinkListOrd<xbNodeType>::InsertKey( const xbNodeType &ntKey, xbUInt32 ul ){
+
+ xbString s;
+ s.Sprintf( "%ld", ul );
+ return InsertKey( ntKey, s );
+}
+
+
+template<class xbNodeType>
+xbInt16 xbLinkListOrd<xbNodeType>::InsertKey( const xbNodeType &ntKey, const xbString &sData ){
+
+ xbLinkListNode<xbNodeType> *p = new xbLinkListNode<xbNodeType>( ntKey, sData );
+ if( p == 0 )
+ return XB_NO_MEMORY;
+
+ if( ulNodeCnt > 0 ){
+ xbLinkListNode<xbNodeType> *currPtr = llStartPtr;
+ xbLinkListNode<xbNodeType> *prevPtr = NULL;
+
+ // find location in the chain
+ while( currPtr && ntKey > currPtr->GetKey() ){
+ prevPtr = currPtr;
+ currPtr = currPtr->GetNextNode();
+ }
+ if( currPtr && ntKey == currPtr->GetKey() && bAllowDupKeys == 0 ){
+ delete p;
+ return XB_KEY_NOT_UNIQUE;
+ }
+
+ if( currPtr == NULL ){
+ // std::cout << "at the end of the chain\n";
+ llEndPtr = p;
+ prevPtr->SetNextNode( p );
+ p->SetPrevNode( prevPtr );
+
+ } else if( currPtr->GetPrevNode() == NULL ){
+ // std::cout << "at the beginning of the chain\n";
+ p->SetNextNode( llStartPtr );
+ llStartPtr->SetPrevNode( p );
+ llStartPtr = p;
+
+ } else {
+ // std::cout << "in the middle of the chain\n";
+ p->SetNextNode( currPtr );
+ p->SetPrevNode( currPtr->GetPrevNode());
+ currPtr->SetPrevNode( p );
+ prevPtr->SetNextNode( p );
+ }
+ } else {
+ // std::cout << "first addition to the chain\n";
+ llStartPtr = p;
+ llEndPtr = p;
+ }
+ ulNodeCnt++;
+ return XB_NO_ERROR;
+}
+
+template<class xbNodeType>
+xbInt16 xbLinkListOrd<xbNodeType>::RemoveKey( const xbNodeType &ntKey ){
+ // Remove the first instance of ntKey from the node chain
+ xbLinkListNode<xbNodeType> *currPtr = llStartPtr;
+ xbLinkListNode<xbNodeType> *prevPtr = NULL;
+
+ while( currPtr && ntKey > currPtr->GetKey() ){
+ prevPtr = currPtr;
+ currPtr = currPtr->GetNextNode();
+ }
+
+ if( currPtr && ntKey == currPtr->GetKey()){
+// ntKey = currPtr->GetKey();
+ if( prevPtr == NULL ){ // this is the first node
+ llStartPtr = currPtr->GetNextNode();
+ // next line fails
+ if( llStartPtr ){
+ llStartPtr->SetPrevNode( NULL );
+ }
+ delete currPtr;
+ ulNodeCnt--;
+ return XB_NO_ERROR;
+ } else if( currPtr->GetNextNode() == NULL ){ // this is the last node
+ llEndPtr = prevPtr;
+ prevPtr->SetNextNode( NULL );
+ delete currPtr;
+ ulNodeCnt--;
+ return XB_NO_ERROR;
+ } else {
+
+ prevPtr->SetNextNode( currPtr->GetNextNode());
+ currPtr->GetNextNode()->SetPrevNode( prevPtr );
+ delete currPtr;
+ ulNodeCnt--;
+ return XB_NO_ERROR;
+ }
+ } else {
+ return XB_NOT_FOUND;
+ }
+}
+
+template<class xbNodeType>
+xbInt16 xbLinkListOrd<xbNodeType>::RemoveFromFront( xbNodeType &ntKey ){
+
+ if( ulNodeCnt <= 0 )
+ return XB_INVALID_NODELINK;
+ xbLinkListNode<xbNodeType> *p = llStartPtr;
+ llStartPtr = p->GetNextNode();
+ if( llStartPtr )
+ llStartPtr->SetPrevNode( NULL );
+ ntKey = p->GetKey();
+ delete p;
+ ulNodeCnt--;
+ return XB_NO_ERROR;
+}
+
+template<class xbNodeType>
+xbInt16 xbLinkListOrd<xbNodeType>::RemoveFromFront(){
+
+ if( ulNodeCnt <= 0 )
+ return XB_INVALID_NODELINK;
+ xbLinkListNode<xbNodeType> *p = llStartPtr;
+ llStartPtr = p->GetNextNode();
+ if( llStartPtr )
+ llStartPtr->SetPrevNode( NULL );
+
+ if( p->GetKey())
+ delete p->GetKey();
+
+ delete p;
+ ulNodeCnt--;
+
+ return XB_NO_ERROR;
+}
+
+
+template<class xbNodeType>
+xbInt16 xbLinkListOrd<xbNodeType>::RemoveFromEnd( xbNodeType &ntKey ){
+
+ if( ulNodeCnt <= 0 )
+ return XB_INVALID_NODELINK;
+ xbLinkListNode<xbNodeType> *p = llEndPtr;
+ llEndPtr = p->GetPrevNode();
+ llEndPtr->SetNextNode( NULL );
+ ntKey = p->GetKey();
+ delete p;
+ ulNodeCnt--;
+ return XB_NO_ERROR;
+}
+
+template<class xbNodeType>
+xbBool xbLinkListOrd<xbNodeType>::GetDupKeys(){
+ return bAllowDupKeys;
+}
+
+template<class xbNodeType>
+void xbLinkListOrd<xbNodeType>::SetDupKeys( xbBool bAllowDupKeys ){
+ this->bAllowDupKeys = bAllowDupKeys;
+}
+
+
+template<class xbNodeType>
+xbBool xbLinkListOrd<xbNodeType>::KeyExists( const xbNodeType &ntKey ) const {
+
+ xbLinkListNode<xbNodeType> *currPtr = llStartPtr;
+ while( currPtr && ntKey > currPtr->GetKey() ){
+ currPtr = currPtr->GetNextNode();
+ }
+ if( currPtr && ntKey == currPtr->GetKey()){
+ return xbTrue;
+ } else {
+ return xbFalse;
+ }
+}
+
+
+template<class xbNodeType>
+xbInt16 xbLinkListOrd<xbNodeType>::GetDataForKey( const xbNodeType &ntKey, xbString &sData ){
+
+ xbLinkListNode<xbNodeType> *currPtr = llStartPtr;
+ while( currPtr && ntKey > currPtr->GetKey() ){
+ currPtr = currPtr->GetNextNode();
+ }
+
+ if( currPtr && ntKey == currPtr->GetKey()){
+ sData = currPtr->GetData();
+ return XB_NO_ERROR;
+ } else {
+ return XB_NOT_FOUND;
+ }
+}
+
+
+template<class xbNodeType>
+xbInt16 xbLinkListOrd<xbNodeType>::UpdateForKey( const xbNodeType &ntKey, const xbString &sData ){
+
+ if( ulNodeCnt == 0 )
+ return InsertKey( ntKey, sData );
+ xbLinkListNode<xbNodeType> * currPtr = llStartPtr;
+ xbLinkListNode<xbNodeType> * prevPtr = NULL;
+ while( currPtr && ntKey > currPtr->GetKey() ) {
+ prevPtr = currPtr;
+ currPtr = currPtr->GetNextNode();
+ }
+
+ if( currPtr && ntKey == currPtr->GetKey() ) {
+ xbLinkListNode<xbNodeType> *p = new xbLinkListNode<xbNodeType>( ntKey, sData );
+ if( prevPtr )
+ prevPtr->SetNextNode( p );
+ else
+ llStartPtr = p;
+ p->SetNextNode( currPtr->GetNextNode() );
+ p->SetPrevNode( currPtr->GetPrevNode() );
+ delete currPtr;
+ return XB_NO_ERROR;
+ }
+
+ return InsertKey( ntKey, sData );
+
+// return 0;
+}
+
+} // namespace
+
+#endif // XB_LINKLIST_SUPPORT
+#endif // XB_XBLNKLSTORD_H__
+
+
diff --git a/src/include/xblnknod.h b/src/include/xblnknod.h
new file mode 100755
index 0000000..ef45be8
--- /dev/null
+++ b/src/include/xblnknod.h
@@ -0,0 +1,94 @@
+/* xblnknod.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_XBLNKNOD_H__
+#define __XB_XBLNKNOD_H__
+
+
+
+#ifdef XB_LINKLIST_SUPPORT
+
+namespace xb{
+
+template<class xbNodeType>
+class XBDLLEXPORT xbLinkListNode {
+ public:
+ xbLinkListNode( const xbNodeType & );
+ xbLinkListNode( const xbNodeType &, const xbString & );
+ xbNodeType GetKey() const;
+ xbString &GetData();
+ xbLinkListNode<xbNodeType> *GetNextNode() const;
+ xbLinkListNode<xbNodeType> *GetPrevNode() const;
+ void SetNextNode( xbLinkListNode<xbNodeType> *llNext );
+ void SetPrevNode( xbLinkListNode<xbNodeType> *llPrev );
+
+ private:
+ xbNodeType ntKey;
+ xbString sData;
+ xbLinkListNode *llNext;
+ xbLinkListNode *llPrev;
+};
+
+ template<class xbNodeType>
+ xbLinkListNode<xbNodeType>::xbLinkListNode( const xbNodeType &key ){
+ ntKey = key;
+ llNext = NULL;
+ llPrev = NULL;
+ }
+
+ template<class xbNodeType>
+ xbLinkListNode<xbNodeType>::xbLinkListNode( const xbNodeType &key, const xbString &s ){
+ ntKey = key;
+ sData = s;
+ llNext = NULL;
+ llPrev = NULL;
+ }
+
+ template<class xbNodeType>
+ xbNodeType xbLinkListNode<xbNodeType>::GetKey() const {
+ return ntKey;
+ }
+
+ template<class xbNodeType>
+ xbString &xbLinkListNode<xbNodeType>::GetData(){
+ return sData;
+ }
+
+ template<class xbNodeType>
+ xbLinkListNode<xbNodeType> *xbLinkListNode<xbNodeType>::GetNextNode() const {
+ return llNext;
+ }
+
+ template<class xbNodeType>
+ xbLinkListNode<xbNodeType> *xbLinkListNode<xbNodeType>::GetPrevNode() const {
+ return llPrev;
+ }
+
+ template<class xbNodeType>
+ void xbLinkListNode<xbNodeType>::SetNextNode( xbLinkListNode<xbNodeType> *lln ){
+ llNext = lln;
+ }
+
+ template<class xbNodeType>
+ void xbLinkListNode<xbNodeType>::SetPrevNode( xbLinkListNode<xbNodeType> *llp ){
+ llPrev = llp;
+ }
+
+} // namespace
+#endif // XB_LINKLIST_SUPPORT
+#endif // XB_XBLNKNOD_H__
+
+
diff --git a/src/include/xblog.h b/src/include/xblog.h
new file mode 100755
index 0000000..5c7d721
--- /dev/null
+++ b/src/include/xblog.h
@@ -0,0 +1,67 @@
+/* xblog.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+#ifndef __XB_XBLOG_H__
+#define __XB_XBLOG_H__
+
+#ifdef CMAKE_COMPILER_IS_GNUCC
+#pragma interface
+#endif
+
+namespace xb{
+
+#ifdef XB_LOGGING_SUPPORT
+
+//! @brief xbLog class.
+/*!
+The xbLog class handles message logging functions.
+
+If logging is enabled in an application, error messages are printed
+in the log file.
+
+Once a logfile reaches a predefined size, the logfile is closed, renamed
+and opened.
+
+The logging functions can be accessed through the xbXBase class.
+Each application has one of those.
+*/
+
+class XBDLLEXPORT xbLog : public xbFile {
+ public:
+ xbLog();
+ xbLog( const xbString &sLogFileName );
+ ~xbLog();
+
+ xbInt16 LogClose ();
+ xbInt16 LogGetStatus ();
+ xbInt16 LogOpen ();
+ void LogSetStatus ( xbBool bLogStatus );
+ void LogSetLogSize( size_t lSize ); // { LogSize = size; }
+ xbInt16 LogWrite ( const xbString &LogEntry, xbInt16 iOutputOption = 0 );
+ xbInt16 LogWriteBytes( xbUInt32 lByteCnt, const char *p );
+ size_t LogGetLogSize() const { return lLogSize; }
+
+ private:
+ xbBool bLoggingStatus; // false = logging off
+ // true = logging on
+ size_t lLogSize;
+ xbInt16 iShareMode;
+};
+
+#endif // XB_LOGGING_SUPPORT
+} // namespace
+#endif // XB_XBLOG_H__
+
+
diff --git a/src/include/xbmemo.h b/src/include/xbmemo.h
new file mode 100755
index 0000000..ad9aac2
--- /dev/null
+++ b/src/include/xbmemo.h
@@ -0,0 +1,224 @@
+/* xbmemo.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_XBMEMO_H__
+#define __XB_XBMEMO_H__
+
+
+// dont use "#pragma interface" with abstract classes
+// #ifdef CMAKE_COMPILER_IS_GNUCC
+// #pragma interface
+// #endif
+
+#ifdef XB_MEMO_SUPPORT
+
+
+
+
+namespace xb{
+
+//! @brief Base class for memo files.
+/*!
+
+The xbMemo class is used as a base class for accessing memo files.
+
+Any DBF file which has any memo fields, will also have a DBT file with the same name.
+Memo fields are stored in the DBT file in 512 or 1024 byte sized blocks.
+
+Calls to the memo routines to read and access memo fields are supported from within
+the dbf class via the GetMemoField and UpdateMemoField routines.
+From an application program point of view, the application program does not need to
+be concerned with the memo classes.<br>
+
+The main difference between the version 3 and version 4 memo files is that
+the version 4 files will reclaim and reuse blocks if available. The version 3
+memo file logic does not.<br>
+
+If you are adding a new style memo table to the logic, you can create a new class
+modeled after xbMemoDbt3 or xbDbtMemo4, using the xbMemo class as a base class.
+
+*/
+
+class XBDLLEXPORT xbMemo : public xbFile {
+ public:
+
+ xbMemo( xbDbf *dbf, xbString const &sFileName );
+
+ /* virtual methods */
+ virtual ~xbMemo();
+ virtual xbInt16 Abort () = 0;
+ virtual xbInt16 CloseMemoFile ();
+ virtual xbInt16 Commit () = 0;
+ virtual xbInt16 CreateMemoFile () = 0;
+
+ virtual xbInt16 DumpMemoHeader () = 0;
+
+
+ virtual xbInt16 GetMemoField ( xbInt16 iFieldNo, xbString &sMemoData ) = 0;
+ virtual xbInt16 GetMemoFieldLen ( xbInt16 iFieldNo, xbUInt32 &ulMemoFieldLen ) = 0;
+ virtual xbInt16 OpenMemoFile () = 0;
+ virtual xbInt16 GetMemoFileType ();
+ virtual xbInt16 PackMemo ( void (*memoStatusFunc)(xbUInt32 ulItemNum, xbUInt32 ulNumItems)) = 0;
+ virtual xbInt16 UpdateMemoField ( xbInt16 iFieldNo, const xbString &sMemoData ) = 0;
+
+ #ifdef XB_DEBUG_SUPPORT
+ virtual xbInt16 DumpMemoFreeChain() = 0;
+ #endif
+
+ #ifdef XB_LOCKING_SUPPORT
+ virtual xbInt16 LockMemo ( xbInt16 iLockFunction );
+ virtual xbBool GetMemoLocked () const;
+ #endif
+
+
+
+ // *********** FIXME *************
+ // next two methods should be protected but are called in the xb_test_xxxx programs testing routines
+ // so for now, they are kept as public
+ virtual xbInt16 CalcLastDataBlock ( xbUInt32 &lLastDataBlock );
+ virtual xbInt16 GetHdrNextBlock ( xbUInt32 &ulBlockNo );
+
+ protected:
+ friend class xbDbf;
+
+ virtual xbInt16 ReadDbtHeader ( xbInt16 iOption ) = 0;
+ virtual xbInt16 UpdateHeaderName () = 0;
+ virtual xbInt16 UpdateHeadNextNode();
+ virtual xbInt16 Zap () = 0;
+
+ xbDbf *dbf; /* pointer to related dbf instance */
+ char cVersion; /* byte 16 off the header block, 0x03 for V3, version IV - ? */
+ xbInt16 iMemoFileType; /* 3 = version III, 4 = version IV */
+ xbUInt32 ulHdrNextBlock; /* next available block , bytes 0-3 of the memo header */
+ void * mbb; /* memo block buffer */
+
+
+ private:
+
+ #ifdef XB_LOCKING_SUPPORT
+ xbBool bFileLocked; /* memo file locked */
+ #endif
+
+};
+
+
+
+#ifdef XB_DBF3_SUPPORT
+//! @brief Derived class for version 3 memo files.
+/*!
+
+The xbMemoDbt3 class is derived from the xbMome class and is used for accessing the
+older Version 3 memo files.
+
+The main difference between the version 3 and version 4 memo files is that
+the version 4 files will reclaim and reuse blocks if available. The version 3
+memo file logic does not.<br>
+
+*/
+
+
+class XBDLLEXPORT xbMemoDbt3 : public xbMemo {
+ public:
+ xbMemoDbt3( xbDbf *dbf, xbString const &sFileName );
+ ~xbMemoDbt3();
+ virtual xbInt16 Abort ();
+ virtual xbInt16 Commit ();
+ virtual xbInt16 CreateMemoFile ();
+ virtual xbInt16 DumpMemoHeader ();
+ virtual xbInt16 GetMemoField ( xbInt16 iFieldNo, xbString &sMemoData );
+ virtual xbInt16 GetMemoFieldLen( xbInt16 iFieldNo, xbUInt32 &ulMemoFieldLen );
+ virtual xbInt16 OpenMemoFile ();
+ virtual xbInt16 PackMemo ( void (*memoStatusFunc) (xbUInt32 ulItemNum, xbUInt32 ulNumItems));
+ virtual xbInt16 UpdateMemoField( xbInt16 iFieldNo, const xbString &sMemoData );
+
+ #ifdef XB_DEBUG_SUPPORT
+ virtual xbInt16 DumpMemoFreeChain();
+ #endif
+
+ protected:
+ virtual xbInt16 ReadDbtHeader( xbInt16 iOption );
+ virtual xbInt16 UpdateHeaderName();
+ virtual xbInt16 Zap();
+
+ private:
+};
+#endif
+
+
+#ifdef XB_DBF4_SUPPORT
+
+//! @brief Derived class for version 4 memo files.
+/*!
+
+The xbMemoDbt4 class is derived from the xbMeme class and is used for accessing the
+current Version 4 memo files.
+
+The main difference between the version 3 and version 4 memo files is that
+the version 4 files will reclaim and reuse blocks if available. The version 3
+memo file logic does not.<br>
+*/
+
+class XBDLLEXPORT xbMemoDbt4 : public xbMemo {
+ public:
+ xbMemoDbt4( xbDbf *dbf, xbString const &sFileName );
+ ~xbMemoDbt4();
+ virtual xbInt16 Abort ();
+ virtual xbInt16 Commit ();
+ virtual xbInt16 CreateMemoFile ();
+ virtual xbInt16 DumpMemoHeader ();
+ virtual xbInt16 GetMemoField ( xbInt16 iFieldNo, xbString &sMemoData );
+ virtual xbInt16 GetMemoFieldLen ( xbInt16 iFieldNo, xbUInt32 &ulMemoFieldLen );
+ virtual xbInt16 GetMemoFieldLen ( xbInt16 iFieldNo, xbUInt32 &ulMemoFieldLen, xbUInt32 &lBlockNo );
+ virtual xbInt16 OpenMemoFile ();
+ virtual xbInt16 PackMemo ( void (*memoStatusFunc) (xbUInt32 ulItemNum, xbUInt32 ulNumItems));
+ virtual xbInt16 UpdateMemoField ( xbInt16 iFieldNo, const xbString &sMemoData );
+
+ #ifdef XB_DEBUG_SUPPORT
+ virtual xbInt16 DumpMemoFreeChain ();
+ virtual xbInt16 DumpMemoInternals ();
+ virtual xbInt16 ReadFreeBlockHeader( xbUInt32 ulBlockNo, xbUInt32 &ulNextBlock, xbUInt32 &ulFreeBlockCnt );
+ #endif
+
+ protected:
+ virtual xbInt16 FindBlockSetInChain( xbUInt32 ulBlocksNeeded, xbUInt32 &ulLastDataBlock, xbUInt32 &ulLocation, xbUInt32 &ulPrevNode, xbBool &bFound );
+ virtual xbInt16 FreeMemoBlockChain( xbUInt32 ulBlockNo );
+ virtual xbInt16 FreeMemoBlockChain( xbUInt32 ulBlockNo, xbUInt32 &ulLastDataBlock );
+ virtual xbInt16 GetBlockSetFromChain( xbUInt32 ulBlocksNeeded, xbUInt32 ulLocation, xbUInt32 ulPrevNode );
+ virtual xbInt16 ReadDbtHeader( xbInt16 iOption );
+ virtual xbInt16 ReadBlockHeader( xbUInt32 ulBlockNo, xbInt16 iOption );
+ virtual xbInt16 UpdateHeaderName ();
+ virtual xbInt16 WriteBlockHeader( xbUInt32 ulBlockNo, xbInt16 iOption );
+ virtual xbInt16 Zap();
+
+ private:
+ xbString sDbfFileNameWoExt;
+ xbUInt32 ulNextFreeBlock;
+ xbUInt32 ulFreeBlockCnt;
+ xbInt16 iField1;
+ xbInt16 iStartPos;
+ xbUInt32 ulFieldLen;
+
+ xbLinkList<xbUInt32> llOldBlocks; // list of previously used memo blocks for field, used by Commit() / Abort()
+ xbLinkList<xbUInt32> llNewBlocks; // list of newly updated memo blocks for field, used by Commit() / Abort()
+
+};
+#endif
+
+
+} /* namespace xb */
+#endif /* XB_MEMO_SUPPORT */
+#endif /* __XB_MEMO_H__ */
+
diff --git a/src/include/xbretcod.h b/src/include/xbretcod.h
new file mode 100755
index 0000000..f2885b1
--- /dev/null
+++ b/src/include/xbretcod.h
@@ -0,0 +1,98 @@
+/* xbretcod.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022,2023 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+#ifndef __XB_RETCODES_H__
+#define __XB_RETCODES_H__
+
+/***********************************************/
+/* Return Codes and Error Messages */
+
+namespace xb{
+
+ #define XB_NO_ERROR 0 // general
+ #define XB_NO_MEMORY -100 // general
+ #define XB_INVALID_OPTION -101 // general
+ #define XB_INVALID_PARAMETER -102 // general
+ #define XB_DUP_TABLE_OR_ALIAS -110 // table manager
+ #define XB_INVALID_NODELINK -120 // linklist
+ #define XB_KEY_NOT_UNIQUE -121 // linklist, index
+ #define XB_MEMCPY_ERROR -122 // memcpy failure
+
+ #define XB_FILE_EXISTS -200 // file
+ #define XB_ALREADY_OPEN -201 // file
+ #define XB_DBF_FILE_NOT_OPEN -202 // file
+ #define XB_FILE_NOT_FOUND -203 // file
+ #define XB_FILE_TYPE_NOT_SUPPORTED -204 // file
+ #define XB_RENAME_ERROR -205 // file
+ #define XB_INVALID_OBJECT -206 // file
+ #define XB_NOT_OPEN -207 // file
+ #define XB_NOT_FOUND -208 // file
+ #define XB_OPEN_ERROR -209 // file
+ #define XB_CLOSE_ERROR -210 // file
+ #define XB_SEEK_ERROR -211 // file
+ #define XB_READ_ERROR -212 // file
+ #define XB_WRITE_ERROR -213 // file
+ #define XB_EOF -214 // file
+ #define XB_BOF -215 // file
+ #define XB_INVALID_BLOCK_SIZE -216 // file
+ #define XB_INVALID_BLOCK_NO -217 // file
+ #define XB_INVALID_RECORD -218 // file
+ #define XB_DELETE_FAILED -219 // file
+ #define XB_INVALID_TABLE_NAME -220 // file
+ #define XB_EMPTY -221 // file
+ #define XB_LIMIT_REACHED -222 // file
+ #define XB_BLOCKREAD_NOT_ENABLED -223 // file
+ #define XB_DIRECTORY_ERROR -224 // file
+
+ #define XB_INVALID_FIELD_TYPE -300 // field
+ #define XB_INVALID_FIELD_NO -301 // field
+ #define XB_INVALID_DATA -302 // field
+ #define XB_INVALID_FIELD_NAME -303 // field
+ #define XB_INVALID_MEMO_FIELD -304 // field
+ #define XB_INVALID_FIELD -305 // field
+ #define XB_INVALID_FIELD_LEN -306 // field
+ #define XB_INVALID_DATE -307 // date field
+
+ #define XB_INVALID_LOCK_OPTION -400 // lock
+ #define XB_LOCK_FAILED -401 // lock
+ #define XB_TABLE_NOT_LOCKED -402 // lock - need table locked for operation
+
+ #define XB_PARSE_ERROR -500 // expression
+ #define XB_INVALID_FUNCTION -501 // expression
+ #define XB_INVALID_PARM -502 // expression
+ #define XB_INCONSISTENT_PARM_LENS -503 // expression
+ #define XB_INCOMPATIBLE_OPERANDS -504 // expression
+ #define XB_UNBALANCED_PARENS -505 // expression
+ #define XB_UNBALANCED_QUOTES -506 // expression
+ #define XB_INVALID_EXPRESSION -507 // expression
+
+ #define XB_INVALID_KEYNO -600 // index
+ #define XB_INVALID_INDEX -601 // index file error
+ #define XB_INVALID_TAG -602 // invalid index tag name, must be <= 10 bytes
+ #define XB_INVALID_PAGE -603 // invalid index page
+
+
+ #define XB_SYNTAX_ERROR -700 // sql syntax error
+
+
+ #define XB_MAX_ERROR_NO -999
+
+
+/* when updating this table, also need to update messages in xbssv.cpp */
+
+
+} /* namespace */
+#endif /* __XB_RETCODES_H__ */
+
diff --git a/src/include/xbsql.h b/src/include/xbsql.h
new file mode 100755
index 0000000..07ffb70
--- /dev/null
+++ b/src/include/xbsql.h
@@ -0,0 +1,161 @@
+/* xbsql.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+This class manages a list of open tables, open indices are connected to the open tables
+
+*/
+
+
+#ifndef __XB_XBSQL_H__
+#define __XB_XBSQL_H__
+
+#ifdef CMAKE_COMPILER_IS_GNUCC
+#pragma interface
+#endif
+
+
+#ifdef XB_SQL_SUPPORT
+
+namespace xb{
+
+
+struct XBDLLEXPORT xbSqlFld{
+ char cType; // F - Database field
+ // L - Literal
+ // E - Expression
+ xbInt16 iFldNo; // Field number if db field
+ xbExp * pExp; // If cType=E, pointer to parsed expression
+ xbString sFldAlias; // Alias name for query display
+ xbSqlFld * Next; // Next field in list
+};
+
+class xbStmt;
+
+
+struct XBDLLEXPORT xbTblJoin { // structure for defining joined tables in the query
+
+ xbString sTableName;
+ xbString sAlias;
+ xbString sJoinExp; // table join expression
+ xbDbf *pDbf; // pointer the the dbf structure for this table
+ xbTag *pTag; // pointer to relevant tag for this table, null for record order
+ xbExp *pLinkExp; // pointer to parsed linkage expression
+ char cJoinType; // M - Master
+ // L - Left or Full Left
+ // R - Right or Full Right
+ // I - Inner
+ // O - Outer or Full Outer Outer
+
+ xbTblJoin *pMaster; // pointer to master table, null if this is the primary master
+ xbLinkList<xbTblJoin *> llSubList; // linked list of subordinate tables
+// xbStmt *pSubQuery; // pointer to sub query
+ xbTblJoin *next; // next tbl
+};
+
+
+class XBDLLEXPORT xbStmt : public xbSsv{
+
+ public:
+ xbStmt( xbXBase *x );
+ ~xbStmt();
+
+ #ifdef XB_DEBUG_SUPPORT
+ xbInt16 DumpStmtInternals();
+ xbInt16 Test();
+ #endif
+
+ xbInt16 ExecuteQuery( const xbString &sCmdLine );
+
+// xbInt16 FetchFirst();
+// xbInt16 FetchNext();
+// xbInt16 FetchPrev();
+// xbInt16 FetchLast();
+// xbString &GetField( const xbString sFldName );
+
+ protected:
+
+ private:
+
+ xbInt16 AddQryTbl( const xbString &sTable, const xbString &sAlias, const xbString &sExpression, const char cJoinType );
+ xbInt16 CvtSqlExp2DbaseExp( const xbString &sExpIn, xbString &sExpOut );
+ xbInt16 GetNextFromSeg( const xbString &sLineIn, xbString &sFromSegOut );
+ xbUInt32 GetNextToken( const xbString &sCmdLineIn, xbString &sTokenOut, xbUInt32 ulStartPos );
+ xbInt16 GetParenCnt( const xbString &sToken );
+ xbInt16 ParseFromStmt( const xbString &sFromLine );
+ xbInt16 ParseStmt( const xbString &sCmdLine );
+ xbInt16 ProcessFromSeg( const xbString &sFromStmtSeg );
+ xbInt16 UpdateJoinList( char cType, const xbString &sTableName, const xbString &sAlias, const xbString &sExp, xbDbf *d, xbExp *e ); //, xbTag *t);
+
+ xbXBase *xbase; // pointer to xbase structure
+
+
+ xbTblJoin * pTblList;
+ xbSqlFld *fl; // field list in sql select statement
+ xbString sStmt; // complete query statment
+ xbString sFields; // list of fields
+ xbString sFrom; // from statment
+ xbString sWhere; // where clause
+ xbString sOrderBy; // sort order
+ xbString sGroupBy; // group by
+ xbString sHaving; // having
+ xbUInt32 ulFromPos;
+ xbUInt32 ulWherePos;
+ xbUInt32 ulOrderByPos;
+ xbUInt32 ulGroupByPos;
+ xbUInt32 ulHavingPos;
+
+
+};
+
+
+class XBDLLEXPORT xbSql : public xbSsv {
+ public:
+ // xbSql();
+ xbSql( xbXBase *x );
+ ~xbSql();
+
+ xbInt16 ExecuteNonQuery( const xbString &sCmdLine );
+ xbXBase *GetXbasePtr() const;
+
+ protected:
+
+ private:
+
+ xbInt16 SqlAlterTable( const xbString &sCmdLine );
+ xbInt16 SqlCreateTable( const xbString &sCmdLine );
+ xbInt16 SqlDelete( const xbString &sCmdLine );
+ xbInt16 SqlDropTable( const xbString &sCmdLine );
+
+ #ifdef XB_INDEX_SUPPORT
+ xbInt16 SqlCreateIndex( const xbString &sCmdLine );
+ xbInt16 SqlDropIndex( const xbString &sCmdLine );
+ #endif // XB_INDEX_SUPPORT
+
+// xbInt16 SqlCreateView( const xbString &sCmdLine );
+// xbInt16 SqlDropView( const xbString &sCmdLine );
+// xbInt16 SqlUpdate( const xbString &sCmdLine );
+// xbInt16 SqlSelect( const xbString &sCmdLine );
+
+ void SqlHelp() const;
+ xbInt16 SqlInsert( const xbString &sCmLine );
+ xbInt16 SqlSet( const xbString &sCmdLine );
+ xbInt16 SqlUse( const xbString &sCmdLine );
+
+ xbXBase *xbase;
+ xbUda uda;
+
+};
+
+} /* namespace xb */
+#endif /* XB_SQL_SUPPORT */
+#endif /* __XB_XBSQL_H__ */ \ No newline at end of file
diff --git a/src/include/xbssv.h b/src/include/xbssv.h
new file mode 100755
index 0000000..3b87a13
--- /dev/null
+++ b/src/include/xbssv.h
@@ -0,0 +1,194 @@
+/* xbssv.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022,2023 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_XBSSV_H__
+#define __XB_XBSSV_H__
+
+#ifdef CMAKE_COMPILER_IS_GNUCC
+#pragma interface
+#endif
+
+
+namespace xb{
+
+class XBDLLEXPORT xbXBase;
+
+///@cond DOXYOFF
+struct XBDLLEXPORT xbErrorMessage{
+ xbInt16 iErrorNo;
+ const char *sErrorText;
+};
+///@endcond DOXYOFF
+
+
+//! @brief Class for handling shared system variables.
+/*!
+This class defines static variables which are referenced across class instances.
+
+This class is designed to have the variables set when the xbXBase class constructor is called
+(xbXBase is a derived class). The xbXbase class is designed to be called first in an application
+programs, and it is only called once. The static values in this class are typically initialized at
+program startup and don't require additional updates.
+
+*/
+
+
+// By design, DBase allows mutliple records in a table all having the same key, but only one entry in a unique index
+// XB_HALT_ON_DUP_KEY tells the library to not allow appending records which generate duplicate keys in a unique index
+//
+#if defined (XB_NDX_SUPPORT) || defined (XB_MDX_SUPPORT)
+#define XB_HALT_ON_DUPKEY 0
+#define XB_EMULATE_DBASE 1
+#endif
+
+
+
+class XBDLLEXPORT xbSsv{
+ public:
+ xbSsv();
+ const static char *ErrorCodeText[];
+
+ void DisplayError ( xbInt16 ErrorCode ) const;
+ xbString& GetDefaultDateFormat () const;
+ xbString& GetDataDirectory () const;
+ xbString& GetTempDirectory () const;
+
+ void GetHomeDir ( xbString &sHomeDirOut );
+
+
+ xbInt16 GetEndianType () const;
+ const char *GetErrorMessage ( xbInt16 ErrorCode ) const;
+ char GetPathSeparator () const;
+
+ void SetDataDirectory ( const xbString &sDataDirectory );
+ void SetDefaultDateFormat ( const xbString &sDefaultDateFormat );
+ void SetTempDirectory ( const xbString &sTempDirectory );
+
+
+ xbBool BitSet ( unsigned char c, xbInt16 iBitNo ) const;
+ void BitDump ( unsigned char c ) const;
+ void BitDump ( char c ) const;
+
+ xbBool GetDefaultAutoCommit () const;
+ void SetDefaultAutoCommit ( xbBool bDefaultAutoCommit );
+
+ xbString& GetLogDirectory () const;
+ xbString& GetLogFileName () const;
+ void SetLogDirectory ( const xbString &sLogDirectory );
+ void SetLogFileName ( const xbString &sLogFileName );
+
+
+ xbBool GetMultiUser () const;
+ void SetMultiUser ( xbBool bMultiUser );
+
+ #if defined (XB_NDX_SUPPORT) || defined (XB_MDX_SUPPORT)
+ xbInt16 GetUniqueKeyOpt () const;
+ xbInt16 SetUniqueKeyOpt ( xbInt16 iUniqueKeyOpt );
+ #endif // (XB_NDX_SUPPORT) || defined (XB_MDX_SUPPORT)
+
+ #ifdef XB_LOCKING_SUPPORT
+ xbInt16 GetDefaultLockRetries () const;
+ void SetDefaultLockRetries ( xbInt16 iRetryCount );
+ xbInt32 GetDefaultLockWait () const;
+ void SetDefaultLockWait ( xbInt32 lRetryWait );
+ xbInt16 GetDefaultLockFlavor () const;
+ void SetDefaultLockFlavor ( xbInt16 iLockFlavor );
+ xbBool GetDefaultAutoLock () const;
+ void SetDefaultAutoLock ( xbBool bAutoLock );
+ void EnableDefaultAutoLock ();
+ void DisableDefaultAutoLock ();
+ #endif // XB_LOCKING_SUPPORT
+
+ #ifdef XB_MDX_SUPPORT
+ xbInt16 GetCreateMdxBlockSize() const;
+ xbInt16 SetCreateMdxBlockSize( xbInt16 ulBlockSize );
+ #endif // XB_MDX_SUPPORT
+
+ #ifdef XB_BLOCKREAD_SUPPORT
+ xbUInt32 GetDefaultBlockReadSize() const;
+ void SetDefaultBlockReadSize( xbUInt32 ulDfltBlockReadSize );
+ #endif // XB_BLOCKREAD_SUPPORT
+
+
+ protected:
+
+ void SetEndianType ();
+
+ static xbInt16 iEndianType; // B=Big Endian L=Little Endian
+ static xbString sNullString; // Null String
+
+
+ private:
+
+ static xbString sDefaultDateFormat;
+ static xbString sDataDirectory; //Data file directory
+ static xbString sTempDirectory; //Temp file directory
+
+ #ifdef XB_LOGGING_SUPPORT
+ static xbString sLogDirectory; //Default location to store log files
+ static xbString sLogFileName; //Default LogFileName
+ #endif
+
+ static xbInt16 iDefaultFileVersion; // 3 = DBase 3
+ // 4 = DBase 4
+ // default version used in CreateTable command
+ // can be over ridden at the Xbase level, or table level
+ // Different versions can be open simultaneously
+
+ static xbBool bDefaultAutoCommit; // Default dbf auto commit switch
+
+ static xbBool bMultiUser; // True if multi user mode is turned on
+ // Turn this off for better performance in single user mode
+ // This needs to be turned on or off before any data tables are opened
+ // turning this on after tables are opened, can result in out of date
+ // file buffers if multiple users are sharing the files
+
+#ifdef XB_LOCKING_SUPPORT
+ static xbInt32 lDefaultLockWait; // Number of milliseconds between lock retries
+ static xbInt16 iDefaultLockRetries; // Number of times to retry a lock before conceding
+ static xbInt16 bDefaultAutoLock; // Autolocking enabled?
+ static xbInt16 iDefaultLockFlavor; // 1 = DBase
+ // 2 = Clipper - not developed yet
+ // 3 = FoxPro - not developed yet
+ // 9 = Xbase64 - not developed yet
+#endif
+
+
+#if defined (XB_NDX_SUPPORT) || defined (XB_MDX_SUPPORT)
+
+ static xbInt16 iUniqueKeyOpt;
+
+ // is one of:
+ // XB_HALT_ON_DUPKEY
+ // XB_EMULATE_DBASE
+
+#endif
+
+
+#ifdef XB_MDX_SUPPORT
+ static xbInt16 iCreateMdxBlockSize; // System level Mdx Block Size
+#endif // XB_MDX_SUPPORT
+
+
+#ifdef XB_BLOCKREAD_SUPPORT
+ static xbUInt32 ulDefaultBlockReadSize;
+#endif // XB_BLOCKREAD_SUPPORT
+
+
+};
+
+} /* namespace xb */
+#endif /* __XB_XBSSV_H__ */ \ No newline at end of file
diff --git a/src/include/xbstring.h b/src/include/xbstring.h
new file mode 100755
index 0000000..7fe1692
--- /dev/null
+++ b/src/include/xbstring.h
@@ -0,0 +1,188 @@
+/* xbstring.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+#ifndef __XBSTRING_H__
+#define __XBSTRING_H__
+
+#ifdef CMAKE_COMPILER_IS_GNUCC
+#pragma interface
+#endif
+
+#include <stdlib.h>
+#include <iostream>
+
+namespace xb{
+
+
+//! @brief Class for handling string data.
+
+/*!
+This class defines a basic string class with all the functions one would expect in a string class.
+
+For purposes of the xbString class, a string is defined as a variable sized array of one byte
+characters terminated with a null (0x00 or \0) byte.<br><br>
+
+This version of the xbString class does not support wide (wchar_t) characters. Perhaps you would
+be interested in creating a class for supporting wide characters.<br><br>
+
+This string class handle strings in a 1-based (not 0 based) fashion.
+Any string routines taking an offset use a 1-based value. That is, the first position of
+the string is position 1, not 0.<br><br>
+
+Position 1 (not 0) is considered the first position in a string.
+A return of 0 would indicate a not found condition. A return of 1, would be the
+first byte.
+*/
+
+
+class XBDLLEXPORT xbString {
+
+ public:
+ //Various constructors
+ xbString(xbUInt32 size);
+ xbString(char c);
+ xbString(const char *s, xbUInt32 lMaxLen);
+ xbString(const xbString &s);
+ xbString(const char * = "");
+ xbString( xbDouble d );
+ ~xbString();
+
+ //operators
+ xbString &operator= (const xbString &s);
+ xbString &operator= (const char *s);
+ operator const char *() const;
+ char &operator[](xbUInt32 n) const;
+ char &operator[](xbInt32 n) const;
+
+ xbString &operator+=(const xbString &s);
+ xbString &operator+=(const char *s);
+ xbString &operator+=(char c);
+ xbString &operator-=(const xbString &s);
+ xbString &operator-=(const char *s);
+ xbString &operator-=(char c);
+
+ xbBool operator == ( const xbString& ) const;
+ xbBool operator == ( const char * ) const;
+ xbBool operator != ( const xbString& ) const;
+ xbBool operator != ( const char * ) const;
+
+ xbBool operator < ( const xbString& ) const;
+ xbBool operator > ( const xbString& ) const;
+ xbBool operator <= ( const xbString& ) const;
+ xbBool operator >= ( const xbString& ) const;
+
+ xbString operator-( const xbString &s );
+ xbString operator+( const char *s );
+ xbString operator+( const xbString &s );
+ xbString operator+( const char c );
+
+ xbString &AddBackSlash( char c );
+ xbString &Append(const xbString &s);
+ xbString &Append(const char *s);
+ xbString &Append(const char *s, xbUInt32 iByteCount );
+ xbString &Append(char c);
+ xbString &Assign(const char *srcStr, xbUInt32 lStartPos, xbUInt32 lCopyLen );
+ xbString &Assign(const char *srcStr, xbUInt32 lStartPos );
+ xbString &Assign(const xbString &s, xbUInt32 ulStartPos, xbUInt32 lCopyLen );
+ xbString &Assign(const xbString &s, xbUInt32 ulStartPos );
+
+ xbString Copy() const;
+ xbUInt32 CountChar( char c ) const;
+ xbUInt32 CountChar( char c, xbInt16 iOpt ) const;
+ xbInt16 CvtHexChar( char &cOut );
+ xbInt16 CvtHexString( xbString &sOut );
+ xbInt16 CvtULongLong( xbUInt64 &ullOut );
+ xbInt16 CvtLongLong( xbInt64 &llOut );
+
+ #ifdef XB_DEBUG_SUPPORT
+ void Dump( const char *title ) const;
+ void Dump( const char *title, xbInt16 iOption ) const;
+ void DumpHex( const char *title ) const;
+ #endif
+
+ xbString &ExtractElement(xbString &s, char delim, xbUInt32 iCnt, xbInt16 iOpt = 0 );
+ xbString &ExtractElement(const char *src, char delim, xbUInt32 iCnt, xbInt16 iOpt = 0 );
+
+ char GetCharacter( xbUInt32 lPos ) const;
+ xbUInt32 GetLastPos(char c) const;
+ xbUInt32 GetLastPos(const char *s) const;
+ char GetPathSeparator() const;
+ xbUInt32 GetSize() const;
+
+ xbBool HasAlphaChars() const;
+ xbBool IsEmpty() const;
+ xbBool IsNull() const;
+
+ xbString &Left( xbUInt32 ulLen );
+ xbUInt32 Len() const; // returns the length of the string
+ xbString &Ltrim();
+ xbString &Ltrunc( xbUInt32 ulCnt );
+
+ xbString &Mid(xbUInt32 ulPos, xbUInt32 lLen );
+ xbString &PadLeft( char c, xbUInt32 ulLen );
+ xbString &PadRight( char c, xbUInt32 ulLen );
+
+ xbUInt32 Pos(char c, xbUInt32 ulStartPos ) const;
+ xbUInt32 Pos(char c) const;
+ xbUInt32 Pos(const char *s) const;
+ xbString &PutAt(xbUInt32 ulPos, char c);
+
+ xbString &Remove( xbUInt32 ulPos, xbUInt32 ulN );
+ xbString &Replace( const char *sReplace, const char *sReplaceWith, xbInt16 iOpt = 0 );
+ xbString &Resize( xbUInt32 lSize );
+ xbString &Rtrim();
+
+ xbString &Set( const char *s );
+ xbString &Set( const xbString &s );
+ xbString &Set( const char *s, xbUInt32 ulSize );
+ xbString &SetNum( xbInt32 lNum );
+ xbString &Sprintf(const char *format, ...);
+
+ const char *Str() const;
+ char *strncpy( char * cDest, xbUInt32 n ) const;
+ xbString &SwapChars( char from, char to );
+
+ xbString &ToLowerCase();
+ xbString &ToUpperCase();
+ xbString &Trim();
+
+ xbBool ValidLogicalValue() const;
+ xbBool ValidNumericValue() const;
+ xbString &ZapChar( char c );
+ xbString &ZapLeadingChar( char c );
+ xbString &ZapTrailingChar( char c );
+
+ friend std::ostream& operator<< ( std::ostream& os, const xbString& s );
+
+ private:
+
+ static const char * NullString;
+ static char cJunkBuf;
+
+ char *data; // pointer to actual string data
+ xbUInt32 size; // size of string plus null terminating byte
+
+ void ctor(const char *s);
+// xbUInt32 CalcSprintfBufSize(const char *format, ...);
+
+// char * xb_realloc( char *pIn, xbUInt32 iLen );
+
+ // next routine could result in buffer over runs if used with improperly sized buffers
+ char * xb_strcpy ( char *target, const char *source);
+
+};
+
+} /* namespace */
+#endif /* __XBSTRING_H__ */
diff --git a/src/include/xbtag.h b/src/include/xbtag.h
new file mode 100755
index 0000000..9b518a3
--- /dev/null
+++ b/src/include/xbtag.h
@@ -0,0 +1,74 @@
+/* xbtag.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_XBTAG_H__
+#define __XB_XBTAG_H__
+
+//#ifdef CMAKE_COMPILER_IS_GNUCC
+//#pragma interface
+//#endif
+
+namespace xb{
+
+
+#ifdef XB_INDEX_SUPPORT
+
+class XBDLLEXPORT xbIx;
+
+
+
+//! @brief xbTag is used for linking index tags to a table (aka dbf file).
+/*!
+
+ Each dbf file (or table) can have zero, one or many tags.
+ Each tag is maintained in a linked list of xbTags.
+
+ NDX index files contain only one index tag.<br>
+ MDX index files can contain one to 47 index tags. The production MDX file is opened automatically
+ and the tags are added to the tag list.
+
+*/
+
+class XBDLLEXPORT xbTag {
+
+ public:
+ xbTag( xbIx *pIx, void *vpTag, xbString &sType, xbString &sTagName, xbString &sExpression, xbString &sFilter, xbBool bUnique, xbBool bSort );
+
+ xbIx *GetIx() const;
+ void *GetVpTag() const;
+ const xbString &GetType() const;
+ const xbString &GetTagName() const;
+ const xbString &GetExpression() const;
+ const xbString &GetFilter() const;
+ xbBool GetUnique() const;
+ xbBool GetSort() const;
+
+ private:
+ xbIx *pIx;
+ void *vpTag;
+ xbString sType;
+ xbString sTagName;
+ xbString sExpression;
+ xbString sFilter;
+ xbBool bUnique;
+ xbBool bSort; // 0 = Ascending, 1 = Descending
+};
+
+#endif // XB_INDEX_SUPPORT
+
+
+} /* namespace xb */
+#endif /* __XB_TAG_H__ */
diff --git a/src/include/xbtblmgr.h b/src/include/xbtblmgr.h
new file mode 100755
index 0000000..2c31e45
--- /dev/null
+++ b/src/include/xbtblmgr.h
@@ -0,0 +1,63 @@
+/* xbtblmgr.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+This class manages a list of open tables, open indices are connected to the open tables
+
+*/
+
+
+#ifndef __XB_XBMGR_H__
+#define __XB_XBMGR_H__
+
+#ifdef CMAKE_COMPILER_IS_GNUCC
+#pragma interface
+#endif
+
+namespace xb{
+
+class XBDLLEXPORT xbDbf;
+
+/* this structure is a linked list of open tables */
+struct XBDLLEXPORT xbTblList{
+ xbTblList *pNext;
+ xbString *psFqTblName; // Fully qualified name of table - same table can be opened multiple times, but must have unique alias
+ xbString *psTblName; // Table name without path, without extension
+ xbString *psTblAlias; // TblAliasName must be unique, same as TblNAme if Alias not provided
+ xbDbf *pDbf;
+};
+
+class XBDLLEXPORT xbTblMgr : public xbSsv {
+ public:
+ xbTblMgr();
+ ~xbTblMgr();
+ xbInt16 AddTblToTblList ( xbDbf *d, const xbString &sFqTblName );
+ xbInt16 AddTblToTblList ( xbDbf *d, const xbString &sFqTblName, const xbString &sTblAlias );
+ xbInt16 DisplayTableList () const;
+ xbDbf * GetDbfPtr ( const xbString &sTblAlias ) const;
+ xbDbf * GetDbfPtr ( xbInt16 sItemNo ) const;
+ xbTblList * GetTblListEntry ( xbDbf *d );
+ xbInt16 GetOpenTableCount () const;
+ xbInt16 RemoveTblFromTblList ( const xbString &sTblAlias );
+ xbInt16 RemoveTblFromTblList ( xbDbf *d );
+
+ protected:
+
+ private:
+ xbTblList * TblList; // List of open database tables
+ xbInt16 iOpenTableCount; // Number of open tables
+
+};
+
+} /* namespace xb */
+
+#endif /* __XB_XBMGR_H__ */ \ No newline at end of file
diff --git a/src/include/xbtypes.h b/src/include/xbtypes.h
new file mode 100755
index 0000000..99b6c22
--- /dev/null
+++ b/src/include/xbtypes.h
@@ -0,0 +1,55 @@
+/* xbtypes.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+#ifndef __XB_XTYPES_H__
+#define __XB_XTYPES_H__
+
+namespace xb{
+
+
+typedef float xbFloat;
+typedef double xbDouble;
+typedef short int xbBool;
+typedef xbUInt64 xbOffT;
+
+
+#define xbTrue 1
+#define xbFalse 0
+
+
+#ifdef HAVE__FILENO_F
+ #define xbFileNo _fileno
+#else
+ #define xbFileNo fileno
+#endif
+
+#ifdef XB_LOCKING_SUPPORT
+ #if defined( HAVE_LONG_LONG )
+ #define LK4026531839 4026531839LL
+ #define LK4026531838 4026531838LL
+ #define LK3026531838 3026531838LL
+ #define LK1000000000 1000000000LL
+ #else
+ #define LK4026531839 4026531839L
+ #define LK4026531838 4026531838L
+ #define LK3026531838 3026531838L
+ #define LK1000000000 1000000000L
+ #endif
+#endif
+
+
+
+} /* namespace */
+#endif /* __XB_XTYPES_H__ */
diff --git a/src/include/xbuda.h b/src/include/xbuda.h
new file mode 100755
index 0000000..e5c0e91
--- /dev/null
+++ b/src/include/xbuda.h
@@ -0,0 +1,52 @@
+/* xbuda.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022,2023 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+This class manages the user data area (UDA)
+
+*/
+
+
+#ifndef __XB_XBUDA_H__
+#define __XB_XBUDA_H__
+
+#ifdef CMAKE_COMPILER_IS_GNUCC
+#pragma interface
+#endif
+
+
+#ifdef XB_EXPRESSION_SUPPORT
+
+
+namespace xb{
+
+class XBDLLEXPORT xbUda {
+
+ public:
+ xbUda();
+ ~xbUda();
+
+ xbInt16 AddTokenForKey( const xbString &sKey, const xbString &sToken );
+ void Clear();
+ xbInt16 DelTokenForKey( const xbString &sKey );
+ xbInt16 GetTokenCnt() const;
+ xbInt16 GetTokenForKey( const xbString &sKey, xbString &sData );
+ xbInt16 UpdTokenForKey( const xbString &sKey, const xbString &sToken );
+ void DumpUda() const;
+
+ private:
+ xbLinkListOrd<xbString> llOrd;
+
+};
+} /* namespace */
+#endif /* XB_EXPRESSION_SUPPORT */
+#endif /* __XBUDA_H__ */ \ No newline at end of file
diff --git a/src/include/xbxbase.h b/src/include/xbxbase.h
new file mode 100755
index 0000000..702da23
--- /dev/null
+++ b/src/include/xbxbase.h
@@ -0,0 +1,235 @@
+/* xbxbase.h
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022,2023 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+
+#ifndef __XB_XBDBLIST_H__
+#define __XB_XBDBLIST_H__
+
+#ifdef CMAKE_COMPILER_IS_GNUCC
+#pragma interface
+#endif
+
+namespace xb{
+
+class XBDLLEXPORT xbLog;
+
+/************************************************************************/
+/*
+ Xbase functions
+
+ Min Parm Count is the minimum number of input parms needed by the function
+
+ Return Type
+ C Char or string
+ D Date
+ L Logical
+ N Numeric
+ 1 Varies - pull return type from first sibling
+ 2 Varies - pull return type from second sibling
+*/
+
+#ifdef XB_FUNCTION_SUPPORT
+
+/*
+struct XBDLLEXPORT xbFunctionInfo {
+ const char * FuncName; // function name
+ char ReturnType; // return type of function
+ xbInt16 iReturnLenCalc; // used to calculate the function return value is
+ // 1 = use value specified in iReturnLenVal
+ // 2 = use length of operand specified in col 4
+ // 3 = use valued of numeric operand specified in col 4
+ // 4 = length of parm 1 * numeric value parm
+ // 5 = larger length of parm 2 or length of parm 3
+ // 6 = if two or more parms, use numeric value from second parm,
+ // otherwise use col4 value
+ xbInt16 iReturnLenVal; // Used in combination with iReturnLenCalc
+
+};
+*/
+/*
+static xbFunctionInfo FunctionList[] =
+// Func Return -Rtrn Len-
+// Name Type -Calc Val-
+{
+ { "ABS", 'N', 1, 4 },
+ { "ALLTRIM", 'C', 2, 1 },
+ { "ASC", 'N', 1, 4 },
+ { "AT", 'N', 1, 4 },
+ { "CDOW", 'C', 1, 9 },
+ { "CHR", 'C', 1, 1 },
+ { "CMONTH", 'C', 1, 9 },
+ { "CTOD", 'D', 1, 8 },
+ { "DATE", 'D', 1, 8 },
+ { "DAY", 'N', 1, 4 },
+ { "DEL", 'C', 1, 1 },
+ { "DELETED", 'L', 1, 1 },
+ { "DESCEND", '1', 2, 1 },
+ { "DOW", 'N', 1, 4 },
+ { "DTOC", 'C', 1, 8 },
+ { "DTOS", 'C', 1, 8 },
+ { "EXP", 'N', 1, 4 },
+ { "IIF", 'C', 5, 0 },
+ { "INT", 'N', 1, 4 },
+ { "ISALPHA", 'L', 1, 1 },
+ { "ISLOWER", 'L', 1, 1 },
+ { "ISUPPER", 'L', 1, 1 },
+ { "LEFT", 'C', 3, 2 },
+ { "LEN", 'N', 1, 4 },
+ { "LOG", 'N', 1, 4 },
+ { "LOWER", 'C', 2, 1 },
+ { "LTRIM", 'C', 2, 1 },
+ { "MAX", 'N', 1, 4 },
+ { "MIN", 'N', 1, 4 },
+ { "MONTH", 'N', 1, 4 },
+ { "RECNO", 'N', 1, 4 },
+ { "RECCOUNT", 'N', 1, 4 },
+ { "REPLICATE", 'C', 4, 0 },
+ { "RIGHT", 'C', 3, 2 },
+ { "RTRIM", 'C', 2, 1 },
+ { "SPACE", 'C', 3, 1 },
+ { "SQRT", 'N', 1, 4 },
+ { "STOD", 'D', 1, 8 },
+ { "STR", 'C', 6, 10 },
+ { "STRZERO", 'C', 3, 2 },
+ { "SUBSTR", 'C', 3, 3 },
+ { "TRIM", 'C', 2, 1 },
+ { "UPPER", 'C', 2, 1 },
+ { "VAL", 'N', 1, 4 },
+ { "YEAR", 'N', 1, 4 },
+ { 0, 0, 0, 0 },
+};
+*/
+#endif
+
+
+
+//! @brief xbXbase class.
+/*!
+ The xbXBase class is the core class that needs to be in every application program.
+*/
+
+class XBDLLEXPORT xbXBase : public xbTblMgr{
+ public:
+ xbXBase();
+ ~xbXBase();
+
+ xbInt16 CloseAllTables();
+ xbInt16 CreateFqn( const xbString &sDirIn, const xbString &sNameIn, const xbString &sExtIn, xbString &sFqfnOut );
+ void DisableMsgLogging();
+ void EnableMsgLogging ();
+ xbInt16 FlushLog();
+
+ //const xbString &GetLogDirectory () const;
+ //const xbString &GetLogFileName () const;
+ const xbString &GetLogFqFileName() const;
+ xbBool GetLogStatus () const;
+
+ xbInt16 OpenHighestVersion( const xbString &sTableName, const xbString &sAlias, xbDbf &dbf, int dummy );
+ xbInt16 OpenHighestVersion( const xbString &sTableName, const xbString &sAlias, xbDbf **dbf );
+
+ xbDbf * Open( const xbString &sTableName, xbInt16 &iRc );
+ xbDbf * Open( const xbString &sTableName, const xbString &sAlias, xbInt16 iOpenMode, xbInt16 iShareMode, xbInt16 iVersion, xbInt16 &iRc );
+
+ // next three methods moved to xbssv for consistency
+ // void SetLogDirectory( const xbString &sLogFileDirectory );
+ // void SetLogFileName ( const xbString &sLogFileName );
+ void SetLogSize ( size_t lSize );
+ size_t GetLogSize () const;
+
+ xbInt16 WriteLogMessage( const xbString &sLogMessage, xbInt16 iOutputOpt = 0 );
+ xbInt16 WriteLogBytes ( xbUInt32 lCnt, const char *p );
+
+ void xbSleep ( xbInt32 lMillisecs );
+
+ xbInt16 GetCmdLineOpt ( xbInt32 lArgc, char **argv, const char *sOptRqst, xbString &sParmOut );
+ xbInt16 GetCmdLineOpt ( xbInt32 lArgc, char **argv, xbString &sOptRqst, xbString &sParmOut );
+
+
+ /* xbase functions */
+ #ifdef XB_FUNCTION_SUPPORT
+ xbInt16 ABS( xbDouble dIn, xbDouble &dOut );
+ xbInt16 ALLTRIM( const xbString &sIn, xbString &sOut );
+ xbInt16 ASC( const xbString &s, xbDouble &dAscOut );
+ xbInt16 AT( const xbString &sSrchFor, const xbString &sBase, xbDouble &dPos );
+ xbInt16 CDOW( xbDate &dInDate, xbString &sOutDow );
+ xbInt16 CHR( xbDouble dAsciCd, xbString &sOut );
+ xbInt16 CMONTH( xbDate &dInDate, xbString &sOutMonth );
+ xbInt16 CTOD( const xbString &sInDate, xbDate &dOutDate );
+ xbInt16 DATE( xbDate &dOutDate );
+ xbInt16 DAY( const xbDate &dInDate, xbDouble &dOutDay );
+ xbInt16 DEL( xbDbf * d, xbString &sOut, xbInt16 iRecBufSw = 0 );
+ xbInt16 DELETED( xbDbf * d, xbBool &bOut, xbInt16 iRecBufSw = 0 );
+ xbInt16 DESCEND( const xbString &sIn, xbString &sOut );
+ xbInt16 DESCEND( const xbDate &dInDate, xbDate &dOutDate );
+ xbInt16 DESCEND( const xbDouble dIn, xbDouble &dsOut );
+ xbInt16 DOW( const xbDate &sInDate, xbDouble &dDowOut );
+ xbInt16 DTOC( xbDate &dInDate, xbString &sOutFmtDate );
+ xbInt16 DTOS( xbDate &dInDate, xbString &sOutFmtDate );
+ xbInt16 EXP( xbDouble dIn, xbDouble &dOut );
+ xbInt16 IIF( xbBool bResult, const xbString &sTrueResult, const xbString &sFalseResult, xbString &sResult );
+ xbInt16 INT( xbDouble dIn, xbDouble &dOut );
+ xbInt16 ISALPHA( const xbString &s, xbBool &bResult );
+ xbInt16 ISLOWER( const xbString &s, xbBool &bResult );
+ xbInt16 ISUPPER( const xbString &s, xbBool &bResult );
+ xbInt16 LEFT( const xbString &sIn, xbUInt32 lCharCnt, xbString &sOut );
+ xbInt16 LEN( const xbString &sIn, xbDouble &dLen );
+ xbInt16 LOG( xbDouble dIn, xbDouble &dOut );
+ xbInt16 LOWER( const xbString &sIn, xbString &sOut );
+ xbInt16 LTRIM( const xbString &sIn, xbString & sOut );
+ xbInt16 MAX( xbDouble dIn1, xbDouble dIn2, xbDouble &dOut );
+ xbInt16 MIN( xbDouble dIn1, xbDouble dIn2, xbDouble &dOut );
+ xbInt16 MONTH( xbDate &dInDate, xbDouble &dMonthOut );
+ xbInt16 RECCOUNT( xbDbf * d, xbDouble &dRecOut );
+ xbInt16 RECNO( xbDbf * d, xbDouble &dRecOut );
+ xbInt16 REPLICATE( const xbString &sIn, xbUInt32 ulRepCnt, xbString &sOut );
+ xbInt16 RIGHT( const xbString &sIn, xbUInt32 iCharCnt, xbString &sOut );
+ xbInt16 RTRIM( const xbString &sIn, xbString &sOut );
+ xbInt16 SPACE( xbInt32 lCnt, xbString &sOut );
+ xbInt16 SQRT( xbDouble dBase, xbDouble &dSqrRt );
+ xbInt16 STOD( const xbString &sIn, xbDate &sDateOut );
+ xbInt16 STR( xbDouble dIn, xbString &sOut );
+ xbInt16 STR( xbDouble dIn, xbUInt32 ulLen, xbString &sOut );
+ xbInt16 STR( xbDouble dIn, xbUInt32 ulLen, xbUInt32 ulDec, xbString &sOut );
+ xbInt16 STR( xbDouble dIn, xbUInt32 ulLen, xbUInt32 ulDec, xbString &sPadChar, xbString &sOut );
+ xbInt16 STRZERO( xbDouble dIn, xbUInt32 ulLen, xbUInt32 ulDec, xbString &sOut );
+ xbInt16 SUBSTR( const xbString &sIn, xbUInt32 ulStartPos, xbUInt32 ulLen, xbString &sOut );
+ xbInt16 TRIM( const xbString &sIn, xbString &sOut );
+ xbInt16 UPPER( const xbString &sIn, xbString &sOut );
+ xbInt16 VAL( const xbString &sIn, xbDouble &dOut );
+ xbInt16 YEAR( xbDate &dInDate, xbDouble &dOutYear );
+ #endif
+
+ protected:
+ friend class xbBcd;
+ friend class xbExp;
+
+ #ifdef XB_BLOCKREAD_SUPPORT
+ friend class xbBlockRead;
+ #endif // XB_BLOCKREAD_SUPPORT
+
+
+ xbInt16 GetFunctionInfo( const xbString &sExpLine, char &cReturnType, xbInt16 &iReturnLenCalc, xbInt32 &lReturnLenVal ) const;
+ static xbInt16 xbMemcmp( const unsigned char *s1, const unsigned char *s2, size_t n );
+
+ private:
+
+#ifdef XB_LOGGING_SUPPORT
+ xbLog *xLog;
+#endif
+
+};
+
+} /* namespace xb */
+#endif /* __XB_DBLIST_H__ */ \ No newline at end of file