summaryrefslogtreecommitdiff
path: root/1Tdata/xbase/xbase64-4.1.4/src/core
diff options
context:
space:
mode:
Diffstat (limited to '1Tdata/xbase/xbase64-4.1.4/src/core')
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbbcd.cpp301
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbblockread.cpp279
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbdate.cpp867
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf.cpp4533
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf3.cpp768
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf4.cpp885
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbexp.cpp2721
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbexpnode.cpp562
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbfields.cpp1189
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbfile.cpp2217
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbfilter.cpp544
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbfuncs.cpp851
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbixbase.cpp789
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbixmdx.cpp4844
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbixndx.cpp2834
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbixtdx.cpp661
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xblog.cpp227
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo.cpp219
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo3.cpp585
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo4.cpp1336
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbssv.cpp658
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbstring.cpp2000
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbtag.cpp121
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbtblmgr.cpp312
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbuda.cpp78
-rwxr-xr-x1Tdata/xbase/xbase64-4.1.4/src/core/xbxbase.cpp803
26 files changed, 0 insertions, 31184 deletions
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbbcd.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbbcd.cpp
deleted file mode 100755
index f86e74f..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbbcd.cpp
+++ /dev/null
@@ -1,301 +0,0 @@
-/* xbbcd.cpp
-
-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
-
- BCD class
-
-*/
-
-#include "xbase.h"
-
-#ifdef XB_INDEX_SUPPORT
-///@cond DOXYOFF
-namespace xb{
-
-
-
-xbBool bcdBitSet( unsigned char c, xbInt16 iBitNo ){
- return c & 1 << iBitNo;
-}
-void bcdBitDump( unsigned char c ){
- for( int i = 7; i >= 0; i-- )
- std::cout << (bcdBitSet( c, i ) ? 1 : 0);
-}
-void bcdBitDump( char c ){
- bcdBitDump( (unsigned char) c );
-}
-
-
-/***********************************************************************/
-void xbBcd::ctor(){
- memset( &bcd, 0x00, sizeof( xbBcdStruct ));
-}
-/***********************************************************************/
-xbBcd::xbBcd( xbDouble d ) {
- Set( d );
-}
-/***********************************************************************/
-xbBcd::xbBcd( const xbString &sNumIn ) {
- Set( sNumIn );
-}
-/***********************************************************************/
-xbBcd::xbBcd( const void *vBcdIn ) {
- memcpy( &bcd, vBcdIn, sizeof( xbBcdStruct ));
-}
-/***********************************************************************/
-void xbBcd::Set( xbDouble d ) {
- ctor();
- xbString s( d );
- StringToBcd( s );
-}
-/***********************************************************************/
-void xbBcd::Set( const xbString &sNumIn ) {
- ctor();
- StringToBcd( sNumIn );
-}
-/***********************************************************************/
-void xbBcd::Set( const void *vBcdIn ) {
- memcpy( &bcd, vBcdIn, sizeof( xbBcdStruct ));
-}
-/***********************************************************************/
-void xbBcd::StringToBcd( const xbString &sIn )
-{
-
- unsigned char cEdc = 0; // encoded digit count
- xbUInt32 iPos; // current position in source string
- xbBool bDecHit = xbFalse; // decimal position hit?
- unsigned char *p = bcd.cData; // pointer to cData
- xbInt16 iBytePos = 0; // next load position in xbs structure
- xbInt16 iBcdDataPos = 0; // current position in output structure
- xbByteSplit xbs; // combiner
-
-
- ctor();
- xbString sNum( sIn );
- xbBool bSign = xbFalse;
-
- sNum.Trim();
- if( sNum[1] == '-' ){
- bSign = 1;
- sNum.ZapLeadingChar( '-' );
- }
- sNum.ZapLeadingChar( '0' );
-
- xbInt16 iDecPos = sNum.Pos( '.' );
- if( iDecPos > 0 ){
- sNum.ZapTrailingChar( '0' );
- cEdc = (unsigned char) (sNum.Len() - 1);
- } else {
- cEdc = (unsigned char) (sNum.Len());
- }
- if( cEdc > 31 ) cEdc = 31; // max 5 bit number
-
-
- if( sNum[1] == '.' ){
- iPos = 2;
- bDecHit = xbTrue;
- while( sNum[iPos] == '0' && iPos <= sNum.Len()){
- bcd.cSigDigits--;
- iPos++;
- }
- } else {
- iPos = 1;
- }
-
- while( iPos <= sNum.Len() ){
- if( sNum[iPos] == '.' )
- bDecHit = true;
- else{
- if( !bDecHit ){
- bcd.cSigDigits++;
- }
- if( iBytePos++ == 0 ){
- xbs.c2 = (unsigned) sNum[iPos] - 0x30;
- } else {
- xbs.c1 = (unsigned) sNum[iPos] - 0x30;
- iBytePos = 0;
- if( iBcdDataPos++ < 10 ){
- memcpy( p++, &xbs, 1 );
- xbs.c1 = 0x00;
- }
- }
- }
- iPos++;
- }
-
- if( iBytePos == 1 && iBcdDataPos < 10 ){
- memcpy( p, &xbs, 1 );
- }
-
- bcd.cSigDigits += 52;
- bcd.cEncDigits = cEdc << 2;
- bcd.cEncDigits = bcd.cEncDigits | 0x01;
- if( bSign )
- bcd.cEncDigits = bcd.cEncDigits | 0x80;
-
-}
-/***********************************************************************/
-void xbBcd::ToChar( char * cOut ){
-
- memcpy( cOut, &bcd, sizeof( xbBcdStruct ));
-}
-/***********************************************************************/
-void xbBcd::ToDouble( xbDouble &d ){
- xbString s;
- ToString( s );
- d = atof( s.Str());
-}
-/***********************************************************************/
-void xbBcd::ToString( xbString &sStringOut ){
-
-// printf( "\n\n\nToString " );
-// printf( "Sig digits [%d] EncodedDigits [%d] sign [%d] sizeof struct [%d]\n",
-// bcd.cSigDigits - 52 , bcd.EncDigits, bcd.Sign, sizeof( xbBcdStruct ));
-
-// this routine converts a bcd numeric key value to a base 10 number in a string
-
-
- xbBool bHasDot = false;
- xbInt16 iSig = bcd.cSigDigits - 52;
- xbByteSplit xbs;
- unsigned char *p = bcd.cData;
- unsigned char c;
-
-// xbInt16 iEnc = bcd.cEncDigits;
- xbInt16 iEnc = GetEncDigitsNoSign();
-
- // set the sign
- // if( bcd.Sign )
- if( bcd.cEncDigits >> 7 )
- sStringOut = "-";
- else
- sStringOut = "";
-
- // do add any needed zeroes after the decimal
- if( iSig <= 0 ){
- if( iEnc > 0 ){
- sStringOut.Append( "." );
- bHasDot = true;
- }
- for( xbInt16 i = iSig; i < 0; i++ )
- sStringOut.Append( "0" );
- }
-
- // do the encoded digits
- while( iEnc > 0 ){
- if( iSig == 0 && !bHasDot )
- sStringOut.Append( "." );
- c = *p++;
- memcpy( &xbs, &c, 1 );
- c = xbs.c2 + 0x30;
- sStringOut.Append((char) c );
- iSig--;
- iEnc--;
- if( iEnc > 0 ){
- if( iSig == 0 && !bHasDot )
- sStringOut.Append( "." );
- c = xbs.c1 + 0x30;
- sStringOut.Append((char) c );
- iSig--;
- iEnc--;
- }
- }
- // do the trailing zeroes
- while( iSig-- > 0 )
- sStringOut.Append( "0" );
- if( sStringOut == "" )
- sStringOut = "0";
-
-}
-
-/***********************************************************************/
-xbInt16 xbBcd::Compare( xbDouble d ){
- xbBcd bcdIn( d );
-
- xbString s;
- bcdIn.ToString( s );
- return Compare( bcdIn );
-}
-
-/***********************************************************************/
-xbInt16 xbBcd::Compare( const xbBcd &bcdIn ){
- // if this == bcdIn return 0
- // if this < bcdIn return -1
- // if this > bcdIn return 1
-
-
- xbInt16 iRc = 0;
-// if( bcd.Sign != bcdIn.GetSign() ){
-// bcd.Sign > 0 ? iRc = -1 : iRc = 1;
-
- if( (unsigned)(bcd.cEncDigits >> 7 ) != bcdIn.GetSign() ){
- (bcd.cEncDigits >> 7 ) > 0 ? iRc = -1 : iRc = 1;
- return iRc;
- }
-
- if( (unsigned) bcd.cSigDigits != bcdIn.GetSigDigits()){
- // if( !bcd.Sign ){ // positive numbers
- if( !(bcd.cEncDigits >> 7 )){ // positive numbers
- if( (unsigned) bcd.cSigDigits > bcdIn.GetSigDigits())
- return 1;
- else
- return -1;
- } else { // negative numbers
- if( (unsigned) bcd.cSigDigits > bcdIn.GetSigDigits())
- return -1;
- else
- return 1;
- }
- }
-
-// iRc = xbXBase::xbMemcmp( bcd.cData, bcdIn.GetData(), (size_t)((bcd.cEncDigits + 1) / 2) );
- iRc = xbXBase::xbMemcmp( bcd.cData, bcdIn.GetData(), (size_t)((GetEncDigitsNoSign() + 1) / 2) );
- if( iRc == 0 )
- return 0;
- // else if((!bcd.Sign && iRc > 0) || (bcd.Sign && iRc < 0 ))
- else if((!(bcd.cEncDigits >> 7) && iRc > 0) || ((bcd.cEncDigits >> 7) && iRc < 0 ))
- return 1;
- else
- return -1;
-}
-
-/***********************************************************************/
-unsigned char xbBcd::GetEncDigitsNoSign() const {
- unsigned char c = bcd.cEncDigits << 1;
- return c >> 3;
-}
-/***********************************************************************/
-unsigned xbBcd::GetSign() const {
- //return bcd.Sign;
- return (unsigned) bcd.cEncDigits >> 7;
-}
-/***********************************************************************/
-unsigned xbBcd::GetSigDigits() const {
- return bcd.cSigDigits;
-}
-/***********************************************************************/
-unsigned xbBcd::GetActualSigDigits() const {
- return bcd.cSigDigits - (xbUInt32) 52;
-}
-/***********************************************************************/
-const unsigned char * xbBcd::GetData() const {
- const unsigned char *p = bcd.cData;
- return p;
-}
-/***********************************************************************/
-const void * xbBcd::GetBcd() const {
- return &bcd;
-}
-} /* namespace */
-///@endcond DOXYOFF
-#endif /* XB_INDEX_SUPPORT */
-
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbblockread.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbblockread.cpp
deleted file mode 100755
index 7e2c5fc..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbblockread.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-/* xbblockread.cpp
-
-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 module handles block read methods. Block reading is used for performance improvement
-during sequential access processing.
-
-*/
-
-#include "xbase.h"
-
-#ifdef XB_BLOCKREAD_SUPPORT
-
-namespace xb{
-
-/************************************************************************/
-xbBlockRead::xbBlockRead( xbDbf * d ) {
- pBlock = NULL;
- ulBlkSize = 0;
- ulFirstBlkRec = 0;
- ulRecCnt = 0;
- ulMaxRecs = 0;
- bEof = xbFalse;
- this->dbf = d;
- tFmTime = 0;
-}
-/************************************************************************/
-xbBlockRead::~xbBlockRead(){
- if( pBlock ){
- free( pBlock );
- pBlock = NULL;
- }
-}
-
-/************************************************************************/
-//! @brief Dump read block internals to stdout.
-/*!
- Dump the current read block internals to stdout.
-*/
-
-
-#ifdef XB_DEBUG_SUPPORT
-void xbBlockRead::DumpReadBlockInternals(){
-
- xbUInt32 ulRecCnt;
- dbf->GetRecordCnt( ulRecCnt );
-
- std::cout << "------- DumpBlockInternals ---------" << std::endl;
- std::cout << "Dflt Blk Size = [" << dbf->GetXbasePtr()->GetDefaultBlockReadSize()
- << "]" << std::endl;
- std::cout << "Dbf Record Count = [" << ulRecCnt << "]" << std::endl;
- std::cout << "Dbf Record Len = [" << dbf->GetRecordLen() << "]" << std::endl;
- std::cout << "ulBlkSize = [" << ulBlkSize << "]" << std::endl;
- std::cout << "ulMaxRecs = [" << ulMaxRecs << "]" << std::endl;
- std::cout << "ulFirstBlkRec = [" << ulFirstBlkRec << "]" << std::endl;
- std::cout << "ulRecCnt = [" << ulRecCnt << "]" << std::endl;
- std::cout << "bEof = [" << bEof << "]" << std::endl;
-}
-#endif // XB_DEBUG_SUPPORT
-/************************************************************************/
-//! @brief Get the first record number in the current block.
-/*!
- Retrieve the first record numer in the current block.<br>
-
- \returns First record number in the current block.
-*/
-
-xbUInt32 xbBlockRead::GetBlockFirstRecNo() const{
- return ulFirstBlkRec;
-}
-/************************************************************************/
-//! @brief Get record for specified record number.
-/*!
- Retrieve a record from read block buffer and copy it into the record buffer.
- If the current record is not in the current block, the routine calls
- GetBlockForRecNo to load the currect block from disk.<br><br>
- For performance reasons, this method assumes a valid record number has been
- passed.<br><br>
-
- \param ulRecNo - Record number to retrieve.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbBlockRead::GetRecord( xbUInt32 ulRecNo ){
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- // std::cout << "xbBlockRead::GetRecord( " << ulRecNo << ")\n";
-
- try{
- if( !( ulRecNo >= ulFirstBlkRec && ulRecNo < (ulFirstBlkRec + ulRecCnt))){
- if(( iRc = GetBlockForRecNo( ulRecNo )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- char *s = pBlock;
- s += (ulRecNo - ulFirstBlkRec) * dbf->GetRecordLen();
- char *t = dbf->RecBuf;
- xbUInt32 ulRecLen = dbf->GetRecordLen();
- for( xbUInt32 l = 0; l < ulRecLen; l++ ){
- *t = *s;
- t++;
- s++;
- }
- dbf->ulCurRec = ulRecNo;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbBlockRead::GetBlockForRecNo() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Get record for specified record number.
-/*!
- Retrieve a block containing specified record. This routine calculates the
- correct block in the DBF file, updates the internal block fields and retrieves
- the block of records from disk and loads into the block buffer.<br><br>
-
- \param ulRecNo - Record number to retrieve.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbBlockRead::GetBlockForRecNo( xbUInt32 ulRecNo ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- xbUInt32 ulDbfRecCnt;
-
- if(( iRc = dbf->GetRecordCnt( ulDbfRecCnt )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- // calc to determine block number for the requested record, 0 based offset
- xbUInt32 ulBlockNo = (xbUInt32)(ulRecNo / ulMaxRecs);
- if( ulRecNo % ulMaxRecs == 0 ) ulBlockNo--;
-
- // calc the first record
- ulFirstBlkRec = (ulBlockNo * ulMaxRecs);
-
- // calc the record count
- if(( ulFirstBlkRec + ulMaxRecs) > ulDbfRecCnt ){
- ulRecCnt = ulDbfRecCnt - ulFirstBlkRec;
- bEof = xbTrue;
- } else {
- ulRecCnt = ulMaxRecs;
- bEof = xbFalse;
- }
-
- // position accordingly
- xbInt64 ulStartPos = dbf->GetHeaderLen() + ((xbInt64) ulFirstBlkRec * dbf->GetRecordLen());
- if(( dbf->xbFseek( ulStartPos, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 110;
- iRc = XB_SEEK_ERROR;
- throw iRc;
- }
-
- if(( dbf->GetFileMtime( tFmTime )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- // read it
- if(( dbf->xbFread( (void *) pBlock, ulRecCnt * dbf->GetRecordLen(), 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- ulFirstBlkRec++; // zero offset in the routine, regular record number from ths point forward
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbBlockRead::GetBlockForRecNo() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Get the current block size.
-/*!
- Retrieve the current block size.<br><br>
-
- \returns Current Block Size.
-*/
-
-xbUInt32 xbBlockRead::GetBlockSize() const{
- return ulBlkSize;
-}
-
-/************************************************************************/
-//! @brief Get the current block record count.
-/*!
- Retrieve the current number of records loaded in the block.<br><br>
-
- \returns Current Block Size.
-*/
-
-xbUInt32 xbBlockRead::GetBlockRecCnt() const {
- return ulRecCnt;
-}
-
-/************************************************************************/
-//! @brief Init the block processing for a iven DBF file.
-/*!
- Initialize the settings for a given DBF file.<br>
- This routine may adjust the block size as needed to eliminate unused
- memory or adjust it bigger if too small.
-
- \param ulRecNo - ulBlockSize - Block size to allocate. If 0 or missing, it uses default block size of 32K.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbBlockRead::Init(xbUInt32 ulBlockSize ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
-
- // calculate the block size
- if( ulBlockSize == 0 )
- ulBlkSize = dbf->GetXbasePtr()->GetDefaultBlockReadSize();
-
- // if not big enough to handle more than one record, bump it up to something meaningful
- if( ulBlkSize < (xbUInt32)(dbf->GetRecordLen() * 2 ))
- ulBlkSize = (xbUInt32) dbf->GetRecordLen() * 10;
-
- ulMaxRecs = (xbUInt32) ulBlkSize / dbf->GetRecordLen();
- ulBlkSize = ulMaxRecs * dbf->GetRecordLen();
-
- // allocate memory for the block
- if(( pBlock = (char *) calloc( 1, ulBlkSize )) == NULL ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbBlockRead::Init() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Set the block size.
-/*!
- St block size for this DBF file.<br>.
-
- \param ulBlkSize - Block Size.
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbBlockRead::SetBlockSize( xbUInt32 ulBlkSize ){
- this->ulBlkSize = ulBlkSize;
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-} /* namespace */
-#endif /* XB_BLOCKREAD_SUPPORT */ \ No newline at end of file
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbdate.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbdate.cpp
deleted file mode 100755
index 54834ac..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbdate.cpp
+++ /dev/null
@@ -1,867 +0,0 @@
-/* xbdate.cpp
-
-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 "xbase.h"
-#include <time.h>
-
-namespace xb{
-
-int xbDate::iDaysInMonths[2][13];
-int xbDate::iAggregatedDaysInMonths[2][13];
-
-/*************************************************************************/
-//! @brief Constructor.
-
-xbDate::xbDate() {
- sDate8.Set( "" );
- SetDateTables();
-}
-
-/*************************************************************************/
-//! @brief Constructor.
-/*!
- \param iInitOpt - Constructor to use to initialize date static variables
- Called by the main xbXbase::xbXBase constructor
-*/
-
-xbDate::xbDate( xbUInt16 ) {
-
- SetDateTables();
- Sysdate();
-}
-/*************************************************************************/
-//! @brief Constructor.
-/*!
- \param sDate8In - Input date.
-*/
-
-xbDate::xbDate( const xbString & sDate8In ) {
-
- if( DateIsValid( sDate8In ))
- sDate8.Set( sDate8In );
- else
- sDate8.Set( "" );
-
- // SetDateTables();
-}
-
-/*************************************************************************/
-//! @brief Constructor.
-/*!
- \param sDate8In - Input date.
-*/
-xbDate::xbDate( const char * sDate8In ) {
-
- if( DateIsValid( sDate8In ))
- sDate8.Set( sDate8In );
- else
- sDate8.Set( "" );
-
- // SetDateTables();
-}
-
-/*************************************************************************/
-//! @brief Constructor.
-/*!
- \param lJulDate - Input julian date.
-*/
-xbDate::xbDate( xbInt32 lJulDate ) {
- // SetDateTables();
- JulToDate8( lJulDate );
-}
-
-/*************************************************************************/
-//! @brief Destructor.
-xbDate::~xbDate(){}
-/*************************************************************************/
-//! @brief Set operator=
-/*!
- \param dt - Date value for set operation.
-*/
-void xbDate::operator=( const xbDate & dt ){
- sDate8.Set( dt.Str());
-}
-/*************************************************************************/
-//! @brief operator +=
-/*!
- This routine adds lDays to the date if the date is not null.
- \param lDays - Number of days to add to the date.
-*/
-void xbDate::operator+=( xbInt32 lDays ){
- if( !IsNull() )
- JulToDate8( JulianDays() + lDays );
-}
-/*************************************************************************/
-//! @brief operator -=
-/*!
- This routine subtracts lDays from the date if the date is not null.
- \param lDays - Number of days to subtract from the date.
-*/
-void xbDate::operator-=( xbInt32 lDays ){
- if( !IsNull() )
- JulToDate8( JulianDays() - lDays );
-}
-/*************************************************************************/
-//! @brief operator ++
-/*!
- This routine adds one day to the date field if the date is not null.
-*/
-void xbDate::operator++(xbInt32){
- if( !IsNull() )
- *this+=1;
-}
-/*************************************************************************/
-//! @brief operator --
-/*!
- This routine subtracts one day from the date field if the date is not null.
-*/
-void xbDate::operator--(xbInt32){
- if( !IsNull())
- *this-=1;
-}
-/*************************************************************************/
-//! @brief operator -
-/*!
- This routine subtracts one date from another date returning the difference.
- \param dt - Date to subtract
- \returns Number of days difference or zero if one of the dates is null.
-*/
-xbInt32 xbDate::operator-( const xbDate &dt ) const{
- if( !IsNull() && !dt.IsNull() )
- return JulianDays() - dt.JulianDays();
- else
- return 0;
-}
-/*************************************************************************/
-//! @brief operator +
-/*!
- This routine adds additional days to a valid date field.
- \param lCount - Number of days to add.
- \returns New date in CCYYMMDD format.
-*/
-const char *xbDate::operator+( xbInt32 lCount ){
- if( !IsNull() )
- JulToDate8( JulianDays() + lCount );
- return sDate8.Str();
-}
-/*************************************************************************/
-//! @brief operator -
-/*!
- This routine subtracts days from a valid date field.
- \param lCount - Number of days to subtract.
- \returns New date in CCYYMMDD format.
-*/
-const char *xbDate::operator-( xbInt32 lCount ){
- if( !IsNull() )
- JulToDate8( JulianDays() - lCount );
- return sDate8;
-}
-/*************************************************************************/
-//! @brief operator ==
-/*!
- This routine compares two dates for equality.
- \param dt - Date to compare.
- \returns xbTrue - Dates match.<br>xbFalse - Dates don't match.
-*/
-xbBool xbDate::operator==( const xbDate &dt ) const{
- if( JulianDays() == dt.JulianDays() )
- return xbTrue;
- else
- return xbFalse;
-}
-/*************************************************************************/
-//! @brief operator !=
-/*!
- This routine compares two dates for inequality.
- \param dt - Date to compare.
- \returns xbTrue - Dates don't match.<br>xbFalse - Dates match.
-*/
-xbBool xbDate::operator!=( const xbDate &dt ) const{
- if( JulianDays() != dt.JulianDays() )
- return xbTrue;
- else
- return xbFalse;
-}
-/*************************************************************************/
-//! @brief operator <
-/*!
- This routine compares two dates
- \param dt - Date to compare.
- \returns xbTrue - Left date is less than right date.<br>
- xbFalse - Left date is not less than right date.
-*/
-xbBool xbDate::operator<( const xbDate &dt ) const {
- if( JulianDays() < dt.JulianDays() )
- return xbTrue;
- else
- return xbFalse;
-}
-/*************************************************************************/
-//! @brief >
-/*!
- This routine compares two dates
- \param dt - Date to compare.
- \returns xbTrue - Left date is greater than right date.<br>
- xbFalse - Left date is not greater than right date.
-*/
-xbBool xbDate::operator>( const xbDate &dt ) const {
- if( JulianDays() > dt.JulianDays() )
- return xbTrue;
- else
- return xbFalse;
-}
-/*************************************************************************/
-//! @brief operator <=
-/*!
- This routine compares two dates
- \param dt - Date to compare.
- \returns xbTrue - Left date is less than or equal to right date.<br>
- xbFalse - Left date is not less than or equal to right date.
-*/
-xbBool xbDate::operator<=( const xbDate &dt ) const {
- if( JulianDays() <= dt.JulianDays() )
- return xbTrue;
- else
- return xbFalse;
-}
-/*************************************************************************/
-//! @brief operator >=
-/*!
- This routine compares two dates
- \param dt - Date to compare.
- \returns xbTrue - Left date is greater than or equal to right date.<br>
- xbFalse - Left date is not greater than or equal to right date.
-*/
-xbBool xbDate::operator>=( const xbDate &dt ) const {
- if( JulianDays() >= dt.JulianDays() )
- return xbTrue;
- else
- return xbFalse;
-}
-/*************************************************************************/
-//! @brief Calculate century for a given year.
-/*!
- This routine calculates a century for a given year. It uses an 80/20
- rolling date window to calculate the century.
-
- \param iCalcYear - Two digit year to calculate a century for.
- \returns Century calculated for the two digit year.
-*/
-xbInt16 xbDate::CalcRollingCenturyForYear( xbInt16 iCalcYear ) const {
-
- xbDate d;
- d.Sysdate();
- xbInt16 iThisYear = d.YearOf();
- xbInt16 iThisCentury = d.CenturyOf();
- iThisYear -= (iThisCentury * 100);
- if( iThisYear < 80 && iCalcYear < (iThisYear+20) )
- return iThisCentury;
- else if( iThisYear >= 80 &&
- iCalcYear < iThisYear &&
- iCalcYear >= (iThisYear-80))
- return iThisCentury;
- else
- return iThisCentury - 1;
-}
-/*************************************************************************/
-//! @brief Get century for date.
-/*!
- \returns the century from the valid date.\ or 0 for a null date.
-*/
-xbInt16 xbDate::CenturyOf() const {
- if( !IsNull() ){
- char Century[3];
- Century[0] = sDate8[1];
- Century[1] = sDate8[2];
- Century[2] = 0x00;
- return( atoi( Century ));
- } else {
- return 0;
- }
-}
-/*************************************************************************/
-//! @brief Get the day of the week.
-/*!
- \param sOutCharDay - Output character day of week (Sun-Sat).
- \returns XB_INVALID_DATE<br>XB_NO_ERROR
-*/
-xbInt16 xbDate::CharDayOf( xbString &sOutCharDay ) {
-
- if( !IsNull()){
- struct tm tblock;
- char buf[25];
-
- tblock.tm_year = YearOf() - 1900;
- tblock.tm_mon = MonthOf() - 1;
- tblock.tm_mday = DayOf( XB_FMT_MONTH );
- tblock.tm_hour = 0;
- tblock.tm_min = 0;
- tblock.tm_sec = 1;
- tblock.tm_isdst = -1;
- if( mktime( &tblock ) == -1 ){
- sOutCharDay = "" ;
- return XB_INVALID_DATE;
- } else {
- strftime( buf, 25, "%A", &tblock );
- sOutCharDay = buf;
- }
- }
- return XB_NO_ERROR;;
-}
-/*************************************************************************/
-//! @brief Get the month from the date.
-/*!
- \param sOutCharMonth - Output character month.
- \returns XB_INVALID_DATE<br>XB_NO_ERROR
-*/
-xbInt16 xbDate::CharMonthOf( xbString &sOutCharMonth ) {
-
- if( !IsNull()){
- struct tm tblock;
- char buf[25];
- tblock.tm_year = YearOf() - 1900;
- tblock.tm_mon = MonthOf() - 1;
- tblock.tm_mday = DayOf( XB_FMT_MONTH );
- tblock.tm_hour = 0;
- tblock.tm_min = 0;
- tblock.tm_sec = 1;
- tblock.tm_isdst = -1;
- if( mktime( &tblock ) == -1 ){
- sOutCharMonth = "";
- return XB_INVALID_DATE;
- } else {
- strftime( buf, 25, "%B", &tblock );
- sOutCharMonth = buf;
- }
- }
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief Check a date for valid data.
-/*!
- \param sDateIn - Date to check for valid formaat of CCYYMMDD.
- \returns xbTrue - Valid date.<br>xbFalse - Not a valid date.
-*/
-xbBool xbDate::DateIsValid( const xbString &sDateIn ) const {
-
- xbInt16 iYear, iMonth, iDay;
- char sYear[5];
- char sMonth[3];
- char sDay[3];
-
- if( sDateIn.Len() != 8 )
- return xbFalse;
-
- if(!isdigit( sDateIn[1] ) || !isdigit( sDateIn[2] ) || !isdigit( sDateIn[3] ) ||
- !isdigit( sDateIn[4] ) || !isdigit( sDateIn[5] ) || !isdigit( sDateIn[6] ) ||
- !isdigit( sDateIn[7] ) || !isdigit( sDateIn[8] ) )
- return xbFalse;
-
- sDay[0] = sDateIn[7];
- sDay[1] = sDateIn[8];
- sDay[2] = 0x00;
- iDay = atoi( sDay );
-
- sMonth[0] = sDateIn[5];
- sMonth[1] = sDateIn[6];
- sMonth[2] = 0x00;
- iMonth = atoi( sMonth );
-
- sYear[0] = sDateIn[1];
- sYear[1] = sDateIn[2];
- sYear[2] = sDateIn[3];
- sYear[3] = sDateIn[4];
- sYear[4] = 0x00;
- iYear = atoi( sYear );
-
- // valid years are 0001 thru 9999
- if( iYear < 1 || iYear > 9999 || iMonth < 1 || iMonth > 12 || iDay < 1 || iDay > 31 )
- return xbFalse;
-
- // April, June, September and November have 30 days
- if(( iMonth==4 || iMonth==6 || iMonth==9 || iMonth==11 )&& iDay > 30 )
- return xbFalse;
-
- // check for February with leap year
- if( iMonth == 2 ){
- if(( iYear % 4 == 0 && iYear % 100 != 0 ) || iYear % 400 == 0 ){
- if( iDay > 29 ){
- return xbFalse;
- }
- } else if( iDay > 28 ){
- return xbFalse;
- }
- }
- return xbTrue;
-}
-
-/*************************************************************************/
-//! @brief
-/*!
- This routine returns the numeric day.
- \param iFormat
- XB_FMT_WEEK Number of day in WEEK 0-6 ( Sat - Fri )<br>
- XB_FMT_MONTH Number of day in MONTH 1-31<br>
- XB_FMT_YEAR Number of day in YEAR 1-366
- \returns XB_INVALID_OPTION<br>XB_NO_ERROR
-*/
-
-xbInt16 xbDate::DayOf( xbInt16 iFormat ) const {
-
- if( !IsNull()){
- xbInt16 iOutDay = 0;
- char sDay[3];
- xbInt16 iDay, iMonth, iYear, iDay2;
-
- // check for valid format switch
- if( iFormat!=XB_FMT_WEEK && iFormat!=XB_FMT_MONTH && iFormat!=XB_FMT_YEAR )
- return XB_INVALID_OPTION;
-
- if( iFormat == XB_FMT_WEEK ){
- //DayOf( XB_FMT_MONTH, iDay );
- iDay = DayOf( XB_FMT_MONTH );
- iMonth = MonthOf();
- iYear = YearOf();
-
- // The following formula uses Zeller's Congruence to determine the day of the week
- if( iMonth > 2 ) // init to February
- iMonth -= 2;
- else {
- iMonth += 10;
- iYear--;
- }
- iDay2 = ((13 * iMonth - 1) / 5) + iDay + ( iYear % 100 ) +
- (( iYear % 100 ) / 4) + ((iYear /100 ) / 4 ) - 2 *
- ( iYear / 100 ) + 77 ;
-
- iOutDay = iDay2 - 7 * ( iDay2 / 7 );
- iOutDay == 6 ? iOutDay = 0 : iOutDay++;
- }
- else if( iFormat == XB_FMT_MONTH ){
- sDay[0] = sDate8[7];
- sDay[1] = sDate8[8];
- sDay[2] = 0x00;
- iOutDay = atoi( sDay );
- } else {
- iOutDay = iAggregatedDaysInMonths[IsLeapYear()][MonthOf()-1] + DayOf( XB_FMT_MONTH );
- }
- return iOutDay;
- } else {
- return 0;
- }
-}
-/*************************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-//! @brief Dump date information to stdout.
-/*!
- \param sTitle - Title for output.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-void xbDate::Dump( const char *sTitle ){
- fprintf( stdout, "%s\n sDate = [%s]\n", sTitle, sDate8.Str() );
-}
-
-/*************************************************************************/
-//! @brief Dump the date tables.
-/*!
- This dumps the internal date structures to stdout.
- \returns void
-*/
-
-void xbDate::DumpDateTables(){
- fprintf( stdout, "Date Tables\n" );
- fprintf( stdout, "Month *-Aggragated Days-* *--Days In Month--*\n" );
- fprintf( stdout, " *-NonLeap Leap-* *--NonLeap Leap--*\n" );
- for( int i = 1; i < 13; i++ )
- fprintf( stdout, " %2d %3d %3d %3d %3d\n", i,
- iAggregatedDaysInMonths[0][i],iAggregatedDaysInMonths[1][i],
- iDaysInMonths[0][i], iDaysInMonths[1][i]);
-}
-#endif
-
-/*************************************************************************/
-//! @brief Format MM/DD/YY date
-/*!
- This routine takes an MM/DD/YY format date as input and populates a
- date class with the appropriate YYYYMMDD data.
-
- \param sCtodInDate - MM/DD/YY formatted date as input.
- \returns XB_INVALID_OPTION<br>XB_NO_ERROR
-*/
-xbInt16 xbDate::CTOD( const xbString &sCtodInDate ){
-
- if( sCtodInDate[1] != ' ' && ( sCtodInDate[3] == '\\' || sCtodInDate[3] == '/') ){
- char yy[3];
- yy[0] = sCtodInDate[7];
- yy[1] = sCtodInDate[8];
- yy[2] = 0x00;
- sDate8.Sprintf( "%02d%c%c%c%c%c%c", CalcRollingCenturyForYear( atoi( yy )),
- sCtodInDate[7], sCtodInDate[8], sCtodInDate[1], sCtodInDate[2], sCtodInDate[4], sCtodInDate[5] );
- return XB_NO_ERROR;
- }
- else{
- return XB_INVALID_DATE;
- }
-}
-/*************************************************************************/
-//! @brief
-/*!
- This routine will reformat a date based on the format specifiers entered
- in sFmtIn. If no input format is specified, the routine will use the
- system default date format.
-
- \param sFmtIn - A format specifier with the following paramaters:<br>
-
- 1) YYDDD - A julian date format
- 2) YY or YYYY will print a 2 or 4 digit year
- 3) M,MM,MMM or MMMM
- M - one digit month if no leading zero
- MM - two digit month, contains leading zero
- MMM - Jan through Dec
- MMMM - January through December
- 4) D,DD,DDD or DDDD
- D - one digit dayif no leading zero
- DD - two digit day, contains leading zero
- DDD - Sun through Sat (or julian if YYDDD)
- DDDD - Sunday through Saturday
-
- \param sOutFmtDate - Reformatted output date.
- \returns XB_NO_ERROR
- <br><br>
- Format Examples:<br>
- MM/DD/YY<br>
- YYYY-MM-DD<br>
- DDDDDDDDDDD MMMMMMMMMMM DD,YYYY
-*/
-xbInt16 xbDate::FormatDate( const xbString &sFmtIn, xbString &sOutFmtDate ){
- xbUInt32 FmtCtr;
- char type;
- xbUInt32 iTypeCtr;
- xbString ws;
- xbString sWrkFmt;
- sOutFmtDate = "";
-
- if( IsNull())
- return XB_NO_ERROR;
-
- /* use format for this specific string if available, else use default format */
- if( strlen( sFmtIn ) > 0 )
- sWrkFmt = sFmtIn;
- else
- sWrkFmt = GetDefaultDateFormat();
-
- if( strstr( sWrkFmt.Str(), "YYDDD" )){
- sOutFmtDate.Sprintf( "%c%c%03d", sDate8[3], sDate8[4], DayOf( XB_FMT_YEAR ));
- } else {
- FmtCtr = 1;
- while( FmtCtr <= sWrkFmt.Len() ){
- if( sWrkFmt[FmtCtr] != 'D' && sWrkFmt[FmtCtr] != 'M' && sWrkFmt[FmtCtr] != 'Y' ){
- sOutFmtDate += sWrkFmt[FmtCtr];
- FmtCtr++;
- iTypeCtr = 0;
- } else {
- type = sWrkFmt[FmtCtr];
- iTypeCtr = 0;
- while( sWrkFmt[FmtCtr] == type ) {
- iTypeCtr++;
- FmtCtr++;
- }
- switch( type ){
- case 'D':
-
- if( iTypeCtr == 1 ){
- sOutFmtDate += ws.Sprintf( "%d", DayOf( XB_FMT_MONTH ));
- }
- else if( iTypeCtr == 2 ){
- sOutFmtDate += ws.Sprintf( "%c%c", sDate8[7], sDate8[8] );
- } else {
- xbString sCDO;
- CharDayOf( sCDO );
- ws.Assign( sCDO, 1, iTypeCtr );
- sOutFmtDate += ws.Str();
- }
- break;
-
- case 'M':
- if( iTypeCtr == 1 ){
- sOutFmtDate += ws.Sprintf( "%d", MonthOf());
- }
- else if( iTypeCtr == 2 ){
- sOutFmtDate += ws.Sprintf( "%c%c", sDate8[5], sDate8[6] );
- } else {
- xbString sCMO;
- CharMonthOf( sCMO );
- ws.Assign( sCMO, 1, iTypeCtr );
- sOutFmtDate += ws.Str();
- }
- break;
-
- case 'Y':
- if( iTypeCtr == 2 ){
- sOutFmtDate += ws.Sprintf( "%c%c", sDate8[3], sDate8[4] );
- }
- else if( iTypeCtr == 4 ){
- sOutFmtDate += ws.Sprintf( "%c%c%c%c", sDate8[1], sDate8[2], sDate8[3], sDate8[4] );
- }
- break;
- default:
- break;
- }
- }
- }
- }
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief Return the date value.
-/*!
- \returns char ptr to date value.
-*/
-const char * xbDate::Str() const{
- return sDate8.Str();
-};
-/*************************************************************************/
-//! @brief Determine if date is a leap year.
-/*!
- \returns xbTrue - Is leapyear.<br> xbFalse - Not a leap year.
-*/
-xbBool xbDate::IsLeapYear() const {
- if( IsNull() )
- return xbFalse;
- xbInt16 iYear = YearOf();
- if(( iYear % 4 == 0 && iYear % 100 != 0 ) || iYear % 400 == 0 )
- return xbTrue;
- else
- return xbFalse;
-}
-/*************************************************************************/
-//! @brief Determine if date is a leap year.
-/*!
- \param iYear - Year to check for leap year status.
- \returns xbTrue - Is leapyear.<br> xbFalse - Not a leap year.
-*/
-xbBool xbDate::IsLeapYear( xbInt16 iYear ) const {
- if(( iYear % 4 == 0 && iYear % 100 != 0 ) || iYear % 400 == 0 )
- return xbTrue;
- else
- return xbFalse;
-}
-/*************************************************************************/
-//! @brief Determine if date is null date
-/*!
- \returns xbTrue - If null date.<br> xbFalse - Not a null date.
-*/
-xbBool xbDate::IsNull() const {
- if( sDate8.Len() < 8 )
- return xbTrue;
- else
- return xbFalse;
-}
-/*************************************************************************/
-//! @brief Calculate julian days for a given date.
-/*!
- \returns The number of days since 01/01/0001 + JUL_OFFSET.
-*/
-xbInt32 xbDate::JulianDays() const{
- if( !IsNull()){
- xbInt32 ly = YearOf() - 1;
- xbInt32 lDays = ly * 365L + ly / 4L - ly / 100L + ly / 400L;
- lDays += DayOf( XB_FMT_YEAR );
- return lDays + JUL_OFFSET;
- } else {
- return 0;
- }
-}
-/*************************************************************************/
-//! @brief Convert the number of julian days to gregorian date.
-/*!
- \param lJulDays - Julian days.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbDate::JulToDate8( xbInt32 lJulDays )
-{
- lJulDays -= JUL_OFFSET;
- // calculate the year
- xbInt16 iYear = (xbInt16)(lJulDays / 365.24 );
- lJulDays -= (iYear * 365L) + (iYear / 4L) - (iYear / 100L) + (iYear / 400L);
- iYear++;
- while( lJulDays <= 0 ){
- iYear--;
- lJulDays += (365L + IsLeapYear( iYear ));
- }
- // this for loop calculates the month by comparing the number of days remaining to one of the tables
- xbInt16 iIsLeap = IsLeapYear(iYear);
- xbInt16 iMonth = 1;
- while( ((xbInt16) lJulDays > iAggregatedDaysInMonths[iIsLeap][iMonth]) && (iMonth < 12) )
- iMonth++;
- lJulDays -= iAggregatedDaysInMonths[iIsLeap][iMonth-1];
- sDate8.Sprintf( "%04d%02d%02ld", iYear, iMonth, lJulDays );
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief Set the date to the last day of month for a given date.
-/*!
- This routine sets the last date of the month.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbDate::LastDayOfMonth(){
- if( !IsNull())
- sDate8.Sprintf( "%4.4d%2.2d%2.2d", YearOf(), MonthOf(), iDaysInMonths[IsLeapYear()][MonthOf()]);
- return XB_NO_ERROR;
-};
-/*************************************************************************/
-//! @brief Return the month for the date.
-/*!
- \returns The month of the date.
-*/
-xbInt16 xbDate::MonthOf() const {
- if( !IsNull()){
- xbInt16 iOutMonth;
- char month[3];
- month[0] = sDate8[5];
- month[1] = sDate8[6];
- month[2] = 0x00;
- iOutMonth = atoi( month );
- return iOutMonth;
- } else {
- return 0;
- }
-}
-
-/*************************************************************************/
-//! @brief Set the date.
-/*!
- \param sDateIn - Input date.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbDate::Set( const xbString & sDateIn ){
-
- if( DateIsValid( sDateIn )){
- sDate8 = sDateIn;
- } else {
- sDate8 = ""; // set to null date if invalid date
- }
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief This routine sets up static data tables on startup.
-/*!
- \returns void
-*/
-void xbDate::SetDateTables() {
- if( iAggregatedDaysInMonths[1][12] != 366 ){ /* first time called ? */
-
- iAggregatedDaysInMonths[0][0] = 0;
- iAggregatedDaysInMonths[0][1] = 31;
- iAggregatedDaysInMonths[0][2] = 59;
- iAggregatedDaysInMonths[0][3] = 90;
- iAggregatedDaysInMonths[0][4] = 120;
- iAggregatedDaysInMonths[0][5] = 151;
- iAggregatedDaysInMonths[0][6] = 181;
- iAggregatedDaysInMonths[0][7] = 212;
- iAggregatedDaysInMonths[0][8] = 243;
- iAggregatedDaysInMonths[0][9] = 273;
- iAggregatedDaysInMonths[0][10] = 304;
- iAggregatedDaysInMonths[0][11] = 334;
- iAggregatedDaysInMonths[0][12] = 365;
- iAggregatedDaysInMonths[1][0] = 0;
- iAggregatedDaysInMonths[1][1] = 31;
- iAggregatedDaysInMonths[1][2] = 60;
- iAggregatedDaysInMonths[1][3] = 91;
- iAggregatedDaysInMonths[1][4] = 121;
- iAggregatedDaysInMonths[1][5] = 152;
- iAggregatedDaysInMonths[1][6] = 182;
- iAggregatedDaysInMonths[1][7] = 213;
- iAggregatedDaysInMonths[1][8] = 244;
- iAggregatedDaysInMonths[1][9] = 274;
- iAggregatedDaysInMonths[1][10] = 305;
- iAggregatedDaysInMonths[1][11] = 335;
- iAggregatedDaysInMonths[1][12] = 366;
-
- iDaysInMonths[0][0] = 0;
- iDaysInMonths[0][1] = 31;
- iDaysInMonths[0][2] = 28;
- iDaysInMonths[0][3] = 31;
- iDaysInMonths[0][4] = 30;
- iDaysInMonths[0][5] = 31;
- iDaysInMonths[0][6] = 30;
- iDaysInMonths[0][7] = 31;
- iDaysInMonths[0][8] = 31;
- iDaysInMonths[0][9] = 30;
- iDaysInMonths[0][10] = 31;
- iDaysInMonths[0][11] = 30;
- iDaysInMonths[0][12] = 31;
- iDaysInMonths[1][0] = 0;
- iDaysInMonths[1][1] = 31;
- iDaysInMonths[1][2] = 29;
- iDaysInMonths[1][3] = 31;
- iDaysInMonths[1][4] = 30;
- iDaysInMonths[1][5] = 31;
- iDaysInMonths[1][6] = 30;
- iDaysInMonths[1][7] = 31;
- iDaysInMonths[1][8] = 31;
- iDaysInMonths[1][9] = 30;
- iDaysInMonths[1][10] = 31;
- iDaysInMonths[1][11] = 30;
- iDaysInMonths[1][12] = 31;
- }
-}
-/*************************************************************************/
-//! @brief Set the date equal to the system date.
-/*!
- \returns XB_NO_ERROR
-*/
-xbInt16 xbDate::Sysdate(){
-
- #ifdef HAVE__LOCALTIME64_S_F
- __time64_t timer;
- _time64( &timer );
- struct tm tblock;
- _localtime64_s( &tblock, &timer );
- tblock.tm_year += 1900;
- tblock.tm_mon++;
- sDate8.Sprintf( "%4d%02d%02d", tblock.tm_year, tblock.tm_mon, tblock.tm_mday );
- #else
- time_t timer;
- timer = time( &timer );
- struct tm *tblock;
- tblock = localtime( &timer );
- tblock->tm_year += 1900;
- tblock->tm_mon++;
- sDate8.Sprintf( "%4d%02d%02d",tblock->tm_year,tblock->tm_mon,tblock->tm_mday );
- #endif
-
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief Returns the year of the date.
-/*!
- \returns The year of the date.
-*/
-xbInt16 xbDate::YearOf() const {
- if( !IsNull()){
- char year[5];
- year[0] = sDate8[1];
- year[1] = sDate8[2];
- year[2] = sDate8[3];
- year[3] = sDate8[4];
- year[4] = 0x00;
- xbInt16 iOutYear = atoi( year );
- return iOutYear;
- } else {
- return 0;
- }
-};
-} /* namespace */ \ No newline at end of file
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf.cpp
deleted file mode 100755
index 8904a6d..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf.cpp
+++ /dev/null
@@ -1,4533 +0,0 @@
-/* xbdbf.cpp
-
-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 "xbase.h"
-
-
-namespace xb{
-
-/************************************************************************/
-//! @brief Constructor
-/*!
- \param x Pointer to xbXbase
-*/
-xbDbf::xbDbf( xbXBase * x ) : xbFile( x ){
- xbase = x;
- SchemaPtr = NULL;
- RecBuf = NULL;
- RecBuf2 = NULL;
-
- #ifdef XB_BLOCKREAD_SUPPORT
- pRb = NULL;
- bBlockReadEnabled = xbFalse; // batch read switch, if xbTrue, then ON
- #endif // XB_BLOCKREAD_SUPPORT
-
- InitVars();
-}
-/************************************************************************/
-void xbDbf::InitVars()
-{
- iNoOfFields = 0;
- iDbfStatus = XB_CLOSED;
- ulCurRec = 0L;
- cVersion = 0x00;
- cUpdateYY = 0x00;
- cUpdateMM = 0x00;
- cUpdateDD = 0x00;
- ulNoOfRecs = 0L;
- uiHeaderLen = 0x00;
- uiRecordLen = 0x00;
- cTransactionFlag = 0x00;
- cEncryptionFlag = 0x00;
- cIndexFlag = 0x00;
- cLangDriver = 0x00;
- iFileVersion = 0; /* Xbase64 file version */
- iAutoCommit = -1;
-
- SetFileName ( "" );
- sAlias.Set ( "" );
- SetDirectory ( GetDataDirectory());
-
- #ifdef XB_LOCKING_SUPPORT
- iLockFlavor = -1;
- bTableLocked = xbFalse;
- bHeaderLocked = xbFalse;
- ulAppendLocked = 0;
- SetAutoLock( -1 );
- lloRecLocks.SetDupKeys( xbFalse );
- #endif // XB_LOCKING_SUPPORT
-
- #ifdef XB_INDEX_SUPPORT
- ixList = NULL;
- pCurIx = NULL;
- vpCurIxTag = NULL;
- sCurIxType = "";
- ClearTagList();
- #endif // XB_INDEX_SUPPORT
-
- #ifdef XB_MEMO_SUPPORT
- Memo = NULL;
- #endif // XB_MEMO_SUPPORT
-
- #ifdef XB_INF_SUPPORT
- llInfData.Clear();
- #endif // XB_INF_SUPPORT
-}
-
-/************************************************************************/
-//! @brief Destructor
-xbDbf::~xbDbf(){
-
- // is there is an uncommited update, discard it.
- // as we don't know if it is an append or an update
- if( iDbfStatus == XB_UPDATED )
- Abort();
-
- if( iDbfStatus != XB_CLOSED )
- Close();
-
- if( SchemaPtr ){
- free( SchemaPtr );
- SchemaPtr = NULL;
- }
- if( RecBuf ){
- free( RecBuf );
- RecBuf = NULL;
- }
- if( RecBuf2){
- free( RecBuf2 );
- RecBuf2 = NULL;
- }
- if( RecBuf ){
- free( RecBuf );
- RecBuf = NULL;
- }
-
- #ifdef XB_BLOCKREAD_SUPPORT
- if( bBlockReadEnabled )
- DisableBlockReadProcessing();
- #endif // XB_BLOCKREAD_SUPPORT
-
- Close();
-}
-/************************************************************************/
-//! @brief Abort any uncommited changes for the current record buffer.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::Abort(){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- if( iDbfStatus == XB_UPDATED ){
- #ifdef XB_MEMO_SUPPORT
- if( MemoFieldsExist()){
- if(( iRc = Memo->Abort()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- #endif
- memcpy( RecBuf, RecBuf2, uiRecordLen );
- iDbfStatus = XB_OPEN;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::Abort() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief Add an index to the internal list of indices for this table.
-/*!
- The index list is used during any table update process to update any open
- index file. Index files can contain one or more tags. Temporary tags
- are not included here because they are created after a table is open
- and will be deleted when the table is closed.
-
- \param ixIn Pointer to index object for a given index file.
- \param sFmt NDX, MDX or TDX.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-
-xbInt16 xbDbf::AddIndex( xbIx * ixIn, const xbString &sFmt ){
-
- xbIxList *ixt; // this
- if(( ixt = (xbIxList *) malloc( sizeof( xbIxList ))) == NULL )
- return XB_NO_ERROR;
-
- ixt->ix = ixIn;
- ixt->next = NULL;
- ixt->sFmt = new xbString( sFmt );
- ixt->sFmt->ToUpperCase();
-
- if( ixList ){
- xbIxList *ixn = ixList; // next
- while( ixn->next ){
- ixn = ixn->next;
- }
- ixn->next = ixt;
- } else {
- ixList = ixt;
- }
- return XB_NO_ERROR;
-}
-#endif // XB_INDEX_SUPPORT
-
-
-/************************************************************************/
-//! @brief Append the current record to the data file.
-/*!
- This method attempts to append the contents of the current record buffer
- to the end of the DBF file, updates the file date, number of records in the file
- and updates any open indices associated with this data file.<br>
-
- To add a record, an application would typically blank the record buffer,
- update various fields in the record buffer, then append the record.<br>
-
- The append method performs the following tasks:<br>
- 1) Create new index key values<br>
- 2) Lock the table<br>
- 3) Lock append bytes<br>
- 4) Lock indices<br>
- 5) Read the dbf header<br>
- 6) Check for dup keys<br>
- 7) Calc last update date, no of recs<br>
- 8) Add keys<br>
- 9) Unlock indices<br>
- 10) Update file header<br>
- 11) Unlock file header<br>
- 12) Append record<br>
- 13) Unlock append bytes<br>
-
-Note: Locking memo files is not needed as the memo file updates are handled outside of the append method.<br>
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::AppendRecord(){
- xbInt16 iErrorStop = 0;
- xbInt16 iRc = XB_NO_ERROR;
- xbUInt32 ulSaveCurRec = 0;
-
- try{
- #ifdef XB_INDEX_SUPPORT
- xbIxList *ixList = GetIxList();
- // do this step first before anything is locked, reduce lock time as much as possible
- while( ixList ){
-
- // std::cout << "xbDbf::CreateKeys(x)\n";
- if(( iRc = ixList->ix->CreateKeys( 1 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- ixList = ixList->next;
- }
- #endif // XB_INDEX_SUPPORT
-
- // lock everything up for an update
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock && !bTableLocked ){
- if(( iRc = LockHeader( XB_LOCK )) != XB_NO_ERROR ){
- if( iRc == XB_LOCK_FAILED ) {
- return iRc;
- } else {
- iErrorStop = 110;
- throw iRc;
- }
- }
- if(( iRc = LockAppend( XB_LOCK )) != XB_NO_ERROR ){
- if( iRc == XB_LOCK_FAILED ){
- LockHeader( XB_UNLOCK );
- return iRc;
- } else {
- iErrorStop = 120;
- throw iRc;
- }
- }
-
- #ifdef XB_INDEX_SUPPORT
- if(( iRc = LockIndices( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- #endif // XB_INDEX_SUPPORT
-
- }
- #endif // XB_LOCKING_SUPPORT
- if(( iRc = ReadHeader( 1, 1 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- #ifdef XB_INDEX_SUPPORT
- ixList = GetIxList();
-
- while( ixList ){
- if(( iRc = ixList->ix->CheckForDupKeys()) != 0 ){
- if( iRc < 0 ){
- iErrorStop = 150;
- throw iRc;
- }
- return XB_KEY_NOT_UNIQUE;
- }
- ixList = ixList->next;
- }
-
- #endif // XB_INDEX_SUPPORT
-
- // calculate the latest header information
- xbDate d;
- d.Sysdate();
- cUpdateYY = (char) d.YearOf() - 1900;
- cUpdateMM = (char) d.MonthOf();
- cUpdateDD = (char) d.DayOf( XB_FMT_MONTH );
- ulSaveCurRec = ulCurRec;
- ulNoOfRecs++;
- ulCurRec = ulNoOfRecs;
-
- #ifdef XB_INDEX_SUPPORT
-
-
- ixList = GetIxList();
- while( ixList ){
- if(( iRc = ixList->ix->AddKeys( ulCurRec )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- ixList = ixList->next;
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock ){
- if(( iRc = LockIndices( XB_UNLOCK )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- }
- #endif // XB_LOCKING_SUPPORT
- #endif // XB_INDEX_SUPPORT
-
- // rewrite the header record
- if(( iRc = WriteHeader( 1, 1 )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock ){
- if(( iRc = LockHeader( XB_UNLOCK )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
- }
- #endif
-
- // write the last record
- if(( iRc = xbFseek( (uiHeaderLen+((xbInt64)(ulNoOfRecs-1)*uiRecordLen)), 0 )) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw iRc;
- }
-
- if(( iRc = xbFwrite( RecBuf, uiRecordLen, 1 )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
-
- // write the end of file marker
- if(( iRc = xbFputc( XB_CHAREOF )) != XB_NO_ERROR ){
- iErrorStop = 220;
- throw iRc;
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock ){
- if(( iRc = LockAppend( XB_UNLOCK )) != XB_NO_ERROR ){
- iErrorStop = 230;
- throw( iRc );
- }
- }
- #endif // XB_LOCKING_SUPPORT
-
- }
- catch (xbInt16 iRc ){
- if( ulSaveCurRec != 0 ){
- ulCurRec = ulSaveCurRec;
- ulNoOfRecs--;
- }
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock ){
- #ifdef XB_INDEX_SUPPORT
- LockIndices( XB_UNLOCK );
- #endif // XB_INDEX_SUPPORT
- LockAppend( XB_UNLOCK );
- LockHeader( XB_UNLOCK );
- }
- #endif // XB_LOCKING_SUPPORT
-
- if( iRc != XB_LOCK_FAILED && iRc != XB_KEY_NOT_UNIQUE ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::Append() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
-
- if( iRc == XB_NO_ERROR )
- iDbfStatus = XB_OPEN;
- return iRc;
-}
-
-/************************************************************************/
-#ifdef XB_INF_SUPPORT
-//! @brief Asscoiate a non production index to a DBF file.
-/*!
-
- The original Dbase (TM) software supported non production indices (NDX) and production indices (MDX).
- The production indices are opened automatically when the DBF file is opened but the non-production
- indices are not. This method is specific to the Xbas64 library and providex a means to link non production
- NDX index files to the DBF file so they will be opened automatically when the DBF file is opened.<br>
-
- This routine requires INF support be enabled when building the library.<br>
- This routine creates a file with the same name as the DBF file, but with an extension of INF.<br>
-
-
- \param sIxType Currently only NDX. Future versions will support additional non prod index types.
- \param sIxName The index name.
- \param iOpt 0 - Add index to .INF if not already there<br>
- 1 - Remove index from .INF if exists
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-
-xbInt16 xbDbf::AssociateIndex( const xbString &sIxType, const xbString &sIxName, xbInt16 iOpt ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- xbString sIxTypeIn = sIxType;
- sIxTypeIn.Trim();
- xbString sIxNameIn = sIxName;
- sIxNameIn.Trim();
-
- if( sIxTypeIn != "NDX" || sIxName == "" )
- return XB_INVALID_INDEX;
-
- if(( iRc = LoadInfData()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- // check if entry exists
- xbLinkListNode<xbString> * llN = llInfData.GetHeadNode();
- xbBool bFound = xbFalse;
- xbString s;
-
- while( llN && !bFound ){
- s = llN->GetKey();
- if( s.Len() > 0 ){
- if( sIxNameIn == s )
- bFound = xbTrue;
- }
- llN = llN->GetNextNode();
- }
-
- xbBool bUpdated = xbFalse;
- if( iOpt == 0 && !bFound ){
- s.Sprintf( "%s%c%c", sIxName.Str(), 0x0d, 0x0a );
- llInfData.InsertAtEnd( s );
- bUpdated = xbTrue;
-
- } else if( iOpt == 1 && bFound ){
- llInfData.RemoveByVal( s );
- bUpdated = xbTrue;
- }
-
- if( bUpdated ){
- if(( iRc = SaveInfData()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- } catch( xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::AssociateIndex() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-#endif // XB_INF_SUPPORT
-
-/************************************************************************/
-//! @brief Blank the record buffer.
-/*!
-
- This method would typically be called to initialize the record buffer before
- updates are applied to append a new record.
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::BlankRecord()
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
-
- if( iDbfStatus == XB_CLOSED ){
- iErrorStop = 100;
- iRc = XB_NOT_OPEN;
- throw iRc;
- }
-
- if( iDbfStatus == XB_UPDATED ){
- if( GetAutoCommit() == 1 ){
- if(( iRc = Commit()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- } else {
- if(( iRc = Abort()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- }
- ulCurRec = 0;
- memset( RecBuf, 0x20, uiRecordLen );
- memset( RecBuf2, 0x20, uiRecordLen );
- }
-
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::BlankRecord() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
-
- return iRc;
-}
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-/*!
- This method is used to check an index tag's intgerity.
-
- \param iTagOpt 0 - Check current tag<br>
- 1 - Check all tags<br>
-
- \param iOutputOpt Output message destination<br>
- 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::CheckTagIntegrity( xbInt16 iTagOpt, xbInt16 iOutputOpt ){
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- if( iTagOpt == 0 ){
- if( pCurIx )
- return pCurIx->CheckTagIntegrity( vpCurIxTag, iOutputOpt );
- else
- return XB_INVALID_TAG;
-
- } else {
-
- xbLinkListNode<xbTag *> *llN = GetTagList();
- xbTag *pTag;
-
- while( llN ){
- pTag = llN->GetKey();
- if(( iRc = pTag->GetIx()->CheckTagIntegrity( pTag->GetVpTag(), iOutputOpt )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- llN = llN->GetNextNode();
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::CheckTagIntegrity() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-/*!
- This method is used to reindex / rebuild index tag.
-
- \param iTagOpt 0 - Reindex current tag<br>
- 1 - Reindex all tags<br>
- 2 - Reindex for tag identified by vpTag
- \param iErrorOpt 0 - Don't delete tag on reindex failure<br>
- 1 - Delete tag on reindex failure
- \param vpTag if option 2 used, pointer to tag to reindex
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::Reindex( xbInt16 iTagOpt, xbInt16 iErrorOpt, xbIx **ppIx, void **vppTag ){
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- void *vp;
-
- xbString sType;
- xbString sTagName;
-
- if( iTagOpt < 0 || iTagOpt > 2 || (iTagOpt == 2 && (!ppIx || !vppTag )))
- return XB_INVALID_OPTION;
-
-
- #ifdef XB_BLOCKREAD_SUPPORT
- xbBool bOriginalBlockReadSts = GetBlockReadStatus();
- #endif
-
- try{
-
- #ifdef XB_BLOCKREAD_SUPPORT
- if( !bOriginalBlockReadSts )
- EnableBlockReadProcessing();
- #endif
-
- if( iTagOpt == 0 ){
- if( pCurIx ){
-
- if(( iRc = pCurIx->Reindex( &vpCurIxTag )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- return iRc;
- } else {
- return XB_INVALID_TAG;
- }
-
- } else if( iTagOpt == 1 ) {
-
- xbLinkListNode<xbTag *> *llN = GetTagList();
- xbTag *pTag;
-
- while( llN ){
- pTag = llN->GetKey();
- vp = pTag->GetVpTag();
- if(( iRc = pTag->GetIx()->Reindex( &vp )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- llN = llN->GetNextNode();
- }
- } else if( iTagOpt == 2 ){
-
- // xbIx *pIx;
- // pIx = *ppIx;
- xbIx *pIx = *ppIx;
- // void *vpTag;
- // vpTag = *vppTag;
- void *vpTag = *vppTag;
-
- if(( iRc = pIx->Reindex( &vpTag )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::Reindex() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
-
- #ifdef XB_BLOCKREAD_SUPPORT
- if( !bOriginalBlockReadSts )
- DisableBlockReadProcessing();
- #endif
-
- return iRc;
-}
-
-/************************************************************************/
-// @brief Clear the index tag list.
-/*
- Protected method. Clears the list inf index tags.
- \returns void.
-*/
-void xbDbf::ClearTagList(){
-
- xbTag *pTag;
- xbBool bDone = xbFalse;
- while( llTags.GetNodeCnt() > 0 && !bDone ){
- if( llTags.RemoveFromFront( pTag ) != XB_NO_ERROR ){
- bDone = xbTrue;
- } else {
- if( pTag )
- delete pTag;
- }
- }
-}
-#endif // XB_INDEX_SUPPORT
-
-/************************************************************************/
-//! @brief Close DBF file/table.
-/*!
- This routine flushes any remaining updates to disk, closes the DBF file and
- any associated memo and index files.
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::Close(){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
-
- if(iDbfStatus == XB_CLOSED)
- return XB_NO_ERROR;
-
- else if( iDbfStatus == XB_UPDATED ){
-
- if( GetAutoCommit() == 1 ){
- if(( iRc = Commit()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- } else {
- if(( iRc = Abort()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- }
-
- if(SchemaPtr){
- free( SchemaPtr );
- SchemaPtr = NULL;
- }
- if(RecBuf){
- free( RecBuf );
- RecBuf = NULL;
- }
- if(RecBuf2){
- free( RecBuf2 );
- RecBuf2 = NULL;
- }
-
- #ifdef XB_MEMO_SUPPORT
- if( iMemoFieldCnt > 0 ){
- Memo->CloseMemoFile();
- delete Memo;
- Memo = NULL;
- }
- #endif
-
- // close any open index files, remove from the ix list
- #ifdef XB_INDEX_SUPPORT
- while( ixList ){
- ixList->ix->Close();
- RemoveIndex( ixList->ix );
- }
- #endif
-
- if(( iRc = xbase->RemoveTblFromTblList( this )) != XB_NO_ERROR ){
- xbString sMsg;
- sMsg.Sprintf( "Alias = [%s]", sAlias.Str());
- xbase->WriteLogMessage( sMsg.Str() );
- iErrorStop = 120;
- throw iRc;
- }
- xbFclose();
- InitVars();
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::Close() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief Close an open index file
-/*!
- All index files are automatically closed when the DBF file is closed.
- Under normal conditions, it is not necessary to explicitly close an index file
- with this routine. Any updates posted to a DBF file while an index is closed
- will not be reflected in the closed index file.
-
- \param pIx Pointer to index object to close.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::CloseIndexFile( xbIx *pIx ){
-
- xbInt16 iErrorStop = 0;
- xbInt16 iRc = XB_NO_ERROR;
-
- try{
-
- // verify index is open and in the list
- xbBool bFound = xbFalse;
- xbIxList *p = GetIxList();
- while( p && !bFound ){
- if( pIx == p->ix )
- bFound = xbTrue;
- p = p->next;
- }
- if( !bFound ){
- iErrorStop = 100;
- iRc = XB_NOT_OPEN;
- throw iRc;
- }
- // close it
- if(( iRc = pIx->Close()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- // remove it from the list
- if(( iRc = RemoveIndex( pIx )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- // refresh the tag list
- if(( iRc = UpdateTagList()) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( pIx == pCurIx ){
- pCurIx = NULL;
- vpCurIxTag = NULL;
- sCurIxType = "";
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::CloseIndexFile() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-#endif // XB_INDEX_SUPPORT
-
-/************************************************************************/
-//! @brief Commit updates to disk
-/*!
-
- This routine commits any pending updates to disk.
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::Commit(){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- if( iDbfStatus == XB_UPDATED ){
- if( ulCurRec == 0 ){
- if(( iRc = AppendRecord()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- } else {
- if(( iRc = PutRecord( ulCurRec )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- }
- }
- catch (xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::Commit() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Copy table (dbf) file structure.
-/*!
-
- This routine will copy the structure of a dbf file and if successful
- return a pointer to the new table in an open state.
-
- \param dNewTable Reference to new table object.
- \param sNewTableName New table (dbf) name.
- \param sNewTableAlias Alias name of new table.
- \param iOverlay xbTrue - Overlay existing file.<br>
- xbFalse - Don't overlay existing file.
- \param iShareMode XB_SINGLE_USER<br>
- XB_MULTI_USER
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-//! Copy DBF structure
-/*!
-*/
-xbInt16 xbDbf::CopyDbfStructure( xbDbf * dNewTable, const xbString &sNewTableName,
- const xbString & sNewTableAlias, xbInt16 iOverlay, xbInt16 iShareMode ) {
-
-// If successful, the table is returned in an open state after executing this method
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbSchema *newTableSchema = NULL;
-
- try{
-
- if( iDbfStatus == XB_CLOSED ){
- iErrorStop = 100;
- iRc = XB_DBF_FILE_NOT_OPEN;
- throw iRc;
- }
-
- if( !dNewTable ){
- iErrorStop = 110;
- iRc = XB_INVALID_OBJECT;
- throw iRc;
- }
-
- // Get the number of schema entries for this table
- xbInt32 lSchemaRecCnt = GetFieldCnt() + 1;
-
- // Allocate a Schema = No Of Fields + 1
- if((newTableSchema=(xbSchema *)malloc( (size_t) lSchemaRecCnt * sizeof(xbSchema)))==NULL){
- iErrorStop = 120;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- // Populate the Schema
- xbInt32 l;
- for( l = 0; l < lSchemaRecCnt-1; l++ ){
- memset( newTableSchema[l].cFieldName, 0x00, 11 );
- for( int x = 0; x < 10 && SchemaPtr[l].cFieldName[x]; x++ )
- newTableSchema[l].cFieldName[x] = SchemaPtr[l].cFieldName[x];
- newTableSchema[l].cType = SchemaPtr[l].cType;
- newTableSchema[l].iFieldLen = SchemaPtr[l].cFieldLen;
- newTableSchema[l].iNoOfDecs = SchemaPtr[l].cNoOfDecs;
- }
-
- // set the last one to zeroes
- memset( newTableSchema[l].cFieldName, 0x00, 11 );
- newTableSchema[l].cType = 0;
- newTableSchema[l].iFieldLen = 0;
- newTableSchema[l].iNoOfDecs = 0;
-
- dNewTable->SetVersion();
- #ifdef XB_MEMO_SUPPORT
- if( MemoFieldsExist())
- dNewTable->SetCreateMemoBlockSize( Memo->GetBlockSize() );
- #endif
-
- // Call the create a table function
- if(( iRc = dNewTable->CreateTable( sNewTableName, sNewTableAlias, newTableSchema, iOverlay, iShareMode )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- }
-
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbDbf::CopyDbfStructure() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
-
- if( newTableSchema )
- free( newTableSchema );
-
- return iRc;
-}
-
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief Create a new tag (index) for this dbf file (table).
-/*!
- This routine creates a new tag (index) on a dbf file. The library currently supports NDX, MDX ans TDX.
- indices. If you don't have a specific need for an NDX file, use MDX.
-
- \param sIxType "MDX", "NDX" or "NTX".
- \param sName Index or tag name.
- \param sKey Index key expression,
- \param sFilter Filter expression. Not applicable for NDX indices.
- \param iDescending xbTrue for descending. Not available for NDX indices.<br>
- xbFalse - ascending
- \param iUnique xbTrue - Unique index<br>xbFalse - Not unique index.
- \param iOverLay xbTrue - Overlay if exists<br>
- xbFalse - Don't overlay if it exists.
- \param pIxOut Pointer to pointer of output index object.
- \param vpTagOut Pointer to pointer of newly created tag,
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::CreateTag( const xbString &sIxType, const xbString &sName, const xbString &sKey, const xbString &sFilter,
- xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverLay, xbIx **pIxOut, void **vpTagOut ){
-
- // this routine is used to open indices and link to files
-
- xbInt16 iErrorStop = 0;
- xbInt16 iRc = XB_NO_ERROR;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bLocked = xbFalse;
- #endif
-
- try{
- xbString sType = sIxType;
- sType.ToUpperCase();
-
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock && !bTableLocked ){
- if(( iRc = LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw( iRc );
- }
- bLocked = xbTrue;
- }
- #endif // XB_LOCKING_SUPPORT
-
- if( sIxType == "" ){
- iErrorStop = 110;
- iRc = XB_INVALID_OPTION;
- throw iRc;
-
- #ifdef XB_NDX_SUPPORT
- } else if( sIxType == "NDX" ){
- xbIxNdx *ixNdx = new xbIxNdx( this );
-
- if(( iRc = ixNdx->CreateTag( sName, sKey, sFilter, iDescending, iUnique, iOverLay, vpTagOut )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- if(( iRc = AddIndex( ixNdx, sIxType )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- *pIxOut = ixNdx;
-
-
-
- // Set the current tag if one not already set
- if( sCurIxType == "" ){
- sCurIxType = "NDX";
- pCurIx = ixNdx;
- vpCurIxTag = ixNdx->GetTag(0);
- }
-
- #endif
-
- #ifdef XB_MDX_SUPPORT
- } else if( sIxType == "MDX" ){
-
- if( GetVersion() == 3 ){ // MDX indexes were version 4 and higher
- iErrorStop = 140;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
-
- xbIxMdx *ixMdx;
- xbString s;
- // look through the index list and see if there is an mdx pointer we can grab
- xbBool bMdxFound = xbFalse;
- xbIxList *ixList = GetIxList();
- while( ixList && !bMdxFound ){
- s = ixList->sFmt->Str();
- if( s == "MDX" ){
- ixMdx = (xbIxMdx *) ixList->ix;
- bMdxFound = xbTrue;
- }
- ixList = ixList->next;
- }
-
- if( !bMdxFound )
- ixMdx = new xbIxMdx( this );
-
- if(( iRc = ixMdx->CreateTag( sName, sKey, sFilter, iDescending, iUnique, iOverLay, vpTagOut )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
-
- if( !bMdxFound ){
- if(( iRc = AddIndex( ixMdx, "MDX" )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
-
- cIndexFlag = 0x01;
- if(( iRc = WriteHeader( 1, 0 )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- }
- *pIxOut = ixMdx;
-
- // set the current tag if one not already set
- if( sCurIxType == "" ){
- sCurIxType = "MDX";
- pCurIx = ixMdx;
- vpCurIxTag = ixMdx->GetTag(0);
- }
- #endif
-
- #ifdef XB_TDX_SUPPORT
- } else if( sIxType == "TDX" ){
-
- if( GetVersion() == 3 ){ // TDX indexes were version 4 and higher
- iErrorStop = 140;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
-
- xbIxTdx *ixTdx;
- xbString s;
- // look through the index list and see if there is an mdx pointer we can grab
- xbBool bTdxFound = xbFalse;
- xbIxList *ixList = GetIxList();
- while( ixList && !bTdxFound ){
- s = ixList->sFmt->Str();
- if( s == "TDX" ){
- ixTdx = (xbIxTdx *) ixList->ix;
- bTdxFound = xbTrue;
- }
- ixList = ixList->next;
- }
- if( !bTdxFound )
- ixTdx = new xbIxTdx( this );
-
- if(( iRc = ixTdx->CreateTag( sName, sKey, sFilter, iDescending, iUnique, iOverLay, vpTagOut )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- if( !bTdxFound ){
- if(( iRc = AddIndex( ixTdx, "TDX" )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- }
- *pIxOut = ixTdx;
-
- // set the current tag if one not already set
- if( sCurIxType == "" ){
-
- sCurIxType = "TDX";
- pCurIx = ixTdx;
- vpCurIxTag = ixTdx->GetTag(0);
- }
-
- #endif
-
- } else {
- iErrorStop = 200;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
-
- if(( iRc = UpdateTagList()) != XB_NO_ERROR ){
- iErrorStop = 300;
- throw iRc;
- }
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::CreateTag() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( bLocked )
- LockTable( XB_UNLOCK );
- #endif // XB_LOCKING_SUPPORT
-
- return iRc;
-}
-#endif // XB_INDEX_SUPPORT
-
-/************************************************************************/
-//! @brief Delete or undelete all records in a dbf file (table).
-/*!
- This routine deletes or un-deletes all records. The xbase file format contains
- a leading one byte character used for flagging a record as deleted. When a record
- is deleted, it's not physically removed from the file, the first byte is flagged as deleted.
-
- \param iOption 0 - Delete all records.<br>
- 1 - Un-delete all deleted records.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::DeleteAll( xbInt16 iOption )
-{
- xbInt16 iErrorStop = 0;
- xbInt16 iRc = XB_NO_ERROR;
- xbUInt32 ulRecCnt;
-
- try{
- if(( iRc = GetRecordCnt( ulRecCnt )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if( ulRecCnt == 0 )
- return XB_NO_ERROR;
- for( xbUInt32 ul = 0; ul < ulRecCnt; ul++ ){
- if(( iRc = GetRecord( ul+1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- if( iOption == 0 ){ /* delete all option */
- if( !RecordDeleted()){
- if(( iRc = DeleteRecord()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = Commit()) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- }
- } else { /* undelete all option */
- if( RecordDeleted()){
- if(( iRc = UndeleteRecord()) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if(( iRc = Commit()) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
- }
- }
- }
- catch (xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED ){
- xbString sMsg;
- sMsg.Sprintf( "xbDbf::DeleteAll() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
- return iRc;
-}
-
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief
-/*!
- This routine deletes all indices associated with the dbf file.
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::DeleteAllIndexFiles(){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bLocked = xbFalse;
- #endif // XB_LOCKING_SUPPORT
-
- #ifdef XB_INF_SUPPORT
- xbString sIxName;
- #endif // XB_INF_SUPPORT
-
- try{
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock && !bTableLocked ){
- if(( iRc = LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw( iRc );
- }
- bLocked = xbTrue;
- }
- #endif // XB_LOCKING_SUPPORT
-
- // close any open index files, delete it, remove from the ix list
- while( ixList ){
-
- // next two lines for debugging
- ixList->ix->GetFileNamePart( sIxName );
- ixList->ix->Close();
- if(( iRc = ixList->ix->xbRemove()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- #ifdef XB_INF_SUPPORT
- // if XB_INF_SUPPORT is enabled, all open non prod indices should be in here
- if( *ixList->sFmt != "MDX" && *ixList->sFmt != "TDX" ){ // production and temp indices not stored in .INF dataset
- if(( iRc = ixList->ix->GetFileNamePart( sIxName )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = AssociateIndex( *ixList->sFmt, sIxName, 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- }
- #endif
- RemoveIndex( ixList->ix );
- }
- } catch( xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::DeleteAllIndexFiles() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- #ifdef XB_LOCKING_SUPPORT
- if( bLocked )
- LockTable( XB_UNLOCK );
- #endif // XB_LOCKING_SUPPORT
- return iRc;
-}
-#endif // XB_INDEX_SUPPORT
-
-/************************************************************************/
-//! @brief Delete all records.
-/*!
- This routine deletes all the records in a table / dbf file.
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::DeleteAllRecords(){
- return DeleteAll( 0 );
-}
-
-/************************************************************************/
-#ifdef XB_INF_SUPPORT
-//! @brief Delete .INF File
-/*!
- The original Dbase (TM) software supported non production indices (NDX) and production indices (MDX).
- The production indices are opened automatically when the DBF file is opened but the non-production
- indices are not. This method is specific to the Xbas64 library and providex a means to link non production
- NDX index files to the DBF file so they will be opened automatically when the DBF file is opened.<br>
-
- This routine requires INF support be enabled when building the library.<br>
- This routine deletes the .INF file.<br>
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::DeleteInfData(){
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- xbString sInfFileName;
- if(( iRc = GetInfFileName( sInfFileName )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- xbFile f( xbase );
- f.SetFileName( sInfFileName );
- if( f.FileExists()){
- if(( iRc = f.xbRemove()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- } catch( xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::DeleteInfData() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-#endif // XB_INF_SUPPORT
-
-/************************************************************************/
-//! @brief Delete the current record.
-/*!
- This routine flags the current record for deletion if it's not already flagged.
-
- \returns XB_NO_ERROR<br>
- XB_INVALID_RECORD
-*/
-
-xbInt16 xbDbf::DeleteRecord(){
- if( RecBuf && ulCurRec > 0 ){
- if( RecBuf[0] != 0x2a){
- if( iDbfStatus != XB_UPDATED ){
- iDbfStatus = XB_UPDATED;
- memcpy( RecBuf2, RecBuf, uiRecordLen ); // save off original before making any updates
- }
- RecBuf[0] = 0x2a;
- }
- return XB_NO_ERROR;
- }
- else
- return XB_INVALID_RECORD;
-}
-/************************************************************************/
-//! @brief Delete a table.
-/*!
- This routine deletes a given table, associated index files if any, the
- memo file if any and the .INF file if any.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::DeleteTable(){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bTableLocked = xbFalse;
- #endif
-
- try{
-
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock && !bTableLocked ){
- if(( iRc = LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- } else {
- bTableLocked = xbTrue;
- }
- }
- #endif // XB_LOCKING_SUPPORT
-
- #ifdef XB_INDEX_SUPPORT
- if(( iRc = DeleteAllIndexFiles()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- #ifdef XB_INF_SUPPORT
- if(( iRc = DeleteInfData()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- #endif // XB_INF_SUPPORT
- #endif // XB_INDEX_SUPPORT
-
- #ifdef XB_MEMO_SUPPORT
- xbInt16 iMemoFldCnt = GetMemoFieldCnt();
- xbString sMemoFileName;
- if(iMemoFldCnt > 0 ){
- sMemoFileName = Memo->GetFqFileName();
- }
- #endif // XB_MEMO_SUPPORT
-
- if(( iRc = Close()) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- if(( iRc = xbRemove()) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
-
- #ifdef XB_MEMO_SUPPORT
- if( iMemoFieldCnt > 0 ){
- xbFile f( xbase );
- if(( iRc = f.xbRemove( sMemoFileName )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
- #endif // XB_MEMO_SUPPORT
-
- } catch( xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::DeleteTable() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- #ifdef XB_LOCKING_SUPPORT
- if( bTableLocked )
- LockTable( XB_UNLOCK );
- #endif // XB_LOCKING_SUPPORT
- return iRc;
-}
-
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief Delete an index tag.
-
-/*!
- This routine deletes an index tag
- \param sIxType Either "NDX", "MDX" or "TDX".<br>
- \param sName Tag name to delete.<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::DeleteTag( const xbString &sIxType, const xbString &sName ){
-
- xbInt16 iErrorStop = 0;
- xbInt16 iRc = XB_NO_ERROR;
- xbIx *pIx = NULL;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bTableLocked = xbFalse;
- #endif
-
- try{
-
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock && !GetTableLocked() ){
- if(( iRc = LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- } else {
- bTableLocked = xbTrue;
- }
- }
- #endif // XB_LOCKING_SUPPORT
-
- if( sIxType == "" ){
- iErrorStop = 110;
- iRc = XB_INVALID_OPTION;
- throw iRc;
-
- #ifdef XB_NDX_SUPPORT
- } else if( sIxType == "NDX" ){
-
- xbIxList *ixl = ixList;
- xbBool bDone = xbFalse;
- while( ixl && !bDone ){
-
- if( ixl->ix->GetTagName( NULL ) == sName ){
- bDone = xbTrue;
-
- // remove from .INF if it's there
- #ifdef XB_INF_SUPPORT
- if(( iRc = AssociateIndex( "NDX", sName, 1 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- #endif // XB_INF_SUPPORT
-
- if(( iRc = ixl->ix->DeleteTag( ixl->ix->GetTag( 0 ))) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- if(( iRc = RemoveIndex( ixl->ix )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
-
- if( !ixList || ixl->ix == pCurIx )
- SetCurTag( "", NULL, NULL );
-
- }
- ixl = ixl->next;
- }
- #endif
-
- #ifdef XB_MDX_SUPPORT
- } else if( sIxType == "MDX" ){
- xbIxList *ixl = ixList;
- xbIxList *ixlNext;
- xbIxList *ixlPrev = NULL;
- xbBool bDone = xbFalse;
- xbIxMdx *pMdx;
- xbMdxTag *pMdxTag;
- xbInt16 iTagCnt = 0;
-
- while( ixl && !bDone ){
- ixlNext = ixl->next;
- pMdx = (xbIxMdx *) ixl->ix;
- iTagCnt = pMdx->GetTagCount();
- for( xbInt16 i = 0; i < iTagCnt && !bDone; i++ ){
- pMdxTag = (xbMdxTag *) pMdx->GetTag( i );
- if( pMdx->GetTagName( pMdxTag ) == sName ){
- bDone = xbTrue;
- iRc = pMdx->DeleteTag( pMdxTag );
- if( iRc > 0 ){
- // Successful delete of only tag in production mdx file - need to remove it from the list, update the dbf header
- cIndexFlag = 0x00;
- if(( iRc = WriteHeader( 1, 0 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- if(( iRc = RemoveIndex( ixl->ix )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if( ixlPrev == NULL ){
- // std::cout << "setting ixList to null or should be\n";
- ixList = ixlNext;
- } else {
- ixlPrev = ixlNext;
- }
- } else if( iRc < 0 ){
- iErrorStop = 170;
- throw iRc;
- }
- if( !ixList || ixl->ix == pCurIx )
- SetCurTag( "", NULL, NULL );
- }
- }
- ixlPrev = ixl;
- ixl = ixlNext;
- }
-
- if( !bDone )
- return XB_INVALID_TAG;
- #endif
-
- #ifdef XB_TDX_SUPPORT
- } else if( sIxType == "TDX" ){
- xbIxList *ixl = ixList;
- xbIxList *ixlNext;
- xbIxList *ixlPrev = NULL;
- xbBool bDone = xbFalse;
- xbIxTdx *pTdx;
- xbMdxTag *pMdxTag;
- xbInt16 iTagCnt = 0;
-
- while( ixl && !bDone ){
- ixlNext = ixl->next;
- pTdx = (xbIxTdx *) ixl->ix;
- iTagCnt = pTdx->GetTagCount();
- for( xbInt16 i = 0; i < iTagCnt && !bDone; i++ ){
- pMdxTag = (xbMdxTag *) pTdx->GetTag( i );
- if( pTdx->GetTagName( pMdxTag ) == sName ){
- bDone = xbTrue;
- iRc = pTdx->DeleteTag( pMdxTag );
- if( iRc > 0 ){
- // Successful delete of only tag in production mdx file - need to remove it from the list, update the dbf header
- cIndexFlag = 0x00;
- if(( iRc = WriteHeader( 1, 0 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- if(( iRc = RemoveIndex( ixl->ix )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if( ixlPrev == NULL ){
- // std::cout << "setting ixList to null or should be\n";
- ixList = ixlNext;
- } else {
- ixlPrev = ixlNext;
- }
- } else if( iRc < 0 ){
- iErrorStop = 170;
- throw iRc;
- }
- if( ixList )
- std::cout << "ixlist not null\n";
- else
- std::cout << "ixlist null\n";
-
- if( !ixList || ixl->ix == pCurIx )
- SetCurTag( "", NULL, NULL );
- }
- }
- ixlPrev = ixl;
- ixl = ixlNext;
- }
-
- if( !bDone )
- return XB_INVALID_TAG;
-
- #endif
-
-
-
- } else {
- iErrorStop = 180;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
-
- if(( iRc = UpdateTagList()) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
-
-
- }
- catch (xbInt16 iRc ){
- if( pIx ) delete pIx;
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::DeleteTag() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
-
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock && GetTableLocked() ){
- LockTable( XB_UNLOCK );
- }
- #endif // XB_LOCKING_SUPPORT
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( bTableLocked ){
- LockTable( XB_UNLOCK );
- }
- #endif // XB_LOCKING_SUPPORT
-
-
- return iRc;
-}
-#endif // XB_INDEX_SUPPORT
-/************************************************************************/
-//! @brief Dump dbf file header.
-/*!
- This routine dumps dbf header information to the console.
-
- \param iOption 1 = Print header only<br>
- 2 = Field data only<br>
- 3 = Header and Field data<br>
- 4 = Header, Field and Memo header data if applicable
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::DumpHeader( xbInt16 iOption ){
- int i;
- int iMemoCtr = 0;
-
- if( iOption < 1 || iOption > 4 )
- return XB_INVALID_OPTION;
-
- xbInt16 iRc = ReadHeader( xbTrue, 0 );
- if( iRc != XB_NO_ERROR )
- return iRc;
-
-// if( iDbfStatus == XB_CLOSED )
-// return XB_NOT_OPEN;
-
- std::cout << "\nDatabase file " << GetFqFileName() << std::endl << std::endl;
-
- if( iOption != 2 ){
- std::cout << "File header data:" << std::endl;
-
- xbInt16 sVer = DetermineXbaseTableVersion( cVersion );
-
- if( sVer == 3 )
- std::cout << "Dbase III file" << std::endl;
- else if ( sVer == 4 )
- std::cout << "Dbase IV file" << std::endl << std::endl;
- else if ( sVer == 5 )
- std::cout << "Dbase V file" << std::endl << std::endl;
- else if ( sVer == 7 )
- std::cout << "Dbase VII file" << std::endl << std::endl;
- else
- std::cout << "Unknown Version" << std::endl;
-
- /* display the bit stream */
- unsigned char c, tfv, displayMask = 1 << 7;
- tfv = cVersion;
- std::cout << "File descriptor bits = ";
- for( c = 1; c<= 8; c++ ){
- std::cout << (tfv & displayMask ? '1' : '0');
- tfv <<= 1;
- }
- std::cout << std::endl;
-
- std::cout << "Descriptor bits legend:" << std::endl;
- std::cout << " 0-2 = version number" << std::endl;
- std::cout << " 3 = presence of dBASE IV memo" << std::endl;
- std::cout << " 4-6 = SQL table presence" << std::endl;
- std::cout << " 7 = Presence of any memo file (dBASE III PLUS or dBASE IV)" << std::endl << std::endl;
-
- std::cout << "Last update date = "
- << (int) cUpdateMM << "/" << (int) cUpdateDD << "/" << (int) cUpdateYY % 100 << std::endl;
-
- std::cout << "Header length = " << uiHeaderLen << std::endl;
- std::cout << "Record length = " << uiRecordLen << std::endl;
- std::cout << "Records in file = " << ulNoOfRecs << std::endl << std::endl << std::endl;
-
- std::cout << "Transaction Flag = ";
- xbase->BitDump( cTransactionFlag );
- std::cout << std::endl;
-
- std::cout << "Encryption Flag = ";
- xbase->BitDump( cEncryptionFlag );
- std::cout << std::endl;
-
- std::cout << "Index Flag = ";
- xbase->BitDump( cIndexFlag );
- std::cout << std::endl;
-
- std::cout << "Lang Driver = " << (int) cIndexFlag << " - ";
- xbase->BitDump( cIndexFlag );
- std::cout << std::endl;
- #ifdef XB_INDEX_SUPPORT
- std::cout << "Open Index Files = " << GetPhysicalIxCnt() << std::endl;
- #endif // XB_INDEX_SUPPORT
- }
-
- if( iOption != 1 ){
- char c;
- std::cout << "Field Name Type Length Decimals IxFlag" << std::endl;
- std::cout << "---------- ---- ------ -------- ------" << std::endl;
- for( i = 0; i < iNoOfFields; i++ ){
-
- SchemaPtr[i].cIxFlag ? c = 'Y' : c = ' ';
-
- if( SchemaPtr[i].cType == 'C' && SchemaPtr[i].cNoOfDecs > 0 )
- printf( "%10s %1c %4d %4d %c\n", SchemaPtr[i].cFieldName,
- SchemaPtr[i].cType, SchemaPtr[i].cFieldLen, 0, c );
- else
- printf( "%10s %1c %4d %4d %c\n", SchemaPtr[i].cFieldName,
- SchemaPtr[i].cType, SchemaPtr[i].cFieldLen, SchemaPtr[i].cNoOfDecs, c );
-
- if( SchemaPtr[i].cType == 'M' )
- iMemoCtr++;
- }
- }
- std::cout << std::endl;
-
-#ifdef XB_MEMO_SUPPORT
- if( iOption > 3 && iMemoCtr > 0 )
- Memo->DumpMemoHeader();
-#endif
-
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Dump record
-/*!
- Dump the contents of the specified record
-
-
- \param ulRecNo Record number of record to be dumped.
- \param iOutputDest 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
-
- \param iOutputFmt 0 = with field names<br>
- 1 = 1 line per rec, no field names<br>
- 2 = 1 line per rec, first line is a list of field names.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::DumpRecord( xbUInt32 ulRecNo, xbInt16 iOutputDest, xbInt16 iOutputFmt ) {
- int i, iRc = XB_NO_ERROR;
-
- xbString sTemp;
- xbString s2;
- if( ulRecNo == 0 || ulRecNo > ulNoOfRecs )
- return XB_INVALID_RECORD;
-
- if( ulCurRec != ulRecNo ){
- iRc = GetRecord( ulRecNo );
- if( iRc != XB_NO_ERROR )
- return iRc;
- }
-
- if( iOutputFmt >= 1 ){
- if( iOutputFmt == 2 ){
- sTemp = "RecNo,DEL";
- for( i = 0; i < iNoOfFields; i++ ){
- s2 = SchemaPtr[i].cFieldName;
- s2.Trim();
- sTemp += ",";
- sTemp += s2;
- }
- xbase->WriteLogMessage( sTemp.Str(), iOutputDest );
- }
-
- if( RecordDeleted() )
- s2.Sprintf( "%ld,DEL", ulRecNo );
- else
- s2.Sprintf( "%ld,", ulRecNo );
-
- for( i = 0; i < iNoOfFields; i++ ){
- GetField( i, sTemp );
- sTemp.Trim();
- s2.Sprintf( "%s,'%s'", s2.Str(), sTemp.Str());
- }
- xbase->WriteLogMessage( s2.Str(),iOutputDest );
- return XB_NO_ERROR;
- }
-
- sTemp.Sprintf( "\nRec Number: %ld", ulRecNo );
- xbase->WriteLogMessage( sTemp.Str(),iOutputDest);
-
- if( RecordDeleted())
- xbase->WriteLogMessage( "Record flagged as deleted", iOutputDest );
-
-
- #ifdef XB_MEMO_SUPPORT
- xbString sMemo;
- #endif
-
- for( i = 0; i < iNoOfFields; i++ ){
-
- #ifdef XB_MEMO_SUPPORT
- GetField( i, sTemp );
- sTemp.Trim();
-
- if(SchemaPtr[i].cType == 'M'){
- GetMemoField( i, sMemo );
- if( sMemo.Len() > 70 )
- sMemo.Resize( 70 );
- s2.Sprintf ( "%c %s = '%s'", SchemaPtr[i].cType, SchemaPtr[i].cFieldName, sMemo.Str());
- xbase->WriteLogMessage( s2.Str(), iOutputDest);
-
- /*
- xbUInt32 ulMlen;
- if( MemoFieldExists( i )){
- Memo->GetMemoFieldLen( i, ulMlen );
- s2.Sprintf( " Len = %d", ulMlen );
- }
- xbase->WriteLogMessage( s2.Str(), iOutputDest);
- */
-
- }
- else{
- s2.Sprintf ( "%c %s = '%s'", SchemaPtr[i].cType, SchemaPtr[i].cFieldName, sTemp.Str());
- xbase->WriteLogMessage( s2.Str(), iOutputDest);
- }
- #else
- GetField( i, sTemp );
- sTemp.Trim();
- s2.Sprintf( "%s = '%s'", SchemaPtr[i].cFieldName, sTemp.Str());
- xbase->WriteLogMessage( s2.Str(), iOutputDest);
- #endif
-
- }
- return XB_NO_ERROR;
-}
-
-
-/************************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-
-
-#ifdef XB_LOCKING_SUPPORT
-//! @brief Dump the table lock status
-/*!
- Debugging routine. Dumps the table lock status to the console.
- \returns void
-*/
-
-void xbDbf::DumpTableLockStatus() const {
-
- std::cout << "File Lock Retry Count = [" << GetLockRetryCount() << "]" << std::endl;
- std::cout << "File Lock Flavor = [";
- switch (GetLockFlavor()){
- case 1:
- std::cout << "Dbase]" << std::endl;
- break;
- case 2:
- std::cout << "Clipper]" << std::endl;
- break;
- case 3:
- std::cout << "Fox]" << std::endl;
- break;
- case 9:
- std::cout << "Xbase64]" << std::endl;
- break;
- default:
- std::cout << "Unknown]" << std::endl;
- break;
- }
- std::cout << "File Auto Lock = [";
-
- if( GetAutoLock())
- std::cout << "ON]" << std::endl;
- else
- std::cout << "OFF]" << std::endl;
- if( GetHeaderLocked())
- std::cout << "Header Locked = [TRUE]\n";
- else
- std::cout << "Header Locked = [FALSE]\n";
-
- if( GetTableLocked())
- std::cout << "Table Locked = [TRUE]\n";
- else
- std::cout << "Table Locked = [FALSE]\n";
-
- if( GetAppendLocked() > 0 )
- std::cout << "Append Locked = [" << GetAppendLocked() << "]\n";
- else
- std::cout << "Append Locked = [FALSE]\n";
-
- #ifdef XB_MEMO_SUPPORT
- if( GetMemoLocked())
- std::cout << "Memo Locked = [TRUE]\n";
- else
- std::cout << "Memo Locked = [FALSE]\n";
- #endif // XB_MEMO_SUPPORT
-
- xbLinkListNode<xbUInt32> * llN = GetFirstRecLock();
- if( llN ){
- while( llN ){
- std::cout << "Record Locked = [" << llN->GetKey() << "]\n";
- llN = llN->GetNextNode();
- }
- } else {
- std::cout << "Record Locked = [None]\n";
- }
-}
-#endif // XB_LOCKING_SUPPORT
-#endif // XB_DEBUG_SUPPORT
-
-/************************************************************************/
-#ifdef XB_LOCKING_SUPPORT
-//! @brief Get the append locked bytes status
-/*!
- \returns The record number of the new record for the append lock operation.
-*/
-
-xbUInt32 xbDbf::GetAppendLocked() const {
- return this->ulAppendLocked;
-}
-
-#endif // XB_LOCKING_SUPPORT
-
-/************************************************************************/
-//! @brief Get auto commit setting.
-/*!
-
- This routine returns the table setting if set, otherwise returns the system
- level setting.
-
- \returns Not 0 - Auto commit on for this table.<br>
- 0 - Auto commit off for this table.
-*/
-
-xbInt16 xbDbf::GetAutoCommit() const {
- return GetAutoCommit( 1 );
-}
-
-/************************************************************************/
-//! @brief Get auto commit setting.
-/*!
-
- \param iOption 0 - Specific setting for this table<br>
- 1 - If this table should be auto updated (takes DBMS setting into account)
- \returns Not 0 - Auto commit on for this table.<br>
- 0 - Auto commit off for this table.
-*/
-
-xbInt16 xbDbf::GetAutoCommit( xbInt16 iOption ) const {
- if( iOption == 1 && iAutoCommit == -1 )
- return xbase->GetDefaultAutoCommit();
- else
- return iAutoCommit;
-}
-
-
-/************************************************************************/
-#ifdef XB_LOCKING_SUPPORT
-//! @brief Get Auto Lock setting.
-/*!
- \returns Auto lock setting.
-*/
-xbInt16 xbDbf::GetAutoLock() const{
- return iAutoLock;
-}
-#endif // XB_LOCKING_SUPPORT
-
-/************************************************************************/
-#ifdef XB_MEMO_SUPPORT
-//! @brief Get the memo file block size used when creating a memo file.
-/*!
- \returns Memo block size.
-*/
-xbUInt32 xbDbf::GetCreateMemoBlockSize() const {
- return ulCreateMemoBlockSize;
-}
-#endif // XB_MEMO_SUPPORT
-
-/************************************************************************/
-//! @brief Get a pointer to the current index object.
-/*!
- \returns Pointer to current index.
-*/
-#ifdef XB_INDEX_SUPPORT
-xbIx *xbDbf::GetCurIx() const {
- return pCurIx;
-}
-/************************************************************************/
-//! @brief Get pointer to current tag for the current index.
-/*!
- An index file can have one or more tags
- NDX index files have one tag per file.
- MDX index files can can have up to 47 tags per file.
- TDX index files can can have up to 47 tags per file.
-
- \returns Pointer to current tag.
-*/
-void *xbDbf::GetCurTag() const {
- return vpCurIxTag;
-}
-/************************************************************************/
-//! @brief Get the current index type.
-/*!
- \returns NDX for single tag index.<br>
- MDX for production multi tag index.<br>
- TDX for temporary tag index.
-*/
-const xbString &xbDbf::GetCurIxType() const {
- return sCurIxType;
-}
-
-/************************************************************************/
-//! @brief Get the current tag name.
-/*!
- \returns Current Tag Name.<br>
-*/
-
-const xbString &xbDbf::GetCurTagName() const {
-
- if( pCurIx )
- return pCurIx->GetTagName( vpCurIxTag );
- else
- return sNullString;
-}
-
-/************************************************************************/
-//! @brief GetFirstKey for tag.
-/*!
-
- Position to the first key for the current tag
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-xbInt16 xbDbf::GetFirstKey(){
- if( pCurIx )
- return pCurIx->GetFirstKey( vpCurIxTag, 1 );
- else
- return XB_INVALID_TAG;
-}
-
-/************************************************************************/
-//! @brief GetHeaderLen for dbf
-/*!
-
- Returns the length of the header portion of the dbf file
- \returns Length of header protion of dbf file
-
-*/
-xbUInt16 xbDbf::GetHeaderLen() const {
- return uiHeaderLen;
-}
-
-/************************************************************************/
-//! @brief GetLastKey for tag.
-/*!
-
- Position to the last key for the current tag
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-xbInt16 xbDbf::GetLastKey(){
- if( pCurIx )
- return pCurIx->GetLastKey( vpCurIxTag, 1 );
- else
- return XB_INVALID_TAG;
-}
-
-/************************************************************************/
-//! @brief GetNextKey for tag.
-/*!
-
- Position to the next key for the current tag
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-xbInt16 xbDbf::GetNextKey(){
- if( pCurIx )
- return pCurIx->GetNextKey( vpCurIxTag, 1 );
- else
- return XB_INVALID_TAG;
-}
-
-/************************************************************************/
-//! @brief GetPrevKey for tag.
-/*!
-
- Position to the previous key for the current tag
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-xbInt16 xbDbf::GetPrevKey(){
- if( pCurIx )
- return pCurIx->GetPrevKey( vpCurIxTag, 1 );
- else
- return XB_INVALID_TAG;
-}
-
-/************************************************************************/
-//! @brief Find record for key.
-/*!
-
- Find a key and position to record if key found
-
- \param sKey String key to find
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-xbInt16 xbDbf::Find( xbString &sKey ){
- if( pCurIx )
- return pCurIx->FindKey( vpCurIxTag, sKey.Str(), (xbInt32) sKey.Len(), 1 );
- else
- return XB_INVALID_TAG;
-}
-
-/************************************************************************/
-//! @brief Find record for key.
-/*!
-
- Find a key and position to record if key found
-
- \param dtKey Date key to find
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-xbInt16 xbDbf::Find( xbDate &dtKey ){
-
- if( pCurIx )
- return pCurIx->FindKey( vpCurIxTag, dtKey, 1 );
- else
- return XB_INVALID_TAG;
-
-}
-/************************************************************************/
-//! @brief Find record for key.
-/*!
-
- Find a key and position to record if key found
-
- \param dtKey Date key to find
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-xbInt16 xbDbf::Find( xbDouble &dKey ){
-
- if( pCurIx )
- return pCurIx->FindKey( vpCurIxTag, dKey, 1 );
- else
- return XB_INVALID_TAG;
-
-}
-
-
-#endif // XB_INDEX_SUPPORT
-
-/************************************************************************/
-//! @brief Return true if dbf file empty or positioned to the first record
-/*!
- \returns Returns true if dbf file is empty or positioned on the first record.
-*/
-xbBool xbDbf::GetBof() {
-/*
- if( GetRecordCount() == 0 || GetCurRecNo() == 1 )
- return xbTrue;
- else
- */
- return xbFalse;
-}
-/************************************************************************/
-//! @brief Return true if dbf file empty or positioned to the last record
-/*!
- \returns Returns true if error, dbf file is empty or positioned on the last record.
-*/
-xbBool xbDbf::GetEof() {
-
- // xbUInt32 ulRecCnt = GetRecordCount();
-
- xbUInt32 ulRecCnt;
- xbInt16 iRc = GetRecordCnt( ulRecCnt );
-
- if( iRc != XB_NO_ERROR || ulRecCnt == 0 || GetCurRecNo() == ulRecCnt )
- return xbTrue;
- else
- return xbFalse;
-}
-/************************************************************************/
-//! @brief Return the current record number.
-/*!
- \returns Returns the current record number.
-*/
-xbUInt32 xbDbf::GetCurRecNo() const {
- return ulCurRec;
-}
-
-/************************************************************************/
-//! @brief Return the current dbf status.
-/*!
- \returns 0 = closed<br>
- 1 = open<br>
- 2 = updates pending<br>
-*/
-xbInt16 xbDbf::GetDbfStatus() const {
- return iDbfStatus;
-}
-/************************************************************************/
-//! @brief Return the number of fields in the table.
-/*!
- \returns The number of fields in the table.
-*/
-xbInt32 xbDbf::GetFieldCnt() const {
- return iNoOfFields;
-}
-
-/************************************************************************/
-#ifdef XB_LOCKING_SUPPORT
-//! @brief Get the first first record lock.
-/*!
- Get the first record lock from a linked list of record locks.
- \returns First record lock.
-*/
-xbLinkListNode<xbUInt32> * xbDbf::GetFirstRecLock() const {
- return lloRecLocks.GetHeadNode();
-}
-#endif // XB_LOCKING_SUPPORT
-/************************************************************************/
-//! @brief Get the first record.
-/*!
- Get the first not deleted record. This routines skips over any deleted records.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::GetFirstRecord()
-{
- return GetFirstRecord( XB_ACTIVE_RECS );
-}
-
-/************************************************************************/
-//! @brief Get the first record.
-/*!
-
- \param iOption XB_ALL_RECS - Get the first record, deleted or not.<br>
- XB_ACTIVE_RECS - Get the first active record.<br>
- XB_DELETED_RECS - Get the first deleted record.<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::GetFirstRecord( xbInt16 iOption )
-{
- if( ulNoOfRecs == 0 )
- return XB_EMPTY;
-
- xbInt16 iRc = GetRecord( 1L );
- while( iRc == XB_NO_ERROR &&
- ((RecordDeleted() && iOption == XB_ACTIVE_RECS) ||
- (!RecordDeleted() && iOption == XB_DELETED_RECS)))
- if( ulCurRec < ulNoOfRecs )
- iRc = GetRecord( ulCurRec + 1 );
- else
- return XB_EOF;
-
- return iRc;
-}
-
-/************************************************************************/
-#ifdef XB_LOCKING_SUPPORT
-//! @brief Return lock status of the table header
-/*! \returns DBF header lock status
-*/
-
-xbBool xbDbf::GetHeaderLocked() const {
- return this->bHeaderLocked;
-}
-#endif // XB_LOCKING_SUPPORT
-
-#ifdef XB_INDEX_SUPPORT
-//! @brief Return pointer to list of index files for the table.
-/*!
- \returns Returns an xbIxList * pointer to list of open index files.
-*/
-
-xbIxList *xbDbf::GetIxList() const{
- return ixList;
-}
-#endif // XB_INDEX_SUPPORT
-
-
-/************************************************************************/
-//! @brief Get the last record.
-/*!
- Get the last not deleted record. This routines skips over any deleted records.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::GetLastRecord()
-{
- return GetLastRecord( XB_ACTIVE_RECS );
-}
-/************************************************************************/
-//! @brief Get the last record.
-/*!
-
- \param iOption XB_ALL_RECS - Get the last record, deleted or not.<br>
- XB_ACTIVE_RECS - Get the last active record.<br>
- XB_DELETED_RECS - Get the last deleted record.<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::GetLastRecord( xbInt16 iOption )
-{
- if( ulNoOfRecs == 0 )
- return XB_EMPTY;
-
- xbInt16 iRc = GetRecord( ulNoOfRecs );
- while( iRc == XB_NO_ERROR &&
- ((RecordDeleted() && iOption == XB_ACTIVE_RECS) ||
- (!RecordDeleted() && iOption == XB_DELETED_RECS)))
- if( ulCurRec > 1 )
- iRc = GetRecord( ulCurRec - 1 );
- else
- return XB_EOF;
-
- return iRc;
-}
-
-
-/************************************************************************/
-#ifdef XB_LOCKING_SUPPORT
-//! @brief Get lock flavor.
-/*!
- This routine is currently in place to provide structure for future locking
- schemes that may differ from the legacy DBase (TM) locking scheme.
- \returns Always 1.
-*/
-
-xbInt16 xbDbf::GetLockFlavor() const{
- if( iLockFlavor == -1 )
- return xbase->GetDefaultLockFlavor();
- else
- return iLockFlavor;
-}
-#endif // XB_LOCKING_SUPPORT
-
-/************************************************************************/
-#ifdef XB_MEMO_SUPPORT
-/************************************************************************/
-#ifdef XB_LOCKING_SUPPORT
-//! @brief Get the lock status of the memo file.
-/*!
- \returns Lock status of memo file.
-*/
-xbBool xbDbf::GetMemoLocked() const {
- if( MemoFieldsExist())
- return Memo->GetMemoLocked();
- else
- return xbFalse;
-}
-#endif // XB_LOCKING_SUPPORT
-
-/************************************************************************/
-//! @brief Get pointer to Memo object.
-/*!
- \returns This routine returns the pointer to the memo object.
-*/
-
-xbMemo * xbDbf::GetMemoPtr(){
- return Memo;
-}
-
-#endif // XB_MEMO_SUPPORT
-
-
-/************************************************************************/
-#ifdef XB_INF_SUPPORT
-//! @brief Return the .INF file name
-/*!
- If NDXIDX support is enabled in the library, and a non production (ndx)
- has been associated with the dbf file, the .INF file name can be retrieved
- with this routine.
-
- \param sInfFileName Output string containing .INF file name.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::GetInfFileName( xbString &sInfFileName ){
-
- sInfFileName = GetFqFileName();
- xbUInt32 lLen = sInfFileName.Len();
- if( lLen < 5 )
- return XB_FILE_NOT_FOUND;
- sInfFileName.PutAt(lLen-2, 'I');
- sInfFileName.PutAt(lLen-1, 'N');
- sInfFileName.PutAt(lLen, 'F');
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Return first node of linked list of .INF items.
-/*!
- \returns List of .INF entries.
-*/
-
-xbLinkListNode<xbString> * xbDbf::GetInfList() const{
- return llInfData.GetHeadNode();
-}
-#endif // XB_INF_SUPPORT
-
-
-/************************************************************************/
-//! @brief Get the next record.
-/*!
- Get the next not deleted record. This routines skips over any deleted records.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::GetNextRecord(){
- return GetNextRecord( XB_ACTIVE_RECS );
-}
-
-/************************************************************************/
-//! @brief Get the next record.
-/*!
- \param iOption XB_ALL_RECS - Get the next record, deleted or not.<br>
- XB_ACTIVE_RECS - Get the next active record.<br>
- XB_DELETED_RECS - Get the next deleted record.<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::GetNextRecord( xbInt16 iOption ){
- if( ulNoOfRecs == 0 )
- return XB_EMPTY;
- else if( ulCurRec >= ulNoOfRecs )
- return XB_EOF;
- xbInt16 iRc = GetRecord( ulCurRec + 1 );
- while( iRc == XB_NO_ERROR &&
- ((RecordDeleted() && iOption == XB_ACTIVE_RECS) ||
- (!RecordDeleted() && iOption == XB_DELETED_RECS)))
- if( ulCurRec < ulNoOfRecs )
- iRc = GetRecord( ulCurRec + 1 );
- else
- return XB_EOF;
- return iRc;
-}
-/************************************************************************/
-//! @brief Get the next record.
-/*!
-
- \param iOption XB_ALL_RECS - Get the next record, deleted or not.<br>
- XB_ACTIVE_RECS - Get the next active record.<br>
- XB_DELETED_RECS - Get the next deleted record.<br>
- \param ulStartRec Get next record, starting from ulStartRec.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::GetNextRecord( xbInt16 iOption , xbUInt32 ulStartRec ){
-
- if( iOption == 0 )
- return GetNextRecord();
- else if( iOption == 1 ){
- if( ulStartRec > 0 )
- ulCurRec = ulStartRec;
- xbInt16 iRc = GetNextRecord();
- while( iRc == XB_NO_ERROR && RecordDeleted())
- iRc = GetNextRecord();
- return iRc;
- }
- else
- return XB_INVALID_OPTION;
-}
-
-
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief Physical count of open index files.
-/*!
-
- Returns a physical count of open index files for the dbf file. An index file
- can contain one or more tags.
- \returns Count of open index files.
-*/
-
-xbInt32 xbDbf::GetPhysicalIxCnt() const {
-
- xbInt32 lCnt = 0;
- #ifdef XB_INDEX_SUPPORT
- xbIxList *p = ixList;
- while( p ){
- lCnt++;
- p = p->next;
- }
- #endif
- return lCnt;
-}
-#endif // XB_INDEX_SUPPORT
-
-
-/************************************************************************/
-//! @brief Get the previous record.
-/*!
- Get the previous not deleted record. This routine skips over any deleted records.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::GetPrevRecord()
-{
- return GetPrevRecord( XB_ACTIVE_RECS );
-}
-
-/************************************************************************/
-//! @brief Get the previous record.
-/*!
-
- \param iOption XB_ALL_RECS - Get the previous record, deleted or not.<br>
- XB_ACTIVE_RECS - Get the previous active record.<br>
- XB_DELETED_RECS - Get the previous deleted record.<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::GetPrevRecord( xbInt16 iOption ){
- if( ulNoOfRecs == 0 )
- return XB_EMPTY;
- else if( ulCurRec <= 1L )
- return XB_BOF;
- xbInt16 iRc = GetRecord( ulCurRec - 1 );
- while( iRc == XB_NO_ERROR &&
- ((RecordDeleted() && iOption == XB_ACTIVE_RECS) ||
- (!RecordDeleted() && iOption == XB_DELETED_RECS)))
- if( ulCurRec > 1 )
- iRc = GetRecord( ulCurRec - 1 );
- else
- return XB_BOF;
-
- return iRc;
-}
-
-
-/************************************************************************/
-//! @brief Get record for specified record number.
-/*!
- Retrieve a record from disk and load it into the record buffer. If auto commit
- is enabled and there are pending updates, this routine will flush the updates
- to disk before proceeding to ulRecNo.
-
- \param ulRecNo - Record number to retrieve.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::GetRecord( xbUInt32 ulRecNo ){
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- /* verify the file is open */
- if( iDbfStatus == XB_CLOSED ){
- iErrorStop = 100;
- iRc = XB_NOT_OPEN;
- throw iRc;
- }
- if( iDbfStatus == XB_UPDATED ){
- if( GetAutoCommit() == 1 ){
- if(( iRc = Commit()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- } else {
- if(( iRc = Abort()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- }
-
-
- // std::cout << "xbdbf::GetRecord: " << ulRecNo << " " << ulNoOfRecs << "\n";
- if( ulRecNo > ulNoOfRecs || ulRecNo == 0L ){
- iErrorStop = 130;
- iRc = XB_INVALID_RECORD;
- throw iRc;
- }
-
- #ifdef XB_BLOCKREAD_SUPPORT
- if( bBlockReadEnabled )
- return pRb->GetRecord( ulRecNo );
- #endif // XB_BLOCK_READ_SUPPORT
-
-
- if(( xbFseek( (uiHeaderLen+(( (xbInt64) ulRecNo-1L ) * uiRecordLen )), SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 140;
- iRc = XB_SEEK_ERROR;
- throw iRc;
- }
-
- if( xbFread( RecBuf, uiRecordLen, 1 ) != XB_NO_ERROR ){
- iErrorStop = 150;
- iRc = XB_READ_ERROR;
- throw iRc;
- }
- ulCurRec = ulRecNo;
- }
-
- catch (xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED ){
- xbString sMsg;
- sMsg.Sprintf( "xbDbf::GetRecord() Exception Caught. Error Stop = [%d] iRc = [%d] record = [%d]", iErrorStop, iRc, ulRecNo );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
- return iRc;
-}
-/************************************************************************/
-//! @brief Get pointer to record buffer
-/*!
- \param iOpt 0 for RecBuf (current) or 1 for RecBuf2 (original contents)
-
- \returns Pointer to record buffer.
-*/
-char * xbDbf::GetRecordBuf( xbInt16 iOpt ) const {
- if( iOpt )
- return RecBuf2;
- else
- return RecBuf;
-}
-
-/************************************************************************/
-//! @brief Get the current number of records in the dbf data file.
-/*!
- \returns Record count or <a href="xbretcod_8h.html">Return Codes</a>
-*/
-/*
-xbUInt32 xbDbf::GetRecordCount(){
-
- xbUInt32 ulCnt;
- xbInt16 iRc = GetRecordCnt( ulCnt );
- if( iRc < 0 )
- return (xbUInt32) iRc;
- else
- return ulCnt;
-}
-*/
-/************************************************************************/
-//! @brief Get the current number of records in the dbf data file.
-/*!
- \param ulRecCnt Output number of records in file.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::GetRecordCnt( xbUInt32 & ulRecCnt )
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bLocked = xbFalse;
- #endif // XB_LOCKING_SUPPORT
-
- try{
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock && !bTableLocked ){
- if(( iRc = LockHeader( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- } else
- bLocked = xbTrue;
- }
- #endif // XB_LOCKING_SUPPORT
-
- if((iRc = ReadHeader(1,1)) != XB_NO_ERROR){
- iErrorStop = 110;
- throw iRc;
- }
- }
- catch( xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED ){
- xbString sMsg;
- sMsg.Sprintf( "xbDbf::GetRecordCnt() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( bLocked ){
- LockHeader( XB_UNLOCK );
- }
- #endif
-
- ulRecCnt = ulNoOfRecs;
- return iRc;
-}
-/************************************************************************/
-//! @brief Get the dbf record length.
-/*!
- \returns Record length.
-*/
-xbUInt16 xbDbf::GetRecordLen() const {
- return uiRecordLen;
-}
-/************************************************************************/
-#ifdef XB_LOCKING_SUPPORT
-//! @brief Get table locked status
-/*!
- \returns Table lock status.
-*/
-xbBool xbDbf::GetTableLocked() const {
- return this->bTableLocked;
-}
-#endif // XB_LOCKING_SUPPORT
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief Get tag list for dbf file.
-/*!
- This routine returns a list of tags for the file.<br>
-
- The library is structured to support one or more files of the same or differing
- index types (NDX/MDX/TDX), with each file supporting one or more index tags.<br>
-
- \returns Tag list for the file/table.
-*/
-xbLinkListNode<xbTag *> *xbDbf::GetTagList() const {
- return llTags.GetHeadNode();
-}
-#endif // XB_INDEX_SUPPORT
-/************************************************************************/
-//! @brief Get the table alias.
-/*!
- This routine returns the table alias.
- \returns Table alias
-*/
-const xbString & xbDbf::GetTblAlias() const {
- return this->sAlias;
-}
-
-/************************************************************************/
-//! @brief Get the pointer to the xbXbase structure,
-/*!
- \returns Pointer to xbXbase structure.
-*/
-xbXBase * xbDbf::GetXbasePtr() const {
- return xbase;
-}
-/************************************************************************/
-#ifdef XB_INF_SUPPORT
-//! @brief Load .INF data file,
-/*!
- Protected method. This routine loads the ndx inf file.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::LoadInfData(){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- // create file name
- xbString sInfFileName;
- if(( iRc = GetInfFileName( sInfFileName )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- // if file does not exist, return no error
- xbFile fMd( xbase );
- if( !fMd.FileExists( sInfFileName ))
- return XB_NO_ERROR;
-
- // open file file in read only mode
- if(( iRc = fMd.xbFopen( "r", sInfFileName, GetShareMode())) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- // clear the linked list
- llInfData.Clear();
-
- // for each entry in the file, add a linked list item
- xbString sRec;
- xbString sLeft3;
- xbString sFn;
-
- while( iRc == XB_NO_ERROR ){
- sRec = "";
- if(( iRc = fMd.xbFgets( 132, sRec )) == XB_NO_ERROR ){
- sLeft3 = sRec;
- sLeft3.Left( 3 );
- sLeft3.ToUpperCase();
- if( sLeft3 == "NDX"){
- sFn.ExtractElement(sRec.Str(), '=', 2 );
- sFn.ZapChar( 0x0d );
- sFn.ZapChar( 0x0a );
- llInfData.InsertAtEnd( sFn );
- }
- }
- }
- // close the file
- if(( iRc = fMd.xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- } catch( xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::LoadInfData() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-#endif // XB_INF_SUPPORT
-
-/************************************************************************/
-#ifdef XB_LOCKING_SUPPORT
-//! @brief Lock append bytes.
-/*!
- This routine locks the append bytes and is used by the AppendRecord function.
-
- \param iLockFunction XB_LOCK<br>XB_UNLOCK
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::LockAppend( xbInt16 iLockFunction )
-{
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulAppendRec;
-
- try{
- if( iLockFunction == XB_LOCK ){
- iErrorStop = 100;
- if( ulAppendLocked > 0 ) /* already have an append lock */
- return XB_NO_ERROR;
-
- ulAppendRec = ulNoOfRecs + 1; /* record number needing to be locked */
- if( GetLockFlavor() == LK_DBASE ){
- iRc = xbLock( XB_LOCK, LK4026531839, 1 );
- if( iRc != XB_NO_ERROR ){
- if( iRc == XB_LOCK_FAILED )
- return iRc;
- else{
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- xbInt64 llAppendRecLockByte = (xbInt64) LK4026531838 - ulAppendRec;
- iRc = xbLock( XB_LOCK, llAppendRecLockByte, 1 );
- if( iRc != XB_NO_ERROR ){
- xbLock( XB_UNLOCK, LK4026531839, 1 );
- if( iRc == XB_LOCK_FAILED ){
- return iRc;
- } else {
- iErrorStop = 120;
- throw iRc;
- }
- }
- ulAppendLocked = ulAppendRec; /* set the append lock switch */
-
-
- // } else { - other lock-table flavor options go here Clipper, Fox, etc - }
-
- } else {
- iErrorStop = 130;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
-
- } else if( iLockFunction == XB_UNLOCK ){
- iErrorStop = 200;
-
- if( ulAppendLocked == 0 ) /* verify we have an active append lock */
- return XB_NO_ERROR;
-
- if( GetLockFlavor() == LK_DBASE ){
- xbInt64 llAppendRecLockByte =(xbInt64) LK4026531838 - ulAppendLocked;
- iRc = xbLock( XB_UNLOCK, llAppendRecLockByte, 1 );
- if( iRc != XB_NO_ERROR ){
- xbLock( XB_UNLOCK, LK4026531839, 1 );
- iErrorStop = 220;
- throw iRc;
- }
- iRc = xbLock( XB_UNLOCK, LK4026531839, 1 );
- if( iRc != XB_NO_ERROR ){
- iErrorStop = 230;
- throw iRc;
- }
-
- ulAppendLocked = 0; /* release the append lock switch */
-
- // } else { - other unlock-table flavor options go here Clipper, Fox, etc - }
-
- } else {
- iErrorStop = 290;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
- } else {
- iErrorStop = 300;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
- } catch( xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::LockAppendBytes() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
-
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Lock Header
-/*!
- This routine locks the file header.
- \param iLockFunction XB_LOCK<br>XB_UNLOCK
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::LockHeader( xbInt16 iLockFunction )
-{
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- try{
-
- if( iLockFunction == XB_LOCK ){
- iErrorStop = 100;
- if( GetHeaderLocked())
- return XB_NO_ERROR;
-
- iErrorStop = 110;
- if( GetLockFlavor() == LK_DBASE ){
-
- iRc = xbLock( XB_LOCK, LK4026531838, 1 );
-
- if( iRc != XB_NO_ERROR ){
- if( iRc == XB_LOCK_FAILED )
- return iRc;
- else{
- iErrorStop = 120;
- throw iRc;
- }
- }
-
- } else {
- iErrorStop = 130;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
-
- SetHeaderLocked( xbTrue );
-
- } else if( iLockFunction == XB_UNLOCK ){
-
- iErrorStop = 200;
- if( !GetHeaderLocked())
- return XB_NO_ERROR;
-
- iErrorStop = 210;
- if( GetLockFlavor() == LK_DBASE ){
- iRc = xbLock( XB_UNLOCK, LK4026531838, 1 );
- if( iRc != XB_NO_ERROR ){
- iErrorStop = 220;
- throw iRc;
- }
- } else {
- iErrorStop = 230;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
- SetHeaderLocked( xbFalse );
- } else {
- iErrorStop = 300;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
-
- } catch (xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::LockHeader() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
- return iRc;
-}
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief Lock Index files.
-/*!
- This routine locks all the index files.
- \param iLockFunction XB_LOCK<br>XB_UNLOCK
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::LockIndices( xbInt16 iLockFunction )
-{
- // this function doesn't take into account any Lack Flavors other than DBASE,
- // would need updated to supprot other lock flavors - Clipper, FoxPro etc
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- xbIxList *ixLI = GetIxList(); // index list item
-
- while( ixLI ){
- if( iLockFunction == XB_LOCK ){
-
- #ifdef XB_NDX_SUPPORT
- if( *ixLI->sFmt == "NDX" ){
- if( !ixLI->ix->GetLocked()){
- if(( iRc = ixLI->ix->xbLock( XB_LOCK, LK4026531838, 1 )) != XB_NO_ERROR ){
- ixLI->ix->xbLock( XB_UNLOCK, LK4026531838, 1 );
- iErrorStop = 100;
- throw iRc;
- }
- ixLI->ix->SetLocked( xbTrue );
- }
- }
- #endif
-
- #ifdef XB_MDX_SUPPORT
- if( *ixLI->sFmt == "MDX" ){
- if( !ixLI->ix->GetLocked()){
- if(( iRc = ixLI->ix->xbLock( XB_LOCK, LK4026531838, 1 )) != XB_NO_ERROR ){
- ixLI->ix->xbLock( XB_UNLOCK, LK4026531838, 1 );
- iErrorStop = 100;
- throw iRc;
- }
- ixLI->ix->SetLocked( xbTrue );
- }
- }
- #endif
-
- #ifdef XB_TDX_SUPPORT
- if( *ixLI->sFmt == "TDX" ){
- if( !ixLI->ix->GetLocked()){
- if(( iRc = ixLI->ix->xbLock( XB_LOCK, LK4026531838, 1 )) != XB_NO_ERROR ){
- ixLI->ix->xbLock( XB_UNLOCK, LK4026531838, 1 );
- iErrorStop = 100;
- throw iRc;
- }
- ixLI->ix->SetLocked( xbTrue );
- }
- }
- #endif
-
- } else if( iLockFunction == XB_UNLOCK ){
-
- #ifdef XB_NDX_SUPPORT
- if( *ixLI->sFmt == "NDX" ){
- if( ixLI->ix->GetLocked()){
- if(( iRc = ixLI->ix->xbLock( XB_UNLOCK, LK4026531838, 1 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- ixLI->ix->SetLocked( xbFalse );
- }
- }
- #endif
-
- #ifdef XB_MDX_SUPPORT
- if( *ixLI->sFmt == "MDX" ){
- if( ixLI->ix->GetLocked()){
- if(( iRc = ixLI->ix->xbLock( XB_UNLOCK, LK4026531838, 1 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- ixLI->ix->SetLocked( xbFalse );
- }
- }
- #endif
-
- #ifdef XB_TDX_SUPPORT
- if( *ixLI->sFmt == "MDX" ){
- if( ixLI->ix->GetLocked()){
- if(( iRc = ixLI->ix->xbLock( XB_UNLOCK, LK4026531838, 1 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- ixLI->ix->SetLocked( xbFalse );
- }
- }
- #endif
-
- }
- ixLI = ixLI->next;
- }
-
- } catch( xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::LockIndices() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
- return iRc;
-}
-#endif // XB_INDEX_SUPPORT
-/************************************************************************/
-#ifdef XB_MEMO_SUPPORT
-//! @brief Lock Memo file.
-/*!
- This routine locks the memo file for updates.
- \param iLockFunction XB_LOCK<br>XB_UNLOCK
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::LockMemo( xbInt16 iLockFunction ){
- if( MemoFieldsExist())
- return Memo->LockMemo( iLockFunction );
- else
- return XB_NO_ERROR;
-}
-#endif // XB_MEMO_SUPPORT
-
-
-
-/************************************************************************/
-//! @brief Loc Record
-/*!
- This routine locks a record for update.
- \param iLockFunction XB_LOCK<br>XB_UNLOCK
- \param ulRecNo Record number to lock
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::LockRecord( xbInt16 iLockFunction, xbUInt32 ulRecNo )
-{
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
-
- if( ulRecNo > ulNoOfRecs )
- return XB_INVALID_RECORD;
-
- if( iLockFunction == XB_LOCK ){
- iErrorStop = 100;
-
- if( lloRecLocks.KeyExists( ulRecNo ))
- return XB_NO_ERROR;
-
- if( GetLockFlavor() == LK_DBASE ){
-
- iRc = xbLock( XB_LOCK, LK4026531838 - ulRecNo, 1 );
- if( iRc != XB_NO_ERROR ){
- if( iRc == XB_LOCK_FAILED ){
- return iRc;
- } else {
- iErrorStop = 110;
- throw iRc;
- }
- }
- // other lock-table flavor options go here Clipper, Fox, etc
-
- } else {
- iErrorStop = 120;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
-
- // add the record lock info to the linked list chain of record locks
- iRc = lloRecLocks.InsertKey( ulRecNo );
- if( iRc != XB_NO_ERROR ){
- xbLock( XB_UNLOCK, LK4026531838 - ulRecNo, 1 );
- iErrorStop = 130;
- throw iRc;
- }
-
- } else if( iLockFunction == XB_UNLOCK ){
-
- iErrorStop = 200;
-
- if( !lloRecLocks.KeyExists( ulRecNo ) )
- return XB_NO_ERROR;
-
- if( GetLockFlavor() == LK_DBASE ){
- iRc = xbLock( XB_UNLOCK, LK4026531838 - ulRecNo, 1 );
- if( iRc != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- } else {
- iErrorStop = 220;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
-
- // remove the record lock info to the linked list chain of record locks
- // next line is crashing
- iRc = lloRecLocks.RemoveKey( ulRecNo );
- if( iRc != XB_NO_ERROR ){
- iErrorStop = 230;
- throw iRc;
- }
-
- } else {
- iErrorStop = 300;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
-
- } catch( xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::LockRecord() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Lock table.
-/*!
- This routine locks the table for updates.
-
- \param iLockFunction XB_LOCK<br>XB_UNLOCK
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::LockTable( xbInt16 iLockFunction )
-{
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- if( iLockFunction == XB_LOCK ){
- iErrorStop = 100;
- if( GetTableLocked())
- return XB_NO_ERROR; // table already locked
-
- iErrorStop = 110;
- if( GetLockFlavor() == LK_DBASE ){
-
- // lOffset = LK4026531838;
- // iLen = 2;
- iRc = xbLock( XB_LOCK, LK4026531838, 2 );
- if( iRc != XB_NO_ERROR ){
- if( iRc == XB_LOCK_FAILED )
- return iRc;
- else{
- iErrorStop = 120;
- throw iRc;
- }
- }
-
- // lOffset = LK3026531838;
- // iLen = LK1000000000;
- iRc = xbLock( XB_LOCK, LK3026531838, LK1000000000);
- if( iRc != XB_NO_ERROR ){
-
- // lOffset = LK4026531838;
- // iLen = 2;
- xbLock( XB_UNLOCK, LK4026531838, 2 );
- if( iRc == XB_LOCK_FAILED ){
- return iRc;
- } else {
- iErrorStop = 130;
- throw iRc;
- }
- }
-
- // iRc = xbLock( XB_UNLOCK, lOffset, iLen );
- iRc = xbLock( XB_UNLOCK, LK3026531838, LK1000000000);
- if( iRc != XB_NO_ERROR ){
- // lOffset = LK4026531838;
- // iLen = 2;
- xbLock( XB_UNLOCK, LK4026531838, 2 );
- iErrorStop = 140;
- throw iRc;
- }
-
- // other lock-table flavor options go here Clipper, Fox, etc
-
- } else {
- iErrorStop = 190;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
- SetTableLocked( xbTrue );
-
- } else if( iLockFunction == XB_UNLOCK ){
-
- iErrorStop = 200;
- if( !GetTableLocked())
- return XB_NO_ERROR; // table already unlocked
-
- iErrorStop = 210;
- if( GetLockFlavor() == LK_DBASE ){
-
- // lOffset = LK4026531838;
- // iLen = 2;
- iRc = xbLock( XB_UNLOCK, LK4026531838, 2 );
- if( iRc != XB_NO_ERROR ){
- iErrorStop = 220;
- throw iRc;
- }
- } else {
- iErrorStop = 290;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
- SetTableLocked( xbFalse );
-
- } else {
- iErrorStop = 300;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
-
- } catch (xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::LockFile() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
- return iRc;
-
-}
-#endif // XB_LOCKING_SUPPORT
-
-
-/************************************************************************/
-//! @brief Check for existence of any memo fields.
-/*!
- \returns xbTrue - Memo fields exist.<br>xbFalse - Memo fields don't exist.
-*/
-xbBool xbDbf::MemoFieldsExist() const {
-
-
-#ifdef XB_MEMO_SUPPORT
- if( iMemoFieldCnt > 0 )
- return xbTrue;
-#endif
- return xbFalse;
-}
-
-/************************************************************************/
-//! @brief Open a table/dbf file.
-/*!
- This routine sets the alias name to the same as the table name.
-
- \param sTableName Table name to open, Include the .dbf or .DBF extension.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::Open( const xbString & sTableName ) {
- return Open( sTableName, sTableName );
-}
-
-/************************************************************************/
-//! @brief Open a table/dbf file.
-/*!
- \param sTableName Table name to open, Include the .dbf or .DBF extension.
- \param sAlias Alias name to assign to this entry.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::Open( const xbString & sTableName, const xbString & sAlias ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- if(( iRc = Open( sTableName, sAlias, XB_READ_WRITE, XB_MULTI_USER )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- // do any .INF data things on the file, like open indices
- #ifdef XB_INF_SUPPORT
- if(( iRc = LoadInfData()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- xbUInt32 llNodeCnt = llInfData.GetNodeCnt();
- if( llNodeCnt > 0 ){
- xbString s2;
- xbLinkListNode<xbString> * llN = llInfData.GetHeadNode();
- for( xbUInt32 i = 0; i < llNodeCnt; i++ ){
- s2 = llN->GetKey();
- #ifdef XB_NDX_SUPPORT
- if(( iRc = OpenIndex( "NDX", s2 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc ;
- }
- #endif // XB_NDX_SUPPORT
- llN = llN->GetNextNode();
- }
- }
- #endif // XB_INF_SUPPORT
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::Open() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief Open an index.
-/*!
- Open an index file for the dbf file.
-
- \param sIxType - "NDX" or "MDX"
- \param sFileName - File name of index,
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::OpenIndex( const xbString &sIxType, const xbString &sFileName ){
-
- // this routine is used to open indices and set up linkages
-
- xbInt16 iErrorStop = 0;
- xbInt16 iRc = XB_NO_ERROR;
- xbIx *pIx = NULL;
-
- try{
- xbString sType = sIxType;
- sType.ToUpperCase();
-
- if( sType == "" ){
- iErrorStop = 100;
- iRc = XB_INVALID_OPTION;
- throw iRc;
-
- #ifdef XB_NDX_SUPPORT
- } else if( sType == "NDX" ){
- pIx = new xbIxNdx( this );
- if(( iRc = pIx->Open( sFileName )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- #endif
-
- #ifdef XB_MDX_SUPPORT
- } else if( sType == "MDX" ){
- pIx = new xbIxMdx( this );
- if(( iRc = pIx->Open( sFileName )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- #endif
-
- } else {
- iErrorStop = 130;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
-
- if(( iRc = AddIndex( pIx, sIxType )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if(( iRc = UpdateTagList()) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- pCurIx = pIx;
- sCurIxType = sIxType;
- vpCurIxTag = pIx->GetTag( 0 );
- }
- catch (xbInt16 iRc ){
- if( pIx ) delete pIx;
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::OpenIndex() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-#endif // XB_INDEX_SUPPORT
-
-
-
-/************************************************************************/
-//! @brief Pack dbf file.
-/*!
- This routine eliminates all deleted records from the file.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::Pack()
-{
- xbUInt32 ulDeletedRecCnt;
- return Pack( ulDeletedRecCnt );
-}
-
-
-/************************************************************************/
-//! @brief Pack dbf file.
-/*!
- This routine eliminates all deleted records from the file and clears
- out any unused blocks in the memo file if one exists.
- \param ulDeletedRecCnt - Output - number of recrods removed from the file.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::Pack( xbUInt32 &ulDeletedRecCnt )
-{
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulLastMovedRec = 0;
- xbUInt32 ulStartPos = 0;
- xbUInt32 ulLastPackedRec = 0;
- xbUInt32 ulMoveRec = 0;
- xbUInt32 ulRecCnt = 0;
- ulDeletedRecCnt = 0;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bLocked = xbFalse;
- #endif // XB_LOCKING_SUPPORT
-
- try{
- if( !FileIsOpen() ){
- iErrorStop = 100;
- iRc = XB_DBF_FILE_NOT_OPEN;
- throw iRc;
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock && !bTableLocked ){
- if(( iRc = LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- } else {
- bLocked = xbTrue;
- }
- }
- #endif
-
- if(( iRc = GetRecordCnt( ulRecCnt )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- xbBool bDone = xbFalse;
- for( xbUInt32 ulI = 1; ulI <= ulRecCnt && !bDone; ulI++ ){
-
- if(( iRc = GetRecord( ulI )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( RecordDeleted()){
- ulDeletedRecCnt++;
- if( ulI > ulLastMovedRec )
- ulStartPos = ulI;
- else
- ulStartPos = ulLastMovedRec;
-
- iRc = GetNextRecord( 1, ulStartPos );
-
- if( iRc == XB_NO_ERROR ){
- ulMoveRec = ulCurRec;
- }
- else if( iRc == XB_EOF ){
- ulMoveRec = 0;
- bDone = xbTrue;
- }
- else{
- iErrorStop = 140;
- throw iRc;
- }
- if( ulMoveRec > 0 ){
- if(( iRc = DeleteRecord()) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- if(( iRc = PutRecord( ulMoveRec )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if(( iRc = UndeleteRecord()) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- if(( iRc = PutRecord( ulI )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
- ulLastPackedRec = ulI;
- }
-
- } else {
- ulLastPackedRec = ulI;
- }
- }
-
- if( ulLastPackedRec < ulRecCnt ){
- // update header record count
-
- xbDate d;
- d.Sysdate();
- cUpdateYY = (char) d.YearOf() - 1900;
- cUpdateMM = (char) d.MonthOf();
- cUpdateDD = (char) d.DayOf( XB_FMT_MONTH );
- ulNoOfRecs = ulLastPackedRec;
-
- // rewrite the header record
- if(( iRc = WriteHeader( 1, 1 )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
-
- // truncate the file to the new size
- if(( iRc = xbTruncate( uiHeaderLen + uiRecordLen * ulLastPackedRec )) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw iRc;
- }
- }
-
- if( ulNoOfRecs > 0 ){
- if(( iRc = GetRecord( 1 )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- } else {
- BlankRecord();
- ulCurRec = 0;
- }
-
- #ifdef XB_MEMO_SUPPORT
- if( iMemoFieldCnt > 0 ){
- if(( iRc = Memo->PackMemo( 0 )) != XB_NO_ERROR ){
- iErrorStop = 220;
- throw iRc;
- }
- }
- #endif // XB_MEMO_SUPPORT
- }
- catch (xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::Pack() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
- #ifdef XB_LOCKING_SUPPORT
- if( bLocked ){
- LockTable( XB_UNLOCK );
- }
- #endif
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Write the current record to disk.
-/*!
- This routine is used to write any updates to the current record buffer to disk.
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::PutRecord() {
- return PutRecord(ulCurRec);
-}
-
-/************************************************************************/
-//! @brief Write record to disk.
-/*!
- This routine is used to write a copy of the current record buffer to disk
- for a given record number.
-
- \param ulRecNo Record number to update.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::PutRecord(xbUInt32 ulRecNo)
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- if( ulRecNo < 1 ){
- iErrorStop = 100;
- throw XB_INVALID_RECORD;
- }
-
- xbUInt32 ulRecCnt;
- if(( iRc = GetRecordCnt( ulRecCnt )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- if( ulRecNo > ulRecCnt ){
- iErrorStop = 120;
- throw XB_INVALID_RECORD;
- }
-
- if( iDbfStatus == XB_CLOSED ){
- iErrorStop = 130;
- iRc = XB_NOT_OPEN;
- throw iRc;
- }
- /* lock the database */
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock && !bTableLocked ){
- if(( iRc = LockHeader( XB_LOCK )) != XB_NO_ERROR ){
- throw iRc;
- }
- }
- #endif // XB_LOCKING_SUPPORT
-
- if(( iRc = ReadHeader( 1, 1 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
-
- // verify valid record number request
- if( ulRecNo > ulNoOfRecs || ulRecNo == 0L ){
- iErrorStop = 160;
- iRc = XB_INVALID_RECORD;
- throw iRc;
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock && !bTableLocked ){
- if(( iRc = LockRecord( XB_LOCK, ulRecNo )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
-
- #ifdef XB_INDEX_SUPPORT
- if(( iRc = LockIndices( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
- #endif // XB_INDEX_SUPPORT
- }
- #endif // XB_LOCKING_SUPPORT
-
- // build keys, check for duplicate keys, add keys
- #ifdef XB_INDEX_SUPPORT
- xbIxList *ixList = GetIxList();
-
- while( ixList ){
- if(( iRc = ixList->ix->CreateKeys( 2 )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
- iRc = ixList->ix->CheckForDupKeys();
- if( iRc != 0 ){
- if( iRc < 0 ){
- iErrorStop = 200;
- throw iRc;
- }
- throw XB_KEY_NOT_UNIQUE;
- }
- ixList = ixList->next;
- }
-
- ixList = GetIxList();
- while( ixList ){
-
- if(( iRc = ixList->ix->AddKeys( ulCurRec )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- ixList = ixList->next;
- }
-
- ixList = GetIxList();
- while( ixList ){
- if(( iRc = ixList->ix->DeleteKeys()) != XB_NO_ERROR ){
- iErrorStop = 220;
- throw iRc;
- }
- ixList = ixList->next;
- }
- #endif // XB_INDEX_SUPPORT
-
- // update latest header date if changed
- xbDate d;
- d.Sysdate();
- if( (cUpdateYY != (char)(d.YearOf() - 1900)) || (cUpdateMM != (char) d.MonthOf()) || (cUpdateDD != (char)d.DayOf( XB_FMT_MONTH))){
- cUpdateYY = (char) d.YearOf() - 1900;
- cUpdateMM = (char) d.MonthOf();
- cUpdateDD = (char) d.DayOf( XB_FMT_MONTH );
- // rewrite the header record - first 8 bytes
- if(( iRc = WriteHeader( 1, 1 )) != XB_NO_ERROR ){
- iErrorStop = 70;
- throw iRc;
- }
- }
-
- // update record
- iRc = xbFseek( (uiHeaderLen+(( (xbInt64) ulRecNo-1L ) * uiRecordLen )),0 );
- if( iRc != XB_NO_ERROR ){
- iErrorStop = 240;
- throw iRc;
- }
-
- if( xbFwrite( RecBuf, uiRecordLen, 1 ) != XB_NO_ERROR ){
- iErrorStop = 250;
- iRc = XB_WRITE_ERROR;
- throw iRc;
- }
-
- #ifdef XB_MEMO_SUPPORT
- if( MemoFieldsExist() ){
- if(( iRc = Memo->Commit()) != XB_NO_ERROR ){
- iErrorStop = 260;
- throw iRc;
- }
- }
- #endif
-
- ulCurRec = ulRecNo;
- iDbfStatus = XB_OPEN;
- }
-
- catch (xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED && iRc != XB_KEY_NOT_UNIQUE ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::PutRecord() Exception Caught. Error Stop = [%d] iRc = [%d] record = [%d]", iErrorStop, iRc, ulRecNo );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock ){
- LockHeader( XB_UNLOCK );
- LockAppend( XB_UNLOCK );
- LockRecord( XB_UNLOCK, ulRecNo );
- #ifdef XB_INDEX_SUPPORT
- LockIndices( XB_UNLOCK );
- #endif // XB_INDEX_SUPPORT
- }
- #endif // XB_LOCKING_SUPPORT
-
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Read dbf file header information.
-/*!
- This method assumes the header has been locked appropriately
- in a multi user environment
-
-
- \param iPositionOption 0 - Don't fseek to beginning of file before read.<br>
- 1 - Start from beginning of file.
-
- \param iReadOption 0 - Read entire 32 byte header<br>
- 1 - Read first eight bytes which includes the last update date and number of records.
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::ReadHeader( xbInt16 iPositionOption, xbInt16 iReadOption ){
-
- char buf[32];
- size_t iReadSize;
-
- if(iPositionOption)
- xbRewind();
- if( iReadOption == 1 )
- iReadSize = 8;
- else
- iReadSize = 32;
-
- if(xbFread(buf, iReadSize, 1) != XB_NO_ERROR)
- return XB_READ_ERROR;
- memcpy(&cVersion, buf, 4);
- ulNoOfRecs = eGetUInt32(&buf[4]);
- if( iReadOption == 1 )
- return XB_NO_ERROR;
-
- uiHeaderLen = eGetUInt16(&buf[8]);
- uiRecordLen = eGetUInt16(&buf[10]);
- cTransactionFlag = buf[14];
- cEncryptionFlag = buf[15];
- cIndexFlag = buf[28];
- cLangDriver = buf[29];
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Return record deletion status.
-/*!
- This routine returns the record deletion status.
- \param iOpt 0 = Current record buffer, 1 = Original record buffer
- \returns xbTrue - Record deleted.<br>xbFalse - Record not deleted.
-*/
-xbInt16 xbDbf::RecordDeleted( xbInt16 iOpt ) const {
- if( !iOpt && RecBuf && RecBuf[0] == 0x2a )
- return xbTrue;
- else if( iOpt && RecBuf2 && RecBuf2[0] == 0x2a )
- return xbTrue;
- else
- return xbFalse;
-}
-
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief Remove an index from the internal list of indices for this table
-/*
- The index list is used during any table update process to update any open
- index file. Index files can contain one or more tags.
-
- \param ixIn Pointer to index object for a given index file.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::RemoveIndex( xbIx * ixIn ){
-
- xbIxList *p = ixList;
- // if index is the first entry in the list
- if( ixList->ix == ixIn ){
- ixList = ixList->next;
- delete p->sFmt;
- delete p->ix;
- free( p );
- return XB_NO_ERROR;
- }
-
- // spin down to the correct ix
- xbIxList *p2 = NULL;
- while( p && p->ix != ixIn ){
- p2 = p;
- p = p->next;
- }
- if( p ){
- p2->next = p->next;
- delete p->sFmt;
- delete p->ix;
- free( p );
- }
- return XB_NO_ERROR;
-}
-#endif // XB_INDEX_SUPPORT
-
-/************************************************************************/
-// @brief Reset number of records.
-/*
- Protected method. Resets number of records to 0.
- \returns void
-*/
-void xbDbf::ResetNoOfRecords() {
- ulNoOfRecs = 0UL;
-}
-
-/************************************************************************/
-#ifdef XB_INF_SUPPORT
-// @brief Update .INF data file.
-/*
- Protected method.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf::SaveInfData(){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbFile fMd( xbase );
-
- try{
-
- xbUInt32 llNodeCnt = llInfData.GetNodeCnt();
-
- xbString sInfFileName;
- if(( iRc = GetInfFileName( sInfFileName )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- // open the file
- if(( iRc = fMd.xbFopen( "w", sInfFileName, GetShareMode())) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- xbString s1;
- xbString s2;
- s2.Sprintf( "[dbase]%c%c", 0x0d, 0x0a );
- if(( iRc = fMd.xbFputs( s2 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- // for each entry in the linked list, write a line
- xbLinkListNode<xbString> * llN = llInfData.GetHeadNode();
- for( xbUInt32 i = 0; i < llNodeCnt; i++ ){
- s2 = llN->GetKey();
- if( i > 0 )
- s1.Sprintf( "NDX%d=%s%c%c", i, s2.Str(), 0x0d, 0x0a );
- else
- s1.Sprintf( "NDX=%s%c%c", s2.Str(), 0x0d, 0x0a );
-
- if(( iRc = fMd.xbFputs( s1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- llN = llN->GetNextNode();
- }
-
- // close the file
- if(( iRc = fMd.xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
-
- } catch( xbInt16 iRc ){
- if( fMd.FileIsOpen())
- fMd.xbFclose();
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::SaveInfData() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-#endif // XB_INF_SUPPORT
-/************************************************************************/
-//! @brief Set auto commit.
-/*!
- This routine sets the auto commit setting for this table.
- \returns XB_NO_ERROR;
-*/
-xbInt16 xbDbf::SetAutoCommit( xbBool iAutoCommit ) {
- this->iAutoCommit = iAutoCommit;
- return XB_NO_ERROR;
-}
-
-
-/************************************************************************/
-//! @brief Set auto lock.
-/*!
- This routine sets the auto lock setting for this table.
- There is an overall system level auto lock default setting and each table
- can have it's own autolock setting. This method controls the table level
- auto lock setting.
-
- \param iAutoLock 1 - Use auto lock for this table.<br>
- 0 - Don't use auto lock for this table.<br>
- -1 - (minus one) Use system default.<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-#ifdef XB_LOCKING_SUPPORT
-void xbDbf::SetAutoLock( xbInt16 iAutoLock ){
- if( iAutoLock == -1 )
- this->iAutoLock = xbase->GetDefaultAutoLock();
- else
- this->iAutoLock = iAutoLock;
-}
-#endif
-
-
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief Set the current tag for the dbf file.
-/*!
- \param sTagName - Tag Name
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::SetCurTag( const xbString &sTagName ){
-
- if( sTagName == "" ){
- SetCurTag( "", 0, 0 );
- return XB_NO_ERROR;
-
- } else {
- xbLinkListNode<xbTag *> *llN = GetTagList();
- xbTag *pTag;
- while( llN ){
- pTag = llN->GetKey();
- if( pTag->GetTagName() == sTagName ){
- SetCurTag( pTag->GetType(), pTag->GetIx(), pTag->GetVpTag());
- return XB_NO_ERROR;
- }
- llN = llN->GetNextNode();
- }
- }
-
- return XB_INVALID_TAG;
-}
-
-/************************************************************************/
-//! @brief Set the current tag for the dbf file.
-/*!
-
- \param sIxType - One of "NDX", MDX or TDX",
- \param pIx - Pointer to index object.
- \param vpTag - Pointer to tag object.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-void xbDbf::SetCurTag( const xbString &sIxType, xbIx *pIx, void *vpTag ){
- pCurIx = pIx;
- vpCurIxTag = vpTag;
- sCurIxType.Set( sIxType );
-}
-#endif // XB_INDEX_SUPPORT
-
-/************************************************************************/
-//! @brief Set the header locked status.
-/*!
- \param bHeaderLocked xbTrue - Locked<br>xbFalse - Not locked.
- \returns void
-*/
-#ifdef XB_LOCKING_SUPPORT
-void xbDbf::SetHeaderLocked( xbBool bHeaderLocked ){
- this->bHeaderLocked = bHeaderLocked;
-}
-#endif
-
-/************************************************************************/
-//! @brief Set lock flavor.
-/*!
- This routine is for future expansion.
- \param iLockFlavor 1 - Use Dbase (tm) style locking.
- \returns void
-*/
-#ifdef XB_LOCKING_SUPPORT
-void xbDbf::SetLockFlavor( xbInt16 iLockFlavor ){
- this->iLockFlavor = iLockFlavor;
-}
-#endif
-
-/************************************************************************/
-//! @brief Set table locked status.
-/*!
- \param bTableLocked - xbTrue Table locked.<br>xbFalse Table unlocked.
- \returns void
-*/
-#ifdef XB_LOCKING_SUPPORT
-void xbDbf::SetTableLocked( xbBool bTableLocked ){
- this->bTableLocked = bTableLocked;
-}
-#endif
-/************************************************************************/
-//! @brief Undelete all records.
-/*!
- This routine will remove the deletion flag on any deleted records in the table.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::UndeleteAllRecords(){
- return DeleteAll( 1 );
-}
-
-/************************************************************************/
-//! @brief Undelete one record.
-/*!
- This routine will undelete the current record, if it is deleted.
- \returns XB_NO_ERROR<br>XB_INVALID_RECORD
-*/
-xbInt16 xbDbf::UndeleteRecord()
-{
- if( RecBuf && ulCurRec > 0 ){
- if( RecBuf[0] != 0x20 ){
- if( iDbfStatus != XB_UPDATED ){
- iDbfStatus = XB_UPDATED;
- memcpy( RecBuf2, RecBuf, uiRecordLen ); // save off original before making updates
- }
- RecBuf[0] = 0x20;
- }
- return XB_NO_ERROR;
- }
- else
- return XB_INVALID_RECORD;
-}
-
-/************************************************************************/
-#ifdef XB_MEMO_SUPPORT
-//! @brief Update memo field
-/*!
- This routine updates a memo field.
- \param iFieldNo - Memo field number to update.
- \param sMemoData - Memo data for update.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::UpdateMemoField( xbInt16 iFieldNo, const xbString &sMemoData ){
- return Memo->UpdateMemoField( iFieldNo, sMemoData );
-}
-/************************************************************************/
-//! @brief Update memo field
-/*!
- This routine updates a memo field.
- \param sFieldName - Memo field name to update.
- \param sMemoData - Memo data for update.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::UpdateMemoField( const xbString & sFieldName, const xbString & sMemoData ){
- return Memo->UpdateMemoField( GetFieldNo( sFieldName ), sMemoData );
-}
-#endif
-
-
-/************************************************************************/
-#ifdef XB_INDEX_SUPPORT
-//! @brief Update SchemaIxFlag
-/*!
- This routine can be called from the DeleteTag routine if a tag has been deleted and the flag needs reset
- \param iFldNo - Which field the index flag needs changed on
- \param cVal - Value to change it to
-*/
-
-void xbDbf::UpdateSchemaIxFlag( xbInt16 iFldNo, unsigned char cVal ){
- if( cVal != 0x00 || cVal != 0x01 )
- SchemaPtr[iFldNo].cIxFlag = cVal;
-}
-
-/************************************************************************/
-
-//! @brief Update tag list.
-/*!
- This routine updates the internal tag list of open index tags.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::UpdateTagList(){
-
- xbInt16 iErrorStop = 0;
- xbInt16 iRc = XB_NO_ERROR;
- xbInt32 lTagCnt;
-
- try{
- ClearTagList();
-
- // For each active index
- xbIxList *p = GetIxList();
- xbIx *ixp;
- while( p ){
- ixp = p->ix;
- // for each tag within the file
- lTagCnt = ixp->GetTagCount();
- for( xbInt32 l = 0; l < lTagCnt; l++ ){
- xbTag *pTag = new xbTag( ixp, ixp->GetTag( l ), *p->sFmt, ixp->GetTagName( ixp->GetTag( l )),
- ixp->GetKeyExpression( ixp->GetTag( l )), ixp->GetKeyFilter( ixp->GetTag( l )),
- ixp->GetUnique( ixp->GetTag( l )), ixp->GetSortOrder( ixp->GetTag( l )));
-
- // append it to the llTags list
- llTags.InsertAtEnd( pTag );
- }
- p = p->next;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::UpdateTagList() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-#endif // XB_INDEX_SUPPORT
-
-/************************************************************************/
-// @brief Write Header
-/*
- Protected method.
-
- \param iPositionOption 0 - Don't fseek to beginning of file before read.<br>
- 1 - Go to beginning of file before read.
- \param iWriteOption 0 - Write entire 32 byte header.<br>
- 1 - Write first eight bytes needed for table updates - last update date and number of records.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::WriteHeader( xbInt16 iPositionOption, xbInt16 iWriteOption )
-{
- char buf[32];
- xbInt32 lWriteLen;
-
- if(iPositionOption)
- xbRewind();
-
- memset(buf, 0, 32);
- if( iWriteOption == 1 )
- lWriteLen = 8;
- else{
- lWriteLen = 32;
- ePutUInt16( &buf[8], uiHeaderLen );
- ePutUInt16( &buf[10], uiRecordLen );
- buf[14] = cTransactionFlag;
- buf[15] = cEncryptionFlag;
- buf[28] = cIndexFlag;
- buf[29] = cLangDriver;
- }
- memcpy(&buf[0], &cVersion, 4);
- ePutUInt32( &buf[4], ulNoOfRecs);
- if(xbFwrite(buf, (size_t) lWriteLen, 1) != XB_NO_ERROR)
- return XB_WRITE_ERROR;
-
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! @brief Zap (remove) everything from the file,
-/*!
- This routine eliminates everything from the dbf file and dbt memo file.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf::Zap(){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bLocked = xbFalse;
- #endif // XB_LOCKING_SUPPORT
-
- try{
- if( iDbfStatus != XB_OPEN ){
- iErrorStop = 100;
- iRc = XB_DBF_FILE_NOT_OPEN;
- throw iRc;
- }
- #ifdef XB_LOCKING_SUPPORT
- if( iAutoLock ){
- if(( iRc = LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- #endif
-
- xbDate d;
- d.Sysdate();
- cUpdateYY = (char) d.YearOf() - 1900;
- cUpdateMM = (char) d.MonthOf();
- cUpdateDD = (char) d.DayOf( XB_FMT_MONTH );
- ulNoOfRecs = 0;
-
- // rewrite the header record
- if(( iRc = WriteHeader( 1, 1 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- // truncate the file to the new size
- if(( iRc = xbTruncate( uiHeaderLen )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- BlankRecord();
- ulCurRec = 0;
-
- #ifdef XB_MEMO_SUPPORT
- if( iMemoFieldCnt ){
- if(( iRc = Memo->Zap()) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- }
- #endif
- #ifdef XB_INDEX_SUPPORT
- xbLinkListNode<xbTag *> *llN = GetTagList();
- xbTag *pTag;
- xbIx *pIx;
- void *vpTag;
- while( llN ){
- pTag = llN->GetKey();
- pIx = pTag->GetIx();
- vpTag = pTag->GetVpTag();
- if(( iRc = pIx->Reindex( &vpTag )) != XB_NO_ERROR ){
- iErrorStop = 60;
- throw iRc;
- }
- llN = llN->GetNextNode();
- }
-
- #endif // XB_INDEX_SUPPORT
- }
- catch (xbInt16 iRc ){
- if( iRc != XB_LOCK_FAILED ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::Zap() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
- #ifdef XB_LOCKING_SUPPORT
- if( bLocked ){
- LockTable( XB_UNLOCK );
- }
- #endif // XB_LOCKING_SUPPORT
- return iRc;
-}
-/************************************************************************/
-#ifdef XB_BLOCKREAD_SUPPORT
-// block read processing is designed to provide a way to rapidly retrieve
-// all the records from a .DBF file in sequential order.
-
-// It is not designed for doing any read/write processing or data retrieval based on a tag sort.
-// It is designed for doing a fast sequentil block read out of a table
-
-
-xbInt16 xbDbf::DisableBlockReadProcessing(){
-
- if( bBlockReadEnabled ){
- bBlockReadEnabled = xbFalse;
- delete pRb;
- pRb = NULL;
- }
- return XB_NO_ERROR;
-}
-
-xbBool xbDbf::GetBlockReadStatus() const {
- return bBlockReadEnabled;
-}
-
-xbInt16 xbDbf::EnableBlockReadProcessing(){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
-
- if( !bBlockReadEnabled ){
- if( iDbfStatus == XB_UPDATED ){
- if( GetAutoCommit() == 1 ){
- if(( iRc = Commit()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- } else {
- if(( iRc = Abort()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- }
- pRb = new xbBlockRead( this );
- if( !pRb ){
- iErrorStop = 120;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- if(( iRc = pRb->Init()) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- bBlockReadEnabled = xbTrue;
- }
-
- } catch( xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbdbf::EnableBlockReadProcessing() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-#endif // XB_BLOCKREAD_SUPPORT
-/************************************************************************/
-} /* namespace */ \ No newline at end of file
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf3.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf3.cpp
deleted file mode 100755
index 926cc0d..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf3.cpp
+++ /dev/null
@@ -1,768 +0,0 @@
-/* xbdbf3.cpp
-
-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 "xbase.h"
-
-
-#ifdef XB_DBF3_SUPPORT
-
-namespace xb{
-
-
-/************************************************************************/
-//! @brief Constructor.
-
-xbDbf3::xbDbf3(xbXBase * x) : xbDbf( x ) {
- #ifdef XB_MEMO_SUPPORT
- ulCreateMemoBlockSize = 512;
- #endif
- iFileVersion = 3;
-};
-
-/************************************************************************/
-//! @brief Destructor.
-
-xbDbf3::~xbDbf3() {};
-
-/************************************************************************/
-//! @brief Create Version 3 table.
-/*!
- This routine creates a Dbase III Plus (tm) DBF file.
-
- \param sTableName DBF table name.
- \param sAlias Table alias
- \param pSchema Pointer to schema structure with field definitions.
- \param iOverlay xbTrue - Overlay.<br> xbFalse - Don't overlay.
- \param iShareMode XB_SINGLE_USER<br>XB_MULTI_USER
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-xbInt16 xbDbf3::CreateTable( const xbString & sTableName, const xbString & sAlias, xbSchema *pSchema, xbInt16 iOverlay, xbInt16 iShareMode ){
-
- xbInt16 i, k, k2;
- xbInt16 rc = 0;
- xbInt16 iErrorStop = 0;
- iDbfStatus = XB_CLOSED;
-
- xbString sNfn;
- try{
- sNfn = sTableName;
- xbase->GetLogStatus();
-
- rc = NameSuffixMissing( sNfn, 1 );
- if( rc > 0 )
- sNfn += ".DBF";
-
- SetFileName( sNfn );
- this->sAlias = sAlias;
-
- /* check if the file already exists */
- if( FileExists( 0 )){
- if( !iOverlay ){
- iErrorStop = 100;
- rc = XB_FILE_EXISTS;
- throw rc;
- }
-
- // remove other files if they exist
- xbString sMname = sNfn;
- xbUInt32 iMnameLen = sMname.Len();
- sMname.PutAt( iMnameLen-2, 'I' );
- sMname.PutAt( iMnameLen-1, 'N' );
- sMname.PutAt( iMnameLen, 'F' );
- xbFile fTemp( xbase );
- fTemp.SetFileName( sMname );
- if( fTemp.FileExists() )
- fTemp.xbRemove();
-
- sMname.PutAt( iMnameLen-2, 'D' );
- sMname.PutAt( iMnameLen-1, 'B' );
- sMname.PutAt( iMnameLen, 'T' );
- fTemp.SetFileName( sMname );
- if( fTemp.FileExists() )
- fTemp.xbRemove();
-
- sMname.PutAt( iMnameLen-2, 'M' );
- sMname.PutAt( iMnameLen-1, 'D' );
- sMname.PutAt( iMnameLen, 'X' );
- fTemp.SetFileName( sMname );
- if( fTemp.FileExists() )
- fTemp.xbRemove();
- }
-
- /* check if we already have a file with this alias */
- if(( rc = xbase->AddTblToTblList( this, GetFqFileName(), sAlias )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
-
- rc = ValidateSchema( pSchema );
- if( rc < 0 ){
- iErrorStop = 120;
- throw rc;
- } else
- iNoOfFields = rc;
-
- #ifdef XB_MEMO_SUPPORT
- // if we have memo fields
- iMemoFieldCnt = 0;
- i = 0;
- while( pSchema[i].cType != 0){
- if( pSchema[i].cType == 'M' )
- iMemoFieldCnt++; /* number of memo fields in the incoming definition */
- i++;
- }
-
- if( iMemoFieldCnt > 0 ){
- xbString sMfn = sNfn; /* memo file name, same as filename except ends with a "t", not an "f" */
- xbUInt32 iMfnLen = sMfn.Len();
- sMfn.PutAt( iMfnLen, 'T' );
-
- // dont overlay the memo file if it exists, and Overlay switch is off
- xbFile fTemp( xbase );
- fTemp.SetFileName( sMfn );
- if( fTemp.FileExists() && !iOverlay ){
- iErrorStop = 130;
- rc = XB_FILE_EXISTS;
- throw rc;
- }
-
- Memo = new xbMemoDbt3( this, fTemp.GetFqFileName());
-
- if(( rc = Memo->CreateMemoFile()) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw rc;
- }
- }
- #endif
-
- /* this is the dBase III version of the class */
- cVersion = 0x03; // 0x03 for Dbase level 5
- #ifdef XB_MEMO_SUPPORT
- if( iMemoFieldCnt > 0 ){
-// cVersion = cVersion |= 0x80; // Version III memo, compiler complaints
- cVersion |= 0x80; // Version III memo
- }
- #endif
-
- if(( rc = xbFopen( "w+b", iShareMode )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw rc;
- }
- uiRecordLen++; /* add one byte for 0x0D */
-
- if(( RecBuf = (char *) malloc( uiRecordLen )) == NULL ){
- iErrorStop = 160;
- throw rc;
- }
-
- if(( RecBuf2 = (char *) malloc( uiRecordLen )) == NULL ){
- iErrorStop = 170;
- rc = XB_NO_MEMORY;
- throw rc;
- }
-
- /* BlankRecord(); */
- memset( RecBuf, 0x20, uiRecordLen );
- memset( RecBuf2, 0x20, uiRecordLen );
- ulCurRec = 0L;
- uiHeaderLen = 33 + iNoOfFields * 32;
- xbDate d;
- d.Sysdate();
- cUpdateYY = (char) (d.YearOf() - 1900);
- cUpdateMM = (char) d.MonthOf();
- cUpdateDD = (char) d.DayOf( XB_FMT_MONTH );
-
- /* write the header prolog */
- if(( rc = WriteHeader( 0, 0 )) != XB_NO_ERROR ){
- iErrorStop = 180;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
- if((SchemaPtr = (xbSchemaRec *) malloc( (size_t) iNoOfFields * sizeof( xbSchemaRec ))) == NULL){
- iErrorStop = 190;
- rc = XB_NO_MEMORY;
- throw rc;
- }
-
- /* write the field information into the header */
- for( i = 0, k = 1; i < iNoOfFields; i++ ){
-
- memset( SchemaPtr[i].cFieldName, 0x00, 11 );
- for( int x = 0; x < 10 && pSchema[i].cFieldName[x]; x++ )
- SchemaPtr[i].cFieldName[x] = pSchema[i].cFieldName[x];
-
- SchemaPtr[i].cType = pSchema[i].cType;
- SchemaPtr[i].cFieldLen = (unsigned char) pSchema[i].iFieldLen;
- SchemaPtr[i].cNoOfDecs = (unsigned char) pSchema[i].iNoOfDecs;
-
- if( SchemaPtr[i].cNoOfDecs > SchemaPtr[i].cFieldLen ){
- iErrorStop = 200;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
-
- k2 = k;
- k += SchemaPtr[i].cFieldLen;
-
- if(( xbFwrite( &SchemaPtr[i].cFieldName, 1, 11 )) != XB_NO_ERROR ) {
- iErrorStop = 210;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
-
- if(( xbFwrite( &SchemaPtr[i].cType, 1, 1 )) != XB_NO_ERROR ) {
- iErrorStop = 220;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
-
- for( int j = 0; j < 4; j++ )
- xbFputc( 0x00 );
-
- if(( xbFwrite( &SchemaPtr[i].cFieldLen, 1, 1 )) != XB_NO_ERROR ) {
- iErrorStop = 230;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
-
- if(( xbFwrite( &SchemaPtr[i].cNoOfDecs, 1, 1 )) != XB_NO_ERROR ) {
- iErrorStop = 240;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
-
- /* 14 bytes reserved */
- for( int j = 0; j < 14; j++ )
- xbFputc( 0x00 );
-
- SchemaPtr[i].pAddress = RecBuf + k2;
- SchemaPtr[i].pAddress2 = RecBuf2 + k2;
- }
-
- /* write the header terminator */
- if(( xbFputc( XB_CHARHDR )) != XB_NO_ERROR ){
- iErrorStop = 250;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
- }
- catch( xbInt16 rc )
- {
- xbString sMsg;
- sMsg.Sprintf( "xbdbf3::CreateTable() Exception Caught Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
-
- sMsg.Sprintf( "Table Name = [%s]", GetFqFileName().Str());
- xbase->WriteLogMessage( sMsg );
- sMsg.Sprintf( "Alias Name = [%s]", sAlias.Str());
- xbase->WriteLogMessage( sMsg );
-
- xbFclose();
- if( RecBuf ){
- free( RecBuf );
- RecBuf = NULL;
- }
- if( RecBuf2 ){
- free( RecBuf2 );
- RecBuf2 = NULL;
- }
- if( SchemaPtr ){
- free( SchemaPtr );
- SchemaPtr = NULL;
- }
-
- InitVars();
- if( rc != XB_FILE_EXISTS )
- xbase->RemoveTblFromTblList( sAlias );
- }
-
- if( rc == XB_NO_ERROR )
- iDbfStatus = XB_OPEN;
-
- return rc;
-}
-
-/************************************************************************/
-//! @brief Get version.
-/*!
- The version info can be retrieved to determine
- which class is being used for a given dbf instance.
- \returns 3
-*/
-
-xbInt16 xbDbf3::GetVersion() const {
- return 3;
-}
-
-
-
-/************************************************************************/
-//! @brief Open dbf file/table.
-/*!
- \param sTableName DBF table name.
- \param sAlias Table alias
- \param iOpenMode XB_READ<br>XB_READ_WRITE
- \param iShareMode XB_SINGLE_USER<br>XB_MULTI_USER
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf3::Open( const xbString & sTableName, const xbString & sAlias,
- xbInt16 iOpenMode, xbInt16 iShareMode ){
- xbInt16 i, j, iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char buf[33];
- char *p;
-
- #ifdef XB_MEMO_SUPPORT
- iMemoFieldCnt = 0;
- #endif
-
- try{
-
- /* verify the file is not already open */
- if( iDbfStatus != XB_CLOSED ){
- iErrorStop = 100;
- iRc = XB_ALREADY_OPEN;
- throw iRc;
- }
- /* copy the file name to the class variable */
- SetFileName( sTableName );
- this->sAlias = sAlias;
-
- if( !FileExists()){
- iErrorStop = 110;
- iRc = XB_FILE_NOT_FOUND;
- throw iRc;
- }
-
- if(( iRc = xbase->AddTblToTblList( this, GetFqFileName(), sAlias )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- /* open the file */
- if(( iRc = xbFopen( iOpenMode, iShareMode )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- /* copy the header into memory */
- if(( iRc = ReadHeader( 1, 0 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
-
- /* check the version */
- if(( cVersion & 0x07 ) != 3 ){
- // if( xFileVersion != 3 && xFileVersion != 4 ){
- iErrorStop = 150;
- iRc = XB_FILE_TYPE_NOT_SUPPORTED;
- throw iRc;
- }
- iFileVersion = 3;
-
- /* calculate the number of fields */
- if( cVersion == (char)0x30 ) {
- iNoOfFields = ( uiHeaderLen - 296 ) / 32 ;
- } else {
- iNoOfFields = ( uiHeaderLen - 33 ) / 32;
- }
-
- if(( RecBuf = (char *) malloc( (size_t) uiRecordLen )) == NULL ){
- iErrorStop = 160;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- if(( RecBuf2 = (char *) malloc( uiRecordLen )) == NULL ) {
- iErrorStop = 170;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- if((SchemaPtr=(xbSchemaRec *)malloc( (size_t) iNoOfFields * sizeof( xbSchemaRec ))) == NULL){
- iErrorStop = 180;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- memset( SchemaPtr, 0x00, ( (size_t) iNoOfFields * sizeof(xbSchemaRec) ));
- /* copy field info into memory */
- for( i = 0, j = 1; i < iNoOfFields; i++ ){
- xbFseek( ((xbInt64)i*32+32), SEEK_SET );
- xbFread( &buf, 1, 32 );
- p = buf;
- for( int x = 0; x < 10 && buf[x]; x++ ){
- SchemaPtr[i].cFieldName[x] = buf[x];
- }
- p = buf + 11;
- SchemaPtr[i].cType = *p++;
- SchemaPtr[i].pAddress = RecBuf + j;
- SchemaPtr[i].pAddress2 = RecBuf2 + j;
- SchemaPtr[i].cFieldLen = (unsigned char) *( p + 4 );
- SchemaPtr[i].cNoOfDecs = (unsigned char) *( p + 5 );
- j += SchemaPtr[i].cFieldLen;
- #ifdef XB_MEMO_SUPPORT
- if( (SchemaPtr[i].cType == 'M' || SchemaPtr[i].cType == 'B' || SchemaPtr[i].cType == 'O' ))
- iMemoFieldCnt++;
- #endif
- }
- ulCurRec = 0L;
- iDbfStatus = XB_OPEN;
- if(( iRc = BlankRecord()) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
-
- #ifdef XB_MEMO_SUPPORT
- if( iMemoFieldCnt > 0 ){ /* does this table have memo fields ? */
-
- // build the file name
- xbString sMfn = GetFqFileName(); /* memo file name, same as filename except ends with a "t", not an "f" */
- xbUInt32 ulMfnLen = sMfn.Len();
- if( sMfn[ulMfnLen] == 'F' )
- sMfn.PutAt( ulMfnLen, 'T' );
- else
- sMfn.PutAt( ulMfnLen, 't' );
- xbFile fTemp( xbase );
- fTemp.SetFileName( sMfn );;
-
- Memo = new xbMemoDbt3( this, fTemp.GetFqFileName());
-
- if(( iRc = Memo->OpenMemoFile()) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw iRc;
- }
- }
- #endif // XB_MEMO_SUPPORT
-
- }
- catch ( xbInt16 iRc )
- {
- xbString sMsg;
- sMsg.Sprintf( "xbdbf3::Open() Exception Caught Error Stop = [%d] iRc = [%d] ShareMode = [%d] OpenMode = [%d]", iErrorStop, iRc, iShareMode, iOpenMode );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- xbFclose();
- if( RecBuf ){
- free( RecBuf );
- RecBuf = NULL;
- }
- if( RecBuf2 ){
- free( RecBuf2 );
- RecBuf2 = NULL;
- }
- if( SchemaPtr ){
- free( SchemaPtr );
- SchemaPtr = NULL;
- }
- InitVars();
-
- #ifdef XB_MEMO_SUPPORT
- if( Memo ){
- Memo->CloseMemoFile();
- delete Memo;
- Memo = NULL;
- }
- #endif // XB_MEMO_SUPPORT
- }
-
- if( iRc == XB_NO_ERROR )
- iDbfStatus = XB_OPEN;
-
- return iRc;
-}
-/************************************************************************/
-//! @brief Rename table.
-/*!
- This routine renames a give table, associated memo and inf files
- \param sNewName - New file name.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf3::Rename( const xbString sNewName ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- xbString sNewDbf;
-
- xbBool bDbfRenamed = xbFalse;
-
- #ifdef XB_INF_SUPPORT
- xbString sNewInf;
- xbString sThisInf;
- xbBool bInfRenamed = xbFalse;
- #endif
-
- #ifdef XB_MEMO_SUPPORT
- xbString sNewDbt;
- xbString sThisDbt;
- xbBool bDbtRenamed = xbFalse;
- #endif // XB_MEMO_SUPPORT
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bLocked = xbFalse;
- #endif
-
- try{
-
- xbString sDir;
- xbString sFile;
- xbString sExt;
-
- xbString sNewNameWoExt;
- sNewNameWoExt.Set( sNewName );
- if( sNewName.Pos( ".DBF" ) > 0 )
- sNewNameWoExt.Left( sNewName.Len() - 4 );
-
- GetFileDirPart ( sDir );
- GetFileNamePart( sFile );
- GetFileExtPart ( sExt );
-
- if( FileExists( sNewDbf )) return XB_FILE_EXISTS;
- sNewDbf.Sprintf( "%s%s.DBF", sDir.Str(), sNewNameWoExt.Str());
-
- #ifdef XB_MEMO_SUPPORT
- sNewDbt.Sprintf( "%s%s.DBT", sDir.Str(), sNewNameWoExt.Str());
- if( FileExists( sNewDbt )) return XB_FILE_EXISTS;
- sThisDbt.Sprintf( "%s%s.DBT", sDir.Str(), sFile.Str());
- #endif
-
- #ifdef XB_INF_SUPPORT
- sNewInf.Sprintf( "%s%s.INF", sDir.Str(), sNewNameWoExt.Str());
- if( FileExists( sNewInf )) return XB_FILE_EXISTS;
- sThisInf.Sprintf( "%s%s.INF", sDir.Str(), sFile.Str());
- #endif // XB_INF_SUPPORT
-
- #ifdef XB_LOCKING_SUPPORT
- if( GetAutoLock() && GetTableLocked() ){
- if(( iRc = LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- bLocked = xbTrue;
- }
- #endif
-
- xbInt16 iOpenMode = GetOpenMode();
- xbInt16 iShareMode = GetShareMode();
- xbBool bWasOpen = xbFalse;
- if( FileIsOpen() ){
- bWasOpen = xbTrue;
- if(( iRc = xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- if(( iRc = xbRename( GetFqFileName().Str(), sNewDbf.Str())) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- } else {
- bDbfRenamed = xbTrue;
- }
- xbString sNameWext;
- sNameWext.Sprintf( "%s.DBF", sNewNameWoExt.Str());
- SetFileName( sNameWext );
-
- if( bWasOpen ){
- if(( iRc = xbFopen( iOpenMode, iShareMode )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- }
-
- #ifdef XB_MEMO_SUPPORT
- if( FileExists( sThisDbt )){
- if( bWasOpen ){
- if(( iRc = Memo->xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- }
- if(( xbRename( sThisDbt.Str(), sNewDbt.Str())) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- Memo->SetFileName( sNewDbt );
- if( bWasOpen ){
- if(( iRc = Memo->xbFopen( iOpenMode, iShareMode )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- }
- bDbtRenamed = xbTrue;
- }
- #endif // XB_MEMO_SUPPORT
-
- #ifdef XB_INF_SUPPORT
- if( FileExists( sThisInf )){
- if(( iRc = xbRename( sThisInf.Str(), sNewInf.Str())) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- } else {
- bInfRenamed = xbTrue;
- }
- }
- #endif // XB_INF_SUPPORT
-
- // rname the table in the table list
- xbTblList *tle = xbase->GetTblListEntry( this );
- if( tle ){
- // std::cout << "setting [" << GetFqFileName().Str() << "][" << sNewNameWoExt.Str() << "]\n";
- tle->psFqTblName->Set( GetFqFileName().Str());
- tle->psTblAlias->Set( sNewNameWoExt.Str());
- }
- }
- catch ( xbInt16 iRc )
- {
- xbString sMsg;
- sMsg.Sprintf( "xbdbf3::Rename() Exception Caught Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
-
- // attempt to reverse things out if unsuccessful
- if( bDbfRenamed ){
- #ifdef XB_MEMO_SUPPORT
- if( bDbtRenamed ){
- xbRename( sNewDbt.Str(), sThisDbt.Str());
- }
- #endif // XB_MEMO_SUPPORT
- #ifdef XB_INF_SUPPORT
- if( bInfRenamed ){
- xbRename( sNewInf.Str(), sNewInf.Str());
- }
- #endif // XB_INF_SUPPORT
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( bLocked ){
- LockTable( XB_UNLOCK );
- }
- #endif
-
- }
- return iRc;
-}
-
-
-/************************************************************************/
-#ifdef XB_MEMO_SUPPORT
-//! @brief Create memo block size.
-/*!
- This routine sets the memo file block size. This value is used when
- the memo file is created so you if you want to change it, this must be
- called before creating the table.
-
- DBF III Plus uses a block size of 512.
-
- \param ulBlockSize - Block size, must be evenly divisible by 512.
- \returns XB_INVALID_BLOCK_SIZE<br>XB_NO_ERROR
-*/
-
-xbInt16 xbDbf3::SetCreateMemoBlockSize( xbUInt32 ulBlockSize ){
-
- if( ulBlockSize != 512 )
- return XB_INVALID_BLOCK_SIZE;
- else
- ulCreateMemoBlockSize = 512;
-
- return XB_NO_ERROR;
-}
-#endif
-
-/************************************************************************/
-//! @brief Set version.
-/*!
- Sets the version to 3. The version info can be retrieved to determine
- which class is being used for a given dbf instance.
- \returns 3
-*/
-
-xbInt16 xbDbf3::SetVersion() {
- iFileVersion = 3;
- return iFileVersion;
-}
-
-
-/************************************************************************/
-//! @brief Validate schema
-/*!
- This routine verifies the field types are valid for Dbase III Plus (tm).
-
- \param s Pointer to schema structure with field definitions.
-
- \returns Number of fields or XB_INVALID_FIELD_TYPE.
-*/
-
-xbInt16 xbDbf3::ValidateSchema( xbSchema * s ){
-
-// This routine validates an input schema
-// Negative return value is an error
-// Positive return value is the number of fields
-// On success, the class variable uiRecordLen will be updated with the record length of the combined total of the fields
-
- xbInt16 iFieldCnt = 0;
- uiRecordLen = 0;
-
- /* count the number of fields and check paramaters */
- xbInt16 i = 0;
- while( s[i].cType != 0 ){
- iFieldCnt++;
- // Version 3 field types
- if( s[i].cType != 'C' &&
- s[i].cType != 'N' &&
- s[i].cType != 'D' &&
- #ifdef XB_MEMO_SUPPORT
- s[i].cType != 'M' &&
- #endif // XB_MEMO_SUPPORT
- s[i].cType != 'L' ){
- return XB_INVALID_FIELD_TYPE;
- }
-
- if(s[i].cType == 'D'){
- s[i].iFieldLen = 8;
- s[i].iNoOfDecs = 0;
- }
-
- else if(s[i].cType == 'C')
- s[i].iNoOfDecs = 0;
-
- // check for numeric fields which are too long
- else if( s[i].cType == 'N' && s[i].iFieldLen > 19 ){
- return XB_INVALID_FIELD_LEN;
- }
- // field len must be >= no of decimals
- else if( s[i].cType == 'N' && s[i].iFieldLen < s[i].iNoOfDecs ){
- return XB_INVALID_FIELD_LEN;
- }
-
- #ifdef XB_MEMO_SUPPORT
- else if(s[i].cType == 'M'){
- s[i].iFieldLen = 10;
- s[i].iNoOfDecs = 0;
- }
- #endif // XB_MEMO_SUPPORT
-
- uiRecordLen += s[i].iFieldLen;
- i++;
- }
- return iFieldCnt;
-}
-
-} /* namespace */
-#endif /* XB_DBF3_SUPPORT */ \ No newline at end of file
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf4.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf4.cpp
deleted file mode 100755
index a1f770e..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbdbf4.cpp
+++ /dev/null
@@ -1,885 +0,0 @@
-/* xbdbf4.cpp
-
-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 "xbase.h"
-
-
-#ifdef XB_DBF4_SUPPORT
-
-namespace xb{
-
-
-/************************************************************************/
-//! @brief Constructor.
-xbDbf4::xbDbf4(xbXBase * x) : xbDbf( x ) {
-
- iFileVersion = 4;
- #ifdef XB_MEMO_SUPPORT
- ulCreateMemoBlockSize = 1024;
- #endif
-};
-
-/************************************************************************/
-//! @brief Destructor.
-xbDbf4::~xbDbf4() {};
-
-/************************************************************************/
-//! @brief Create Version 4 table.
-/*!
- This routine creates a Dbase IV (tm) DBF file.
-
- \param sTableName DBF table name.
- \param sAlias Table alias
- \param pSchema Pointer to schema structure with field definitions.
- \param iOverlay xbTrue - Overlay.<br> xbFalse - Don't overlay.
- \param iShareMode XB_SINGLE_USER<br>XB_MULTI_USER
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf4::CreateTable( const xbString &sTableName, const xbString &sAlias, xbSchema * pSchema, xbInt16 iOverlay, xbInt16 iShareMode ){
-
- xbInt16 i, k, k2;
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- iDbfStatus = XB_CLOSED;
-
- xbString sNfn;
-
- try{
- sNfn = sTableName;
- xbase->GetLogStatus();
-
- rc = NameSuffixMissing( sNfn, 1 );
- if( rc > 0 )
- sNfn += ".DBF";
-
- SetFileName( sNfn );
- this->sAlias = sAlias;
-
- /* check if the file already exists */
- if( FileExists( 0 )){
- if( !iOverlay ){
- iErrorStop = 100;
- rc = XB_FILE_EXISTS;
- throw rc;
- }
-
- // remove other files if they exist
- xbString sMname = sNfn;
- xbUInt32 iMnameLen = sMname.Len();
- sMname.PutAt( iMnameLen-2, 'I' );
- sMname.PutAt( iMnameLen-1, 'N' );
- sMname.PutAt( iMnameLen, 'F' );
- xbFile fTemp( xbase );
- fTemp.SetFileName( sMname );
- if( fTemp.FileExists() )
- fTemp.xbRemove();
-
- sMname.PutAt( iMnameLen-2, 'D' );
- sMname.PutAt( iMnameLen-1, 'B' );
- sMname.PutAt( iMnameLen, 'T' );
- fTemp.SetFileName( sMname );
- if( fTemp.FileExists() )
- fTemp.xbRemove();
-
- sMname.PutAt( iMnameLen-2, 'M' );
- sMname.PutAt( iMnameLen-1, 'D' );
- sMname.PutAt( iMnameLen, 'X' );
- fTemp.SetFileName( sMname );
- if( fTemp.FileExists() )
- fTemp.xbRemove();
- }
-
- /* check if we already have a file with this alias */
- if(( rc = xbase->AddTblToTblList( this, GetFqFileName(), sAlias )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
-
- rc = ValidateSchema( pSchema );
- if( rc < 0 ){
- iErrorStop = 120;
- throw rc;
- } else
- iNoOfFields = rc;
-
- #ifdef XB_MEMO_SUPPORT
- // if we have memo fields
- iMemoFieldCnt = 0;
- i = 0;
- while( pSchema[i].cType != 0){
- if( pSchema[i].cType == 'M' )
- iMemoFieldCnt++; /* number of memo fields in the incoming definition */
- i++;
- }
-
- if( iMemoFieldCnt > 0 ){
- xbString sMfn = sNfn; /* memo file name, same as filename except ends with a "t", not an "f" */
- xbUInt32 ulMfnLen = sMfn.Len();
- sMfn.PutAt( ulMfnLen, 'T' );
-
- // dont overlay the memo file if it exists, and Overlay switch is off
- xbFile fTemp( xbase );
- fTemp.SetFileName( sMfn );
- if( fTemp.FileExists() && !iOverlay ){
- iErrorStop = 130;
- rc = XB_FILE_EXISTS;
- throw rc;
- }
-
- Memo = new xbMemoDbt4( this, fTemp.GetFqFileName());
-
- if(( rc = Memo->CreateMemoFile()) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw rc;
- }
- }
- #endif
-
- /* this is the dBase IV version of the class */
- cVersion = 0x03; // 0x03 for Dbase level 5
- #ifdef XB_MEMO_SUPPORT
- if( iMemoFieldCnt > 0 ){
-// cVersion = cVersion |= 0x88; // version IV memos, compiler complains about this
- cVersion |= 0x88; // version IV memos
- }
- #endif
-
- if(( rc = xbFopen( "w+b", iShareMode )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw rc;
- }
- uiRecordLen++; /* add one byte for 0x0D */
-
- if(( RecBuf = (char *) malloc( uiRecordLen )) == NULL ){
- iErrorStop = 160;
- throw rc;
- }
-
- if(( RecBuf2 = (char *) malloc( uiRecordLen )) == NULL ){
- iErrorStop = 170;
- rc = XB_NO_MEMORY;
- throw rc;
- }
-
- /* BlankRecord(); */
- memset( RecBuf, 0x20, uiRecordLen );
- memset( RecBuf2, 0x20, uiRecordLen );
- ulCurRec = 0L;
- uiHeaderLen = 33 + iNoOfFields * 32;
- xbDate d;
- d.Sysdate();
- cUpdateYY = (char) (d.YearOf() - 1900);
- cUpdateMM = (char) d.MonthOf();
- cUpdateDD = (char) d.DayOf( XB_FMT_MONTH );
- cIndexFlag = 0;
- // Default language driver to 0x1b
- cLangDriver = 0x1b;
-
- /* write the header prolog */
- if(( rc = WriteHeader( 0, 0 )) != XB_NO_ERROR ){
- iErrorStop = 180;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
- if((SchemaPtr=(xbSchemaRec *)malloc( (size_t) iNoOfFields * sizeof( xbSchemaRec ))) == NULL){
- iErrorStop = 190;
- rc = XB_NO_MEMORY;
- throw rc;
- }
-
- /* write the field information into the header */
- for( i = 0, k = 1; i < iNoOfFields; i++ ){
-
- memset( SchemaPtr[i].cFieldName, 0x00, 11 );
- for( int x = 0; x < 10 && pSchema[i].cFieldName[x]; x++ )
- SchemaPtr[i].cFieldName[x] = pSchema[i].cFieldName[x];
-
- SchemaPtr[i].cType = pSchema[i].cType;
- SchemaPtr[i].cFieldLen = (unsigned char) pSchema[i].iFieldLen;
- SchemaPtr[i].cNoOfDecs = (unsigned char) pSchema[i].iNoOfDecs;
-
- if( SchemaPtr[i].cNoOfDecs > SchemaPtr[i].cFieldLen ){
- iErrorStop = 110;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
-
- k2 = k;
- k += SchemaPtr[i].cFieldLen;
-
- if(( xbFwrite( &SchemaPtr[i].cFieldName, 1, 11 )) != XB_NO_ERROR ) {
- iErrorStop = 200;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
-
- if(( xbFwrite( &SchemaPtr[i].cType, 1, 1 )) != XB_NO_ERROR ) {
- iErrorStop = 210;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
-
- for( int j = 0; j < 4; j++ )
- xbFputc( 0x00 );
-
- if(( xbFwrite( &SchemaPtr[i].cFieldLen, 1, 1 )) != XB_NO_ERROR ) {
- iErrorStop = 220;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
-
- if(( xbFwrite( &SchemaPtr[i].cNoOfDecs, 1, 1 )) != XB_NO_ERROR ) {
- iErrorStop = 230;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
-
- /* 14 bytes reserved */
- for( int j = 0; j < 14; j++ )
- xbFputc( 0x00 );
-
- SchemaPtr[i].pAddress = RecBuf + k2;
- SchemaPtr[i].pAddress2 = RecBuf2 + k2;
- }
-
- /* write the header terminator */
- if(( xbFputc( XB_CHARHDR )) != XB_NO_ERROR ){
- iErrorStop = 240;
- rc = XB_WRITE_ERROR;
- throw rc;
- }
- }
- catch( xbInt16 rc )
- {
- xbString sMsg;
- sMsg.Sprintf( "xbdbf4::CreateTable() Exception Caught Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
-
- sMsg.Sprintf( "Table Name = [%s]", GetFqFileName().Str());
- xbase->WriteLogMessage( sMsg );
- sMsg.Sprintf( "Alias Name = [%s]", sAlias.Str());
- xbase->WriteLogMessage( sMsg );
-
- xbFclose();
- if( RecBuf ){
- free( RecBuf );
- RecBuf = NULL;
- }
- if( RecBuf2 ){
- free( RecBuf2 );
- RecBuf2 = NULL;
- }
- if( SchemaPtr ){
- free( SchemaPtr );
- SchemaPtr = NULL;
- }
-
- InitVars();
- if( rc != XB_FILE_EXISTS )
- xbase->RemoveTblFromTblList( sAlias );
- }
-
- if( rc == XB_NO_ERROR )
- iDbfStatus = XB_OPEN;
-
- return rc;
-}
-
-/************************************************************************/
-//! @brief Get version.
-/*!
- The version info can be retrieved to determine
- which class is being used for a given dbf instance.
- \returns 4
-*/
-
-xbInt16 xbDbf4::GetVersion() const {
- return 4;
-}
-
-/************************************************************************/
-//! @brief Open dbf file/table.
-/*!
- \param sTableName DBF table name.
- \param sAlias Table alias
- \param iOpenMode XB_READ<br>XB_READ_WRITE
- \param iShareMode XB_SINGLE_USER<br>XB_MULTI_USER
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbDbf4::Open( const xbString & sTableName, const xbString & sAlias,
- xbInt16 iOpenMode, xbInt16 iShareMode ){
- xbInt16 i, j, iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char buf[33];
- char *p;
-
- #ifdef XB_MEMO_SUPPORT
- iMemoFieldCnt = 0;
- #endif
-
- try{
- /* verify the file is not already open */
- if( iDbfStatus != XB_CLOSED ){
- iErrorStop = 100;
- iRc = XB_ALREADY_OPEN;
- throw iRc;
- }
- /* copy the file name to the class variable */
- SetFileName( sTableName );
- this->sAlias = sAlias;
-
- if( !FileExists()){
- iErrorStop = 110;
- iRc = XB_FILE_NOT_FOUND;
- throw iRc;
- }
-
- if(( iRc = xbase->AddTblToTblList( this, GetFqFileName(), sAlias )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- /* open the file */
- if(( iRc = xbFopen( iOpenMode, iShareMode )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- /* copy the header into memory */
- if(( iRc = ReadHeader( 1, 0 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
-
- /* check the version */
- //if(( xFileVersion = DetermineXbaseTableVersion( cVersion )) != 4 ){
- if(( cVersion & 0x07 ) != 3 ){
- iErrorStop = 150;
- iRc = XB_FILE_TYPE_NOT_SUPPORTED;
- throw iRc;
- }
- iFileVersion = 4;
-
- /* calculate the number of fields */
- if( cVersion == (char)0x30 ) {
- iNoOfFields = ( uiHeaderLen - 296 ) / 32 ;
- } else {
- iNoOfFields = ( uiHeaderLen - 33 ) / 32;
- }
-
- if(( RecBuf = (char *) malloc( uiRecordLen )) == NULL ){
- iErrorStop = 160;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- if(( RecBuf2 = (char *) malloc( uiRecordLen )) == NULL ) {
- iErrorStop = 170;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- if((SchemaPtr=(xbSchemaRec *)malloc((size_t) iNoOfFields * sizeof( xbSchemaRec ))) == NULL){
- iErrorStop = 180;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- memset( SchemaPtr, 0x00, (size_t) iNoOfFields * (size_t) sizeof( xbSchemaRec ));
- /* copy field info into memory */
- for( i = 0, j = 1; i < iNoOfFields; i++ ){
- xbFseek( ((xbInt64)i*32+32), SEEK_SET );
- xbFread( &buf, 1, 32 );
- p = buf;
- for( int x = 0; x < 10 && buf[x]; x++ ){
- SchemaPtr[i].cFieldName[x] = buf[x];
- }
- p = buf + 11;
- SchemaPtr[i].cType = *p++;
- SchemaPtr[i].pAddress = RecBuf + j;
- SchemaPtr[i].pAddress2 = RecBuf2 + j;
- SchemaPtr[i].cFieldLen = (unsigned char) *( p + 4 );
- SchemaPtr[i].cNoOfDecs = (unsigned char) *( p + 5 );
- SchemaPtr[i].cIxFlag = (unsigned char) *( p + 19 );
- j += SchemaPtr[i].cFieldLen;
- #ifdef XB_MEMO_SUPPORT
- if( (SchemaPtr[i].cType == 'M' || SchemaPtr[i].cType == 'B' || SchemaPtr[i].cType == 'O' ))
- iMemoFieldCnt++;
- #endif
- }
- ulCurRec = 0L;
- iDbfStatus = XB_OPEN;
- if(( iRc = BlankRecord()) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
-
-
- #ifdef XB_MEMO_SUPPORT
- if( iMemoFieldCnt > 0 ){ /* does this table have memo fields ? */
-
- // build the file name
- xbString sMfn = GetFqFileName(); /* memo file name, same as filename except ends with a "t", not an "f" */
- xbUInt32 ulMfnLen = sMfn.Len();
- if( sMfn[ulMfnLen] == 'F' )
- sMfn.PutAt( ulMfnLen, 'T' );
- else
- sMfn.PutAt( ulMfnLen, 't' );
- xbFile fTemp( xbase );
- fTemp.SetFileName( sMfn );
-
- Memo = new xbMemoDbt4( this, fTemp.GetFqFileName());
-
- if(( iRc = Memo->OpenMemoFile()) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw iRc;
- }
- }
- #endif
-
- #ifdef XB_MDX_SUPPORT
-
-// printf( "cIndexFlag [%x]\n", cIndexFlag );
-
- if( cIndexFlag ){
- // create the file name
- xbString sIxFileName = GetFqFileName();
- sIxFileName.Trim();
- xbUInt32 lLen = sIxFileName.Len();
- sIxFileName.PutAt( lLen-2, 'M' );
- sIxFileName.PutAt( lLen-1, 'D' );
- sIxFileName.PutAt( lLen, 'X' );
- if(( iRc = OpenIndex( "MDX", sIxFileName )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- }
- #endif
-
- }
- catch ( xbInt16 iRc )
- {
- xbString sMsg;
- sMsg.Sprintf( "xbdbf4::Open() Exception Caught Error Stop = [%d] iRc = [%d] ShareMode = [%d] OpenMode = [%d]", iErrorStop, iRc, iShareMode, iOpenMode );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- xbFclose();
- if( RecBuf ){
- free( RecBuf );
- RecBuf = NULL;
- }
- if( RecBuf2 ){
- free( RecBuf2 );
- RecBuf2 = NULL;
- }
- if( SchemaPtr ){
- free( SchemaPtr );
- SchemaPtr = NULL;
- }
- InitVars();
-
-#ifdef XB_MEMO_SUPPORT
- if( Memo ){
- Memo->CloseMemoFile();
- delete Memo;
- Memo = NULL;
- }
-#endif
- }
-
- if( iRc == XB_NO_ERROR )
- iDbfStatus = XB_OPEN;
-
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Rename table.
-/*!
- This routine renames a table, associated memo, mdx and inf files
- \param sNewName - New file name.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbDbf4::Rename( const xbString sNewName ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- xbString sNewDbf;
-
- #ifdef XB_MEMO_SUPPORT
- xbString sNewDbt;
- xbBool bDbtRenamed = xbFalse;
- xbString sThisDbt;
- #endif
-
- #ifdef XB_MDX_SUPPORT
- xbString sNewMdx;
- xbBool bMdxRenamed = xbFalse;
- xbString sThisMdx;
- #endif
-
- #ifdef XB_INF_SUPPORT
- xbString sNewInf;
- xbString sThisInf;
- xbBool bInfRenamed = xbFalse;
- #endif // XB_INF_SUPPORT
-
- xbBool bDbfRenamed = xbFalse;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bLocked = xbFalse;
- #endif // XB_LOCKIN_SUPPORT
-
-
- try{
-
- xbString sDir;
- xbString sFile;
- xbString sExt;
- xbString sNewNameWoExt;
- sNewNameWoExt.Set( sNewName );
- if( sNewName.Pos( ".DBF" ) > 0 )
- sNewNameWoExt.Left( sNewName.Len() - 4 );
-
-// std::cout << "NewName wo ext = [" << sNewNameWoExt.Str() << "]\n";
-
- GetFileDirPart ( sDir );
- GetFileNamePart( sFile );
- GetFileExtPart ( sExt );
-
- sNewDbf.Sprintf( "%s%s.DBF", sDir.Str(), sNewNameWoExt.Str());
-
- #ifdef XB_MEMO_SUPPORT
- sNewDbt.Sprintf( "%s%s.DBT", sDir.Str(), sNewNameWoExt.Str());
- if( FileExists( sNewDbt )) return XB_FILE_EXISTS;
- sThisDbt.Sprintf( "%s%s.DBT", sDir.Str(), sFile.Str());
- #endif
-
- #ifdef XB_MDX_SUPPORT
- sNewMdx.Sprintf( "%s%s.MDX", sDir.Str(), sNewNameWoExt.Str());
- if( FileExists( sNewMdx )) return XB_FILE_EXISTS;
- sThisMdx.Sprintf( "%s%s.MDX", sDir.Str(), sFile.Str());
- #endif
-
- #ifdef XB_INF_SUPPORT
- sNewInf.Sprintf( "%s%s.INF", sDir.Str(), sNewNameWoExt.Str());
- if( FileExists( sNewInf )) return XB_FILE_EXISTS;
- sThisInf.Sprintf( "%s%s.INF", sDir.Str(), sFile.Str());
- #endif // XB_INF_SUPPORT
-
-
-/*
- std::cout << "xbDbf3::Rename dir = [" << sDir.Str() << "] file = [" << sFile.Str() << "] ext = [" << sExt.Str() << "]\n";
- std::cout << "xbDbf3::Rename new dbf = [" << sNewDbf.Str() << "]\n";
- std::cout << "xbDbf3::Rename new dbt = [" << sNewDbt.Str() << "]\n";
- std::cout << "xbDbf3::Rename new inf = [" << sNewInf.Str() << "]\n";
- std::cout << "xbDbf3::Rename new mdx = [" << sNewMdx.Str() << "]\n";
-*/
-
- if( FileExists( sNewDbf )) return XB_FILE_EXISTS;
-
- #ifdef XB_LOCKING_SUPPORT
- if( GetAutoLock() ){
- if(( iRc = LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- bLocked = xbTrue;
- }
- #endif
-
- xbInt16 iOpenMode = GetOpenMode();
- xbInt16 iShareMode = GetShareMode();
- xbBool bWasOpen = xbFalse;
- if( FileIsOpen() ){
- bWasOpen = xbTrue;
- if(( iRc = xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- if(( iRc = xbRename( GetFqFileName().Str(), sNewDbf.Str())) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- } else {
- bDbfRenamed = xbTrue;
- }
- xbString sNameWext;
- sNameWext.Sprintf( "%s.DBF", sNewNameWoExt.Str());
- SetFileName( sNameWext );
-
-
- if( bWasOpen ){
- if(( iRc = xbFopen( iOpenMode, iShareMode )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- }
-
- #ifdef XB_MEMO_SUPPORT
- if( FileExists( sThisDbt )){
- if(( iRc = Memo->xbFseek( 8, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
-
- sNewNameWoExt.PadRight( ' ', 8 );
- for( int i = 1; i < 9; i++ )
- Memo->xbFputc( sNewNameWoExt[i] );
-
- if( bWasOpen ){
- if(( iRc = Memo->xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
-
- Memo->SetFileName( sNewDbt );
- if(( xbRename( sThisDbt.Str(), sNewDbt.Str())) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
-
- if( bWasOpen ){
- if(( iRc = Memo->xbFopen( iOpenMode, iShareMode )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
-
- bDbtRenamed = xbTrue;
- }
- #endif
-
- #ifdef XB_MDX_SUPPORT
- if( FileExists( sThisMdx )){
- xbIxMdx *ixMdx;
- xbString s;
- xbBool bMdxFound = xbFalse;
- xbIxList *ixList = GetIxList();
- while( ixList && !bMdxFound ){
- s = ixList->sFmt->Str();
- if( s == "MDX" ){
- ixMdx = (xbIxMdx *) ixList->ix;
- bMdxFound = xbTrue;
- }
- }
-
- if( bMdxFound ){
- if(( iRc = ixMdx->xbFseek( 4, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
-
- sNewNameWoExt.PadRight( ' ', 8 );
- for( int i = 1; i < 9; i++ )
- ixMdx->xbFputc( sNewNameWoExt[i] );
-
- if( bWasOpen ){
- if(( iRc = ixMdx->xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
- }
-
- ixMdx->SetFileName( sNewMdx );
- if(( xbRename( sThisMdx.Str(), sNewMdx.Str())) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw iRc;
- }
-
- if( bWasOpen ){
- if(( iRc = ixMdx->xbFopen( iOpenMode, iShareMode )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- }
- bMdxRenamed = xbTrue;
- }
- }
- #endif // XB_MDX_SUPPORT
-
- #ifdef XB_INF_SUPPORT
- if( FileExists( sThisInf )){
- if(( xbRename( sThisInf.Str(), sNewInf.Str())) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- } else {
- bInfRenamed = xbTrue;
- }
- }
- #endif // XB_INF_SUPPORT
-
- // rename the table in the table list
- xbTblList *tle = xbase->GetTblListEntry( this );
- if( tle ){
- tle->psFqTblName->Set( GetFqFileName().Str());
- tle->psTblAlias->Set( sNewNameWoExt.Str());
- }
-
-
- }
- catch ( xbInt16 iRc )
- {
- xbString sMsg;
- sMsg.Sprintf( "xbdbf4::Rename() Exception Caught Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
-
- // attempt to reverse things out if unsuccessful
- if( bDbfRenamed ){
-
- #ifdef XB_MEMO_SUPPORT
- if( bDbtRenamed ){
- xbRename( sNewDbt.Str(), sThisDbt.Str());
- }
- #endif
-
- #ifdef XB_MDX_SUPPORT
- if( bMdxRenamed ){
- xbRename( sNewMdx.Str(), sThisMdx.Str());
- }
- #endif
-
- #ifdef XB_INF_SUPPORT
- if( bInfRenamed ){
- xbRename( sNewInf.Str(), sNewInf.Str());
- }
- #endif // XB_INF_SUPPORT
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( GetAutoLock() ){
- iRc = LockTable( XB_UNLOCK );
- }
- #endif
-
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( bLocked ){
- LockTable( XB_UNLOCK );
- }
- #endif
-
- return iRc;
-}
-
-/************************************************************************/
-#ifdef XB_MEMO_SUPPORT
-
-//! @brief Create memo block size.
-/*!
- This routine sets the memo file block size. This value is used when
- the memo file is created so you if you want to change it, this must be
- called before creating the table.
-
- The default size for version 4 is 1024.
-
- \param ulBlockSize - Block size, must be evenly divisible by 512.
- \returns XB_INVALID_BLOCK_SIZE<br>XB_NO_ERROR
-*/
-
-xbInt16 xbDbf4::SetCreateMemoBlockSize( xbUInt32 ulBlockSize ){
-
- if( ulBlockSize % 512 )
- return XB_INVALID_BLOCK_SIZE;
- else
- ulCreateMemoBlockSize = ulBlockSize;
-
- return XB_NO_ERROR;
-}
-#endif // XB_MEMO_SUPPORT
-/************************************************************************/
-//! @brief Set version.
-/*!
- Sets the version to 4. The version info can be retrieved to determine
- which class is being used for a given dbf instance.
- \returns 4
-*/
-xbInt16 xbDbf4::SetVersion() {
- iFileVersion = 4;
- return iFileVersion;
-}
-/************************************************************************/
-//! @brief Validate schema
-/*!
- This routine verifies the field types are valid for Dbase IV (tm).
-
- \param s Pointer to schema structure with field definitions.
-
- \returns Number of fields or XB_INVALID_FIELD_TYPE.
-*/
-
-
-xbInt16 xbDbf4::ValidateSchema( xbSchema * s ){
-
- xbInt16 iFieldCnt = 0;
- uiRecordLen = 0;
-
- // Count the number of fields and check paramaters
- xbInt16 i = 0;
- while( s[i].cType != 0 ){
- iFieldCnt++;
- // Version IV field types
- if( s[i].cType != 'C' &&
- s[i].cType != 'N' &&
- s[i].cType != 'F' &&
- s[i].cType != 'D' &&
- #ifdef XB_MEMO_SUPPORT
- s[i].cType != 'M' &&
- #endif /* XB_MEMO_SUPPORT */
- s[i].cType != 'L' ){
- return XB_INVALID_FIELD_TYPE;
- }
-
- if(s[i].cType == 'D'){
- s[i].iFieldLen = 8;
- s[i].iNoOfDecs = 0;
- }
-
- else if(s[i].cType == 'C')
- s[i].iNoOfDecs = 0;
-
- // check for numeric fields which are too long
- else if((s[i].cType == 'N' || s[i].cType == 'F') && s[i].iFieldLen > 19 ){
- return XB_INVALID_FIELD_LEN;
- }
-
- // field len must be greater then number of decimals
- else if((s[i].cType == 'N' || s[i].cType == 'F') && s[i].iFieldLen < s[i].iNoOfDecs ){
- return XB_INVALID_FIELD_LEN;
- }
-
- #ifdef XB_MEMO_SUPPORT
- else if(s[i].cType == 'M'){
- s[i].iFieldLen = 10;
- s[i].iNoOfDecs = 0;
- }
- #endif // XB_MEMO_SUPPORT
-
- uiRecordLen += s[i].iFieldLen;
- i++;
- }
- return iFieldCnt;
-}
-
-} /* namespace */
-#endif /* XB_DBF4_SUPPORT */ \ No newline at end of file
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbexp.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbexp.cpp
deleted file mode 100755
index b2d4db9..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbexp.cpp
+++ /dev/null
@@ -1,2721 +0,0 @@
-/* xbexp.cpp
-
-XBase64 Software Library
-
-Copyright (c) 1997,2003,2014,2017,2021,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 module is part of the expression logic and has the code
-for parsing various tokens out of an expression
-
-*/
-
-#include "xbase.h"
-
-#ifdef XB_EXPRESSION_SUPPORT
-
-namespace xb{
-
-/*************************************************************************/
-//! Constructor
-/*!
- \param x Pointer to xbXBase instance.
-*/
-
-xbExp::xbExp( xbXBase *x ){
- xbase = x;
- dbf = NULL;
- nTree = NULL;
-}
-
-/*************************************************************************/
-//! Constructor
-/*!
- \param x Pointer to xbXBase instance.
- \param d Pointer to xbDbf instance.
-*/
-xbExp::xbExp( xbXBase *x, xbDbf *d ){
- xbase = x;
- dbf = d;
- nTree = NULL;
-}
-
-/*************************************************************************/
-//! Deconstrucor.
-
-xbExp::~xbExp() {
-
- if( nTree )
- delete nTree;
-}
-
-/*************************************************************************/
-//! Calulate expression return length
-/*!
-
- This function returns the maximum possible length of an expression
- The create index functions use this for determining the fixed length keys
- It sets the return length field in the node.
-
- \param n Start node
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::CalcFunctionResultLen( xbExpNode * n ) const{
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbInt16 iReturnLenCalc = 0;;
- xbInt32 lReturnLenVal = 0;
- xbString sNodeText;
-
-
- try{
-
- n->GetNodeText( sNodeText );
- char cReturnType = 0;
- if(( iRc = xbase->GetFunctionInfo( sNodeText, cReturnType, iReturnLenCalc, lReturnLenVal )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- if( iReturnLenCalc == 1 ){
- // use the value from iReturnLenVal
- n->SetResultLen( (xbUInt32) lReturnLenVal );
- }
- else if( iReturnLenCalc == 2 ){
- // use the length from the child node identified in lReturnLenVal
- xbExpNode *nChild = n->GetChild( (xbUInt32) lReturnLenVal - 1 );
- if( !nChild ){
- iErrorStop = 110;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- n->SetResultLen( nChild->GetResultLen());
- }
-
- else if( iReturnLenCalc == 3 ){
- // use the length from the child node identified in lReturnLenVal
- xbExpNode *nChild = n->GetChild( (xbUInt32) lReturnLenVal - 1 );
- if( !nChild ){
- iErrorStop = 120;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- n->SetResultLen( (xbUInt32) nChild->GetNumericResult());
- }
- else if( iReturnLenCalc == 4 ){
- // use the value from the length in parm 1 multiplied by the value in parm 2 (REPLICATE)
- xbExpNode *nChild1 = n->GetChild( 0 );
- xbExpNode *nChild2 = n->GetChild( 1 );
- if( !nChild1 || !nChild2 ){
- iErrorStop = 130;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- n->SetResultLen( nChild1->GetResultLen() * (xbUInt32) nChild2->GetNumericResult());
- }
- else if( iReturnLenCalc == 5 ){
- // use the larger of the length of the value in parm2 or parm 3 (IIF statement)
- xbExpNode *nChild2 = n->GetChild( 1 );
- xbExpNode *nChild3 = n->GetChild( 2 );
- if( !nChild2 || !nChild3 ){
- iErrorStop = 140;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- if( nChild2->GetResultLen() >= nChild3->GetResultLen())
- n->SetResultLen( nChild2->GetResultLen());
- else
- n->SetResultLen( nChild3->GetResultLen());
- }
-
- else if( iReturnLenCalc == 6 ){
-
- if( n->GetChildCnt() >= 2 ){
- xbExpNode *nChild2 = n->GetChild( 1 );
- n->SetResultLen( (xbUInt32) nChild2->GetNumericResult());
- } else {
- n->SetResultLen( (xbUInt32) lReturnLenVal );
- }
-
- } else {
- iErrorStop = 150;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::GetFunctionResultLen() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- }
- return iRc;
-}
-
-/*************************************************************************/
-//! Check parens and quotes
-/*!
- This routine looks for unbalanced parens and quotes
-
- \param sExpression Expression to examine.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbExp::CheckParensAndQuotes( const xbString &sExpression ){
-
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- xbBool bInQuotes = xbFalse;
- xbInt16 iLparenCtr = 0;
- xbInt16 iRparenCtr = 0;
- xbInt16 iQuoteType = 0;
- const char *s = sExpression;
-
- try{
-
- while( *s ){
- if( !bInQuotes ){
- if( *s == '(' ){
- iLparenCtr++;
- } else if( *s == ')' ){
- iRparenCtr++;
- } else if( *s == '\'' ){
- bInQuotes++;
- iQuoteType = 0;
- } else if( *s == '"' ){
- bInQuotes++;
- iQuoteType = 1;
- }
- } else {
- if(( *s == '\'' && iQuoteType == 0 ) || (*s == '"' && iQuoteType == 1 ))
- bInQuotes--;
- }
- s++;
- }
- if( iLparenCtr != iRparenCtr ){
- iErrorStop = 100;
- iRc = XB_UNBALANCED_PARENS;
- throw iRc;
- }
- if( bInQuotes ){
- iErrorStop = 110;
- iRc = XB_UNBALANCED_QUOTES;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::CheckParensAndQuots() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( sExpression );
- }
- return iRc;
-}
-/*************************************************************************/
-//! Clear tree handle.
-/*!
- This routine clears the expression tree and frees any associated memory.
- \returns void.
-*/
-
-void xbExp::ClearTreeHandle(){
- if( nTree ){
- nTree = NULL;
- }
-}
-
-/*************************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-//! Dump the tree.
-/*!
- \param iOption - Output opton.
- \returns void.
-*/
-
-void xbExp::DumpTree( xbInt16 iOption ){
- nTree->DumpNode( iOption );
-}
-
-//! Dump token
-/*!
- \param iOption - Output opton.
- \returns void.
-*/
-
-
-void xbExp::DumpToken( xbExpToken &t, xbInt16 iOption ){
-
- xbString sMsg;
- sMsg = "Processing Token";
- xbase->WriteLogMessage( sMsg.Str(), iOption );
-
- sMsg.Sprintf( "Expression = [%s]", t.sExpression.Str());
- xbase->WriteLogMessage( sMsg.Str(), iOption );
-
- sMsg.Sprintf( "Token = [%s]", t.sToken.Str());
- xbase->WriteLogMessage( sMsg.Str(), iOption );
-
- sMsg.Sprintf( "NodeType = [%c]", t.cNodeType );
- xbase->WriteLogMessage( sMsg.Str(), iOption );
-
- sMsg.Sprintf( "ReturnType = [%c]", t.cReturnType );
- xbase->WriteLogMessage( sMsg.Str(), iOption );
-
- sMsg.Sprintf( "Sts = [%d]", t.iSts );
- xbase->WriteLogMessage( sMsg.Str(), iOption );
-
- sMsg.Sprintf( "PrevNodeType = [%c]", t.cPrevNodeType );
- xbase->WriteLogMessage( sMsg.Str(), iOption );
-
- sMsg.Sprintf( "PrevReturnType = [%c]", t.cPrevReturnType );
- xbase->WriteLogMessage( sMsg.Str(), iOption );
-}
-
-#endif
-
-/*************************************************************************/
-//! Get date result.
-/*!
- If the expression generates a date return type, this method retrieves the date value.
- \param dtResult - Output date value.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::GetDateResult( xbDate &dtResult ){
- if( nTree ){
- dtResult.JulToDate8( (xbInt32) nTree->GetNumericResult() );
- return XB_NO_ERROR;
- }
- else{
- //dtResult = ?;
- return XB_PARSE_ERROR;
- }
-}
-/*************************************************************************/
-//! Get bool result.
-/*!
- If the expression generates a boolean return type, this method retrieves the boolean value.
- \param bResult - Output boolean value.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbExp::GetBoolResult( xbBool &bResult){
- if( nTree ){
- bResult = nTree->GetBoolResult();
- return XB_NO_ERROR;
- }
- else{
- return XB_PARSE_ERROR;
- }
-}
-
-/*************************************************************************/
-//! Get the next node in the tree.
-/*!
- \param n Node to starting point. To get the first node of the entire tree, set n = NULL
- \returns Pointer to next node.
-*/
-
-xbExpNode *xbExp::GetNextNode( xbExpNode * n ) const {
-
- // to get the first node of the entire tree, set n = NULL
- // std::cout << "In GetNextNode\n";
-
- if( n == nTree )
- return NULL;
-
- else if( !n ){
- if( !nTree )
- return NULL;
- else
- return nTree->GetFirstNode();
- }
- return n->GetNextNode();
-}
-
-/*************************************************************************/
-//! GetNextToken
-/*! This method returns the next token in an expression of one or more tokens
- \param t Token
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::GetNextToken( xbExpToken &t ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- t.iSts = XB_NO_ERROR;
- t.sExpression.Ltrim();
-
- if( t.sExpression.Len() == 0 ){
- t.iSts = XB_END_OF_EXPRESSION;
- return XB_NO_ERROR;
- }
-
- // Check for date constant
- if((t.sExpression.Len() >= 10 && t.sExpression[1] == '{' && t.sExpression[4] == '/' && t.sExpression[7] == '/') &&
- (t.sExpression[10] == '}' || (t.sExpression.Len() >= 12 && t.sExpression[12] == '}'))){
- if(( iRc = GetTokenDateConstant( t )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- // Check for parens
- else if( t.sExpression[1] == '(' || t.sExpression[1] == '{' ){
- if(( iRc = GetTokenParen( t )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- // Check for a char constant
- else if( t.sExpression[1] == '"' || t.sExpression[1] == '\'' ){
- if(( iRc = GetTokenCharConstant( t )) != XB_NO_ERROR ){
- iErrorStop = 120;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
- // Check for logical constant
- else if( IsLogicalConstant( t.sExpression )){
- if(( iRc = GetTokenLogicalConstant( t )) != XB_NO_ERROR ){
- iErrorStop = 130;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
- // check for numeric constant
- else if( IsNumericConstant( t.sExpression, t.cPrevNodeType )){
- if(( iRc = GetTokenNumericConstant( t )) != XB_NO_ERROR ){
- iErrorStop = 140;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
- // check for operator
- else if( IsOperator( t.sExpression )){
- if(( iRc = GetTokenOperator( t )) != XB_NO_ERROR ){
- iErrorStop = 150;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
- // check for function
- else if( IsFunction( t.sExpression, t.cReturnType )){
- if(( iRc = GetTokenFunction( t )) != XB_NO_ERROR ){
- iErrorStop = 160;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
- else if(( iRc = GetTokenDatabaseField( t )) != XB_NO_ERROR ){
- iErrorStop = 170;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
-
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::GetNextToken() Exception Caught. Error Stop = [%d] iRc = [%d] Expression = [%s]", iErrorStop, iRc, t.sExpression.Str() );sMsg.Sprintf( "xbexp::GetNextToken() Exception Caught. Error Stop = [%d] iRc = [%d] Expression = [%s]", iErrorStop, iRc, t.sExpression.Str() );sMsg.Sprintf( "xbexp::GetNextToken() Exception Caught. Error Stop = [%d] iRc = [%d] Expression = [%s]", iErrorStop, iRc, t.sExpression.Str() );sMsg.Sprintf( "xbexp::GetNextToken() Exception Caught. Error Stop = [%d] iRc = [%d] Expression = [%s]", iErrorStop, iRc, t.sExpression.Str() );
- xbase->WriteLogMessage( sMsg.Str() );
- }
- return iRc;
-}
-
-/*************************************************************************/
-//! Get numeric result.
-/*!
- If the expression generates a numeric return type, this method retrieves the numeric value.
- \param dResult - Output numeric value.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::GetNumericResult( xbDouble &dResult){
- if( nTree ){
- dResult = nTree->GetNumericResult();
- return XB_NO_ERROR;
- }
- else{
- dResult = 0;
- return XB_PARSE_ERROR;
- }
-}
-/*************************************************************************/
-//! Get result length.
-/*!
- This routine returns the result length.
- \returns Result length.
-*/
-
-xbInt16 xbExp::GetResultLen() const{
- if( nTree )
- return nTree->GetResultLen();
- else
- return 0;
-}
-
-/*************************************************************************/
-//! Get return type.
-/*!
- \returns Expression return type.
-*/
-
-char xbExp::GetReturnType() const{
- if( nTree )
- return nTree->GetReturnType();
- else
- return ' ';
-}
-
-/*************************************************************************/
-//! Get string result.
-/*!
- If the expression generates a string return type, this method retrieves the string value.
- \param sResult - Output string value.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::GetStringResult( xbString &sResult){
- if( nTree ){
- sResult = nTree->GetStringResult();
- return XB_NO_ERROR;
- }
- else{
- sResult = "";
- return XB_PARSE_ERROR;
- }
-}
-
-/*************************************************************************/
-//! Get string result.
-/*!
- If the expression generates a string return type, this method retrieves the string value.
- \param vpResult - Pointer to user supplied buffer for result.
- \param ulLen - Max size of buffer.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbExp::GetStringResult( char * vpResult, xbUInt32 ulLen ){
- if( nTree ){
- nTree->GetStringResult().strncpy((char *) vpResult, ulLen );
- return XB_NO_ERROR;
- }
- else{
- return XB_PARSE_ERROR;
- }
-}
-
-
-
-/*************************************************************************/
-//! GetTokenCharConstant
-/*! This method returns the character constant in a pair of quotes
-
- This routine returns the tokens inside a set of matching quotes in sOutToken
- If there is nothing between the quotes then sOutToken is returned empty
- sOutRemainder contains whatever remains to the right of the right quote
-
- \param t Token
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-
-xbInt16 xbExp::GetTokenCharConstant( xbExpToken &t ){
-
- const char *s = t.sExpression;
- const char *sToken; // pointer to beginning of token
- xbInt16 iQuoteType;
- xbUInt32 ulTokenLen = 0;
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbBool bDone = xbFalse;
-
- try{
- if( *s == '"' )
- iQuoteType = 0;
- else
- iQuoteType = 1;
- s++;
- sToken = s;
- while( *s && !bDone ){
- if(( *s == '"' && iQuoteType == 0 ) || (*s == '\'' && iQuoteType == 1 ))
- bDone = xbTrue;
- s++;
- ulTokenLen++;
- }
- if( bDone ){ // found matching paren
- t.cNodeType = XB_EXP_CONSTANT;
- t.cReturnType = XB_EXP_CHAR;
- t.sToken.Set( sToken, ulTokenLen - 1 );
- t.sExpression.Ltrunc( ulTokenLen + 1 );
- } else {
- iRc = XB_PARSE_ERROR;
- t.iSts = XB_UNBALANCED_QUOTES;
- iErrorStop = 100;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::GetTokenCharConstant() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- }
- return iRc;
-}
-
-
-/*************************************************************************/
-//! GetTokenDateConstant
-/*! This method returns the date constant in a pair of {}
-
- Date format is one of {mm/dd/yy} or {mm/dd/yyyy}
- \param t Token.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::GetTokenDateConstant( xbExpToken &t ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char wBuf[13];
- xbDate dt;
-
- try{
- memset( wBuf, 0x00, 13 );
- t.cNodeType = XB_EXP_CONSTANT;
- t.cReturnType = XB_EXP_DATE;
-
- if( t.sExpression[10] == '}' ){
- for( xbInt16 i = 0; i < 8; i++ )
- wBuf[i] = t.sExpression[i+2];
-
- if(( iRc = dt.CTOD( wBuf )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- t.sToken.Set( dt.Str() );
- t.sExpression.Ltrunc( 10 );
-
- } else if( t.sExpression[12] == '}' ){
-
- wBuf[0] = t.sExpression[8];
- wBuf[1] = t.sExpression[9];
- wBuf[2] = t.sExpression[10];
- wBuf[3] = t.sExpression[11];
- wBuf[4] = t.sExpression[2];
- wBuf[5] = t.sExpression[3];
- wBuf[6] = t.sExpression[5];
- wBuf[7] = t.sExpression[6];
-
- t.sToken.Set( wBuf );
- t.sExpression.Ltrunc( 12 );
- } else {
- iRc = XB_PARSE_ERROR;
- t.iSts = XB_INVALID_DATE;
- iErrorStop = 110;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::GetTokenDateConstant() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- }
- return iRc;
-}
-/*************************************************************************/
-//! GetTokenField
-/*! This method gets a database field token
-
- Looks for a xbase field in one of the following formats
-
- FIELDNAME
- or
- TABLENAME->FIELDNAME
-
- \param t Token.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::GetTokenDatabaseField( xbExpToken &t ){
-
- const char *s = t.sExpression;
- xbUInt32 ulTokenLen = 0;
- xbUInt32 ulTokenLen2 = 0;
-
- while( *s && !IsTokenSeparator( *s ) && !IsWhiteSpace( *s )) {
- ulTokenLen++;
- s++;
- }
-
- // go past any white space
- while( *s && !IsTokenSeparator( *s ) && IsWhiteSpace( *s )) {
- ulTokenLen2++;
- s++;
- }
-
- // look for ->
- // remove the table name from before the ->
- if( strncmp( s, "->", 2 ) == 0 ){
- ulTokenLen2+=2;
- s+=2;
-
-/*
- if( strncmp( s, "->", 2 ) == 0 || strncmp( s, ".", 1 ) == 0){
- if( *s == '.' ){
- ulTokenLen2+=1;
- s+=1;
- } else {
- ulTokenLen2+=2;
- s+=2;
- }
-*/
-
- // go past white space
- while( *s && !IsTokenSeparator( *s ) && IsWhiteSpace( *s )) {
- ulTokenLen2++;
- s++;
- }
- // go to the end
- while( *s && !IsTokenSeparator( *s ) && !IsWhiteSpace( *s )) {
- ulTokenLen2++;
- s++;
- }
- ulTokenLen += ulTokenLen2;
- }
- t.cNodeType = XB_EXP_FIELD;
- t.cReturnType = XB_EXP_UNKNOWN;
- t.sToken.Set( t.sExpression, ulTokenLen );
- t.sExpression.Ltrunc( ulTokenLen );
-
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! GetTokenFunction
-/*!
- This method gets a function and everything between the following quotes
- \param t Token
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-
-xbInt16 xbExp::GetTokenFunction( xbExpToken &t ){
-
- xbUInt32 lPos = t.sExpression.Pos( '(' );
- if( lPos == 0 )
- return XB_PARSE_ERROR;
-
- xbBool bDone = xbFalse;
- xbUInt32 lLen = t.sExpression.Len();
- xbInt16 iDepthCtr = 1;
-
- while( ++lPos <= lLen && !bDone ){
- if( t.sExpression[lPos] == ')' ){
- iDepthCtr--;
- if( iDepthCtr == 0 )
- bDone = xbTrue;
- } else if( t.sExpression[lPos] == '(' ){
- iDepthCtr++;
- }
- }
-
- t.cNodeType = XB_EXP_FUNCTION;
- t.sToken.Set( t.sExpression, lPos-1 );
- t.sExpression.Ltrunc( lPos-1 );
-
-// std::cout << "lPos = [" << lPos << "] done= [" << bDone << "][" << t.sExpression << "] len=[" << lLen << "] return type = [" << t.cReturnType << "]\n";
-
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! GetTokenCharConstant
-/*! This method returns the character constant in a pair of quotes
-
- This routine returns the tokens inside a set of matching quotes in sOutToken
- If there is nothing between the quotes then sOutToken is returned empty
- sOutRemainder contains whatever remains to the right of the right quote
-
- \param t Token
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::GetTokenLogicalConstant( xbExpToken &t ){
-
- t.cNodeType = XB_EXP_CONSTANT;
- t.cReturnType = XB_EXP_LOGICAL;
- t.sToken = t.sExpression[2];
-
- if( t.sExpression[3] == '.' )
- t.sExpression.Ltrunc( 3 );
- else if( t.sExpression[6] == '.' )
- t.sExpression.Ltrunc( 6 );
- else if( t.sExpression[7] == '.' )
- t.sExpression.Ltrunc( 7 );
-
- return XB_NO_ERROR;
-}
-
-
-/*************************************************************************/
-//! GetTokenNumericConstant
-/*! This method returns a numeric constant in
-
- This routine returns a numeric constant token
- sOutRemainder contains whatever remains to the right of the right quote
-
- \param t Token
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::GetTokenNumericConstant( xbExpToken &t ){
-
- const char * s = t.sExpression;
- xbUInt32 ulTokenLen = 0;
- t.sToken = "";
-
- t.cNodeType = XB_EXP_CONSTANT;
- t.cReturnType = XB_EXP_NUMERIC;
-
- // capture the leading sign
- if( *s == '-' || *s == '+' || *s == '.' ){
- t.sToken = *s;
- ulTokenLen++;
- s++;
-
- // go past any white space between sign and number
- while( *s && IsWhiteSpace( *s )){
- s++;
- ulTokenLen++;
- }
- }
-
- // add the number to the token
- while( *s && (isdigit( *s ) || *s == '.' )){
- t.sToken += *s;
- s++;
- ulTokenLen++;
- }
- t.sExpression.Ltrunc( ulTokenLen );
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! GetTokenOperator
-/*! This method returns the operator
-
- \param t Token
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-
-xbInt16 xbExp::GetTokenOperator( xbExpToken &t ){
-
- const char *s = t.sExpression;
-
- // Logical operators
- if((strncmp( s, "<>", 2 ) == 0 ) || (strncmp( s, "!=", 2 ) == 0 ) ||
- (strncmp( s, "<=", 2 ) == 0 ) || (strncmp( s, ">=", 2 ) == 0 )){
- t.cReturnType = XB_EXP_LOGICAL;
- t.sToken.Assign( s, 1, 2 );
- t.sExpression.Ltrunc( 2 );
- t.cNodeType = XB_EXP_OPERATOR;
- return XB_NO_ERROR;
- }
-
- if( *s == '=' || *s == '<' || *s == '>' || *s == '$' || *s == '#' ){
- t.cReturnType = XB_EXP_LOGICAL;
- t.sToken.Assign( s, 1, 1 );
- t.sExpression.Ltrunc( 1 );
- t.cNodeType = XB_EXP_OPERATOR;
- return XB_NO_ERROR;
- }
-
- if( (strncmp( s, ".NOT.", 5 ) == 0 ) || (strncmp( s, ".AND.", 5 ) == 0 )){
- t.cReturnType = XB_EXP_LOGICAL;
- t.sToken.Assign( s, 1, 5 );
- t.sExpression.Ltrunc( 5 );
- t.cNodeType = XB_EXP_OPERATOR;
- return XB_NO_ERROR;
- }
-
- if( (strncmp( s, "NOT ", 4 ) == 0 ) || (strncmp( s, "AND ", 4 ) == 0 )){
- t.cReturnType = XB_EXP_LOGICAL;
- t.sToken.Assign( s, 1, 3 );
- t.sExpression.Ltrunc( 3 );
- t.cNodeType = XB_EXP_OPERATOR;
- return XB_NO_ERROR;
- }
-
- if( strncmp( s, ".OR.", 4 ) == 0 ) {
- t.cReturnType = XB_EXP_LOGICAL;
- t.sToken.Assign( s, 1, 4 );
- t.sExpression.Ltrunc( 4 );
- t.cNodeType = XB_EXP_OPERATOR;
- return XB_NO_ERROR;
- }
-
- if( strncmp( s, "OR ", 3 ) == 0 ) {
- t.cReturnType = XB_EXP_LOGICAL;
- t.sToken.Assign( s, 1, 2 );
- t.sExpression.Ltrunc( 2 );
- t.cNodeType = XB_EXP_OPERATOR;
- return XB_NO_ERROR;
- }
-
- // Numeric operators
- if(( strncmp( s, "**", 2 ) == 0 ) || ( strncmp( s, "+=", 2 ) == 0 ) ||
- ( strncmp( s, "-=", 2 ) == 0 ) || ( strncmp( s, "*=", 2 ) == 0 ) || ( strncmp( s, "/=", 2 ) == 0 )){
- t.cReturnType = XB_EXP_NUMERIC;
- t.sToken.Assign( s, 1, 2 );
- t.sExpression.Ltrunc( 2 );
- t.cNodeType = XB_EXP_OPERATOR;
- return XB_NO_ERROR;
- }
-
- // Pre/post increment/decrement operators ++ or --
- if(( strncmp( s, "--", 2 ) == 0 ) || ( strncmp( s, "++", 2 ) == 0 )){
- t.cReturnType = XB_EXP_NUMERIC;
- t.sToken.Assign( s, 1, 2 );
- t.sExpression.Ltrunc( 2 );
- if( t.sExpression.Len() > 0 && (isdigit( t.sExpression[1] ) || isalpha( t.sExpression[1] )))
- t.cNodeType = XB_EXP_PRE_OPERATOR;
- else
- t.cNodeType = XB_EXP_POST_OPERATOR;
-
- return XB_NO_ERROR;
- }
-
- if( *s == '*' || *s == '/' || *s == '%' || *s == '^' ){
- t.cReturnType = XB_EXP_NUMERIC;
- t.sToken.Assign( s, 1, 1 );
- t.sExpression.Ltrunc( 1 );
- t.cNodeType = XB_EXP_OPERATOR;
- return XB_NO_ERROR;
- }
-
- // multi return type operators
- t.cReturnType = XB_EXP_UNKNOWN;
- if( *s == '+' || *s == '-' ){
- t.sToken.Assign( s, 1, 1 );
- t.sExpression.Ltrunc( 1 );
- t.cNodeType = XB_EXP_OPERATOR;
- return XB_NO_ERROR;
- }
- return XB_PARSE_ERROR;
-}
-
-/*************************************************************************/
-//! GetTokenParen
-/*! This method returns the tokens in a pair of enclosed parens
-
- This routine returns the tokens inside a set of matching parens in sOutToken
- If there is nothing between the parens then sOutToken is returned empty
- sOutRemainder contains whatever remains to the right of the right paren
-
- \param t Token
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbExp::GetTokenParen( xbExpToken &t ){
-
- const char * s = t.sExpression;
- const char * sToken; // pointer to beginning of token
- xbInt16 iParenType = 0;
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbInt16 iDepthCtr = 0; // depth inside of nested parens
- xbUInt32 ulTokenLen = 0;
- xbBool bDone = xbFalse;
-
- try{
- if( *s == '{' )
- iParenType = 0;
- else
- iParenType = 1;
- iDepthCtr = 1;
- s++;
- sToken = s;
-
- while( *s && !bDone ){
- if(( *s == ')' && iParenType == 1 ) || (*s == '}' && iParenType == 0 )){
- iDepthCtr--;
- if( iDepthCtr == 0 )
- bDone = xbTrue;
- } else if(( *s == '(' && iParenType == 1 ) || (*s == '{' && iParenType == 0 )){
- iDepthCtr++;
- }
- s++;
- ulTokenLen++;
- }
-
- if( bDone ){ // found matching paren
- t.cNodeType = XB_EXP_NOTROOT;
- t.cReturnType = XB_EXP_UNKNOWN;
- t.sToken.Set( sToken, ulTokenLen - 1 );
- t.sExpression.Ltrunc( ulTokenLen + 1 );
- } else {
- t.sToken = "";
- t.cNodeType = XB_EXP_NOTROOT;
- t.cReturnType = XB_EXP_UNKNOWN;
- t.iSts = XB_UNBALANCED_PARENS;
- iRc = XB_PARSE_ERROR;
- iErrorStop = 100;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::GetTokenParen() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- }
- return iRc;
-}
-
-/*************************************************************************/
-//! Get the expression tree handle.
-/*!
- \returns Pointer to the top most node in the expression tree.
-*/
-xbExpNode *xbExp::GetTreeHandle(){
- return nTree;
-}
-
-/*************************************************************************/
-//! Is Function
-/*! This method determines if the next token is a function.
-
- \param sExpression - String expression to be evaluated.
- \param cReturnType Output - Return type.
- \returns xbTrue - Is a function.<br>
- xbFalse - Is not a function.
-*/
-
-xbBool xbExp::IsFunction( const xbString & sExpression, char &cReturnType ){
-
- xbInt16 i = 0;
- xbInt32 l = 0;
- if( sExpression.Pos( '(' ) > 0 ){
- if( xbase->GetFunctionInfo( sExpression, cReturnType, i, l ) == XB_NO_ERROR )
- return xbTrue;
- }
- return xbFalse;
-}
-
-/*************************************************************************/
-//! Is Logical constant
-/*! This method determines if the next token is a logical constant (T/F, etc).
-
- \param sExpression - String expression to be evaluated.
- \returns xbTrue - Is a logical constant.<br>
- xbFalse - Is not a logical constant.
-*/
-
-xbBool xbExp::IsLogicalConstant( const xbString & sExpression ){
-
- const char *s = sExpression;
- if(( strncmp( s, ".T.", 3 ) == 0 ) || ( strncmp( s, ".F.", 3 ) == 0 ))
- return xbTrue;
- else if( strncmp( s, ".TRUE.", 6 ) == 0 )
- return xbTrue;
- else if( strncmp( s, ".FALSE.", 7 ) == 0 )
- return xbTrue;
-
- return xbFalse;
-}
-
-/*************************************************************************/
-//! Is Numeric constant
-/*! This method determines if the next token is a numeric constant.
-
- \param sExpression - String expression to be evaluated.
- \param cPrevNodeType - Type of previous node.
- \returns xbTrue - Is a numeric constant.<br>
- xbFalse - Is not a numeric constant.
-*/
-xbBool xbExp::IsNumericConstant( const xbString & sExpression, char cPrevNodeType ){
-
- // check for positive, negative or decimal number constants
-
- const char *s = sExpression;
- if(( *s == '-' && ( cPrevNodeType == 'O' || cPrevNodeType == 0 )) ||
- ( *s == '+' && ( cPrevNodeType == 'O' || cPrevNodeType == 0 ))){
- s++;
- while( *s && IsWhiteSpace( *s ))
- s++;
- }
- if( *s == '.' )
- s++;
-
- if( isdigit( *s ))
- return xbTrue;
- else
- return xbFalse;
-}
-
-/*************************************************************************/
-//! Is Operator.
-/*! This method determines if the next token is an operator.
-
- \param sExpression - String expression to be evaluated.
- \returns xbTrue - Is an operator.<br>
- xbFalse - Is not an operator.
-*/
-xbBool xbExp::IsOperator( const xbString & sExpression ){
-
- const char *s = sExpression;
- if( *s == '+' || *s == '-' || *s == '/' || *s == '^' || *s == '=' || *s == '$' ||
- *s == '#' || *s == '*' || *s == '<' || *s == '>' || *s == '%' )
- return xbTrue;
-
- if( strncmp( s, "!=", 2 ) == 0 )
- return xbTrue;
-
- if((strncmp( s, ".NOT.", 5 ) == 0 ) || (strncmp( s, ".OR.", 4 ) == 0 ) || (strncmp( s, ".AND.", 5 ) == 0 ))
- return xbTrue;
-
- if((strncmp( s, "NOT ", 4 ) == 0 ) || (strncmp( s, "OR ", 3 ) == 0 ) || (strncmp( s, "AND ", 4 ) == 0 ))
- return xbTrue;
-
- return xbFalse;
-}
-
-/*************************************************************************/
-//! Is Token separator
-/*! This method determines if the next token is a separator.
-
- \param sExpression - String expression to be evaluated.
- \returns xbTrue - Is a token separator.<br>
- xbFalse - Is not a token separator.
-*/
-char xbExp::IsTokenSeparator( char c ){
- if( c == '-' || c == '+' || c == '*' || c == '/' || c == '$' || c == '#' ||
- c == '<' || c == '>' || c == '^' || c == '=' || c == '.' || c == '!' )
- return c;
- else
- return 0;
-}
-/*************************************************************************/
-//! Is White space
-/*! This method determines if a given character is white space.
-
- \param c - Character to be evaluated.
- \returns xbTrue - Is white space.<br>
- xbFalse - Is not white space.
-*/
-xbBool xbExp::IsWhiteSpace( char c ){
- return(( c == 0x20 )? 1 : 0 );
-}
-
-/*************************************************************************/
-//! Get operator weight.
-/*!
- This method determines the priority of an operator
-
- Operator precendence
- 10 .AND. .OR. .NOT. (not really an operator)
- 9 > or < (includes <= or >=)
- 6 unary plus or minus (+,-) -- not passed this routine
- 5 prefix increment and/or decrement (++,--)
- 4 exponentiation ** or ^
- 3 multiplication,division or modulus (*,/,%)
- 2 Addition, subtraction (+,-)
- 1 Postfix increment and/or decrement (++,--)
-
- \param sOper - Operator.
- \returns Operator weight
-
-*/
-
-xbInt16 xbExp::OperatorWeight( const xbString &sOper ){
-
- if( sOper == "" || sOper.Len() > 5 )
- return 0;
-
- else if( sOper == "--0" || sOper == "++0" ) // 0 is prefix
- return 9;
- else if( sOper == "**" || sOper == "^" )
- return 8;
- else if( sOper == "*" || sOper == "/" || sOper == "%" || sOper == "*=" || sOper == "/=" )
- return 7;
- else if( sOper == "+" || sOper == "-" || sOper == "+=" || sOper == "-=" )
- return 6;
- else if( sOper == "--1" || sOper == "++1" ) // 1 is post fix
- return 5;
- else if( sOper == ">" || sOper == ">=" || sOper == "<" || sOper == "<=" ||
- sOper == "<>" || sOper == "!=" || sOper == "#" || sOper == "$" || sOper == "=" )
- return 4;
- else if( sOper == ".NOT." || sOper == "NOT" )
- return 3;
- else if( sOper == ".AND." || sOper == "AND" )
- return 2;
- else if( sOper == ".OR." || sOper == "OR" )
- return 1;
-
- return 0;
-}
-
-
-/*************************************************************************/
-//! Parse expression.
-/*!
- \param sExpression - Expression to parse.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::ParseExpression( const xbString &sExpression ){
- return ParseExpression( sExpression, (xbInt16) 0 );
-}
-
-/*************************************************************************/
-//! Parse expression.
-/*!
- \param dbf - Pointer to xbDbf instance.
- \param sExpression - Expression to parse.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::ParseExpression( xbDbf *dbf, const xbString &sExpression ){
- this->dbf = dbf;
- return ParseExpression( sExpression, (xbInt16) 0 );
-}
-
-/*************************************************************************/
-//! Parse expression.
-/*!
- \param sExpression - Expression to parse.
- \param iWeight.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbExp::ParseExpression( const xbString &sExpression, xbInt16 iWeight ){
-
- xbExpNode *n = NULL;
- xbExpNode *nLastNode = NULL; // pointer to the last node processed
- xbExpToken t;
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbString s;
- xbBool bNewNode = xbFalse;
-
- try {
-
- if( nTree )
- delete nTree;
-
- if(( iRc = CheckParensAndQuotes( sExpression )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- t.sExpression = sExpression;
-
- xbString sOriginalExp;
- while( t.iSts == XB_NO_ERROR && iRc == XB_NO_ERROR ){
-
- sOriginalExp = t.sExpression; // test code
- iRc = GetNextToken( t );
- if( !iRc && !t.iSts ){
-
- // comment / uncomment debug / live
- // DumpToken( t, 0 );
-
- if( t.cNodeType == XB_EXP_NOTROOT ){
- xbExp enr( xbase, dbf );
- if(( iRc = enr.ParseExpression( t.sToken, iWeight + 10 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- n = enr.GetTreeHandle();
- enr.ClearTreeHandle();
-
- } else {
-
- switch( t.cNodeType ) {
-
- case XB_EXP_CONSTANT:
- n = new xbExpNode( t.sToken, t.cNodeType );
- bNewNode = xbTrue;
- if(( iRc = ParseExpressionConstant( t, n )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- break;
-
- case XB_EXP_FUNCTION:
- n = new xbExpNode( t.cNodeType );
- bNewNode = xbTrue;
- if(( iRc = ParseExpressionFunction( t, n, iWeight )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- break;
-
- case XB_EXP_FIELD:
- n = new xbExpNode( t.cNodeType );
- bNewNode = xbTrue;
- if(( iRc = ParseExpressionField( t, n )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- break;
-
- case XB_EXP_OPERATOR:
- case XB_EXP_PRE_OPERATOR:
- case XB_EXP_POST_OPERATOR:
- n = new xbExpNode( t.sToken, t.cNodeType );
- bNewNode = xbTrue;
- if(( iRc = ParseExpressionOperator( t, n, iWeight )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- break;
-
- default:
- iErrorStop = 160;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- // break;
- }
- }
- t.cPrevNodeType = t.cNodeType;
- t.cPrevReturnType = t.cReturnType;
-
- // determine where in the expression tree to insert the latest node "n"
- // Is this the first node to be added to the tree?
- if( !nTree ){
- nTree = n;
- }
-
- // else if last node was XB_EXB_PRE_OPERATOR then append this as child to last node
- else if( nLastNode && nLastNode->GetNodeType() == XB_EXP_PRE_OPERATOR ){
- n->SetParent( nLastNode );
- nLastNode->AddChild( n );
- }
-
- // else if last node was XB_EXB_POST_OPERATOR then append this as child to last node
- else if( nLastNode && n->GetNodeType() == XB_EXP_POST_OPERATOR ){
- n->AddChild( nLastNode );
- nLastNode->SetParent( n );
- if( nLastNode == nTree ){
- nTree = n;
- } else {
- nLastNode->GetParent()->RemoveLastChild();
- nLastNode->GetParent()->AddChild( n );
- n->SetParent( nLastNode->GetParent() );
- }
- }
-
- else if( n->GetNodeType() == XB_EXP_OPERATOR ){
- xbExpNode * nWorkNode = nLastNode;
- while( nWorkNode && ( nWorkNode->GetNodeType() != XB_EXP_OPERATOR || n->GetWeight() <= nWorkNode->GetWeight())){
- nWorkNode = nWorkNode->GetParent();
- }
-
- if( !nWorkNode ){ // we are at the top
- nTree->SetParent( n );
- n->AddChild( nTree );
- nTree = n;
-
- } else if( nWorkNode->GetChildCnt() == 1 ){
- nWorkNode->AddChild( n );
- n->SetParent( nWorkNode );
-
- } else if( nWorkNode->GetChildCnt() == 2 ){
- xbExpNode * nChild2 = nWorkNode->GetChild(1);
- n->AddChild( nChild2 );
- nWorkNode->RemoveLastChild();
- nWorkNode->AddChild( n );
- n->SetParent( nWorkNode );
-
- } else{
- // should not be stopping on anything but an operator node with one or two children
- iErrorStop = 170;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- } else {
- n->SetParent( nLastNode );
- nLastNode->AddChild( n );
- }
- nLastNode = n;
- n = NULL;
- }
- }
-
- // for each node in the tree, calculate the length if it's not already set
- xbExpNode * nWork = GetNextNode( NULL );
- xbExpNode * nChild1;
- xbExpNode * nChild2;
-
- while( nWork ){
- if( nWork->GetReturnType() == XB_EXP_UNKNOWN ){
- nWork->GetNodeText( s );
-
- // std::cout << "XB_EXP_UNKNOWN logic [" << s << "][" << nWork->GetChildCnt() << "]\n";
- // if this is "-" and child 1 and child 2 are both dates, set this result type to numeric
- if( s == "-" && nWork->GetChildCnt() == 2 &&
- nWork->GetChild(0)->GetReturnType() == XB_EXP_DATE && nWork->GetChild(1)->GetReturnType() == XB_EXP_DATE )
- nWork->SetReturnType( XB_EXP_NUMERIC );
- else if( nWork->GetChildCnt() > 0 )
- nWork->SetReturnType( nWork->GetChild(0)->GetReturnType());
- else{
- iErrorStop = 180;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
- if( nWork->GetResultLen() == 0 ){
-
- switch( nWork->GetReturnType() ){
-
- case XB_EXP_NUMERIC:
- nWork->SetResultLen( 4 );
- break;
-
- case XB_EXP_CHAR:
- if( nWork->GetNodeType() != XB_EXP_OPERATOR ){
- iErrorStop = 190;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- if( nWork->GetChildCnt() < 2 ){
- iErrorStop = 200;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- nChild1 = nWork->GetChild( 0 );
- nChild2 = nWork->GetChild( 1 );
- nWork->SetResultLen( nChild1->GetResultLen() + nChild2->GetResultLen());
- break;
-
- case XB_EXP_DATE:
- nWork->SetResultLen( 8 );
- break;
-
- case XB_EXP_LOGICAL:
- nWork->SetResultLen( 1 );
- break;
-
- default:
- iErrorStop = 210;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- // break;
- }
- }
- if( nWork->IsUnaryOperator() ){
- if( nWork->GetChildCnt() != 1 ){
- iErrorStop = 220;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- } else if( nWork->IsOperator() && nWork->GetChildCnt() != 2 ){
- iErrorStop = 230;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- nWork = GetNextNode( nWork );
- }
- }
- catch (xbInt16 iRc ){
- if( bNewNode && n )
- delete n;
- xbString sMsg;
- sMsg.Sprintf( "xbexp::ParseExpression() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- }
- return iRc;
-}
-/*************************************************************************/
-//! Parse expression constant.
-/*!
- \param t - Token.
- \param n - Node.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbExp::ParseExpressionConstant( xbExpToken &t, xbExpNode *n ){
-
- xbDate dtWork;
- n->SetReturnType( t.cReturnType );
-
- // std::cout << "parse expression constant[" << t.sToken << "]\n";
-
- switch( t.cReturnType ){
- case XB_EXP_CHAR:
- n->SetResultLen( t.sToken.Len() );
- n->SetResult( t.sToken );
- break;
-
- case XB_EXP_DATE:
- n->SetResultLen( 8 );
- dtWork.Set( t.sToken );
- n->SetResult( dtWork );
- break;
-
- case XB_EXP_LOGICAL:
- n->SetResultLen( 1 );
- if( strncmp( t.sToken, "T", 1 ) == 0 )
- n->SetResult( (xbBool) xbTrue );
- else
- n->SetResult( (xbBool) xbFalse );
- break;
-
- case XB_EXP_NUMERIC:
- n->SetResultLen( 4 );
- n->SetResult( strtod( t.sToken, 0 ));
- n->SetResult( t.sToken );
- break;
-
- default:
- return XB_PARSE_ERROR;
- // break;
- }
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! Parse expression field.
-/*!
- \param t - Token.
- \param n - Node.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbExp::ParseExpressionField( xbExpToken &t, xbExpNode *n ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbDbf * pDbf;
- xbString sFieldName;
-
- // do the db lookup and set the field number for the field
-
- try{
-
- xbUInt32 lPos;
-
- if(( lPos = t.sToken.Pos( "->" )) > 0 ){
- // table name is part of the token
- xbString sTableName = t.sToken;
- sTableName.Left( lPos-1 );
- sFieldName = t.sToken;
- sFieldName.Mid( lPos + 2, t.sToken.Len() - lPos - 1 );
- pDbf = (xbDbf *) xbase->GetDbfPtr( sTableName );
-
-
-/*
- // updated 1/2/23 to support either table.field or table->field
- if((( lPos = t.sToken.Pos( "->" )) > 0) || (( lPos = t.sToken.Pos( "." )) > 0) ){
- // table name is part of the token
- xbString sTableName = t.sToken;
- sTableName.Left( lPos-1 );
- sFieldName = t.sToken;
- if( t.sToken[lPos] == '.' )
- sFieldName.Mid( lPos + 1, t.sToken.Len() - lPos );
- else // ->
- sFieldName.Mid( lPos + 2, t.sToken.Len() - lPos - 1 );
- pDbf = (xbDbf *) xbase->GetDbfPtr( sTableName );
-*/
-
- } else {
- // table name is not part of the token
- pDbf = dbf;
- sFieldName = t.sToken;
- }
- if( !pDbf ){
- iErrorStop = 100;
- iRc = XB_INVALID_FIELD;
- throw iRc;
- }
- xbInt16 iFieldNo = 0;
-
- if(( iRc = pDbf->GetFieldNo( sFieldName, iFieldNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- char cFieldType;
- if(( iRc = pDbf->GetFieldType( iFieldNo, cFieldType )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- n->SetDbfInfo( pDbf, iFieldNo );
- switch( cFieldType ){
- case XB_CHAR_FLD:
- n->SetReturnType( XB_EXP_CHAR );
- break;
-
- case XB_LOGICAL_FLD:
- n->SetReturnType( XB_EXP_LOGICAL );
- break;
-
- case XB_NUMERIC_FLD:
- case XB_FLOAT_FLD:
- n->SetReturnType( XB_EXP_NUMERIC );
- break;
-
- case XB_DATE_FLD:
- n->SetReturnType( XB_EXP_DATE );
- break;
-
- case XB_MEMO_FLD:
- default:
- iErrorStop = 130;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- // break;
- }
- n->SetNodeText( sFieldName );
- xbInt16 iResultLen = 0;
- if(( iRc = pDbf->GetFieldLen( iFieldNo, iResultLen )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- n->SetResultLen( (xbUInt32) iResultLen );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::ParseExpressionField() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- }
- return iRc;
-}
-
-/*************************************************************************/
-//! Parse expression function.
-/*!
- \param t - Token.
- \param n - Node.
- \param iWeight
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbExp::ParseExpressionFunction( xbExpToken &t, xbExpNode *n, xbInt16 iWeight ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- // find the first "("
- xbUInt32 lPos = t.sToken.Pos( '(' );
- if( lPos == 0 ){
- iErrorStop = 100;
- iRc = XB_INVALID_FUNCTION;
- throw iRc;
- }
- // Get the function name and look it up in the table
-
-
- xbString sFunc = t.sToken;
- sFunc.Left( lPos - 1 ).Trim();
- char cReturnType;
- xbInt16 i = 0;
- xbInt32 l = 0;
- if(( iRc = xbase->GetFunctionInfo( sFunc, cReturnType, i, l )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- n->SetNodeText( sFunc );
-
-
- // Get the function parms
- xbString sParms = t.sToken;
- sParms.Mid( lPos+1, t.sToken.Len() - lPos );
- lPos = sParms.GetLastPos( ')' );
- if( lPos == 0 ){
- iErrorStop = 120;
- iRc = XB_INVALID_FUNCTION;
- throw iRc;
- }
-
- // remove the trailing ")" paren
- sParms.Left( lPos - 1 ).Trim();
-
- // if this function has parms, put them in the tree
- if( sParms.Len() > 0 ){
- xbExp enr( xbase, dbf );
-
- // create a linked list of parms
- xbLinkList<xbString> llParms;
- if(( iRc = ParseExpressionFunctionParms( sParms, llParms )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- // for each function parm, recursively process it
- xbLinkListNode<xbString> * llN = llParms.GetHeadNode();
- xbString sParm;
- while( llN ){
- sParm = llN->GetKey();
- if(( iRc = enr.ParseExpression( sParm, iWeight + 10 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- n->AddChild( enr.GetTreeHandle());
- enr.ClearTreeHandle();
- llN = llN->GetNextNode();
- }
- llParms.Clear();
- }
-
- if( cReturnType == '1' ){
- if( n->GetChildCnt() > 0 ){
- xbExpNode *n1 = n->GetChild( 0 );
- n->SetReturnType( n1->GetReturnType());
- }
-
- } else {
- n->SetReturnType( cReturnType );
- }
-
- if(( iRc = CalcFunctionResultLen( n )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::ParseExpressionFunction() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- }
- return iRc;
-}
-
-/*************************************************************************/
-//! Parse expression function.
-/*!
-
- Creates a linked list of function parms as xbStrings
- This function pulls out the parms and addresses embedded parens and quotes within the parms
-
- \param sParms
- \param lParms
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::ParseExpressionFunctionParms( const xbString &sParms, xbLinkList<xbString> & llParms ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbInt16 iParenCtr = 0;
- xbInt16 iInQuotes = 0;
- xbInt16 iDoubleQuotes = 0;
- xbInt16 iSingleQuotes = 0;
- xbInt32 lStartPos = 0;
- xbInt32 lParmLen = 0;
-
- xbString sParm;
-
- try{
- const char *sp = sParms;
-
- while( *sp ){
- if( *sp == '(')
- iParenCtr++;
- else if( *sp == ')' )
- iParenCtr--;
- else if( !iInQuotes && *sp == '"' ){
- iInQuotes++;
- iDoubleQuotes++;
- } else if( iInQuotes && *sp == '"' ){
- iInQuotes--;
- iDoubleQuotes--;
- }
- else if( !iInQuotes && *sp == '\'' ){
- iInQuotes++;
- iSingleQuotes++;
- } else if( iInQuotes && *sp == '\'' ){
- iInQuotes--;
- iSingleQuotes--;
-
- } else if( !iInQuotes && !iParenCtr && *sp == ',' ){
- // found a valid comma - at the end of a parm
- // add it to the end of the linked list
- sParm = sParms;
- sParm.Mid( (xbUInt32) lStartPos + 1, (xbUInt32) lParmLen ).Trim(); // mid is one based
- llParms.InsertAtEnd( sParm );
-
- // set the start pos for the next one on the list
- lStartPos += lParmLen + 1;
- lParmLen = -1;
- // lParmLen = 0;
- }
- lParmLen++;
- sp++;
- }
- if( lParmLen > 0 ){
- // get the last parm, it didn't end with a comma
- sParm = sParms;
- sParm.Mid( (xbUInt32) lStartPos + 1, (xbUInt32) lParmLen ).Trim();
- llParms.InsertAtEnd( sParm );
- }
-
- }
- // try / catch not used in this method, structure added for potential future use
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::ParseExpressionFunctionParms() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- }
- return iRc;
-}
-/*************************************************************************/
-//! Parse expression operator.
-/*!
- \param t - Token.
- \param n - Node.
- \param iWeight
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbExp::ParseExpressionOperator( xbExpToken &t, xbExpNode *n, xbInt16 iWeight ){
-
- n->SetResult( t.sToken );
- n->SetWeight( iWeight + OperatorWeight( t.sToken) );
-
-// std::cout << "ParseExpressionOperator [" << t.cPrevNodeType << "][" << t.sToken << "] Weight = [" << iWeight;
-// std::cout << "] PrevReturnType [" << t.cPrevReturnType;
-// std::cout << "] Operator weight [" << OperatorWeight( t.sToken ) << "] getweight [" << n->GetWeight() << "]\n";
-
- if( t.sToken == "**" || t.sToken == "^" ||
- t.sToken == "*" || t.sToken == "/" || t.sToken == "%" || t.sToken == "*=" || t.sToken == "/=" )
- n->SetReturnType( XB_EXP_NUMERIC );
-
- else if( t.sToken == "--" || t.sToken == "++" || t.sToken == "+=" || t.sToken == "-=" ) // could be date or numeric
- n->SetReturnType( XB_EXP_UNKNOWN );
-
- else if( t.cPrevReturnType == XB_EXP_CHAR && ( t.sToken == "+" || t.sToken == "-" ))
- n->SetReturnType( XB_EXP_CHAR );
-
- else if( t.sToken == ".AND." || t.sToken == ".OR." || t.sToken == ".NOT." ||
- t.sToken == "AND" || t.sToken == "OR" || t.sToken == "NOT" ||
- t.sToken == ">" || t.sToken == ">=" || t.sToken == "<" ||
- t.sToken == "<=" || t.sToken == "<>" || t.sToken == "!=" ||
- t.sToken == "$" || t.sToken == "#" || t.sToken == "=" )
- n->SetReturnType( XB_EXP_LOGICAL );
-
-
- else if( t.cPrevReturnType == XB_EXP_UNKNOWN )
- n->SetReturnType( XB_EXP_UNKNOWN );
-
- // added for date constant logic 10/28/17
- else if(( t.sToken == "+" || t.sToken == "-" ) && t.cPrevReturnType == XB_EXP_DATE )
- n->SetReturnType( XB_EXP_DATE );
-
- else if( t.sToken == "+" || t.sToken == "-" )
- n->SetReturnType( XB_EXP_NUMERIC );
-
- return XB_NO_ERROR;
-}
-
-
-/************************************************************************/
-//! ProcessExpression
-/*! This method processes an expression tree leaving the result in the
- root node of the tree
-*/
-xbInt16 xbExp::ProcessExpression(){
- return ProcessExpression( 0 );
-}
-/************************************************************************/
-//! ProcessExpression
-/*! This method processes a parsed expression tree leaving the result in the
- root node of the tree
- \param iRecBufSw Record buffer to use when evaluating expression.<br>
- 0 - Current record buffer.<br>
- 1 - Original record buffer.
-*/
-
-xbInt16 xbExp::ProcessExpression( xbInt16 iRecBufSw ){
-
-// iRecBufSw 0 - Record Buffer
-// 1 - Original Record Buffer
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
-
- xbExpNode * nWork = GetNextNode( NULL );
- xbExpNode * nChild1;
- xbDbf * dbf;
- xbString sWork1;
- xbString sWork2;
- xbString sOperator;
- xbDate dtWork1;
-
- xbBool bWork;
- xbDouble dWork;
-
- while( nWork ){
- switch( nWork->GetNodeType() ){
-
- case XB_EXP_CONSTANT:
- break;
-
- case XB_EXP_PRE_OPERATOR: // increment value before setting in head node
- if( nWork->GetChildCnt() != 1 ){
- iErrorStop = 100;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- nChild1 = nWork->GetChild( 0 );
- //if( nChild1->GetReturnType() == XB_EXP_DATE )
- // nChild1->SetResult( (xbDouble) nChild1->GetDateResult().JulianDays());
-
- nWork->GetNodeText( sWork1 );
- if( sWork1 == "++" )
- nChild1->SetResult( nChild1->GetNumericResult() + 1 );
- else
- nChild1->SetResult( nChild1->GetNumericResult() - 1 );
-
- nWork->SetResult( nChild1->GetNumericResult());
-
- //if( nChild1->GetReturnType() == XB_EXP_DATE ){
- // dtWork1.JulToDate8( (xbInt32) nChild1->GetNumericResult());
- // nChild1->SetResult( dtWork1 );
- // nWork->SetResult( dtWork1 );
- // }
- break;
-
- case XB_EXP_POST_OPERATOR: // increment value after setting in head node
- if( nWork->GetChildCnt() != 1 ){
- iErrorStop = 110;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- nChild1 = nWork->GetChild( 0 );
- //if( nChild1->GetReturnType() == XB_EXP_DATE ){
- // nWork->SetResult( nChild1->GetDateResult());
- // nChild1->SetResult( (xbDouble) nChild1->GetDateResult().JulianDays());
- //}
- //else
- nWork->SetResult( nChild1->GetNumericResult());
-
- nWork->GetNodeText( sWork1 );
- if( sWork1 == "++" )
- nChild1->SetResult( nChild1->GetNumericResult() + 1 );
- else
- nChild1->SetResult( nChild1->GetNumericResult() - 1 );
-
- //if( nChild1->GetReturnType() == XB_EXP_DATE ){
- // dtWork1.JulToDate8( (xbInt32) nChild1->GetNumericResult());
- // nChild1->SetResult( dtWork1 );
- // }
- break;
-
- case XB_EXP_FIELD:
-
- if(( dbf = nWork->GetDbf()) == NULL ){
- iErrorStop = 120;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- switch( nWork->GetReturnType()){
- case XB_EXP_CHAR:
- if(( iRc = dbf->GetField( nWork->GetFieldNo(), sWork1, iRecBufSw )) < XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- nWork->SetResult( sWork1 );
- break;
-
- case XB_EXP_DATE:
-
- if(( iRc = dbf->GetField( nWork->GetFieldNo(), sWork1, iRecBufSw )) < XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if( sWork1 == " " ){
- // std::cout << "xbExp::ProcessExpression() line 1938 sWork is spaces\n";
- //nWork->SetResult( (xbDouble) 21474835648 ); // dbase sets a date value in both ndx and mdx index files to this if spaces on dbf record
- nWork->SetResult( (xbDouble) XB_NULL_DATE );
- } else {
- dtWork1.Set( sWork1 );
- nWork->SetResult( (xbDouble) dtWork1.JulianDays() );
- }
- break;
-
- case XB_EXP_LOGICAL:
- if(( iRc = dbf->GetLogicalField( nWork->GetFieldNo(), bWork, iRecBufSw )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- nWork->SetResult( bWork );
- break;
-
- case XB_EXP_NUMERIC:
- if(( iRc = dbf->GetDoubleField( nWork->GetFieldNo(), dWork, iRecBufSw )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- nWork->SetResult( dWork );
- break;
-
- default:
- iErrorStop = 170;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- // break;
- }
- break;
-
-
- case XB_EXP_OPERATOR:
- if(( iRc = ProcessExpressionOperator( nWork )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
-
- break;
-
- case XB_EXP_FUNCTION:
- if(( iRc = ProcessExpressionFunction( nWork, iRecBufSw )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
- break;
-
- default:
- iErrorStop = 200;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- // break;
- }
- nWork = GetNextNode( nWork );
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::ProcessExpression() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- }
- return iRc;
-}
-/*************************************************************************/
-//! ProcessExpression
-/*! This method processes an expression tree for a given node.
-*/
-
-xbInt16 xbExp::ProcessExpressionFunction( xbExpNode * n, xbInt16 iRecBufSw ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
-
- xbString sFunction;
- xbString sResult;
- xbDouble dResult;
- xbDate dtResult;
- xbBool bResult;
-
- n->GetNodeText( sFunction );
-
- // process functions with no children first
- xbExpNode * nChild1;
- if( n->GetChildCnt() == 0 ){
- if( sFunction == "DATE" ){
- if(( iRc = xbase->DATE( dtResult )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- n->SetResult( dtResult );
- } else if( sFunction == "DEL" ){
- if(( iRc = xbase->DEL( dbf, sResult, iRecBufSw )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "DELETED" ){
- if(( iRc = xbase->DELETED( dbf, bResult, iRecBufSw )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- n->SetResult( bResult );
- } else if( sFunction == "RECCOUNT" ){
- if(( iRc = xbase->RECCOUNT( dbf, dResult )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "RECNO" ){
- if(( iRc = xbase->RECNO( dbf, dResult )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- n->SetResult( dResult );
- }
- // process functions with one child
- } else if( n->GetChildCnt() == 1 ){
-
- nChild1 = n->GetChild( 0 );
-
- if( sFunction == "ABS" ){
- if(( iRc = xbase->ABS( nChild1->GetNumericResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "ALLTRIM" ){
- if(( iRc = xbase->ALLTRIM( nChild1->GetStringResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "ASC" ){
- if(( iRc = xbase->ASC( nChild1->GetStringResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 220;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "CDOW" ){
- xbDate d( (xbInt32) nChild1->GetNumericResult());
- if(( iRc = xbase->CDOW( d, sResult )) != XB_NO_ERROR ){
- iErrorStop = 230;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "CHR" ){
- if(( iRc = xbase->CHR( nChild1->GetNumericResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 240;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "CMONTH" ){
- xbDate d( (xbInt32) nChild1->GetNumericResult());
- if(( iRc = xbase->CMONTH( d, sResult )) != XB_NO_ERROR ){
- iErrorStop = 250;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "CTOD" ){
- if(( iRc = xbase->CTOD( nChild1->GetStringResult(), dtResult )) != XB_NO_ERROR ){
- iErrorStop = 260;
- throw iRc;
- }
- n->SetResult( dtResult );
- } else if( sFunction == "DAY" ){
- xbDate d( (xbInt32) nChild1->GetNumericResult());
- if(( iRc = xbase->DAY( d, dResult )) != XB_NO_ERROR ){
- iErrorStop = 270;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "DESCEND" ){
-
- if( n->GetReturnType() == XB_EXP_CHAR ){
- if(( iRc = xbase->DESCEND( nChild1->GetStringResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 280;
- throw iRc;
- }
- n->SetResult( sResult );
-
- } else if( n->GetReturnType() == XB_EXP_DATE ){
- xbDate d( (xbInt32) nChild1->GetNumericResult());
- if(( iRc = xbase->DESCEND( d, dtResult )) != XB_NO_ERROR ){
- iErrorStop = 290;
- throw iRc;
- }
- n->SetResult( dtResult );
-
- } else if( n->GetReturnType() == XB_EXP_NUMERIC ){
- if(( iRc = xbase->DESCEND( nChild1->GetNumericResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 300;
- throw iRc;
- }
- n->SetResult( dResult );
-
- } else {
- iErrorStop = 310;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
-
- } else if( sFunction == "DOW" ){
- xbDate d( (xbInt32) nChild1->GetNumericResult());
- if(( iRc = xbase->DOW( d, dResult )) != XB_NO_ERROR ){
- iErrorStop = 320;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "DTOC" ){
- xbDate d( (xbInt32) nChild1->GetNumericResult());
- if(( iRc = xbase->DTOC( d, sResult )) != XB_NO_ERROR ){
- iErrorStop = 330;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "DTOS" ){
- xbDate d( (xbInt32) nChild1->GetNumericResult());
- if(( iRc = xbase->DTOS( d, sResult )) != XB_NO_ERROR ){
- iErrorStop = 340;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "EXP" ){
- if(( iRc = xbase->EXP( nChild1->GetNumericResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 350;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "INT" ){
- if(( iRc = xbase->INT( nChild1->GetNumericResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 360;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "ISALPHA" ){
- if(( iRc = xbase->ISALPHA( nChild1->GetStringResult(), bResult )) != XB_NO_ERROR ){
- iErrorStop = 370;
- throw iRc;
- }
- n->SetResult( bResult );
- } else if( sFunction == "ISLOWER" ){
- if(( iRc = xbase->ISLOWER( nChild1->GetStringResult(), bResult )) != XB_NO_ERROR ){
- iErrorStop = 380;
- throw iRc;
- }
- n->SetResult( bResult );
- } else if( sFunction == "ISUPPER" ){
- if(( iRc = xbase->ISUPPER( nChild1->GetStringResult(), bResult )) != XB_NO_ERROR ){
- iErrorStop = 390;
- throw iRc;
- }
- n->SetResult( bResult );
- } else if( sFunction == "LEN" ){
- if(( iRc = xbase->LEN( nChild1->GetStringResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 400;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "LOG" ){
- if(( iRc = xbase->LOG( nChild1->GetNumericResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 410;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "LTRIM" ){
- if(( iRc = xbase->LTRIM( nChild1->GetStringResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 420;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "LOWER" ){
- if(( iRc = xbase->LOWER( nChild1->GetStringResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 430;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "MONTH" ){
- xbDate d( (xbInt32) nChild1->GetNumericResult());
- if(( iRc = xbase->MONTH( d, dResult )) != XB_NO_ERROR ){
- iErrorStop = 440;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "RTRIM" ){
- if(( iRc = xbase->RTRIM( nChild1->GetStringResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 450;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "STOD" ){
- if(( iRc = xbase->STOD( nChild1->GetStringResult(), dtResult )) != XB_NO_ERROR ){
- iErrorStop = 460;
- throw iRc;
- }
- n->SetResult( dtResult );
- } else if( sFunction == "SPACE" ){
- if(( iRc = xbase->SPACE( (xbInt32) nChild1->GetNumericResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 470;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "SQRT" ){
- if(( iRc = xbase->SQRT( nChild1->GetNumericResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 480;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "STR" ){
- if(( iRc = xbase->STR( nChild1->GetNumericResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 490;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "TRIM" ){
- if(( iRc = xbase->TRIM( nChild1->GetStringResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 500;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "UPPER" ){
- if(( iRc = xbase->UPPER( nChild1->GetStringResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 510;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "VAL" ){
- if(( iRc = xbase->VAL( nChild1->GetStringResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 520;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "YEAR" ){
- xbDate d( (xbInt32) nChild1->GetNumericResult());
- if(( iRc = xbase->YEAR( d, dResult )) != XB_NO_ERROR ){
- iErrorStop = 530;
- throw iRc;
- }
- n->SetResult( dResult );
- } else {
- iErrorStop = 540;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- } else if( n->GetChildCnt() == 2 ){
- xbExpNode * nChild2;
- nChild1 = n->GetChild( 0 );
- nChild2 = n->GetChild( 1 );
-
- if( sFunction == "AT" ){
- if(( iRc = xbase->AT( nChild1->GetStringResult(), nChild2->GetStringResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 700;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "LEFT" ){
- if(( iRc = xbase->LEFT( nChild1->GetStringResult(), (xbUInt32) nChild2->GetNumericResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 710;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "MAX" ){
- if(( iRc = xbase->MAX( nChild1->GetNumericResult(), nChild2->GetNumericResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 720;
- throw iRc;
- }
- n->SetResult( dResult );
- } else if( sFunction == "MIN" ){
- if(( iRc = xbase->MIN( nChild1->GetNumericResult(), nChild2->GetNumericResult(), dResult )) != XB_NO_ERROR ){
- iErrorStop = 730;
- throw iRc;
- }
- n->SetResult( dResult );
- }
- else if( sFunction == "REPLICATE" ){
- if(( iRc = xbase->REPLICATE( nChild1->GetStringResult(), (xbUInt32) nChild2->GetNumericResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 800;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "RIGHT" ){
- if(( iRc = xbase->RIGHT( nChild1->GetStringResult(), (xbUInt32) nChild2->GetNumericResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 810;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "STR" ){
- if(( iRc = xbase->STR( nChild1->GetNumericResult(), (xbUInt32) nChild2->GetNumericResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 820;
- throw iRc;
- }
- n->SetResult( sResult );
- } else {
- iErrorStop = 830;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- } else if( n->GetChildCnt() == 3 ){
- xbExpNode * nChild2;
- xbExpNode * nChild3;
- nChild1 = n->GetChild( 0 );
- nChild2 = n->GetChild( 1 );
- nChild3 = n->GetChild( 2 );
-
- if( sFunction == "IIF" ){
- if(( iRc = xbase->IIF( nChild1->GetBoolResult(), nChild2->GetStringResult(), nChild3->GetStringResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 900;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "STR" ){
- if(( iRc = xbase->STR( nChild1->GetNumericResult(), (xbUInt32) nChild2->GetNumericResult(), (xbUInt32) nChild3->GetNumericResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 910;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "STRZERO" ){
- if(( iRc = xbase->STRZERO( nChild1->GetNumericResult(), (xbUInt32) nChild2->GetNumericResult(), (xbUInt32) nChild3->GetNumericResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 920;
- throw iRc;
- }
- n->SetResult( sResult );
- } else if( sFunction == "SUBSTR" ){
- if(( iRc = xbase->SUBSTR( nChild1->GetStringResult(), (xbUInt32) nChild2->GetNumericResult(), (xbUInt32) nChild3->GetNumericResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 930;
- throw iRc;
- }
- n->SetResult( sResult );
- } else {
- iErrorStop = 950;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- } else if( n->GetChildCnt() == 4 ){
- xbExpNode * nChild2;
- xbExpNode * nChild3;
- xbExpNode * nChild4;
- nChild1 = n->GetChild( 0 );
- nChild2 = n->GetChild( 1 );
- nChild3 = n->GetChild( 2 );
- nChild4 = n->GetChild( 3 );
-
- if( sFunction == "STR" ){
- if(( iRc = xbase->STR( nChild1->GetNumericResult(), (xbUInt32) nChild2->GetNumericResult(),
- (xbUInt32) nChild3->GetNumericResult(), nChild4->GetStringResult(), sResult )) != XB_NO_ERROR ){
- iErrorStop = 1000;
- throw iRc;
- }
- n->SetResult( sResult );
- } else {
- iErrorStop = 1010;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
-
- } else {
- iErrorStop = 2000;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::ProcessExpressionFunction() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- }
- return iRc;
-}
-/*************************************************************************/
-//! Process Expression Operator
-/*! This method processes an expression operator for a given node.
-*/
-
-xbInt16 xbExp::ProcessExpressionOperator( xbExpNode * n ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- xbExpNode * nChild1 = NULL;
- xbExpNode * nChild2 = NULL;
- xbString sOperator;
- xbString sWork1;
- xbString sWork2;
- xbDate dtWork1;
-
- xbString sMsg;
-
- try{
- n->GetNodeText( sOperator );
- nChild1 = n->GetChild( 0 );
- if( !n->IsUnaryOperator())
- nChild2 = n->GetChild( 1 );
-
- switch( n->GetReturnType()){
- case XB_EXP_CHAR:
- if( sOperator == "+" ){
- sWork1 = nChild1->GetStringResult();
- sWork1 += nChild2->GetStringResult();
- n->SetResult( sWork1 );
- } else if( sOperator == "-" ){
- sWork1 = nChild1->GetStringResult();
- sWork1.Rtrim();
- sWork1 += nChild2->GetStringResult();
- sWork1.PadRight( ' ', n->GetResultLen());
- n->SetResult( sWork1 );
- } else {
- iErrorStop = 100;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- break;
-
- case XB_EXP_NUMERIC:
- if( sOperator == "+" )
- n->SetResult( nChild1->GetNumericResult() + nChild2->GetNumericResult());
- else if( sOperator == "-" ){
- n->SetResult( nChild1->GetNumericResult() - nChild2->GetNumericResult());
-
- }
- else if( sOperator == "*" )
- n->SetResult( nChild1->GetNumericResult() * nChild2->GetNumericResult());
- else if( sOperator == "/" )
- n->SetResult( nChild1->GetNumericResult() / nChild2->GetNumericResult());
- else if( sOperator == "^" || sOperator == "**" )
- n->SetResult( pow( nChild1->GetNumericResult(), nChild2->GetNumericResult()));
- else if( sOperator == "+=" ){
- n->SetResult( nChild1->GetNumericResult() + nChild2->GetNumericResult());
- nChild1->SetResult( n->GetNumericResult() );
- }
- else if( sOperator == "-=" ){
- n->SetResult( nChild1->GetNumericResult() - nChild2->GetNumericResult());
- nChild1->SetResult( n->GetNumericResult() );
- }
- else if( sOperator == "*=" ){
- n->SetResult( nChild1->GetNumericResult() * nChild2->GetNumericResult());
- nChild1->SetResult( n->GetNumericResult() );
- }
- else if( sOperator == "/=" ){
- n->SetResult( nChild1->GetNumericResult() / nChild2->GetNumericResult());
- nChild1->SetResult( n->GetNumericResult() );
- } else {
- iErrorStop = 200;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- break;
-
-
- case XB_EXP_DATE:
- // if date values in the leaf nodes, convert to numeric for operator logic
-
- if( sOperator == "+" )
- n->SetResult( nChild1->GetNumericResult() + nChild2->GetNumericResult());
- else if( sOperator == "-" ){
- n->SetResult( nChild1->GetNumericResult() - nChild2->GetNumericResult());
- xbDate d( (xbInt32) n->GetNumericResult());
- }
- else if( sOperator == "+=" ){
- n->SetResult( nChild1->GetNumericResult() + nChild2->GetNumericResult());
- nChild1->SetResult( n->GetNumericResult() );
- }
- else if( sOperator == "-=" ){
- n->SetResult( nChild1->GetNumericResult() - nChild2->GetNumericResult());
- nChild1->SetResult( n->GetNumericResult() );
- } else {
- iErrorStop = 300;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- break;
-
- case XB_EXP_LOGICAL:
-
- if( !n->IsUnaryOperator() && (nChild1->GetReturnType() != nChild2->GetReturnType())){
- iErrorStop = 400;
- iRc = XB_INCOMPATIBLE_OPERANDS;
- throw iRc;
- }
-
- if( sOperator == ".AND." || sOperator == "AND" )
- n->SetResult((xbBool) (nChild1->GetBoolResult() && nChild2->GetBoolResult()) );
-
- else if( sOperator == ".OR." || sOperator == "OR" )
- n->SetResult((xbBool) (nChild1->GetBoolResult() || nChild2->GetBoolResult()) );
-
- else if( sOperator == ".NOT." || sOperator == "NOT" ){
- if( nChild1->GetBoolResult())
- n->SetResult((xbBool) xbFalse );
- else
- n->SetResult((xbBool) xbTrue );
- }
-
- else if( sOperator == ">" ){
-
- if( nChild1->GetReturnType() == XB_EXP_CHAR )
- n->SetResult((xbBool)(nChild1->GetStringResult() > nChild2->GetStringResult()));
-
- else if( nChild1->GetReturnType() == XB_EXP_NUMERIC )
- n->SetResult((xbBool)(nChild1->GetNumericResult() > nChild2->GetNumericResult()));
-
- else if( nChild1->GetReturnType() == XB_EXP_DATE ){
- xbDouble d1 = nChild1->GetNumericResult();
- xbDouble d2 = nChild2->GetNumericResult();
- if( d1 == XB_NULL_DATE ) d1 = 0;
- if( d2 == XB_NULL_DATE ) d2 = 0;
- n->SetResult((xbBool)( d1 > d2));
- // n->SetResult((xbBool)(nChild1->GetNumericResult() > nChild2->GetNumericResult()));
-
- } else {
- iErrorStop = 410;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
-
- else if( sOperator == ">=" ){
- if( nChild1->GetReturnType() == XB_EXP_CHAR )
- n->SetResult((xbBool)(nChild1->GetStringResult() >= nChild2->GetStringResult()));
-
- else if( nChild1->GetReturnType() == XB_EXP_NUMERIC )
- n->SetResult((xbBool)(nChild1->GetNumericResult() >= nChild2->GetNumericResult()));
-
- else if( nChild1->GetReturnType() == XB_EXP_DATE ){
- xbDouble d1 = nChild1->GetNumericResult();
- xbDouble d2 = nChild2->GetNumericResult();
- if( d1 == XB_NULL_DATE ) d1 = 0;
- if( d2 == XB_NULL_DATE ) d2 = 0;
- n->SetResult((xbBool)( d1 >= d2));
- //n->SetResult((xbBool)(nChild1->GetNumericResult() >= nChild2->GetNumericResult()));
-
- } else {
- iErrorStop = 420;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
-
- else if( sOperator == "<" ){
-
- if( nChild1->GetReturnType() == XB_EXP_CHAR ){
- n->SetResult((xbBool)( nChild1->GetStringResult() < nChild2->GetStringResult()));
-
- } else if( nChild1->GetReturnType() == XB_EXP_NUMERIC ){
- n->SetResult((xbBool)( nChild1->GetNumericResult() < nChild2->GetNumericResult()));
-
- } else if( nChild1->GetReturnType() == XB_EXP_DATE ){
- xbDouble d1 = nChild1->GetNumericResult();
- xbDouble d2 = nChild2->GetNumericResult();
- if( d1 == XB_NULL_DATE ) d1 = 0;
- if( d2 == XB_NULL_DATE ) d2 = 0;
-
- n->SetResult((xbBool)( d1 < d2));
-
- // std::cout << "xbexp() line 2567 [" << nChild1->GetNumericResult() << "][" << nChild2->GetNumericResult() << "]\n";
-
- } else {
- iErrorStop = 430;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
-
- else if( sOperator == "<=" ){
-
- if( nChild1->GetReturnType() == XB_EXP_CHAR )
- n->SetResult((xbBool)( nChild1->GetStringResult() <= nChild2->GetStringResult()));
-
- else if( nChild1->GetReturnType() == XB_EXP_NUMERIC )
- n->SetResult((xbBool)( nChild1->GetNumericResult() <= nChild2->GetNumericResult()));
-
- else if( nChild1->GetReturnType() == XB_EXP_DATE ){
- xbDouble d1 = nChild1->GetNumericResult();
- xbDouble d2 = nChild2->GetNumericResult();
- if( d1 == XB_NULL_DATE ) d1 = 0;
- if( d2 == XB_NULL_DATE ) d2 = 0;
- n->SetResult((xbBool)( d1 <= d2));
- // n->SetResult((xbBool)( nChild1->GetNumericResult() <= nChild2->GetNumericResult()));
-
- } else {
- iErrorStop = 440;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
-
- else if( sOperator == "<>" || sOperator == "#" || sOperator == "!=" ){
-
- if( nChild1->GetReturnType() == XB_EXP_CHAR )
- n->SetResult((xbBool)( nChild1->GetStringResult() != nChild2->GetStringResult()));
-
- else if( nChild1->GetReturnType() == XB_EXP_NUMERIC )
- n->SetResult((xbBool)( nChild1->GetNumericResult() != nChild2->GetNumericResult()));
-
- else if( nChild1->GetReturnType() == XB_EXP_DATE ){
- xbDouble d1 = nChild1->GetNumericResult();
- xbDouble d2 = nChild2->GetNumericResult();
- if( d1 == XB_NULL_DATE ) d1 = 0;
- if( d2 == XB_NULL_DATE ) d2 = 0;
- n->SetResult((xbBool)( d1 != d2));
- // n->SetResult((xbBool)( nChild1->GetNumericResult() != nChild2->GetNumericResult()));
-
- } else {
- iErrorStop = 450;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
- }
-
- else if( sOperator == "$" ){
- if( nChild1->GetReturnType() == XB_EXP_CHAR )
- if( nChild2->GetStringResult().Pos( nChild1->GetStringResult()) > 0 )
- n->SetResult((xbBool) xbTrue );
- else
- n->SetResult((xbBool) xbFalse );
- else {
- iErrorStop = 460;
- iRc = XB_INCOMPATIBLE_OPERANDS;
- throw iRc;
- }
- }
-
- else if( sOperator == "=" ){
-
- if( nChild1->GetReturnType() == XB_EXP_CHAR ){
- xbString sChld1 = nChild1->GetStringResult();
- xbString sChld2 = nChild2->GetStringResult();
- sChld1.Rtrim();
- sChld2.Rtrim();
- n->SetResult((xbBool)( sChld1 == sChld2 ));
-
- } else if( nChild1->GetReturnType() == XB_EXP_NUMERIC ){
- n->SetResult((xbBool)( nChild1->GetNumericResult() == nChild2->GetNumericResult()));
-
- } else if( nChild1->GetReturnType() == XB_EXP_DATE ){
- xbDouble d1 = nChild1->GetNumericResult();
- xbDouble d2 = nChild2->GetNumericResult();
- if( d1 == XB_NULL_DATE ) d1 = 0;
- if( d2 == XB_NULL_DATE ) d2 = 0;
- n->SetResult((xbBool)( d1 == d2));
- // n->SetResult((xbBool)( nChild1->GetNumericResult() == nChild2->GetNumericResult()));
-
- } else {
- iErrorStop = 470;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
-
-
- } else {
- iErrorStop = 500;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- }
-
- break;
-
- default:
- iErrorStop = 600;
- iRc = XB_PARSE_ERROR;
- throw iRc;
- // break;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbexp::ProcessExpressionOperator() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- }
- return iRc;
-}
-
-/*************************************************************************/
-}; // namespace
-#endif // XB_EXPRESSION_SUPPORT
-/*************************************************************************/
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbexpnode.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbexpnode.cpp
deleted file mode 100755
index d11e8cc..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbexpnode.cpp
+++ /dev/null
@@ -1,562 +0,0 @@
-/* xbexpnode.cpp
-
-XBase64 Software Library
-
-Copyright (c) 1997,2003,2014,2017,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 "xbase.h"
-
-#ifdef XB_EXPRESSION_SUPPORT
-
-namespace xb{
-/************************************************************************/
-//! @brief Constructor
-xbExpNode::xbExpNode(){
- sNodeText = "";
- cReturnType = 0;
- cNodeType = 0;
- dResult = 0;
- iFieldNo = 0;
- ulResultLen = 0;
- iWeight = 0;
- nParent = NULL;
- dbf = NULL;
-}
-
-/************************************************************************/
-//! @brief Constructor
-/*!
- \param sNodeText Node text.
- \param cReturnType Return type.
- \param cNodeType Node type.
-*/
-
-xbExpNode::xbExpNode( xbString &sNodeText, char cReturnType, char cNodeType ){
- this->sNodeText = sNodeText;
- this->cReturnType = cReturnType;
- this->cNodeType = cNodeType;
- dResult = 0;
- iFieldNo = 0;
- ulResultLen = 0;
- iWeight = 0;
- nParent = NULL;
- dbf = NULL;
-}
-
-/************************************************************************/
-//! @brief Constructor
-/*!
- \param sNodeText Node text.
- \param cNodeType Node type.
-*/
-xbExpNode::xbExpNode( xbString &sNodeText, char cNodeType ){
- this->sNodeText = sNodeText;
- this->cReturnType = 0x00;
- this->cNodeType = cNodeType;
- dResult = 0;
- iFieldNo = 0;
- ulResultLen = 0;
- iWeight = 0;
- nParent = NULL;
- dbf = NULL;
-}
-
-/************************************************************************/
-//! @brief Constructor
-/*!
- \param cNodeType Node type.
-*/
-xbExpNode::xbExpNode( char cNodeType ){
- this->cReturnType = 0x00;
- this->cNodeType = cNodeType;
- dResult = 0;
- iFieldNo = 0;
- ulResultLen = 0;
- iWeight = 0;
- nParent = NULL;
- dbf = NULL;
-}
-
-/************************************************************************/
-//! @brief Deconstructor
-xbExpNode::~xbExpNode(){
-
- xbExpNode * n;
- while( llChildren.GetNodeCnt() > 0 ){
- llChildren.RemoveFromFront( n );
- delete n;
- }
-}
-
-/************************************************************************/
-//! @brief Add child node to linked list.
-/*!
- \param n Pointer to node to add to linked list.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbExpNode::AddChild( xbExpNode *n ){
- n->SetParent( this );
- return llChildren.InsertAtEnd( n );
-}
-
-/************************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-
-//! @brief Dump Node.
-/*!
- \param iOption xbTrue - Print child info if they exist.<bt>
- xbFalse - Don't print child info.
- \returns void.
-*/
-void xbExpNode::DumpNode( xbInt16 iOption ) const {
- xbString sMsg;
- std::cout << "Me=[" << this << "] ";
- if( nParent )
- std::cout << "Par=[" << nParent << "] ";
-
- std::cout << "nTyp=[" << cNodeType << "] ";
- std::cout << "dTyp=[" << cReturnType << "] ";
- if( iWeight != 0 )
- std::cout << "W=[" << iWeight << "] ";
-
- if( cNodeType == XB_EXP_FIELD )
- std::cout << "FieldNo=[" << iFieldNo << "] ";
-
- std::cout << "Txt=[" << sNodeText << "] ";
- if( sResult != "" )
- std::cout << "sVal=[" << sResult << "] ";
-
- if( ulResultLen > 0 )
- std::cout << "Len=[" << ulResultLen << "] ";
- if( cReturnType == XB_EXP_DATE ){
- xbDate d( (xbInt32) dResult );
- std::cout << "dtVal=[" << d.Str() << "] ";
- }
-
- if( cReturnType == XB_EXP_DATE || cReturnType == XB_EXP_NUMERIC ){
- sMsg.Sprintf( "dVal=[%f]\n", dResult );
- std::cout << sMsg.Str();
- }
-
- if( cReturnType == XB_EXP_LOGICAL ){
- sMsg.Sprintf( "lVal=[%d]\n", (xbInt32) dResult );
- std::cout << sMsg.Str();
- }
-
- if( iOption ){
- xbLinkListNode<xbExpNode *> *lln = llChildren.GetHeadNode();
- xbExpNode *n;
- if( lln ){
- std::cout << " Children: ";
- while( lln ){
- n = lln->GetKey();
- std::cout << " [" << n << "]";
- lln = lln->GetNextNode();
- }
- std::cout << std::endl;
-
- lln = llChildren.GetHeadNode();
- while( lln ){
- n = lln->GetKey();
- n->DumpNode( iOption );
- lln = lln->GetNextNode();
- }
- }
- }
-
- std::cout << std::endl;
-}
-#endif
-
-/************************************************************************/
-//! @brief Get boolean result.
-/*!
- \returns Boolean result.
-*/
-
-xbBool xbExpNode::GetBoolResult() const {
- return (xbBool) dResult;
-}
-
-/************************************************************************/
-//! @brief Get pointer to child.
-/*!
- \param ulChildNo - Which child? 1,2 or3
- \returns Pointer to child node or null if none exists.
-*/
-xbExpNode *xbExpNode::GetChild( xbUInt32 ulChildNo ) const {
-
- xbLinkListNode<xbExpNode *> *lln = llChildren.GetNodeForNo( ulChildNo );
- if( lln )
- return lln->GetKey();
- else
- return 0x00;
-}
-/************************************************************************/
-//! @brief Get child count.
-/*!
- \returns Child count.
-*/
-xbUInt32 xbExpNode::GetChildCnt() const{
- return llChildren.GetNodeCnt();
-}
-
-/************************************************************************/
-//! @brief Get the current child number for this node.
-/*!
- \returns Child number: 1, 2 or 3.
-*/
-
-xbUInt32 xbExpNode::GetChildNo() const {
-
- if( !nParent )
- return 0;
-
- for( xbUInt32 i = 0; i < nParent->GetChildCnt(); i++ ){
- if( this == nParent->GetChild( i )){
- // std::cout << "get child no [" << this << "][" << nParent->GetChild(i) << "]\n";
- return i;
- }
- }
- return 0;
-}
-
-/************************************************************************/
-//! @brief Get the dbf pointer.
-/*!
- \returns Pointer to dbf.
-*/
-xbDbf *xbExpNode::GetDbf() const {
- return dbf;
-}
-/************************************************************************/
-//! @brief Get the field number.
-/*!
- \returns Field number for field node.
-*/
-
-xbInt16 xbExpNode::GetFieldNo() const {
- return iFieldNo;
-}
-
-/*************************************************************************/
-//! @brief Get the first node.
-/*!
- \returns Pointer to left most child node or *this if childless.
-*/
-
-xbExpNode *xbExpNode::GetFirstNode() {
- xbExpNode *n = this;
- while( n && n->GetChildCnt() > 0 )
- n = n->GetChild(0);
- return n;
-}
-
-/*************************************************************************/
-//! @brief Get the next node.
-/*!
- \returns Pointer to right node or parent if right node does not exist.
-*/
-
-xbExpNode *xbExpNode::GetNextNode() const {
-
- if( HasRightSibling())
- return GetRightSibling()->GetFirstNode();
- else
- return nParent;
-}
-
-/************************************************************************/
-//! @brief Get the node text.
-/*!
- \param sOutText Output string containing node text.
- \returns void
-*/
-
-void xbExpNode::GetNodeText( xbString &sOutText ) const{
- sOutText = sNodeText;
-}
-
-/************************************************************************/
-//! @brief Get the node type.
-/*!
- \returns Node type.
-*/
-
-char xbExpNode::GetNodeType() const{
- return cNodeType;
-}
-
-/************************************************************************/
-//! @brief Get numeric result.
-/*!
- \returns Numeric result.
-*/
-
-xbDouble xbExpNode::GetNumericResult() const {
- return dResult;
-}
-
-/************************************************************************/
-//! @brief Get parent.
-/*!
- \returns Pointer to parent node.
-*/
-
-xbExpNode *xbExpNode::GetParent() const{
- return nParent;
-}
-
-/************************************************************************/
-//! @brief Get result length.
-/*!
- \returns Result length.
-*/
-xbUInt32 xbExpNode::GetResultLen() const{
- return ulResultLen;
-}
-/************************************************************************/
-//! @brief Get result type.
-/*!
- \returns Result type.
-*/
-char xbExpNode::GetReturnType() const{
- return cReturnType;
-}
-
-/*************************************************************************/
-//! @brief Get right sibling.
-/*!
- \returns Pointer to right sibling.
-*/
-
-xbExpNode *xbExpNode::GetRightSibling() const {
-
- xbExpNode * nParent;
- if(( nParent = GetParent()) == NULL )
- return NULL;
-
- if( nParent->GetChildCnt() <= 0 )
- return NULL;
-
- xbUInt32 ulChildNo = GetChildNo();
-
- if( ulChildNo < (nParent->GetChildCnt() - 1))
- return nParent->GetChild( ulChildNo + 1 );
- else
- return NULL;
-}
-/************************************************************************/
-//! @brief Get string result.
-/*!
- \returns String result.
-*/
-xbString &xbExpNode::GetStringResult(){
- return sResult;
-}
-/************************************************************************/
-//! @brief Get node weight.
-/*!
- Each node is assigned a weight used internally to detmerine processing sequence.
- \returns Node weight.
-*/
-
-xbInt16 xbExpNode::GetWeight() const {
- return iWeight;
-}
-
-/*************************************************************************/
-//! @brief Determine if node has a right sibling.
-/*!
- \returns xbTrue - Node has right sibling.<br>
- xbFalse - Node has no right sibling.
-*/
-
-xbBool xbExpNode::HasRightSibling() const {
-
- // std::cout << "in HasRightSibling [" << sNodeText << "]\n";
-
- if( nParent == NULL )
- return xbFalse;
-
- xbUInt32 ulChildNo = GetChildNo();
-
- if( ulChildNo < (nParent->GetChildCnt() - 1)){
- // std::cout << "Has Right Sibling = " << iChildNo << "] of [" << nParent->GetChildCnt() << "]\n";
- return xbTrue;
-}
- else
- return xbFalse;
-}
-
-
-/*************************************************************************/
-//! @brief Determine if node is an operator.
-/*!
- \returns xbTrue - Node is an operator.<br>
- xbFalse - Node is not an operator.
-*/
-
-xbBool xbExpNode::IsOperator() const {
-
- if( cNodeType == XB_EXP_OPERATOR )
- return xbTrue;
- else
- return xbFalse;
-}
-
-/*************************************************************************/
-//! @brief Determine if node is a unary operator.
-/*!
- \returns xbTrue - Node is a unary operator.<br>
- xbFalse - Node is not a unary operator.
-*/
-xbBool xbExpNode::IsUnaryOperator() const {
-
- if( cNodeType == XB_EXP_PRE_OPERATOR || cNodeType == XB_EXP_POST_OPERATOR )
- return xbTrue;
- else if( cNodeType == XB_EXP_OPERATOR && (sNodeText == ".NOT." || sNodeText == "NOT" ))
- return xbTrue;
- else
- return xbFalse;
-}
-/************************************************************************/
-//! @brief Remove last child from node.
-/*!
- \returns void.
-*/
-
-void xbExpNode::RemoveLastChild(){
- xbExpNode *n;
- llChildren.RemoveFromEnd( n );
-}
-
-/************************************************************************/
-//! @brief Set dbf info on node.
-/*!
- \param dbf Pointer to dbf.
- \param iFieldNo Field number of field.
- \returns void.
-*/
-void xbExpNode::SetDbfInfo( xbDbf *dbf, xbInt16 iFieldNo ){
- this->dbf = dbf;
- this->iFieldNo = iFieldNo;
-}
-
-/************************************************************************/
-//! @brief Set dbf info on node.
-/*!
- \param dbf Pointer to dbf.
- \returns void.
-*/
-void xbExpNode::SetDbfInfo( xbDbf *dbf ){
- this->dbf = dbf;
-}
-/************************************************************************/
-//! @brief Set node type.
-/*!
- \param cNodeType Node type.
- \returns void.
-*/
-void xbExpNode::SetNodeType( char cNodeType ){
- this->cNodeType = cNodeType;
-}
-
-/************************************************************************/
-//! @brief Set node text.
-/*!
- \param sNodeText Node text.
- \returns void.
-*/
-void xbExpNode::SetNodeText( xbString & sNodeText ){
- this->sNodeText = sNodeText;
-}
-
-/************************************************************************/
-//! @brief Set parent.
-/*!
- \param n Pointer to parent.
- \returns void.
-*/
-void xbExpNode::SetParent( xbExpNode *n ){
- this->nParent = n;
-}
-
-/************************************************************************/
-//! @brief Set date result.
-/*!
- \param dtResult Date result.
- \returns void.
-*/
-void xbExpNode::SetResult( xbDate &dtResult ){
- this->dResult = dtResult.JulianDays();
-}
-
-/************************************************************************/
-//! @brief Set boolean result.
-/*!
- \param bResult Boolean result.
- \returns void.
-*/
-void xbExpNode::SetResult( xbBool bResult ){
- this->dResult = bResult;
-}
-/************************************************************************/
-//! @brief Set numeric result.
-/*!
- \param dResult Double numeric result.
- \returns void.
-*/
-void xbExpNode::SetResult( xbDouble dResult ){
- this->dResult = dResult;
-}
-/************************************************************************/
-//! @brief Set string result.
-/*!
- \param sResult String result.
- \returns void.
-*/
-void xbExpNode::SetResult( xbString &sResult ){
- this->sResult = sResult;
-}
-/************************************************************************/
-//! @brief Set result length.
-/*!
- \param ulResultLen Set result length.
- \returns void.
-*/
-void xbExpNode::SetResultLen( xbUInt32 ulResultLen ){
- this->ulResultLen = ulResultLen;
-}
-/************************************************************************/
-//! @brief Set return type.
-/*!
- \param cReturnType Return Type.
- \returns void.
-*/
-void xbExpNode::SetReturnType( char cReturnType ){
- this->cReturnType = cReturnType;
-}
-/************************************************************************/
-//! @brief Set weight.
-/*!
- \param iWeight Weight to set this node at.
- \returns void.
-*/
-void xbExpNode::SetWeight( xbInt16 iWeight ){
- this->iWeight = iWeight;
-}
-/*************************************************************************/
-}; // namespace
-#endif // XB_EXPRESSION_SUPPORT
-/*************************************************************************/
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbfields.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbfields.cpp
deleted file mode 100755
index 85ac145..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbfields.cpp
+++ /dev/null
@@ -1,1189 +0,0 @@
-/* xbfields.cpp
-
-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 "xbase.h"
-
-namespace xb{
-
-/************************************************************************/
-//! @brief Get xbDouble field for field name.
-/*!
- \param sFieldName Name of field to retrieve.
- \param dFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetDoubleField( const xbString &sFieldName, xbDouble &dFieldValue ) const {
- return GetDoubleField( GetFieldNo( sFieldName ), dFieldValue );
-}
-
-/************************************************************************/
-//! @brief Get xbDouble field for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param dFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetDoubleField( xbInt16 iFieldNo, xbDouble &dFieldValue ) const {
- xbInt16 iRc = XB_NO_ERROR;
- char buf[21];
- memset( buf, 0x00, 21 );
- if(( iRc = GetRawField( iFieldNo, buf, 21, 0 )) >= XB_NO_ERROR ){
- dFieldValue = strtod( buf, NULL );
- return XB_NO_ERROR;
- } else
- return iRc;
-}
-/************************************************************************/
-//! @brief Get xbDouble field for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param dFieldValue Output field value.
- \param iRecBufSw 0 - Record buffer with any updates.<br>1 - Record buffer with original data.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetDoubleField( xbInt16 iFieldNo, xbDouble &dFieldValue, xbInt16 iRecBufSw ) const {
- xbInt16 iRc = XB_NO_ERROR;
- char buf[21];
- memset( buf, 0x00, 21 );
- if(( iRc = GetRawField( iFieldNo, buf, 21, iRecBufSw )) >= XB_NO_ERROR ){
- dFieldValue = strtod( buf, NULL );
- return XB_NO_ERROR;
- } else
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Get xbDate field for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param dtFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetDateField( xbInt16 iFieldNo, xbDate &dtFieldValue ) const{
- xbString s;
- xbInt16 iRc;
- if(( iRc = GetField( iFieldNo, s )) != XB_NO_ERROR )
- return iRc;
- return dtFieldValue.Set( s );
- // return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Get xbDate field for field name.
-/*!
- \param sFieldName Name of field to retrieve.
- \param dtFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetDateField( const xbString &sFieldName, xbDate &dtFieldValue ) const{
- xbString s;
- xbInt16 iRc;
- if(( iRc = GetField( sFieldName, s )) != XB_NO_ERROR )
- return iRc;
- return dtFieldValue.Set( s );
- // return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Get xbString field for field name.
-/*!
- \param sFieldName Name of field to retrieve
- \param sFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetField( const xbString &sFieldName, xbString &sFieldValue ) const{
- return GetField( GetFieldNo( sFieldName ), sFieldValue, 0 );
-}
-/************************************************************************/
-//! @brief Get field data for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param sFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetField( xbInt16 iFieldNo, xbString &sFieldValue ) const{
- return GetField( iFieldNo, sFieldValue, 0 );
-}
-/************************************************************************/
-//! @brief Get field data for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param sFieldValue Output field value.
- \param iRecBufSw 0 - Record buffer with any updates.<br>1 - Record buffer with original data.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetField( xbInt16 iFieldNo, xbString &sFieldValue, xbInt16 iRecBufSw) const
-{
- xbUInt32 iLen;
- if( iFieldNo < 0 || iFieldNo >= iNoOfFields ) {
- sFieldValue = "";
- return XB_INVALID_FIELD_NO;
- }
- iLen = SchemaPtr[iFieldNo].cFieldLen;
- sFieldValue = "";
- if( iRecBufSw )
- sFieldValue.Append( (char *) SchemaPtr[iFieldNo].pAddress2, iLen ); // original record buffer
- else
- sFieldValue.Append( (char *) SchemaPtr[iFieldNo].pAddress, iLen ); // current record buffer
- return XB_NO_ERROR;
-}
-
-
-/************************************************************************/
-//! @brief Get decimal for field name.
-/*!
- This routine retreives a field's decimal length.
- \param sFieldName Name of field to retrieve
- \param iFieldDecimal Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetFieldDecimal( const xbString &sFieldName, xbInt16 & iFieldDecimal ) const {
- return GetFieldDecimal( GetFieldNo( sFieldName ), iFieldDecimal );
-}
-
-
-/************************************************************************/
-//! @brief Get decimal for field number.
-/*!
- This routine retreives a field's decimal length.
- \param iFieldNo Number of field to retrieve
- \param iFieldDecimal Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetFieldDecimal( xbInt16 iFieldNo, xbInt16 & iFieldDecimal ) const {
-
- if( iFieldNo < 0 || iFieldNo >= iNoOfFields ) {
- return XB_INVALID_FIELD_NO;
- }
- iFieldDecimal = SchemaPtr[iFieldNo].cNoOfDecs;
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Get field length for field name.
-/*!
-
- This function retrieves a field's length.
-
- \param sFieldName Name of field to retrieve
- \param iFieldLen Output field length value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetFieldLen( const xbString &sFieldName, xbInt16 &iFieldLen ) const {
- return GetFieldLen( GetFieldNo( sFieldName ), iFieldLen );
-}
-
-
-/************************************************************************/
-//! @brief Get field length for field number.
-/*!
- This function retrieves a field's length.
-
- \param iFieldNo Name of field to retrieve
- \param iFieldLen Output field length value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetFieldLen( xbInt16 iFieldNo, xbInt16 &iFieldLen ) const {
- if( iFieldNo >= 0 && iFieldNo < iNoOfFields ){
- iFieldLen = SchemaPtr[iFieldNo].cFieldLen;
- return XB_NO_ERROR;
- } else
- return XB_INVALID_FIELD_NO;
-}
-
-/************************************************************************/
-//! @brief Get the field number for name.
-/*! Returns the field number for the named field.
-
- All field get/put methods require either a field number or field name as
- one of the parameters. Using the methods that take the field numbers will
- yield slightly better performance because the methods that take a name, have
- to look up the number.
-
- \param sFieldName Name of field.
- \param iFieldNo Output field number for the given name.
- \returns Number of field named fldName.
-*/
-
-xbInt16 xbDbf::GetFieldNo( const xbString & sFieldName, xbInt16 &iFieldNo ) const
-{
- int i;
-
- if( sFieldName.Len() > 10 )
- return XB_INVALID_FIELD_NAME;
-
- for( i = 0; i < iNoOfFields; i++ ){
- if( sFieldName == SchemaPtr[i].cFieldName ){
- iFieldNo = i;
- return XB_NO_ERROR;
- }
- }
- return XB_INVALID_FIELD_NAME;
-}
-
-/************************************************************************/
-//! Get field ID number for a given field name.
-/*! Returns the field number for the named field.
-
- \param sFieldName Name of field.
- \returns Number of field or XB_INVALID_FIELD_NAME.
-*/
-
-xbInt16 xbDbf::GetFieldNo( const xbString &sFieldName ) const {
- int i;
-
- if( sFieldName.Len() > 10 )
- return XB_INVALID_FIELD_NAME;
-
- for( i = 0; i < iNoOfFields; i++ ){
- if( sFieldName == SchemaPtr[i].cFieldName )
- return i;
- }
- return XB_INVALID_FIELD_NAME;
-}
-
-/************************************************************************/
-//! Get field type for field number.
-/*!
- \param iFieldNo Field number.
- \param cFieldType Output field type.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetFieldType( xbInt16 iFieldNo, char & cFieldType ) const{
-
- if( iFieldNo >= 0 && iFieldNo < iNoOfFields ){
- cFieldType = SchemaPtr[iFieldNo].cType;
- return XB_NO_ERROR;
- }
- else
- return XB_INVALID_FIELD_NO;
-}
-
-/************************************************************************/
-//! Get field type for field name.
-/*!
- \param sFieldName Field name.
- \param cFieldType Output field type.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetFieldType( const xbString &sFieldName, char & cFieldType ) const{
- return( GetFieldType( GetFieldNo( sFieldName ), cFieldType));
-}
-
-/************************************************************************/
-//! @brief Returns the name of the specified field.
-/*! Returns a pointer to the name for the field specified by iFieldNo.
-
- \param iFieldNo Number of field.
- \param sFieldName Output variable containing the field name.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetFieldName( xbInt16 iFieldNo, xbString &sFieldName ) const{
- if( iFieldNo >= 0 && iFieldNo < iNoOfFields ){
- sFieldName = SchemaPtr[iFieldNo].cFieldName;
- return XB_NO_ERROR;
- }
- else
- return XB_INVALID_FIELD_NO;
-}
-
-/************************************************************************/
-//! @brief Get xbFloat field for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param fFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetFloatField( xbInt16 iFieldNo, xbFloat & fFieldValue ) const {
-
- char cFieldType;
- xbInt16 rc = GetFieldType( iFieldNo, cFieldType );
- if( rc < 0 )
- return rc;
-
- if( cFieldType != 'N' && cFieldType != 'F' )
- return XB_INVALID_FIELD_TYPE;
-
- xbString sTemp;
- rc = GetField( iFieldNo, sTemp, 0 );
- if( rc < 0 )
- return rc;
-
- fFieldValue = (xbFloat) atof( sTemp.Str());
- return XB_NO_ERROR;
-}
-
-
-/************************************************************************/
-//! @brief Get xbFloat field for field name.
-/*!
- \param sFieldName Number of field to retrieve.
- \param fFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetFloatField( const xbString & sFieldName, xbFloat & fFieldValue ) const {
- return GetFloatField( GetFieldNo(sFieldName ), fFieldValue );
-}
-
-/************************************************************************/
-//! @brief Get logical field for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param sFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetLogicalField( xbInt16 iFieldNo, xbString &sFieldValue ) const {
-
- char cFieldType;
- xbInt16 iRc = GetFieldType( iFieldNo, cFieldType );
- if( iRc < 0 )
- return iRc;
- else if( cFieldType != 'L' )
- return XB_INVALID_FIELD_TYPE;
-
- if(( iRc = GetField( iFieldNo, sFieldValue )) < XB_NO_ERROR )
- return iRc;
- else
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Get logical field for field name.
-/*!
- \param sFieldName Name of field to retrieve.
- \param sFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetLogicalField( const xbString &sFieldName, xbString &sFieldValue ) const {
- return GetLogicalField( GetFieldNo( sFieldName ), sFieldValue );
-}
-
-
-/************************************************************************/
-//! @brief Get logical field for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param bFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetLogicalField( xbInt16 iFieldNo, xbBool &bFieldValue ) const {
- return GetLogicalField( iFieldNo, bFieldValue, 0 );
-}
-
-/************************************************************************/
-//! @brief Get logical field for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param bFieldValue Output field value.
- \param iRecBufSw 0 - Record buffer with any updates.<br>1 - Record buffer with original data.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetLogicalField( xbInt16 iFieldNo, xbBool &bFieldValue, xbInt16 iRecBufSw ) const {
-
- char cFieldType;
- xbInt16 iRc = GetFieldType( iFieldNo, cFieldType );
- if((iRc = GetFieldType( iFieldNo, cFieldType )) != XB_NO_ERROR )
- return iRc;
-
- if( cFieldType != 'L' )
- return XB_INVALID_FIELD_TYPE;
-
- xbString sFieldValue;
- if(( iRc = GetField( iFieldNo, sFieldValue, iRecBufSw )) < XB_NO_ERROR )
- return iRc;
-
- if( sFieldValue == 'T' || sFieldValue == 't' || sFieldValue == 'Y' || sFieldValue == 'y' )
- bFieldValue = xbTrue;
- else
- bFieldValue = xbFalse;
-
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Get logical field for field name.
-/*!
- \param sFieldName Name of field to retrieve.
- \param bFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetLogicalField( const xbString &sFieldName, xbBool &bFieldValue ) const {
- return GetLogicalField( GetFieldNo( sFieldName ), bFieldValue );
-}
-/************************************************************************/
-//! @brief Get long field for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param lFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetLongField( xbInt16 iFieldNo, xbInt32 & lFieldValue ) const {
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- char cFieldType;
- xbString sTemp;
-
- try{
-
- if(( iRc = GetFieldType( iFieldNo, cFieldType )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- if( cFieldType != 'N' && cFieldType != 'F' && cFieldType != 'M' ){
- iErrorStop = 110;
- iRc = XB_INVALID_FIELD_TYPE;
- throw iRc;
- }
-
- if(( iRc = GetField( iFieldNo, sTemp, 0 )) < 0 ){
- iErrorStop = 120;
- throw iRc;
- }
- sTemp.Trim();
-
- if( !sTemp.ValidNumericValue() ){
- iErrorStop = 130;
- iRc = XB_INVALID_DATA;
- throw iRc;
- }
-
- if( sTemp.Pos( '.' ) > 0){
- iErrorStop = 140;
- iRc = XB_INVALID_DATA;
- throw iRc;
- }
-
- lFieldValue = atol( sTemp.Str());
- }
-
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbDbf::GetLongField() Exception Caught. Error Stop = [%d] rc = [%d] [%s]", iErrorStop, iRc, sTemp.Str() );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
-
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-#ifdef XB_MEMO_SUPPORT
-//! @brief Get memo field for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param sMemoValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetMemoField( xbInt16 iFieldNo, xbString &sMemoValue ){
- return Memo->GetMemoField( iFieldNo, sMemoValue );
-}
-/************************************************************************/
-//! @brief Get memo field for field name.
-/*!
-
- \param sFieldName Name of field to retrieve.
- \param sMemoValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetMemoField( const xbString & sFieldName, xbString & sMemoValue ){
- return Memo->GetMemoField( GetFieldNo( sFieldName ), sMemoValue );
-}
-
-/************************************************************************/
-//! @brief Get the memo field count for this table.
-/*!
- \returns Returns the number of memo fields in the table,
-*/
-xbInt16 xbDbf::GetMemoFieldCnt() const {
- return iMemoFieldCnt;
-}
-/************************************************************************/
-//! @brief Get memo field length for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param ulMemoFieldLen Output memo field value length.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetMemoFieldLen( xbInt16 iFieldNo, xbUInt32 & ulMemoFieldLen ){
- return Memo->GetMemoFieldLen( iFieldNo, ulMemoFieldLen );
-}
-/************************************************************************/
-//! @brief Get memo field length for field name.
-/*!
- \param sFieldName Name of field to retrieve.
- \param ulMemoFieldLen Output memo field value length.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetMemoFieldLen( const xbString &sFieldName, xbUInt32 &ulMemoFieldLen ){
- return Memo->GetMemoFieldLen( GetFieldNo( sFieldName ), ulMemoFieldLen );
-}
-
-#endif // XB_MEMO_SUPPORT
-
-/************************************************************************/
-//! @brief Get field null status
-/*!
- \param iFieldNo Number of field to retrieve.
- \param bIsNull Output field value. If field is all spaces on record buffer, returns true.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetNullSts( xbInt16 iFieldNo, xbBool &bIsNull ) const {
- return GetNullSts( iFieldNo, bIsNull, 0 );
-}
-
-/************************************************************************/
-//! @brief Get field null status
-/*!
- \param iFieldName Field Name of field to retrieve.
- \param bIsNull Output field value. If field is all spaces on record buffer, returns true.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetNullSts( const xbString &sFieldName, xbBool &bIsNull ) const {
- return GetNullSts( GetFieldNo( sFieldName ), bIsNull, 0 );
-}
-
-/************************************************************************/
-//! @brief Get field null status
-/*!
- \param iFieldNo Number of field to retrieve.
- \param bIsNull Output field value. If field is all spaces on record buffer, returns true.
- \param iRecBufSw 0 - Record buffer with any updates.<br>1 - Record buffer with original data.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetNullSts( xbInt16 iFieldNo, xbBool &bIsNull, xbInt16 iRecBufSw ) const
-{
- if( iFieldNo < 0 || iFieldNo >= iNoOfFields ) {
- return XB_INVALID_FIELD_NO;
- }
- bIsNull = xbTrue;
- char *p;
- if( iRecBufSw )
- p = (char *) SchemaPtr[iFieldNo].pAddress2;
- else
- p = (char *) SchemaPtr[iFieldNo].pAddress;
-
- xbUInt32 ulLen = SchemaPtr[iFieldNo].cFieldLen;
- xbUInt32 ul = 0;
-
- while( ul < ulLen && bIsNull ){
- if( *p++ != ' ' )
- bIsNull = xbFalse;
- else
- ul++;
- }
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Get unsigned long field for field number.
-/*!
- \param iFieldNo Number of field to retrieve.
- \param ulFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::GetULongField( xbInt16 iFieldNo, xbUInt32 & ulFieldValue ) const {
-
- xbInt16 rc = 0;
- xbInt16 iErrorStop = 0;
- char cFieldType;
-
- try{
-
- if(( rc = GetFieldType( iFieldNo, cFieldType )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if( cFieldType != 'N' && cFieldType != 'F' && cFieldType != 'M' ){
- iErrorStop = 110;
- rc = XB_INVALID_FIELD_TYPE;
- throw rc;
- }
- xbString sTemp;
- if(( rc = GetField( iFieldNo, sTemp, 0 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- sTemp.Trim();
- if( !sTemp.ValidNumericValue() || ((int) sTemp.Pos( '.' ) > 0)){
- iErrorStop = 130;
- rc = XB_INVALID_DATA;
- throw rc;
- }
- ulFieldValue = strtoul( sTemp.Str(), NULL, 10 );
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbDbf::GetULongField() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Get long field for field name.
-/*!
- \param sFieldName Number of field to retrieve.
- \param lFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetLongField( const xbString &sFieldName, xbInt32 &lFieldValue ) const {
- return GetLongField( GetFieldNo( sFieldName ), lFieldValue );
-}
-
-/************************************************************************/
-//! @brief Get unsigned long field for field name.
-/*!
- \param sFieldName Number of field to retrieve.
- \param ulFieldValue Output field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::GetULongField( const xbString &sFieldName, xbUInt32 &ulFieldValue ) const {
- return GetULongField( GetFieldNo( sFieldName ), ulFieldValue );
-}
-
-/************************************************************************/
-//! @brief Get raw field data for field number.
-/*!
-
- This is a protected method, used by other methods. This method would be
- subject to buffer overflows if made public.
-
- \param iFieldNo Number of field to retrieve.
- \param cBuf Pointer to buffer area provided by calling application program.
- \param ulBufSize Size of data to copy
- \param iRecBufSw 0 - Record buffer with any updates.<br>1 - Record buffer with original data.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-
-xbInt16 xbDbf::GetRawField( xbInt16 iFieldNo, char *cBuf, xbUInt32 ulBufSize, xbInt16 iRecBufSw ) const
-{
- if( iFieldNo < 0 || iFieldNo >= iNoOfFields ) {
- return XB_INVALID_FIELD_NO;
- }
-
- size_t stCopySize;
- if( ulBufSize > (size_t) (SchemaPtr[iFieldNo].cFieldLen ))
- stCopySize = (size_t) (SchemaPtr[iFieldNo].cFieldLen );
- else
- stCopySize = ulBufSize - 1;
-
- if( iRecBufSw )
- memcpy( cBuf, SchemaPtr[iFieldNo].pAddress2, stCopySize );
- else
- memcpy( cBuf, SchemaPtr[iFieldNo].pAddress, stCopySize );
-
- cBuf[stCopySize] = 0x00;
- return XB_NO_ERROR;
-}
-
-
-/************************************************************************/
-//! @brief Put double field for field name.
-/*!
- \param sFieldName Name of field to update.
- \param dFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::PutDoubleField( const xbString &sFieldName, xbDouble dFieldValue ){
- return PutDoubleField( GetFieldNo( sFieldName ), dFieldValue );
-}
-
-/************************************************************************/
-//! @brief Put double field for field number.
-/*!
- \param iFieldNo Number of field to update.
- \param dFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::PutDoubleField( xbInt16 iFieldNo, xbDouble dFieldValue ){
-
- xbInt16 rc;
- xbString sDoubleFmt;
- xbString sDoubleFmt2;
- xbString sDoubleVal;
- xbInt16 iFieldLen;
- xbInt16 iNoOfDecs;
-
- if(( rc = GetFieldDecimal( iFieldNo, iNoOfDecs )) != XB_NO_ERROR )
- return rc;
-
- if(( rc = GetFieldLen( iFieldNo, iFieldLen )) != XB_NO_ERROR )
- return rc;
-
- sDoubleFmt.Sprintf( "%d.%df", iFieldLen, iNoOfDecs );
- sDoubleFmt2 = "%-";
- sDoubleFmt2 += sDoubleFmt;
- sDoubleVal.Sprintf( sDoubleFmt2.Str(), dFieldValue );
- sDoubleVal.Rtrim();
- return PutField( iFieldNo, sDoubleVal );
-}
-
-/************************************************************************/
-//! @brief Put date field for field name.
-/*!
- \param sFieldName Name of field to update.
- \param dtFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::PutDateField(const xbString &sFieldName, const xbDate &dtFieldValue ){
- return PutField( GetFieldNo( sFieldName ), dtFieldValue.Str() );
-}
-
-/************************************************************************/
-//! @brief Put date field for field number.
-/*!
- \param iFieldNo Number of field to update.
- \param dtFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::PutDateField( xbInt16 iFieldNo, const xbDate &dtFieldValue ){
- return PutField( iFieldNo, dtFieldValue.Str() );
-}
-
-/************************************************************************/
-//! @brief Put field for field name.
-/*!
- \param sFieldName Name of field to update.
- \param sFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::PutField(const xbString &sFieldName, const xbString &sFieldValue ) {
- return PutField( GetFieldNo( sFieldName ), sFieldValue );
-}
-/************************************************************************/
-//! @brief Put field for field number.
-/*!
- \param iFieldNo Number of field to update.
- \param sFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::PutField( xbInt16 iFieldNo, const xbString &sFieldValue ) {
- xbInt16 iLen;
- xbInt16 iDecPos; /* Decimal Position */
- char * startpos;
- char * tp; /* Target Pointer */
-
- if( iFieldNo < 0 || iFieldNo >= iNoOfFields )
- return XB_INVALID_FIELD_NO;
-
- if( SchemaPtr[iFieldNo].cType == 'L' && !sFieldValue.ValidLogicalValue())
- return XB_INVALID_DATA;
-
- else if( SchemaPtr[iFieldNo].cType == 'D' ){
- xbDate d;
- if( !d.DateIsValid( sFieldValue ))
- return XB_INVALID_DATA;
- iLen = 8;
- }
- else
- {
- iLen = (xbInt16) sFieldValue.Len();
- if( SchemaPtr[iFieldNo].cType == 'F' || SchemaPtr[iFieldNo].cType == 'N' || SchemaPtr[iFieldNo].cType == 'M' ){
- if( !sFieldValue.ValidNumericValue()) {
- return XB_INVALID_DATA;
- }
- else {
- iDecPos = (xbInt16) sFieldValue.Pos( "." ); // 0 is no decimal
- int mlod; // max no of digits left of decimal point digit count
-
-
- if( SchemaPtr[iFieldNo].cNoOfDecs > 0 )
- mlod = SchemaPtr[iFieldNo].cFieldLen - SchemaPtr[iFieldNo].cNoOfDecs - 1;
- else
- mlod = iLen;
-
- if( iDecPos == 0 ){ // no decimal in incoming data
-
- // check digits to the left of the decimal
- if( SchemaPtr[iFieldNo].cNoOfDecs > 0 && iLen > mlod ) /* no decimal in incoming data */
- return XB_INVALID_DATA;
-
- else if( SchemaPtr[iFieldNo].cNoOfDecs == 0 && iLen > SchemaPtr[iFieldNo].cFieldLen )
- return XB_INVALID_DATA;
-
- }
- else // decimal in incoming data
- {
- if( (iDecPos-1) > mlod ) // too many digits to the left of dec in incoming data
- return XB_INVALID_DATA;
-
- // check digits to the right of the decimal
- else if((iLen - iDecPos) > SchemaPtr[iFieldNo].cNoOfDecs )
- return XB_INVALID_DATA;
- }
- }
- }
- }
-
- // do all field edits before this point
- if( iDbfStatus != XB_UPDATED ){
- iDbfStatus = XB_UPDATED;
- memcpy( RecBuf2, RecBuf, uiRecordLen ); // save the original record bufer before making updates
- }
-
- memset( SchemaPtr[iFieldNo].pAddress, 0x20, SchemaPtr[iFieldNo].cFieldLen );
-
- if( iLen > SchemaPtr[iFieldNo].cFieldLen )
- iLen = SchemaPtr[iFieldNo].cFieldLen;
-
- if( SchemaPtr[iFieldNo].cType == 'F' || SchemaPtr[iFieldNo].cType == 'N'
- || SchemaPtr[iFieldNo].cType == 'M') {
-
- xbInt16 iDecPos = (xbInt16) sFieldValue.Pos( "." );
- if( iDecPos == 0 ){
- iLen = (xbInt16) sFieldValue.Len();
- iDecPos = 0;
- }
- else{
- iLen = iDecPos - 1;
- }
-
- if( SchemaPtr[iFieldNo].cNoOfDecs > 0 ){
- tp = SchemaPtr[iFieldNo].pAddress;
- tp += SchemaPtr[iFieldNo].cFieldLen - SchemaPtr[iFieldNo].cNoOfDecs - 1;
- *tp++ = '.';
-
- if( iDecPos == 0 ){
- for( xbInt32 i = 0; i < SchemaPtr[iFieldNo].cNoOfDecs; i++ )
- *tp++ = '0';
- } else {
- xbInt32 j = iDecPos + 1;
- for( xbInt32 i = 0; i < SchemaPtr[iFieldNo].cNoOfDecs; i++, j++ ){
- if( j <= (xbInt32) sFieldValue.Len())
- *tp++ = sFieldValue[j];
- else
- *tp++ = '0';
- }
- }
- startpos= SchemaPtr[iFieldNo].pAddress +
- SchemaPtr[iFieldNo].cFieldLen -
- SchemaPtr[iFieldNo].cNoOfDecs - iLen - 1;
-
- }
- else
- startpos=SchemaPtr[iFieldNo].pAddress+SchemaPtr[iFieldNo].cFieldLen-iLen;
- }
- else
- startpos = SchemaPtr[iFieldNo].pAddress;
-
- memcpy( startpos, sFieldValue.Str(), (size_t) iLen );
- return 0;
-}
-
-/************************************************************************/
-//! @brief Put float field for field number.
-/*!
- \param iFieldNo Number of field to update.
- \param fFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::PutFloatField( xbInt16 iFieldNo, xbFloat fFieldValue ){
-
- xbInt16 rc;
- xbString sFloatFmt;
- xbString sFloatFmt2;
- xbString sFloatVal;
- xbInt16 iFieldLen;
- xbInt16 iNoOfDecs;
-
- if(( rc = GetFieldDecimal( iFieldNo, iNoOfDecs )) != XB_NO_ERROR )
- return rc;
-
- if(( rc = GetFieldLen( iFieldNo, iFieldLen )) != XB_NO_ERROR )
- return rc;
-
- sFloatFmt.Sprintf( "%d.%df", iFieldLen, iNoOfDecs );
- sFloatFmt2 = "%-";
- sFloatFmt2 += sFloatFmt;
- sFloatVal.Sprintf( sFloatFmt2.Str(), fFieldValue );
- sFloatVal.Rtrim();
- return PutField( iFieldNo, sFloatVal );
-}
-
-/************************************************************************/
-//! @brief Put float field for field name.
-/*!
- \param sFieldName Name of field to update.
- \param fFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::PutFloatField( const xbString &sFieldName, xbFloat fFieldValue ){
- return PutFloatField( GetFieldNo( sFieldName ), fFieldValue );
-}
-
-/************************************************************************/
-//! @brief Put logical field for field number.
-/*!
- \param iFieldNo Number of field to update.
- \param sFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::PutLogicalField( xbInt16 iFieldNo, const xbString &sFieldValue ) {
- return PutField( iFieldNo, sFieldValue );
-}
-
-/************************************************************************/
-//! @brief Put logical field for field name.
-/*!
- \param sFieldName Name of field to update.
- \param sFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::PutLogicalField( const xbString &sFieldName, const xbString &sFieldValue ) {
- return PutField( GetFieldNo( sFieldName ), sFieldValue );
-}
-
-/************************************************************************/
-//! @brief Put logical field for field number.
-/*!
- \param iFieldNo Number of field to update.
- \param bFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::PutLogicalField( xbInt16 iFieldNo, xbBool bFieldValue ) {
-
- if( bFieldValue )
- return PutField( iFieldNo, "T" );
- else
- return PutField( iFieldNo, "F" );
-}
-
-/************************************************************************/
-//! @brief Put logical field for field name.
-/*!
- \param sFieldName Name of field to update.
- \param bFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-xbInt16 xbDbf::PutLogicalField( const xbString &sFieldName, xbBool bFieldValue ) {
- return PutLogicalField( GetFieldNo( sFieldName ), bFieldValue );
-}
-
-/************************************************************************/
-//! @brief Put long field for field number.
-/*!
- \param iFieldNo Number of field to update.
- \param lFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::PutLongField( xbInt16 iFieldNo, xbInt32 lFieldValue ) {
- xbString sLong;
- sLong.Sprintf( "%ld", (xbInt32) lFieldValue );
- return PutField( iFieldNo, sLong.Str() );
-}
-
-/************************************************************************/
-//! @brief Put long field for field name.
-/*!
- \param sFieldName Name of field to update.
- \param lFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::PutLongField( const xbString &sFieldName, xbInt32 lFieldValue ) {
- return PutLongField( GetFieldNo( sFieldName ), lFieldValue );
-}
-
-/************************************************************************/
-//! @brief Put unsigned long field for field number.
-/*!
- \param iFieldNo Number of field to update.
- \param ulFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::PutULongField( xbInt16 iFieldNo, xbUInt32 ulFieldValue ) {
- xbString sLong;
- sLong.Sprintf( "%lu", (xbInt32) ulFieldValue );
- return PutField( iFieldNo, sLong.Str() );
-}
-
-/************************************************************************/
-//! @brief Put unsigned long field for field name.
-/*!
- \param sFieldName Name of field to update.
- \param ulFieldValue Field value.
- \returns The field routines return one of:<br>
- XB_NO_ERROR<br>XB_INVALID_DATA<br>XB_INVALID_FIELD_NO<br>XB_INVALID_FIELD_NAME<br>
- XB_INVALID_FIELD_TYPE<br>XB_INVALID_DATA
-*/
-
-xbInt16 xbDbf::PutULongField( const xbString &sFieldName, xbUInt32 ulFieldValue ) {
- return PutLongField( GetFieldNo( sFieldName ), (xbInt32) ulFieldValue );
-}
-
-/************************************************************************/
-#ifdef XB_MEMO_SUPPORT
-//! @brief Check if memo field exists for field name.
-/*!
- \param sFieldName Name of field to check.
- \returns xbTrue Field exists.<br> xbFale Field does not exist.
-*/
-
-xbBool xbDbf::MemoFieldExists( const xbString &sFieldName ) const{
- return MemoFieldExists( GetFieldNo( sFieldName ));
-}
-
-/************************************************************************/
-//! @brief Check if memo field exists for field number.
-/*!
- \param iFieldNo Number of field to check.
- \returns xbTrue Field exists.<br> xbFale Field does not exist.
-*/
-
-xbBool xbDbf::MemoFieldExists( xbInt16 iFieldNo ) const{
-
- xbInt32 lFld = 0L;
- GetLongField( iFieldNo, lFld );
- if( lFld == 0L )
- return xbFalse;
- else
- return xbTrue;
-}
-
-#endif
-
-} /* namespace */
-
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbfile.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbfile.cpp
deleted file mode 100755
index 6376e9a..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbfile.cpp
+++ /dev/null
@@ -1,2217 +0,0 @@
-/* xbfile.cpp
-
-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 module handles all the low level file I/O and is the base class
-for the table, memo and index classes
-
-*/
-
-#include "xbase.h"
-
-namespace xb{
-
-/************************************************************************/
-//! @brief Class Constructor.
-xbFile::xbFile( xbXBase * x ){
- fp = NULL;
- bFileOpen = xbFalse;
- ulBlockSize = 0;
- iFileNo = 0;
- xbase = x;
- if( GetMultiUser() == xbTrue )
- iShareMode = XB_MULTI_USER;
- else
- iShareMode = XB_SINGLE_USER;
- iOpenMode = 0;
- #ifdef XB_LOCKING_SUPPORT
- iLockRetries = -1;
- #endif
- #ifdef HAVE_SETENDOFFILE_F
- fHandle = NULL;
- #endif
-}
-
-/************************************************************************/
-//! @brief Class Destructor.
-xbFile::~xbFile(){
- if( bFileOpen )
- xbFclose();
-}
-
-/************************************************************************/
-//! @brief Create a unique file name.
-/*!
- Given a directory and file extension as inputs, create a unique file name.
-
- \param sDirIn Directory
- \param sExtIn File Extension
- \param sFqnOut A fully qualifed unique file name as output
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-/*
-xbInt16 xbFile::CreateUniqueFileName( const xbString & sDirIn, const xbString & sExtIn, xbString &sFqnOut ){
- return CreateUniqueFileName( sDirIn, sExtIn, sFqnOut, 0 );
-}
-*/
-/************************************************************************/
-//! @brief Create a unique file name.
-/*!
- Given a directory and file extension as inputs, create a unique file name.
-
- \param sDirIn Directory
- \param sExtIn File Extension
- \param iOption 0 - look only for one file for a given directory and extension<br>
- 1 - if file name extension is "dbf" or "DBF", verify unique dbt or DBT (memo) file is also available<br>
- \param sFqnOut A fully qualifed unique file name as output
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::CreateUniqueFileName( const xbString & sDirIn, const xbString & sExtIn, xbString &sFqnOut, xbInt16 iOption ){
-
- xbBool bUniqueFileNameFound = xbFalse;
- xbFile f( xbase);
- xbInt32 l = 1;
- xbString sMemoFileName;
-
- xbString sDir = sDirIn;
- char c = GetPathSeparator();
- if( sDirIn.Len() > 0 && sDirIn[sDirIn.Len()] != c )
- sDir += c;
-
- while( !bUniqueFileNameFound ){
- sFqnOut.Sprintf( "%sxbTmp%03d.%s", sDir.Str(), l, sExtIn.Str());
- if( iOption == 1 && sExtIn == "DBF" ){
- sMemoFileName.Sprintf( "%sxbTmp%03d.DBT", sDirIn.Str(), l );
- }
- else if( iOption == 1 && sExtIn == "dbf" ){
- sMemoFileName.Sprintf( "%sxbTmp%03d.dbt", sDirIn.Str(), l );
- }
- if( f.FileExists( sFqnOut ) || ( sMemoFileName.Len() > 0 && f.FileExists( sMemoFileName ))){
- l++;
- }
- else
- {
- bUniqueFileNameFound = xbTrue;
- }
- if( l > 999 )
- return XB_FILE_EXISTS;
- }
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Determine which version the memo (dbt) file is.
-/*!
-
- This routine uses the first byte in the dbf file to determine which memo
- file version is in use. The main difference between version 3 and 4 is that
- version 4 will reuse blocks if they become available. Version 3 does not.
-
- \param cFileTypeByte is an output field and is one of:<br>
- <br>
- 0 - none<br>
- 3 - Dbase III+<br>
- 4 - Dbase IV<br>
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::DetermineXbaseMemoVersion( unsigned char cFileTypeByte ) const {
-
-
- if( BitSet( cFileTypeByte, 3 ) && BitSet( cFileTypeByte, 7 ))
- return 4;
- else if( BitSet( cFileTypeByte, 7 ))
- return 3;
-
- return 0;
-}
-/*************************************************************************/
-//! @brief Determine xbase dbf version.
-/*!
-
- This routine is used to determine which version of the Xbase classes can
- be used for a given DBF file.<br>
-
- It attempts to use the highest version compiled into the library.<br>
-
- References:<br>
- This routine uses the first byte from the dbf file.<br>
- Per DBase documentation:<br>
- Valid dBASE for Windows table file, bits 0-2 indicate version number: 3 for dBASE Level 5, 4 for dBASE Level 7.<br>
- Bit 3 and bit 7 indicate presence of a dBASE IV or dBASE for Windows memo file;<br>
- Bits 4-6 indicate the presence of a dBASE IV SQL table;<br>
- Bit 7 indicates the presence of any .DBT memo file (either a dBASE III PLUS type or a dBASE IV or dBASE for Windows memo file).<br>
-<br>
- Bachmann spec (used extensively in library build), page 7 - does not match DBase documentation<br>
-<br>
- returns<br>
- 0 - unknown<br>
- 3 - Dbase level 3<br>
- 4 - Dbase level 4<br>
- 5 - Dbase Level 5 (future)<br>
- 7 - Dbase Level 7 (future)<br>
-<br>
- 1x - Clipper files (future)<br>
- 2x - Foxbase files (future)<br>
-<br>
-*/
-
-xbInt16 xbFile::DetermineXbaseTableVersion( unsigned char cFileTypeByte ) const {
-
- xbInt16 iMemoVersion = DetermineXbaseMemoVersion(cFileTypeByte);
- char cDbfLevel = cFileTypeByte & 0x07;
-
- #ifdef XB_DBF4_SUPPORT
- if( cDbfLevel == 3 && iMemoVersion != 3 )
- return 4;
- #endif
-
- #ifdef XB_DBF3_SUPPORT
- if( cDbfLevel == 3 && iMemoVersion != 4 )
- return 3;
- #endif
-
- return 0;
-}
-
-/*************************************************************************/
-//! @brief Get a portable double value.
-/*!
-
- This routine returns a double value from an 8 byte character stream,
- accounting for endian type.
-
- Converts a double (64 bit floating point) value stored at p from a portable
- format to the machine format.
-
- \param p pointer to memory containing the portable double value
-
- \returns the double value.
-*/
-
-xbDouble xbFile::eGetDouble( const char *p ) const {
- xbDouble d;
- const char *sp;
- char *tp;
- xbInt16 i;
-
- tp = (char *) &d;
- sp = p;
- if( iEndianType == 'L' )
- for( i = 0; i < 8; i++ ) *tp++ = *sp++;
- else
- {
- sp+=7;
- for( i = 0; i < 8; i++ ) *tp++ = *sp--;
- }
-
- return d;
-}
-
-/*************************************************************************/
-//! @brief Get a portable long value.
-
-/*!
- This routine returns a long int value from a 4 byte character stream,
- accounting for endian type.
-
- \param p pointer to memory containing the portable long value
-
- \returns the long value.
-*/
-
-xbInt32 xbFile::eGetInt32( const char *p ) const {
- xbInt32 l;
- char *tp;
- xbInt16 i;
-
- tp = (char *) &l;
- if( iEndianType == 'L' )
- for( i = 0; i < 4; i++ ) *tp++ = *p++;
- else {
- p+=3;
- for( i = 0; i < 4; i++ ) *tp++ = *p--;
- }
- return l;
-
-}
-/*************************************************************************/
-//! @brief Get a portable unsigned long value.
-
-/*!
- This routine returns an unsigned long int value from a 4 byte character stream,
- accounting for endian type.
-
- \param p pointer to memory containing the portable long value
-
- \returns the unsigned long value.
-*/
-
-xbUInt32 xbFile::eGetUInt32( const char *p ) const {
- xbUInt32 ul;
- xbInt16 i;
- char *tp;
-
- tp = (char *) &ul;
- if( iEndianType == 'L' )
- for( i = 0; i < 4; i++ ) *tp++ = *p++;
- else{
- p+=3;
- for( i = 0; i < 4; i++ ) *tp++ = *p--;
- }
- return ul;
-}
-
-/*************************************************************************/
-//! @brief Get a portable short value.
-
-/*!
- This routine returns a short int value from a 2 byte character stream,
- accounting for endian type.
-
- \param p pointer to memory containing the portable long value
-
- \returns the short value.
-*/
-
-xbInt16 xbFile::eGetInt16(const char *p) const {
- xbInt16 s, i;
- char *tp;
- tp = (char *) &s;
- if( iEndianType == 'L' )
- for( i = 0; i < 2; i++ ) *tp++ = *p++;
- else{
- p++;
- for( i = 0; i < 2; i++ ) *tp++ = *p--;
- }
- return s;
-}
-/*************************************************************************/
-//! @brief Get a portable unsigned short value.
-
-/*!
- This routine returns a short unsigned int value from a 2 byte character stream,
- accounting for endian type.
-
- \param p pointer to memory containing the portable long value
-
- \returns the short value.
-*/
-
-xbUInt16 xbFile::eGetUInt16(const char *p) const {
- xbInt16 i;
- xbUInt16 uI;
- char *tp;
-
- tp = (char *) &uI;
- if( iEndianType == 'L' )
- for( i = 0; i < 2; i++ ) *tp++ = *p++;
- else{
- p++;
- for( i = 0; i < 2; i++ ) *tp++ = *p--;
- }
- return uI;
-}
-
-
-/*************************************************************************/
-//! @brief Write a portable double value to memory location.
-/*!
- Converts a double (64 bit floating point) value from machine format to a
- portable format and stores the converted value in the memory referenced
- by c.
-
- This routine puts a double value to an 8 byte character stream
-
- \param c Pointer to memory to hold converted value
- \param d Input value to be converted
-*/
-
-void xbFile::ePutDouble( char *c, xbDouble d ){
- const char *sp;
- char *tp;
- xbInt16 i;
-
- tp = c;
- sp = (const char *) &d;
- if( iEndianType == 'L' )
- for( i = 0; i < 8; i++ ) *tp++ = *sp++;
- else
- {
- sp+=7;
- for( i = 0; i < 8; i++ ) *tp++ = *sp--;
- }
- return;
-}
-
-/*************************************************************************/
-//! @brief Write a portable short value to memory location.
-/*!
- Converts a short (16 bit integer) value from machine format to a
- portable format and stores the converted value in the memory referenced
- by c.
-
- This routine puts a short value to a 2 byte character stream
-
- \param c Pointer to memory to hold converted value
- \param s Input value to be converted
-*/
-
-void xbFile::ePutInt16( char * c, xbInt16 s ){
- const char *sp;
- char *tp;
- xbInt16 i;
-
- tp = c;
- sp = (const char *) &s;
-
- if( iEndianType == 'L' )
- for( i = 0; i < 2; i++ ) *tp++ = *sp++;
- else{ /* big endian */
- sp++;
- for( i = 0; i < 2; i++ ) *tp++ = *sp--;
- }
- return;
-}
-/*************************************************************************/
-//! @brief Write a portable unsigned short value to memory location.
-/*!
- Converts an unsigned short (16 bit integer) value from machine format to a
- portable format and stores the converted value in the memory referenced
- by c.
-
- This routine puts an unsigned short value to a 2 byte character stream
-
- \param c Pointer to memory to hold converted value
- \param s Input value to be converted
-*/
-
-void xbFile::ePutUInt16( char * c, xbUInt16 s ){
- const char *sp;
- char *tp;
- xbInt16 i;
-
- tp = c;
- sp = (const char *) &s;
-
- if( iEndianType == 'L' )
- for( i = 0; i < 2; i++ ) *tp++ = *sp++;
- else{ /* big endian */
- sp++;
- for( i = 0; i < 2; i++ ) *tp++ = *sp--;
- }
- return;
-}
-
-/*************************************************************************/
-//! @brief Write a portable long value to memory location.
-/*!
- Converts a long (32 bit integer) value from machine format to a
- portable format and stores the converted value in the memory referenced
- by c.
-
- This routine puts a long value to a 4 byte character stream.
-
- \param c Pointer to memory to hold converted value
- \param l Input value to be converted
-*/
-
-void xbFile::ePutInt32( char * c, xbInt32 l )
-{
- const char *sp;
- char *tp;
- xbInt16 i;
-
- tp = c;
- sp = (const char *) &l;
- if( iEndianType == 'L' )
- for( i = 0; i < 4; i++ ) *tp++ = *sp++;
- else {
- sp+=3;
- for( i = 0; i < 4; i++ ) *tp++ = *sp--;
- }
- return;
-}
-
-
-/*************************************************************************/
-//! @brief Write a portable unsigned long value to memory location.
-/*!
- Converts an unsigned long (32 bit integer) value from machine format to a
- portable format and stores the converted value in the memory referenced
- by c.
-
- This routine puts an unsigned long value to a 4 byte character stream.
-
- \param c Pointer to memory to hold converted value
- \param ul Input value to be converted
-*/
-
-void xbFile::ePutUInt32( char * c, xbUInt32 ul )
-{
- const char *sp;
- char *tp;
- xbInt16 i;
-
- tp = c;
- sp = (const char *) &ul;
- if( iEndianType == 'L' )
- for( i = 0; i < 4; i++ ) *tp++ = *sp++;
- else
- {
- sp+=3;
- for( i = 0; i < 4; i++ ) *tp++ = *sp--;
- }
- return;
-}
-
-/************************************************************************/
-//! @brief Determines if a file exists.
-/*!
- \returns xbTrue if file exists<br>
- xbFalse if file does not exist
-
-*/
-xbBool xbFile::FileExists() const {
- return FileExists( sFqFileName, 0 );
-}
-/************************************************************************/
-//! @brief Determines if a file exists.
-/*!
- \param iOption if 1, assume this is a request for a dbf file and
- check for the a dbt memo file also, returns true if both files are found
-
- \returns xbTrue if both files exist<br>
- xbFalse if file does not exist
-
-*/
-xbBool xbFile::FileExists( xbInt16 iOption ) const {
- return FileExists( sFqFileName, iOption );
-}
-
-/************************************************************************/
-//! @brief Determines if a file exists.
-/*!
- \param sFileName - file name to check for
-
- \returns xbTrue if file exists<br>
- xbFalse if file does not exist
-*/
-
-xbBool xbFile::FileExists(const xbString &sFileName ) const {
- return FileExists( sFileName, 0 );
-}
-
-/************************************************************************/
-//! @brief Determines if a file exists.
-/*!
- \param sFileName - file name to check for
- \param iOption if 1, assume this is a request for a dbf file and
- check for the a dbt memo file also, returns true if both files are found
-
- \returns xbTrue if both dbf and dbt files exist<br>
- xbFalse if file does not exist
-*/
-
-xbBool xbFile::FileExists( const xbString & sFileName, xbInt16 iOption ) const {
-
- struct stat buffer;
- if(( stat( sFileName.Str(), &buffer ) != 0 )){
- return xbFalse;
- }
-
- #ifdef XB_MEMO_SUPPORT
- if( iOption == 1 ){
- xbString sFileName2 = sFileName;
-
- if( sFileName2[sFileName2.Len()] == 'F' )
- sFileName2.PutAt( sFileName2.Len(), 'T' );
- else
- sFileName2.PutAt( sFileName2.Len(), 't' );
-
- if(( stat( sFileName2.Str(), &buffer) != 0 ))
- return xbFalse;
- }
- #endif
- return xbTrue;
-}
-
-/************************************************************************/
-//! @brief Determines if file is open.
-/*!
-
- \returns xbTrue if file is open<br>
- xbFalse if file is not open
-*/
-
-xbBool xbFile::FileIsOpen() const {
- return bFileOpen;
-}
-/************************************************************************/
-//! @brief Get the block size.
-/*!
- \returns Block Size
-*/
-
-xbUInt32 xbFile::GetBlockSize() const {
- return ulBlockSize;
-}
-
-/************************************************************************/
-//! @brief Get the directory name.
-/*!
- \returns the directory name of the file
-*/
-
-const xbString & xbFile::GetDirectory() const {
- return sDirectory;
-}
-
-/************************************************************************/
-//! @brief Get the directory part of the file name.
-/*!
- \param sFileDirPartOut - the returned directory name
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::GetFileDirPart( xbString & sFileDirPartOut ) const {
- return GetFileDirPart( sFqFileName, sFileDirPartOut );
-}
-
-/************************************************************************/
-//! @brief Get the directory part of the file name.
-/*!
- \param sCompleteFileNameIn - a fully qualfied input file name
- \param sFileDirPartOut - the returned directory name part out of sCompleteFileNameIn
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbFile::GetFileDirPart( const xbString & sCompleteFileNameIn, xbString & sFileDirPartOut ) const {
-
- sFileDirPartOut = sCompleteFileNameIn;
- sFileDirPartOut.SwapChars( '\\', '/' );
- xbUInt32 iPos = sFileDirPartOut.GetLastPos( '/' );
-
- if( iPos > 0 ){
- xbString sTemp = sFileDirPartOut;
- sFileDirPartOut.Assign( sTemp, 1, iPos );
- return XB_NO_ERROR;
- }
- return XB_INVALID_DATA;
-}
-
-/************************************************************************/
-//! @brief Get the extension part of the file name.
-/*!
- \param sFileNameExtOut - the returned extension part out of sCompleteFileNameIn
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbFile::GetFileExtPart( xbString & sFileNameExtOut ) const {
- return GetFileExtPart( sFqFileName, sFileNameExtOut );
-}
-
-/************************************************************************/
-//! @brief Get the extension part of the file name.
-/*!
- \param sCompleteFileNameIn - a fully qualfied input file name
-
- \param sFileExtPartOut - the returned directory name part out of sCompleteFileNameIn
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbFile::GetFileExtPart( const xbString & sCompleteFileNameIn, xbString & sFileExtPartOut ) const {
-
-
- sFileExtPartOut = sCompleteFileNameIn;
- xbUInt32 iPos = sFileExtPartOut.GetLastPos( '.' );
- if( iPos > 0 ){ /* get rid of the directory part of the name */
- sFileExtPartOut.Ltrunc( iPos );
- return XB_NO_ERROR;
- }
- return XB_INVALID_DATA;
-}
-/************************************************************************/
-//! @brief Get the time of last file modification timestamp as reported by the OS.
-/*!
- \param mtime - returned time of last file modification
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::GetFileMtime( time_t &mtime ){
-
- struct stat buffer;
- if( stat( sFqFileName.Str(), &buffer ))
- return XB_FILE_NOT_FOUND;
- else{
- mtime = buffer.st_mtime;
- return XB_NO_ERROR;
- }
-}
-/************************************************************************/
-//! @brief Get the file name.
-/*!
- \returns the file name portion of the file
-*/
-
-const xbString & xbFile::GetFileName() const {
- return sFileName;
-}
-
-
-/************************************************************************/
-//! @brief Get the name part of the file name.
-/*!
- \param sFileNamePartOut - the returned file name part out of sCompleteFileNameIn
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbFile::GetFileNamePart( xbString & sFileNamePartOut ) const {
- return GetFileNamePart( sFqFileName, sFileNamePartOut );
-}
-
-/************************************************************************/
-//! @brief Get the name part of the file name.
-/*!
- \param sCompleteFileNameIn - a fully qualified input file name
- \param sFileNamePartOut - the returned file name part out of sCompleteFileNameIn
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-//*********** fixme should this be static?????
-
-xbInt16 xbFile::GetFileNamePart( const xbString & sCompleteFileNameIn, xbString & sFileNamePartOut ) const {
- /* extract the file name part out of the string */
-
- sFileNamePartOut = sCompleteFileNameIn;
- sFileNamePartOut.SwapChars( '\\', '/' );
- xbUInt32 iPos = sFileNamePartOut.GetLastPos( '/' );
- if( iPos > 0 ) /* get rid of the directory part of the name */
- sFileNamePartOut.Ltrunc( iPos );
- iPos = sFileNamePartOut.Pos( '.' );
- if( iPos > 0 ){ /* get rid of the extension part of the name */
- xbString sTemp = sFileNamePartOut;
- sFileNamePartOut.Assign( sTemp, 1, iPos-1 );
- }
- return XB_NO_ERROR;
-}
-
-
-/************************************************************************/
-//! @brief Get the size of the file as reported by the OS.
-/*!
- \param ullFileSize - unsigned long long field as output
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::GetFileSize( xbUInt64 &ullFileSize ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
-
- if(( iRc = xbFseek( 0, SEEK_END )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- ullFileSize = xbFtell();
- }
-
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFile::GetFileSize() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Get the file type aka Capitalized file extension
-/*!
- \param sFileTypeOut - the returned extension part out of sCompleteFileNameIn
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbFile::GetFileType( xbString & sFileTypeOut ) const {
-
- xbInt16 iRc = GetFileExtPart( sFqFileName, sFileTypeOut );
- sFileTypeOut.ToUpperCase();
- return iRc;
-}
-/************************************************************************/
-//! @brief Get the fully qualified file name.
-/*!
- \returns the fully qualfied name of the file
-*/
-
-const xbString & xbFile::GetFqFileName() const {
- return sFqFileName;
-}
-
-/************************************************************************/
-//! @brief Get the open mode of the file.
-/*!
- \returns XB_READ<br>
- XB_READ_WRITE<br>
- XB_WRITE<BR>
-*/
-
-xbInt16 xbFile::GetOpenMode() const {
- return iOpenMode;
-}
-
-/************************************************************************/
-//! @brief Get the share mode of the file.
-/*!
- \returns XB_SINGLE_USER - (file buffering on><br>
- XB_MULTI_USER - (file buffering off)<br>
-*/
-
-xbInt16 xbFile::GetShareMode() const {
- return iShareMode;
-}
-
-/************************************************************************/
-//! @brief Get the file type byte and version of the dbf file.
-/*!
-
- Pull the first bye off the DBF file for further inspection.
- First byte has various bits set to determine what the file format is.
-
- \param sFileName - Name of file to examine
- \param iVersion - Returned file version
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::GetXbaseFileTypeByte( const xbString &sFileName, xbInt16 &iVersion )
-{
- unsigned char cFileTypeByte;
- return GetXbaseFileTypeByte( sFileName, cFileTypeByte, iVersion );
-}
-
-/************************************************************************/
-//! @brief Get the file type byte and version of the dbf file.
-/*!
- Pull the first bye off the DBF file for further inspection.
- First byte has various bits set to determine what the file format is.
-
- \param sFileName - Name of file to examine
- \param cFileTypeByte - Retruned first byte of dbf file
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbFile::GetXbaseFileTypeByte( const xbString &sFileName, unsigned char &cFileTypeByte )
-{
- xbInt16 iVersion;
- return GetXbaseFileTypeByte( sFileName, cFileTypeByte, iVersion );
-}
-
-/************************************************************************/
-//! @brief Get the file type byte and version of the dbf file.
-/*!
- Pull the first bye off the DBF file for further inspection.
- First byte has various bits set to determine what the file format is.
-
-
- \param sFileName - Name of file to examine
- \param cFileTypeByte - Returned first byte of dbf file
- \param iVersion - Returned file version
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::GetXbaseFileTypeByte( const xbString &sFileName, unsigned char &cFileTypeByte, xbInt16 &iVersion ){
- xbInt16 iErrorStop = 0;
- xbInt16 iRc = XB_NO_ERROR;
- size_t stRc;
- FILE *tfp;
-
- try{
-
- iVersion = 0;
- cFileTypeByte = 0x00;
- #ifdef HAVE__FSOPEN_F
- // 0x40 is SH_DENYNO or _SH_DENYNO
- if(( tfp = _fsopen( sFileName.Str(), "r", 0x40 )) == NULL ){
- iErrorStop = 100;
- iRc = XB_OPEN_ERROR;
- throw iRc;
- }
- #else
- if(( tfp = fopen( sFileName.Str(), "r" )) == NULL ){
- iErrorStop = 110;
- iRc = XB_OPEN_ERROR;
- throw iRc;
- }
- #endif
-
- #ifdef HAVE_FSEEKO_F
- iRc = fseeko( tfp, 0, SEEK_SET );
- #else
- iRc = fseek( tfp, 0, SEEK_SET );
- #endif
-
- if( iRc != 0 ){
- iErrorStop = 120;
- iRc = XB_SEEK_ERROR;
- throw iRc;
- }
- stRc = fread( &cFileTypeByte, (size_t) 1, (size_t) 1, tfp );
- if( stRc != (size_t) 1 ){
- iErrorStop = 130;
- iRc = XB_READ_ERROR;
- throw iRc;
- }
- iRc = XB_NO_ERROR;
- fclose( tfp );
- iVersion = DetermineXbaseTableVersion( cFileTypeByte );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFile::GetXbaseFileType() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Determines status of file extension.
-/*!
-
- \param sFileName - Name of file to examine
- \param iOption - Inspection type<br>
- 1 check for DBF<br>
- 2 check for NDX<br>
- 3 check for MDX<br>
- 4 check for NTX<br>
-
- \returns 0 if suffix found<br>
- 1 if suffix not found, lower case<br>
- 2 is suffix not found, upper case<br>
-
-*/
-
-xbInt16 xbFile::NameSuffixMissing( const xbString & sFileName, xbInt16 iOption ) const {
-
- xbUInt32 ulLen = sFileName.Len();
- if( ulLen <= 4 ){
- if( sFileName[ulLen] >= 'A' && sFileName[ulLen] <= 'Z' )
- return 2;
- else
- return 1;
- }
- if( iOption == 1 && sFileName[ulLen-3] == '.' &&
- ( sFileName[ulLen-2] == 'd' || sFileName[ulLen-2] == 'D' ) &&
- ( sFileName[ulLen-1] == 'b' || sFileName[ulLen-1] == 'B' ) &&
- ( sFileName[ulLen] == 'f' || sFileName[ulLen] == 'F' )
- )
- return 0;
- if( iOption == 2 && sFileName[ulLen-3] == '.' &&
- ( sFileName[ulLen-2] == 'n' || sFileName[ulLen-2] == 'N' ) &&
- ( sFileName[ulLen-1] == 'd' || sFileName[ulLen-1] == 'D' ) &&
- ( sFileName[ulLen] == 'x' || sFileName[ulLen] == 'X' )
- )
- return 0;
- if( iOption == 3 && sFileName[ulLen-3] == '.' &&
- ( sFileName[ulLen-2] == 'm' || sFileName[ulLen-2] == 'M' ) &&
- ( sFileName[ulLen-1] == 'd' || sFileName[ulLen-1] == 'D' ) &&
- ( sFileName[ulLen] == 'x' || sFileName[ulLen] == 'X' )
- )
- return 0;
- if( iOption == 4 && sFileName[ulLen-3] == '.' &&
- ( sFileName[ulLen-2] == 'n' || sFileName[ulLen-2] == 'N' ) &&
- ( sFileName[ulLen-1] == 't' || sFileName[ulLen-1] == 'T' ) &&
- ( sFileName[ulLen] == 'x' || sFileName[ulLen] == 'X' )
- )
- return 0;
- // next line might be problematic if file naem has mixed case and extension is missing
- if( sFileName[ulLen-4] >= 'A' && sFileName[ulLen-4] <= 'Z' )
- return 2;
- else
- return 1;
-}
-
-/***********************************************************************/
-//! @brief Read a block of data from file.
-/*!
-
- \param ulBlockNo - block number to read
- \param lReadSize - size of data to read at block location, set to 0 to read blocksize
- \param *buf - pointer to buffer to write output data, assumed to be previosuly allocated
- and large enough to contain data
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-
-xbInt16 xbFile::ReadBlock( xbUInt32 ulBlockNo, size_t lReadSize, void * buf ){
- return ReadBlock( ulBlockNo, ulBlockSize, lReadSize, buf );
-}
-
-/***********************************************************************/
-//! @brief Read a block of data from file.
-/*!
-
- \param ulBlockNo - block number to read
- \param ulBlockSize - block size
- \param lReadSize - size of data to read at block location, set to 0 to read blocksize
- \param buf - pointer to buffer to write output data, assumed to be previosuly allocated
- and large enough to contain data
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-xbInt16 xbFile::ReadBlock( xbUInt32 ulBlockNo, xbUInt32 ulBlockSize, size_t lReadSize, void * buf ){
-
- xbInt16 iErrorStop = 0;
- xbInt16 iRc = XB_NO_ERROR;
-
- try{
- if( ulBlockSize <= 0 ){
- iErrorStop = 100;
- iRc = XB_INVALID_BLOCK_SIZE;
- throw iRc;
- }
-
- if(( iRc = xbFseek(((xbInt64) ulBlockNo*ulBlockSize ), SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 110;
- iRc = XB_SEEK_ERROR;
- throw iRc;
- }
-
- if( lReadSize <= 0 )
- lReadSize = ulBlockSize;
-
- if(( iRc = xbFread( buf, lReadSize, 1 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- iRc = XB_READ_ERROR;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFile::ReadBlock() Exception Caught. Error Stop = [%d] iRc = [%d] BlkNo=[%ld] BlkSize=[%ld] ReadSize=[%ld]", iErrorStop, iRc, ulBlockNo, ulBlockSize, lReadSize );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/************************************************************************/
-//! @brief Set the block size.
-/*!
-
- \param ulBlockSize - unsigned long block size, divisible by 512
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::SetBlockSize( xbUInt32 ulBlockSize ){
- if( ulBlockSize %512 != 0 )
- return XB_INVALID_BLOCK_SIZE;
-
- this->ulBlockSize = ulBlockSize;
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! @brief Set the directory.
-/*!
- \param sDirectory - Valid directory name
-*/
-
-void xbFile::SetDirectory( const xbString & sDirectory ){
-
- this->sDirectory = sDirectory;
- char cLastChar = sDirectory[sDirectory.Len()];
- if( cLastChar != '/' && cLastChar != '\\' )
- sFqFileName.Sprintf( "%s/%s", sDirectory.Str(), sFileName.Str());
- else
- sFqFileName.Sprintf( "%s%s", sDirectory.Str(), sFileName.Str());
-
- #ifdef WIN32
- sFqFileName.SwapChars( '/', '\\' );
- #else
- sFqFileName.SwapChars( '\\', '/' );
- #endif
-}
-
-/************************************************************************/
-//! @brief Set the filename.
-/*!
- This routine builds out two internal variables from the input file name<br>
- sFileName - the file name part<br>
- sFqFileName - the fully qualified file name<br>
-
-
- \param sFileName - Input file name
-*/
-void xbFile::SetFileName( const xbString & sFileName ){
-
- if( sFileName == "" ){
- sFqFileName = "";
- return;
- }
-
- char cPathSep = sFileName.GetPathSeparator();
-
- if( cPathSep ){
-
- xbString sName;
- xbString sExt;
- // GetFileDirPart( this->sDirectory );
- GetFileNamePart( sFileName, sName );
- GetFileExtPart( sFileName, sExt );
- this->sFileName.Sprintf( "%s.%s", sName.Str(), sExt.Str());
- sFqFileName = sFileName;
-
- } else {
-
- this->sFileName = sFileName;
- if( sDirectory.Len() == 0 ){
- sDirectory = GetDataDirectory();
- char cLastChar = sDirectory[sDirectory.Len()];
- if( cLastChar != '/' && cLastChar != '\\' )
- sFqFileName.Sprintf( "%s/%s", sDirectory.Str(), sFileName.Str() );
- else
- sFqFileName = sDirectory + sFileName;
- }
- else{
- char cLastChar = sDirectory[sDirectory.Len()];
- if( cLastChar != '/' && cLastChar != '\\' )
- sFqFileName.Sprintf( "%s/%s", sDirectory.Str(), sFileName.Str() );
- else
- sFqFileName = sDirectory + sFileName;
- }
- }
-
- #ifdef WIN32
- sFqFileName.SwapChars( '/', '\\' );
- #else
- sFqFileName.SwapChars( '\\', '/' );
- #endif
-}
-
-/************************************************************************/
-//! @brief Set the fully qualifed filename.
-/*!
- \param sFqFileName - Fully qualifed input file name
-*/
-
-void xbFile::SetFqFileName( const xbString & sFqFileName ){
- this->sFqFileName = sFqFileName;
-
- xbString sDir;
- xbString sName;
- xbString sExt;
-
- GetFileDirPart ( sFqFileName, sDir );
- GetFileNamePart( sFqFileName, sName );
- GetFileExtPart ( sFqFileName, sExt );
-
- sDirectory = sDir;
- sFileName.Sprintf( "%s.%s", sName.Str(), sExt.Str() );
-
- #ifdef WIN32
- this->sDirectory.SwapChars ( '/', '\\' );
- this->sFqFileName.SwapChars( '/', '\\' );
- #else
- this->sDirectory.SwapChars ( '\\', '/' );
- this->sFqFileName.SwapChars( '\\', '/' );
- #endif
-}
-
-/************************************************************************/
-//! @brief Set Home Folders.
-/*!
- Create xbase64 log, data and temp folders in the home directory for current usre.
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::SetHomeFolders(){
-
- xbInt16 iErrorStop = 0;
- xbInt16 iRc = XB_NO_ERROR;
- xbString sHomeDir;
- char cPathSeparator;
- xbString sDflt;
-
- try{
-
- GetHomeDir( sHomeDir );
- //std::cout << "CreateHomeFolders() home dir = [" << sHomeDir.Str() << "]\n";
-
- if( FileExists( sHomeDir ) == xbFalse ){
- iErrorStop = 100;
- iRc = XB_DIRECTORY_ERROR;
- throw iRc;
- }
-
- #ifdef WIN32
- cPathSeparator = '\\';
- #else
- cPathSeparator = '/';
- #endif
- sDflt.Sprintf( ".%c", cPathSeparator );
- // set the default folders just in case later steps fail
- xbase->SetDataDirectory( sDflt );
- #ifdef XB_LOGGING_SUPPORT
- xbase->SetLogDirectory( sDflt );
- #endif
-
- if( sHomeDir[sHomeDir.Len()] != cPathSeparator )
- sHomeDir += cPathSeparator;
-
- xbString sWork( sHomeDir );
- sWork += "xbase64";
-
- if( FileExists( sWork ) == xbFalse ){
- #ifdef WIN32
- if( CreateDirectory( sWork.Str(), NULL ) == 0 ){
- iErrorStop = 130;
- iRc = XB_DIRECTORY_ERROR;
- throw iRc;
- }
- #else
- // 0777 mode is correct, the mode will be modified by the user's umask
- if( mkdir( sWork.Str(), 0777 ) == -1 ){
- iErrorStop = 140;
- iRc = XB_DIRECTORY_ERROR;
- throw iRc;
- }
- #endif
- }
-
- #ifdef XB_LOGGING_SUPPORT
- sWork.Sprintf( "%sxbase64%clogs", sHomeDir.Str(), cPathSeparator );
- // std::cout << "logdir = " << sWork.Str() << "\n";
-
- if( FileExists( sWork ) == xbFalse ){
- #ifdef WIN32
- if( CreateDirectory( sWork.Str(), NULL ) == 0 ){
- iErrorStop = 110;
- iRc = XB_DIRECTORY_ERROR;
- throw iRc;
- }
- #else
- if( mkdir( sWork.Str(), 0777 ) == -1 ){
- iErrorStop = 120;
- iRc = XB_DIRECTORY_ERROR;
- throw iRc;
- }
- #endif
- }
- xbase->SetLogDirectory( sWork );
- #endif // XB_LOGGING_SUPPORT
-
- sWork.Sprintf( "%sxbase64%cdata", sHomeDir.Str(), cPathSeparator );
- // std::cout << "datadir = " << sWork.Str() << "\n";
- if( FileExists( sWork ) == xbFalse ){
- #ifdef WIN32
- if( CreateDirectory( sWork.Str(), NULL ) == 0 ){
- iErrorStop = 130;
- iRc = XB_DIRECTORY_ERROR;
- throw iRc;
- }
- #else
- if( mkdir( sWork.Str(), 0777 ) == -1 ){
- iErrorStop = 140;
- iRc = XB_DIRECTORY_ERROR;
- throw iRc;
- }
- #endif
- }
-
- sWork.Sprintf( "%sxbase64%ctemp%c", sHomeDir.Str(), cPathSeparator, cPathSeparator );
- // std::cout << "tempdir = " << sWork.Str() << "\n";
- if( FileExists( sWork ) == xbFalse ){
- #ifdef WIN32
- if( CreateDirectory( sWork.Str(), NULL ) == 0 ){
- iErrorStop = 150;
- iRc = XB_DIRECTORY_ERROR;
- throw iRc;
- }
- #else
- if( mkdir( sWork.Str(), 0777 ) == -1 ){
- iErrorStop = 160;
- iRc = XB_DIRECTORY_ERROR;
- throw iRc;
- }
- #endif
- }
- xbase->SetTempDirectory( sWork );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFile::CreateHomeFolders() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Write a block of data to file.
-/*!
-
- \param ulBlockNo - block number to write
- \param lWriteSize - size of data to write, set to 0 to write blocksize
- \param *buf - pointer to buffer of data to be written
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-xbInt16 xbFile::WriteBlock( xbUInt32 ulBlockNo, size_t lWriteSize, void * buf ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
-
- if( ulBlockSize == 0 ){
- iErrorStop = 100;
- iRc = XB_INVALID_BLOCK_SIZE;
- throw iRc;
- }
- if( lWriteSize <= 0 )
- lWriteSize = ulBlockSize;
- if(( iRc = xbFseek(( (xbInt64) ulBlockNo*ulBlockSize), SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- if(( iRc = xbFwrite( buf, lWriteSize, 1 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFile::WriteBlock() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fclose.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbFclose(){
-
- int iRc = 0;
- if( bFileOpen ){
- iRc = fclose( fp );
- if( iRc != 0 ){
- return XB_CLOSE_ERROR;
- }
- else{
- bFileOpen = xbFalse;
- }
- iFileNo = 0;
- }
- return XB_NO_ERROR;
-}
-
-
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary feof.
-/*!
- \returns non zero if end-of-file is set for the stream.
-*/
-xbInt16 xbFile::xbFeof(){
- return feof( fp );
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fflush.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbFflush() {
-
- if( fflush( fp ) )
- return XB_WRITE_ERROR;
- else
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fgetc.
-/*!
- \param c - output integer returned by fgetc
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbFgetc( xbInt32 &c ) {
-
- int i;
-
- i = fgetc( fp );
- if( i == EOF )
- return XB_EOF;
-
- c = i;
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fgetc.
-/*!
- \param c - output character returned by fgetc
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbFgetc( char &c ) {
-
- int i;
- i = fgetc( fp );
- if( i == EOF )
- return XB_EOF;
-
- c = (char) i;
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fgets.
-/*!
- \param lSize - reads in at most, one character less than lSize
- \param s - an xbString containing data returned by fseek
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbFgets( size_t lSize, xbString &s ) {
-
- s = "";
- if( feof( fp ))
- return XB_EOF;
-
- char *sBuf = (char *) malloc( lSize + 1 );
-
- if( fgets( sBuf, (xbInt32) lSize, fp ) == NULL ){
- free( sBuf );
- return XB_EOF;
- }
- s.Set( sBuf );
- free( sBuf );
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fopen.
-/*!
-
- This routine supports all the standard C library open modes. The Xbase routines only
- use "r" and "r+b".
-
- \param sOpenMode
- <table>
- <tr><th>OpenMode<th>Description
- <tr><td>r<td>Reading
- <tr><td>r+<td>Reading and Writing
- <tr><td>w<td>Open for writing. Truncate to zero bytes if it exists
- <tr><td>w+<td>Open for reading and writing, truncate to zero bytes if it exists
- <tr><td>a<td>Open for append
- <tr><td>a+<td>Open for reading and writing (at end).
- </table>
- The mode can also include the letter "b" for binary ie; "r+b". The "b" is ignored on
- POSIX compliant systems, but is included for cross platform compatibility.
- \param sFileName File name to open
- \param iShareMode
- XB_SINGLE_USER<br>
- XB_MULTI_USER<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbFopen( const xbString &sOpenMode, const xbString &sFileName, xbInt16 iShareMode ) {
- if( sFileName == "" || sFqFileName == "" )
- SetFileName( sFileName );
- return xbFopen( sOpenMode, iShareMode );
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fopen.
-/*!
-
- This routine supports all the standard C library open modes. The Xbase routines only
- use "r" and "r+".
-
-
- \param sOpenMode
- <table>
- <tr><th>OpenMode<th>Description
- <tr><td>r<td>Reading
- <tr><td>r+<td>Reading and Writing
- <tr><td>w<td>Open for writing. Truncate to zero bytes if it exists
- <tr><td>w+<td>Open for reading and writing, truncate to zero bytes if it exists
- <tr><td>a<td>Open for append
- <tr><td>a+<td>Open for reading and writing (at end).
- </table>
- The mode can also include the letter "b" for binary ie; "r+b". The "b" is ignored on
- POSIX compliant systems, but is included for cross platform compatibility.
- \param iShareMode
- XB_SINGLE_USER<br>
- XB_MULTI_USER<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbFopen( const xbString & sOpenMode, xbInt16 iShareMode ) {
-
- #ifdef HAVE__FSOPEN_F
- if(( fp = _fsopen( sFqFileName.Str(), sOpenMode.Str(), 0x40 )) != NULL ){
- #else
- if(( fp = fopen( sFqFileName.Str(), sOpenMode.Str())) != NULL ){
- #endif
-
- if( sOpenMode == "r" )
- iOpenMode = XB_READ;
- else if( sOpenMode == "w" )
- iOpenMode = XB_WRITE;
- else
- iOpenMode = XB_READ_WRITE;
-
- bFileOpen = xbTrue;
- this->iShareMode = iShareMode;
-
- #ifdef HAVE__FILENO_F
- iFileNo = _fileno( fp );
- #else
- iFileNo = fileno( fp );
- #endif
-
- #ifdef HAVE_SETENDOFFILE_F
- //used by visual studio, 32 bit
- fHandle = (HANDLE) _get_osfhandle( iFileNo );
- #endif
-
- #ifdef XB_LOCKING_SUPPORT
- if( iShareMode )
- xbFTurnOffFileBuffering();
- #endif
-
- return XB_NO_ERROR;
- }
- else
- return XB_OPEN_ERROR;
-}
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fopen.
-/*!
- \param iOpenMode
- XB_READ<br>
- XB_READ_WRITE<br>
- \param iShareMode
- XB_SINGLE_USER<br>
- XB_MULTI_USER<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbFopen( xbInt16 iOpenMode, xbInt16 iShareMode ) {
- this->iOpenMode = iOpenMode;
- if( iOpenMode == XB_READ_WRITE )
- return xbFopen( "r+b", iShareMode );
- else if( iOpenMode == XB_READ )
- return xbFopen( "r", iShareMode );
- else
- return XB_INVALID_OPTION;
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fputc.
-/*!
- \param c Character to write
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbFile::xbFputc( xbInt32 c ) {
- return xbFputc( c, 1 );
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fputc.
-/*!
- \param c Character to write
- \param iNoOfTimes Number of times to write the character
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbFile::xbFputc( xbInt32 c, xbInt32 iNoOfTimes ) {
-
- for( xbInt32 l = 0; l < iNoOfTimes; l++ )
- if( fputc( c, fp ) != (int) c )
- return XB_WRITE_ERROR;
-
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fputs.
-/*!
- \param s xbString to write to file
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbFputs( const xbString & s ){
- if( fputs( s.Str(), fp ) < 0 )
- return XB_WRITE_ERROR;
- else
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fread.
-/*!
- \param p Pointer to data to write
- \param size size of write
- \param nmemb Number of times to read it
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbFread( void *p, size_t size, size_t nmemb ) {
-
- size_t iRc;
- iRc = fread( p, size, nmemb, fp );
- if( iRc == nmemb )
- return XB_NO_ERROR;
- else
- return XB_READ_ERROR;
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fseek.
-/*!
- \param lOffset Position in file to seek to
- \param iWhence SEEK_SET - from beginning of file<br>
- SEEK_CUR - from current position<br>
- SEEK_END - from end of file<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbFseek( xbInt64 lOffset, xbInt32 iWhence ) {
-
- xbInt32 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try {
-
- #if defined(HAVE_FSEEKO_F)
- iRc = fseeko( fp, lOffset, iWhence );
- if( iRc != 0 ){
- iErrorStop = 100;
- throw iRc;
- }
-
- #elif defined(HAVE__FSEEKI64_F)
- iRc = _fseeki64( fp, lOffset, iWhence );
- if( iRc != 0 ){
- iErrorStop = 110;
- throw iRc;
- }
- #else
- #ifdef XB_PLATFORM_32
- /* if request is larger than 2 gig,this is a part of a locking request,
- assuming offset is less than 4 gig, split the request into 2 fseek calls */
- if( lOffset > 2147483647 && iWhence == SEEK_SET ){
- /* move forward max amt - 2G */
- if(( iRc = fseek( fp, 2147483647, SEEK_SET )) != 0 ){
- iErrorStop = 120;
- throw iRc;
- }
- lOffset -= 2147483647;
- iWhence = SEEK_CUR;
- }
- #endif
- iRc = fseek( fp, (long) lOffset, iWhence );
- if( iRc != 0 ){
- iErrorStop = 310;
- throw iRc;
- }
- #endif
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFile::xbFseek() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- iRc = XB_SEEK_ERROR;
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary ftell.
-/*!
- Returns the current file position.
- \returns Current file position.
-*/
-
-size_t xbFile::xbFtell() {
- return (size_t) ftell( fp );
-}
-
-/************************************************************************/
-//! @brief Turn off file buffering.
-/*!
- Turns off file buffering. File buffering can't be used while in multi user mode.
-
-*/
-
-void xbFile::xbFTurnOffFileBuffering() {
- setvbuf( fp, NULL, _IONBF, 0 );
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for standard libary fwrite.
-/*!
- \param p Pointer to data buffer to write
- \param size Size of data to write
- \param nmemb Number of times to write data buffer
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbFile::xbFwrite( const void *p, size_t size, size_t nmemb ) {
-
- size_t iRc;
- iRc = fwrite( p, size, nmemb, fp );
- if( iRc == nmemb )
- return XB_NO_ERROR;
- else
- return XB_READ_ERROR;
-}
-
-/************************************************************************/
-//! @brief Read file until a particular character is encountered on input stream.
-/*!
- This routine will read until cDelim is encountered or eof, which ever occurs first.
-
- \param cDelim Delimiter to stop writing at.
- \param sOut Output xbString containing data read
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbReadUntil( const char cDelim, xbString &sOut ){
-
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char c;
-
- try{
- sOut = "";
- if(( iRc = xbFgetc( c )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- sOut = c;
- while( iRc == XB_NO_ERROR && c != cDelim ){
- if(( iRc = xbFgetc( c )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- sOut += c;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFile::xbReadUntil() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Delete file.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbFile::xbRemove() {
- return xbRemove( sFqFileName.Str(), 0 );
-}
-
-/************************************************************************/
-//! @brief Delete file.
-/*!
- \param sFileNameIn Name of file to delete
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbRemove( const xbString & sFileNameIn ) {
- return xbRemove( sFileNameIn, 0 );
-}
-
-
-/************************************************************************/
-//! @brief Delete file.
-/*!
- \param sFileNameIn Name of file to delete
- \param iOption If Set to 1, assume this is a delete request for a dbf file, and should rename the dbt file also
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbFile::xbRemove( const xbString & sFileNameIn, xbInt16 iOption ) {
-
- xbInt32 iRc = remove( sFileNameIn.Str());
-
- if( iRc != 0 )
- return XB_DELETE_FAILED;
-
- if( iOption == 1 ){
- xbString sFileName2 = sFileNameIn;
-
- if( sFileName2[sFileName2.Len()] == 'F' )
- sFileName2.PutAt( sFileName2.Len(), 'T' );
- else
- sFileName2.PutAt( sFileName2.Len(), 't' );
-
- iRc = remove( sFileName2.Str());
- if( iRc != 0 )
- return XB_DELETE_FAILED;
- }
-
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Rename file.
-/*!
- \param sOldName Original file name
- \param sNewName New file name
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbFile::xbRename( const xbString & sOldName, const xbString & sNewName ){
- if( rename( sOldName.Str(), sNewName.Str()))
- return XB_RENAME_ERROR;
- else
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for rewind.
-/*!
- Set file pointer at beginning of file.
-*/
-
-void xbFile::xbRewind() {
- rewind( fp );
-}
-
-/************************************************************************/
-//! @brief Xbase wrapper for ftruncate.
-/*!
- Set file size to llSize
- \param llSize New file size.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbFile::xbTruncate( xbInt64 llSize ) {
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- try{
- #ifdef HAVE_FTRUNCATE_F
- if(( iRc = ftruncate( iFileNo, llSize )) != 0 ){
- iErrorStop = 100;
- iRc = XB_WRITE_ERROR;
- throw iRc;
- }
- #elif defined(HAVE_SETENDOFFILE_F)
- if(( iRc = xbFseek( llSize, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- if(( iRc = SetEndOfFile( fHandle )) == 0 ){
- iErrorStop = 120;
- iRc = XB_WRITE_ERROR;
- throw iRc;
- } else {
- iRc = XB_NO_ERROR;
- }
- #else
-
- // check that cmake can find function SetEndOfFile -
- // cmake could not find for Borland 5.5
- FATAL_COMPILE_ERROR
- CANT_LOCATE_FUNCTION_ftruncate_or_SetEndOfFile
-
- #endif
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFile::xbTruncate() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-
-#ifdef XB_LOCKING_SUPPORT
-
-//! @brief Lock / unlock file.
-/*!
- \param iFunction XB_LOCK<br>
- XB_UNLOCK<br>
- \param lOffset Position in file to lock
- \param stLen Length to lock
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbFile::xbLock( xbInt16 iFunction, xbInt64 lOffset, size_t stLen ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbInt16 iTries = 0;
-
- try{
- #ifdef HAVE_FCNTL_F
- /* Unix lock function */
-
- if(( iRc = xbFseek( lOffset, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- struct flock fl;
- switch( iFunction ){
- case( XB_LOCK ):
- fl.l_type = F_WRLCK;
- break;
- case( XB_UNLOCK ):
- fl.l_type = F_UNLCK;
- break;
- default:
- iErrorStop = 110;
- iRc = XB_INVALID_LOCK_OPTION;
- throw iRc;
- break;
- }
- fl.l_whence = SEEK_CUR;
- fl.l_start = 0;
- fl.l_len = (xbInt32) stLen;
- do{
- iRc = fcntl( iFileNo, F_SETLK, &fl );
- if( iRc && (errno == EACCES || errno == EAGAIN )){
- iTries++;
- xbase->xbSleep( GetDefaultLockWait() );
- } else if( iRc ){
- iErrorStop = 120;
- iRc = XB_LOCK_FAILED;
- throw iRc;
- }
- } while( iRc && iTries < GetLockRetryCount());
- if( iRc )
- iRc = XB_LOCK_FAILED; // lock failed, don't log an exception
-
- #elif defined(HAVE_LOCKFILE_F)
- /* Windows 64 byte lock functions */
- /* split a quad word into two double words */
- typedef union{
- size_t Qword;
- xbUInt32 Dword[2];
- } Qsplit;
-
- Qsplit lPos;
- Qsplit lLen;
- lPos.Qword = (size_t) lOffset;
- lLen.Qword = stLen;
-
- do{
- if( iFunction == XB_LOCK ){
- if(( iRc = LockFile( fHandle, lPos.Dword[0], lPos.Dword[1], lLen.Dword[0], lLen.Dword[1] )) == 0 ){
- iTries++;
- xbase->xbSleep( GetDefaultLockWait() );
- }
- }
- else if( iFunction == XB_UNLOCK ){
- if(( iRc = UnlockFile( fHandle, lPos.Dword[0], lPos.Dword[1], lLen.Dword[0], lLen.Dword[1] )) == 0 ){
- iTries++;
- xbase->xbSleep( GetDefaultLockWait() );
- }
- }
- else
- {
- iErrorStop = 130;
- iRc = XB_INVALID_LOCK_OPTION;
- throw iRc;
- }
- } while( iRc == 0 && iTries < GetLockRetryCount());
- if( iRc == 0 )
- iRc = XB_LOCK_FAILED; // lock failed, don't log an exception
- else
- iRc = XB_NO_ERROR;
-
- #elif defined(HAVE_LOCKING_F) || defined(HAVE__LOCKING_F)
-
- /* older 32 bit locking functions */
- xbInt32 iLockType;
- if( iFunction == XB_LOCK ){
- iLockType = 2;
- } else if( iFunction == XB_UNLOCK ){
- iLockType = 0;
- } else {
- iErrorStop = 140;
- iRc = XB_INVALID_LOCK_OPTION;
- throw iRc;
- }
-
- if(( iRc = xbFseek( lOffset, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 150;
- iRc = XB_SEEK_ERROR;
- throw iRc;
- }
-
- do{
- #ifdef HAVE__LOCKING_F
- if(( iRc = _locking( iFileNo, iLockType, stLen )) != 0 ){
- #else
- if(( iRc = locking( iFileNo, iLockType, stLen )) != 0 ){
- #endif
- iTries++;
- xbase->xbSleep( GetDefaultLockWait() );
- }
- } while( iRc != 0 && iTries < GetLockRetryCount());
-
- if( iRc != 0 )
- iRc = XB_LOCK_FAILED; // lock failed, don't log an exception
- else
- iRc = XB_NO_ERROR;
-
- #else
-
- FATAL ERROR - CANT BUILD LIBRARY IN CURRENT CONFIG - MISSING - no file locking function defined in xbfile.cpp
-
- #endif
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFile::xbLock() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
-
- return iRc;
-
-
-}
-
-//! @brief Return the locking retry setting.
-/*!
-
- \returns The lock retry setting for this file or ths system default setting if the lock retry for the file
- has not been set.
-*/
-
-xbInt16 xbFile::GetLockRetryCount() const {
-
- if( iLockRetries == -1 )
- return xbase->GetDefaultLockRetries();
- else
- return iLockRetries;
-}
-
-//! @brief Set the lock retry countr for this specific file.
-/*!
- \param iLockRetries The number of retries to attempt before returning failure for this file
-*/
-
-void xbFile::SetLockRetryCount( xbInt16 iLockRetries ) {
- this->iLockRetries = iLockRetries;
-}
-
-#endif
-
-
-/***********************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-//! @brief Debugging routine - dump mem to the log file.
-/*!
- This routine dumps data from meemory to the log file. This is
- primarily used for debugging and analysis purposes.
-
- \param p Pointer to data to write
- \param lBlxkSize Size of block
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbFile::DumpMemToDisk( char *p, size_t lSize ){
-
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbString sDir;
- xbString sFn;
-
- FILE *fpd = NULL;
-
- try{
-
- // sDir = GetLogDirectory();
- sDir = xbase->GetLogDirectory();
-
- char cLastChar = sDir[sDir.Len()];
-
- // build logfile name
- if( cLastChar != '/' && cLastChar != '\\' )
- sFn.Sprintf( "%s/MemDump.txt", sDir.Str());
- else
- sFn.Sprintf( "%sMemDump.txt", sDir.Str());
-
- // open the dump file for append
- #ifdef HAVE__FSOPEN_F
- if(( fpd = _fsopen( sFn.Str(), "w+b", 0x40 )) == NULL ){
- #else
- if(( fpd = fopen( sFn.Str(), "w+b")) == NULL ){
- #endif
- iErrorStop = 100;
- iRc = XB_OPEN_ERROR;
- throw iRc;
- }
-
- int i;
- // dump the block to the file
- for( size_t l = 0; l < lSize; l++ ){
- i = *p;
- if( fputc( i, fpd ) == EOF ){
- iErrorStop = 110;
- iRc = XB_WRITE_ERROR;
- throw iRc;
- }
- p++;
- }
- // close the dump file
- fclose( fpd );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFile::DumpBlockToDisk() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( fpd )
- fclose( fpd );
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Debugging routine - dump a block to the log file.
-/*!
- This routine dumps a block to the log file. This is
- primarily used for debugging and analysis purposes.
-
- \param ulBlockNo Block number to write
- \param lBlxkSize Size of block
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbFile::DumpBlockToDisk( xbUInt32 ulBlockNo, size_t lBlkSize ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- xbUInt32 ulStartBlock;
- xbUInt32 ulEndBlock;
-
- char *p = 0x00;
-
- xbString sDir;
- xbString sFn;
- char *buf = NULL;
- FILE *fpd = NULL;
- try{
-
- if( ulBlockNo == 0 ){
- ulStartBlock = 0;
- xbUInt64 ullFileSizeulBlockNo;
- if(( iRc = GetFileSize( ullFileSizeulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- ulEndBlock = (xbUInt32) (ullFileSizeulBlockNo / lBlkSize);
- } else {
- ulStartBlock = ulBlockNo;
- ulEndBlock = ulBlockNo;
- }
-
- if(( buf = (char *) malloc( lBlkSize )) == NULL ){
- iErrorStop = 110;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
-// sDir = GetLogDirectory();
- sDir = xbase->GetLogDirectory();
- char cLastChar = sDir[sDir.Len()];
-
- for( xbUInt32 l = ulStartBlock; l < ulEndBlock; l++ ){
-
- if(( iRc = ReadBlock( l, lBlkSize, buf )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- // build logfile name
- if( cLastChar != '/' && cLastChar != '\\' )
- sFn.Sprintf( "%s/BlockDump.B%ld", sDir.Str(), l);
- else
- sFn.Sprintf( "%sBlockDump.%ld", sDir.Str(), l);
-
- // open the dump file for append
- #ifdef HAVE__FSOPEN_F
- if(( fpd = _fsopen( sFn.Str(), "w+b", 0x40 )) == NULL ){
- #else
- if(( fpd = fopen( sFn.Str(), "w+b")) == NULL ){
- #endif
- iErrorStop = 130;
- iRc = XB_OPEN_ERROR;
- throw iRc;
- }
-
- // dump the block to the file
- p = buf;
- for( size_t l = 0; l < lBlkSize; l++ ){
- //if( fputc( *p, fpd ) != *p ){
- if( fputc( *p, fpd ) == EOF ){
- iErrorStop = 140;
- iRc = XB_WRITE_ERROR;
- throw iRc;
- }
- p++;
- }
- // close the dump file
- fclose( fpd );
- }
-
- // free the buffer
- if( buf )
- free( buf );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFile::DumpBlockToDisk() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( buf )
- free( buf );
- if( fpd )
- fclose( fpd );
- }
- return iRc;
-}
-#endif
-/***********************************************************************/
-} /* namespace xb */
-
-
-
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbfilter.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbfilter.cpp
deleted file mode 100755
index 5c5f276..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbfilter.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-/* xbfilter.cpp
-
-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 module handles uda (user data area) methods
-
-*/
-
-#include "xbase.h"
-
-
-// might need to change thisto XB_EXPRESSION_SUPPORT
-#ifdef XB_FILTER_SUPPORT
-
-
-namespace xb{
-
-/************************************************************************/
-xbFilter::xbFilter( xbDbf *dbf ) {
- this->dbf = dbf;
- this->exp = NULL;
- lLimit = 0; // max number of responses
- lCurQryCnt = 0; // current number, this query + = moving fwd
- // - = moving backwards
-
- #ifdef XB_INDEX_SUPPORT
- pIx = NULL; // if index is set, the class uses the index tag, otherwise table
- vpTag = NULL;
- #endif // XB_INDEX_SUPPORT
-
-}
-/************************************************************************/
-xbFilter::~xbFilter() {
- if( exp )
- delete exp;
-}
-/************************************************************************/
-xbInt32 xbFilter::GetLimit() const {
- return lLimit;
-}
-/************************************************************************/
-xbInt32 xbFilter::GetQryCnt() const {
- return lCurQryCnt;
-}
-/************************************************************************/
-void xbFilter::SetLimit( xbInt32 lLimit ){
- this->lLimit = lLimit;
-}
-/************************************************************************/
-void xbFilter::ResetQryCnt(){
- this->lCurQryCnt = 0;
-}
-
-/************************************************************************/
-xbInt16 xbFilter::Set( const char *sFilter ) {
- xbString sFilt( sFilter );
- return Set( sFilt );
-}
-
-/************************************************************************/
-xbInt16 xbFilter::Set( xbString &sFilter ) {
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- if( exp )
- delete exp;
-
- exp = new xbExp( dbf->GetXbasePtr(), dbf );
- if(( iRc = exp->ParseExpression( sFilter.Str() )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if( exp->GetReturnType() != XB_EXP_LOGICAL ){
- iErrorStop = 110;
- iRc = XB_INVALID_EXPRESSION;
- delete exp;
- exp = NULL;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFilter::SetExpression() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/************************************************************************/
-xbInt16 xbFilter::GetFirstRecord( xbInt16 iOption ) {
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- if( !exp ){
- iErrorStop = 100;
- throw iRc;
- }
-
- lCurQryCnt = 0;
- if(( iRc = dbf->GetFirstRecord( iOption )) != XB_NO_ERROR ){
- if( iRc == XB_EMPTY || iRc == XB_EOF )
- return iRc;
- else{
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- xbBool bFound = xbFalse;
- while( !bFound && iRc == XB_NO_ERROR ){
- if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( !bFound ){
- if(( iRc = dbf->GetNextRecord( iOption )) != XB_NO_ERROR ){
- if( iRc == XB_EOF ){
- return iRc;
- } else {
- iErrorStop = 140;
- throw iRc;
- }
- }
- }
- }
- lCurQryCnt++;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFilter::GetFirstRecord() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/************************************************************************/
-xbInt16 xbFilter::GetNextRecord( xbInt16 iOption ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- if( !exp ){
- iErrorStop = 100;
- throw iRc;
- }
-
- if( lLimit != 0 && abs( lCurQryCnt ) >= lLimit )
- return XB_LIMIT_REACHED;
-
- if(( iRc = dbf->GetNextRecord( iOption )) != XB_NO_ERROR ){
- if( iRc == XB_EOF )
- return iRc;
- else{
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- xbBool bFound = xbFalse;
- while( !bFound && iRc == XB_NO_ERROR ){
- if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( !bFound ){
- if(( iRc = dbf->GetNextRecord( iOption )) != XB_NO_ERROR ){
- if( iRc == XB_EOF ){
- return iRc;
- } else {
- iErrorStop = 140;
- throw iRc;
- }
- }
- }
- }
- lCurQryCnt++;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFilter::GetNextRecord() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/************************************************************************/
-xbInt16 xbFilter::GetPrevRecord( xbInt16 iOption ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- if( !exp ){
- iErrorStop = 100;
- throw iRc;
- }
-
- if( lLimit != 0 && abs( lCurQryCnt ) >= lLimit )
- return XB_LIMIT_REACHED;
-
- if(( iRc = dbf->GetPrevRecord( iOption )) != XB_NO_ERROR ){
- if( iRc == XB_BOF )
- return iRc;
- else{
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- xbBool bFound = xbFalse;
- while( !bFound && iRc == XB_NO_ERROR ){
- if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( !bFound ){
- if(( iRc = dbf->GetPrevRecord( iOption )) != XB_NO_ERROR ){
- if( iRc == XB_BOF ){
- return iRc;
- } else {
- iErrorStop = 140;
- throw iRc;
- }
- }
- }
- }
- lCurQryCnt--;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFilter::GetPrevRecord() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/************************************************************************/
-xbInt16 xbFilter::GetLastRecord( xbInt16 iOption ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- if( !exp ){
- iErrorStop = 100;
- throw iRc;
- }
-
- lCurQryCnt = 0;
- if(( iRc = dbf->GetLastRecord( iOption )) != XB_NO_ERROR ){
- if( iRc == XB_EOF )
- return iRc;
- else{
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- xbBool bFound = xbFalse;
- while( !bFound && iRc == XB_NO_ERROR ){
- if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( !bFound ){
- if(( iRc = dbf->GetPrevRecord( iOption )) != XB_NO_ERROR ){
- if( iRc == XB_BOF ){
- return iRc;
- } else {
- iErrorStop = 140;
- throw iRc;
- }
- }
- }
- }
- lCurQryCnt--;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFilter::GetLastRecord() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-
-#ifdef XB_INDEX_SUPPORT
-
-/************************************************************************/
-xbInt16 xbFilter::GetFirstRecordIx( xbInt16 iOption ) {
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- if( !exp ){
- iErrorStop = 100;
- throw iRc;
- }
-
- lCurQryCnt = 0;
- if(( iRc = dbf->GetCurIx()->GetFirstKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){
- if( iRc == XB_EMPTY || iRc == XB_EOF )
- return iRc;
- else{
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- xbBool bFound = xbFalse;
- while( !bFound && iRc == XB_NO_ERROR ){
- if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( !bFound ){
- // if(( iRc = pIx->GetNextKey( vpTag, iOption )) != XB_NO_ERROR ){
- if(( iRc = dbf->GetCurIx()->GetNextKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){
- if( iRc == XB_EOF ){
- return iRc;
- } else {
- iErrorStop = 140;
- throw iRc;
- }
- }
- }
- }
- lCurQryCnt++;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFilter::GetFirstRecordIx() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/************************************************************************/
-xbInt16 xbFilter::GetNextRecordIx( xbInt16 iOption ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- if( !exp ){
- iErrorStop = 100;
- throw iRc;
- }
-
- if( lLimit != 0 && abs( lCurQryCnt ) >= lLimit )
- return XB_LIMIT_REACHED;
-
- if(( iRc = dbf->GetCurIx()->GetNextKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){
- if( iRc == XB_EOF )
- return iRc;
- else{
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- xbBool bFound = xbFalse;
- while( !bFound && iRc == XB_NO_ERROR ){
- if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( !bFound ){
- // if(( iRc = pIx->GetNextKey( vpTag, iOption )) != XB_NO_ERROR ){
- if(( iRc = dbf->GetCurIx()->GetNextKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){
- if( iRc == XB_EOF ){
- return iRc;
- } else {
- iErrorStop = 140;
- throw iRc;
- }
- }
- }
- }
- lCurQryCnt++;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFilter::GetNextRecordIx() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/************************************************************************/
-xbInt16 xbFilter::GetPrevRecordIx( xbInt16 iOption ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- if( !exp ){
- iErrorStop = 100;
- throw iRc;
- }
-
- if( lLimit != 0 && abs( lCurQryCnt ) >= lLimit )
- return XB_LIMIT_REACHED;
-
- if(( iRc = dbf->GetCurIx()->GetPrevKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){
- if( iRc == XB_BOF )
- return iRc;
- else{
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- xbBool bFound = xbFalse;
- while( !bFound && iRc == XB_NO_ERROR ){
- if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( !bFound ){
- //if(( iRc = pIx->GetPrevKey( vpTag, iOption )) != XB_NO_ERROR ){
- if(( iRc = dbf->GetCurIx()->GetPrevKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){
- if( iRc == XB_BOF ){
- return iRc;
- } else {
- iErrorStop = 140;
- throw iRc;
- }
- }
- }
- }
- lCurQryCnt--;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFilter::GetPrevRecordIx() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/************************************************************************/
-xbInt16 xbFilter::GetLastRecordIx( xbInt16 iOption ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- if( !exp ){
- iErrorStop = 100;
- throw iRc;
- }
- lCurQryCnt = 0;
- if(( iRc = dbf->GetCurIx()->GetLastKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){
- if( iRc == XB_EOF )
- return iRc;
- else{
- iErrorStop = 110;
- throw iRc;
- }
- }
- xbBool bFound = xbFalse;
- while( !bFound && iRc == XB_NO_ERROR ){
- if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( !bFound ){
- if(( iRc = dbf->GetCurIx()->GetPrevKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){
- if( iRc == XB_BOF ){
- return iRc;
- } else {
- iErrorStop = 140;
- throw iRc;
- }
- }
- }
- }
- lCurQryCnt--;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbFilter::GetLastRecordIx() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- dbf->GetXbasePtr()->WriteLogMessage( sMsg.Str() );
- dbf->GetXbasePtr()->WriteLogMessage( dbf->GetXbasePtr()->GetErrorMessage( iRc ));
- }
- return iRc;
-}
-#endif // XB_INDEX_SUPPORT
-
-
-/************************************************************************/
-} /* namespace */
-#endif /* XB_FILTER_SUPPORT */ \ No newline at end of file
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbfuncs.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbfuncs.cpp
deleted file mode 100755
index f127211..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbfuncs.cpp
+++ /dev/null
@@ -1,851 +0,0 @@
-/* xbfuncs.cpp
-
-XBase64 Software Library
-
-Copyright (c) 1997,2003,2014,2017,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 "xbase.h"
-
-#ifdef XB_FUNCTION_SUPPORT
-
-namespace xb{
-
-
-// All funtions have a similar structure, return an xbInt16 return code
-// Have a variable number of input operands and one output operand
-
-/************************************************************************/
-//! @brief Calculate absolute value of a numeric expression.
-/*!
- Expression function ABS().
- \param dIn Input - Numeric expression.
- \param dOut Output - Absolute value.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbXBase::ABS( xbDouble dIn, xbDouble &dOut ){
- if( dIn < 0 )
- dOut = dIn * -1;
- else
- dOut = dIn;
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Trim leading and trailing white space from a string.
-/*!
- Expression function ALLTRIM().
- \param sIn Input - Input string to trim.
- \param sOut Output - Trimmed string.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbXBase::ALLTRIM( const xbString &sIn, xbString &sOut ){
- sOut = sIn;
- sOut.Trim();
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Return ASCII code for the first character in a string.
-/*!
- Expression function ASC().
- \param sIn Input - Input character string.
- \param dAscOut Output - Ascii code of first character in string.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::ASC( const xbString &sIn, xbDouble &dAscOut ){
- if( sIn == "" )
- return XB_PARSE_ERROR;
-
- dAscOut = sIn[1];
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief Return number indicating starting position of string within a string.
-/*!
- Expression function AT().
- \param s1 Input - Input string to search for.
- \param s2 Input - Input string to search.
- \param dPos Output - Position of string s1 within s2.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::AT( const xbString &s1, const xbString &s2, xbDouble &dPos ){
- /* looks for s1 in s2 */
- xbInt32 lCnt = 0;
- const char *p;
- const char *p2 = s2;
- if( strlen( s1 ) > strlen( s2 )) return 0;
- if(( p = strstr( s2, s1 )) == NULL )
- return XB_NO_ERROR;
- while( p2++ != p ) lCnt++;
- dPos = lCnt + 1;
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Return character weekday name for date.
-/*!
- Expression function CDOW().
- \param dInDate Input - Input date.
- \param sOutDow Output - Character day of week.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::CDOW( xbDate &dInDate, xbString &sOutDow ){
- return dInDate.CharDayOf( sOutDow );
-}
-
-/*************************************************************************/
-//! @brief Convert numeric expression to a character.
-/*!
- Expression function CHR().
- \param dAsciCd Input - Numeric expression.
- \param sOut Output - Character result.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::CHR( xbDouble dAsciCd, xbString &sOut ){
- static char buf[2];
- buf[0] = (char) dAsciCd;
- buf[1] = 0x00;
- sOut = buf;
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Return character month name for date.
-/*!
- Expression function CMONTH().
- \param dInDate Input - Input date.
- \param sOutMonth Output - Character month.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::CMONTH( xbDate &dInDate, xbString &sOutMonth ){
- return dInDate.CharMonthOf( sOutMonth );
-}
-/*************************************************************************/
-//! @brief Return date from character input date.
-/*!
- Expression function CTOD().
- \param sInDate Input - Input date in MM/DD/YY format.
- \param dOutDate Output - Output date.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::CTOD( const xbString &sInDate, xbDate &dOutDate ){
- return dOutDate.CTOD( sInDate );
-}
-/*************************************************************************/
-//! @brief Return system date.
-/*!
- Expression function DATE().
- \param dOutDate Output - Output date.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::DATE( xbDate &dOutDate ){
- return dOutDate.Sysdate();
-}
-/*************************************************************************/
-//! @brief Return the day of the month from a date.
-/*!
- Expression function DAY().
- \param dInDate Input - Input date.
- \param dOutDay Output - Output day of month.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::DAY( const xbDate &dInDate, xbDouble &dOutDay ){
- xbInt16 iOutDay;;
- iOutDay = dInDate.DayOf( XB_FMT_MONTH );
- if( iOutDay < 0 ){
- return iOutDay;
- }else{
- dOutDay = iOutDay;
- return XB_NO_ERROR;
- }
-}
-/*************************************************************************/
-//! @brief Return record deletion status for current record.
-/*!
- Expression function DEL().
- \param dbf Input - Table to check record deletion status.
- \param iRecBufSw Input - Which buffer. 0 = Current record buffer, 1 = Original record buffer
- \param sOut Output - "*" if record is deleted, otherise space.
- \returns XB_NO_ERROR<br>XB_PARSE_ERROR.
-
-*/
-xbInt16 xbXBase::DEL( xbDbf *dbf , xbString &sOut, xbInt16 iRecBufSw ) {
-
- if( dbf ){
- if( dbf->RecordDeleted( iRecBufSw ))
- sOut = "*";
- else
- sOut = " ";
- return XB_NO_ERROR;
- } else {
- return XB_PARSE_ERROR;
- }
-}
-
-/*************************************************************************/
-//! @brief Return record deletion status for current record.
-/*!
- Expression function DELETED().
- \param dbf Input - Table to check record deletion status for.
- \param iRecBufSw Input - Which buffer. 0 = Current record buffer, 1 = Original record buffer
- \param bOut Output - xbTrue if record is deleted.<br>xbFalse if record is not deleted.
- \returns XB_NO_ERROR<br>XB_PARSE_ERROR.
-*/
-xbInt16 xbXBase::DELETED( xbDbf *dbf , xbBool &bOut, xbInt16 iRecBufSw ) {
-
- if( dbf ){
- bOut = dbf->RecordDeleted( iRecBufSw );
- return XB_NO_ERROR;
- } else {
- return XB_PARSE_ERROR;
- }
-}
-
-/*************************************************************************/
-//! @brief Clipper DESCEND function.
-/*!
- Expression function DESCEND().
- \param dtInDate Input - Input date.
- \param dtOutDate Output - Output date.
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbXBase::DESCEND( const xbDate &dtInDate, xbDate &dtOutDate ){
- xbDate d( "29991231" );
- dtOutDate.JulToDate8( 2415021 + d.JulianDays() - dtInDate.JulianDays());
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Clipper DESCEND function.
-/*!
- Expression function DESEND().
- \param dIn Input - Input number.
- \param dOut Output - Output number.
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbXBase::DESCEND( xbDouble dIn, xbDouble &dOut ){
- dOut = dIn * -1;
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Clipper DESCEND function.
-/*!
- Expression function DESEND().
- \param sIn Input - Input string.
- \param sOut Output - Output string.
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbXBase::DESCEND( const xbString &sIn, xbString &sOut ){
-
- sOut = sIn;
- for( xbUInt32 l = 0; l < sIn.Len(); l++ )
- sOut.PutAt( l+1, (char) (255 - sOut[l+1]));
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Return number of day of week.
-/*!
- Expression function DOW().
- \param dtInDate Input - Input date.
- \param dDowOut Output - Output day of week.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::DOW( const xbDate &dtInDate, xbDouble &dDowOut ){
- xbInt16 iDow;
- iDow = dtInDate.DayOf( XB_FMT_WEEK );
- if( iDow < 0 ){
- return XB_PARSE_ERROR;
- }else{
- dDowOut = iDow;
- return XB_NO_ERROR;
- }
-}
-
-/*************************************************************************/
-//! @brief Return character date from input date.
-/*!
- Expression function DTOC().
- \param dInDate Input - Input date.
- \param sOutFmtDate Output - Output date.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::DTOC( xbDate &dInDate, xbString &sOutFmtDate ){
- return dInDate.FormatDate( "MM/DD/YY", sOutFmtDate );
-}
-/*************************************************************************/
-//! @brief Return char CCYYMMDD date from input date.
-/*!
- Expression function DTOS().
- \param dtInDate Input - Input date.
- \param sOutFmtDate Output - Output date.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::DTOS( xbDate &dtInDate, xbString &sOutFmtDate ){
- return dtInDate.FormatDate( "YYYYMMDD", sOutFmtDate );
-}
-/*************************************************************************/
-//! @brief Return exponent value.
-/*!
- Expression function EXP().
- This function returns e**x where e is approximately 2.71828 and x is dIn.
-
- \param dIn Input - exp value.
- \param dOut Output - value.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbXBase::EXP( xbDouble dIn, xbDouble &dOut )
-{
- dOut = exp( dIn );
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief Immediate if.
-/*!
- Expression function IIF().
- \param bResult Input - boolean expression.
- \param sTrueResult Input - value if boolean expression is true.
- \param sFalseResult Input - value if boolean expression is false.
- \param sResult Output - sTrueResult or sFalseResult depending on bResultvalue.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbXBase::IIF( xbBool bResult, const xbString &sTrueResult, const xbString &sFalseResult, xbString &sResult )
-{
- if( sFalseResult.Len() != sTrueResult.Len())
- return XB_INCONSISTENT_PARM_LENS;
- if( bResult )
- sResult = sTrueResult;
- else
- sResult = sFalseResult;
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief Convert number to integer, truncate any decimals.
-/*!
- Expression function INT().
- \param dIn Input - Input number.
- \param dOut Output - integer.
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbXBase::INT( xbDouble dIn, xbDouble &dOut )
-{
- xbInt64 ll = (xbInt64) dIn;
- dOut = (xbDouble) ll;
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Check if string begins with alpha character.
-/*!
- Expression function ISALPHA().
- \param sIn Input - Input string.
- \param bResult Output - xbTrue if string begins with alpha character.<br>xbFalse if string does not begin with alpha character.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbXBase::ISALPHA( const xbString &sIn, xbBool &bResult ){
- if( isalpha(sIn[1]))
- bResult = 1;
- else
- bResult = 0;
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Check if string begins with lower case alpha character.
-/*!
- Expression function ISLOWER().
- \param sIn Input - Input string.
- \param bResult Output - xbTrue if string begins with lower case alpha character.<br>
- xbFalse if string does not begin with lower case alpha character.
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbXBase::ISLOWER( const xbString &sIn, xbBool &bResult ){
- if( islower(sIn[1]))
- bResult = 1;
- else
- bResult = 0;
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief Check if string begins with upper case alpha character.
-/*!
- Expression function ISUPPER().
- \param sIn Input - Input string.
- \param bResult Output - xbTrue if string begins with upper case alpha character.<br>
- xbFalse if string does not begin with upper case alpha character.
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbXBase::ISUPPER( const xbString &sIn, xbBool &bResult ){
- if( isupper(sIn[1]))
- bResult = 1;
- else
- bResult = 0;
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Return left characters from string.
-/*!
- Expression function LEFT().
- \param sIn Input - string.
- \param ulCharCnt Input - number of characters to extract from string.
- \param sOut Output - resultant string.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbXBase::LEFT( const xbString &sIn, xbUInt32 ulCharCnt, xbString &sOut ){
- sOut.Assign( sIn, 1, ulCharCnt );
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Return length of string.
-/*!
- Expression function LEN().
- \param sIn Input - Input string.
- \param dOut Output - string length.
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbXBase::LEN( const xbString &sIn, xbDouble &dOut ){
- dOut = sIn.Len();
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Calculate logarithm.
-/*!
- Expression function LOG().
- \param dIn Input - numeric expression.
- \param dOut Output - numeric log value.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbXBase::LOG( xbDouble dIn, xbDouble &dOut ){
- dOut = log( dIn );
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief Trim left side of string.
-/*!
- Expression function LTRIM().
- \param sIn Input - string.
- \param sOut Output - string result.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbXBase::LTRIM( const xbString &sIn, xbString &sOut ){
- sOut = sIn;
- sOut.Ltrim();
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief Convert upper case to lower case.
-/*!
- Expression function LOWER().
- \param sIn Input - string.
- \param sOut Output - string result.
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbXBase::LOWER( const xbString &sIn, xbString &sOut ){
- sOut = sIn;
- sOut.ToLowerCase();
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Return higher of two values.
-/*!
- Expression function MAX().
- \param d1 Input - Numeric value 1.
- \param d2 Input - Numeric value 2.
- \param dOut Output - Higher of d1 or d2.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbXBase::MAX( xbDouble d1, xbDouble d2, xbDouble &dOut )
-{
- if( d1 > d2 )
- dOut = d1;
- else
- dOut = d2;
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Return lessor of two values.
-/*!
- Expression function MIN().
- \param d1 Input - Numeric value 1.
- \param d2 Input - Numeric value 2.
- \param dOut Output - Lessor of d1 or d2.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbXBase::MIN( xbDouble d1, xbDouble d2, xbDouble &dOut )
-{
- if( d1 < d2 )
- dOut = d1;
- else
- dOut = d2;
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Return number of month for a given date.
-/*!
- Expression function MONTH().
- \param dInDate Input date.
- \param dOutMonth - Month number.
- \returns XB_NO_ERROR.<br>XB_PARSE_ERROR.
-*/
-xbInt16 xbXBase::MONTH( xbDate &dInDate, xbDouble &dOutMonth ){
-
- xbInt16 iRc = dInDate.MonthOf();
- if( iRc < 0 )
- return XB_PARSE_ERROR;
- else{
- dOutMonth = iRc;
- return XB_NO_ERROR;
- }
-}
-
-/*************************************************************************/
-//! @brief Return number of records in a given table.
-/*!
- Expression function RECCOUNT().
- \param dbf - Table.
- \param dOut - Number of records.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::RECCOUNT( xbDbf *dbf , xbDouble &dOut ) {
-
- xbUInt32 ulRecCnt;
- xbInt16 iRc = dbf->GetRecordCnt( ulRecCnt );
- dOut = (xbDouble) ulRecCnt;
- return iRc;
-
-}
-
-/*************************************************************************/
-//! @brief Return current record number for a given table.
-/*!
- Expression function RECNO().
- \param dbf - Table.
- \param dOut - Record number.
- \returns XB_NO_ERROR.<br>XB_PARSE_ERROR.
-*/
-
-xbInt16 xbXBase::RECNO( xbDbf *dbf , xbDouble &dOut ) {
- if( dbf ){
- dOut = (xbDouble) dbf->GetCurRecNo();
- return XB_NO_ERROR;
- } else {
- dOut = -1;
- return XB_PARSE_ERROR;
- }
-}
-
-/*************************************************************************/
-//! @brief Repeat character expression N times.
-/*!
- Expression function REPLICATE().
- \param sIn Inout - String to replicate.
- \param ulRepCnt Input - Number of times to repeat.
- \param sOut Output - String result.
- \returns XB_NO_ERROR.<br>XB_PARSE_ERROR.
-*/
-xbInt16 xbXBase::REPLICATE( const xbString &sIn, xbUInt32 ulRepCnt, xbString &sOut ){
- sOut = "";
- for( xbUInt32 i = 0; i < ulRepCnt; i++ )
- sOut += sIn;
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Return right characters from string.
-/*!
- Expression function RIGHT().
- \param sIn Input - string.
- \param ulCharCnt Input - number of characters to extract from string.
- \param sOut Output - resultant string.
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbXBase::RIGHT( const xbString &sIn, xbUInt32 ulCharCnt, xbString &sOut ){
- if( sIn.Len() < ulCharCnt )
- sOut = sIn;
- else
- sOut.Assign( sIn, sIn.Len() - ulCharCnt + 1, ulCharCnt );
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Trim right side of string.
-/*!
- Expression function RTRIM().
- \param sIn Input - string.
- \param sOut Output - string result.
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbXBase::RTRIM( const xbString &sIn, xbString &sOut ){
- sOut = sIn;
- sOut.Rtrim();
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Generate a string of N spaces.
-/*!
- Expression function SPACE().
- \param lCnt Input - Number of spaces.
- \param sOut Output - Output string consisting of specified number of spaces.
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbXBase::SPACE( xbInt32 lCnt, xbString &sOut ){
- sOut = "";
- for( xbInt32 i = 0; i < lCnt; i++ )
- sOut += ' ';
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Calculate a square root.
-/*!
- Expression function SQRT().
- \param dBase Input - Base number.
- \param dSqrRoot Output - Square root.
- \returns XB_NO_ERROR.
-*/
-
-xbInt16 xbXBase::SQRT( xbDouble dBase, xbDouble &dSqrRoot )
-{
- dSqrRoot = sqrt( dBase );
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Converts a valid 8 byte (CCYYMMDD) input date into a date class.
-/*!
- Expression function STOD().
- \param sInDate Input - Input date.
- \param dtOutDate Output - Output date.
- \returns XB_NO_ERROR.<br>XB_INVALID_DATE.
-*/
-
-xbInt16 xbXBase::STOD( const xbString &sInDate, xbDate &dtOutDate ){
-
- if( dtOutDate.DateIsValid( sInDate )){
- dtOutDate = sInDate;
- return XB_NO_ERROR;
- } else {
- return XB_INVALID_DATE;
- }
-}
-
-/*************************************************************************/
-//! @brief Convert number to a character string.
-/*!
- Expression function STR().
- \param dIn Input - Number.
- \param sOut Output - String.
- \returns XB_NO_ERROR.
-*/
-
-xbInt16 xbXBase::STR( xbDouble dIn, xbString &sOut) {
- xbString sPadChar = " ";
- return STR( dIn, 10, 0, sPadChar, sOut );
-}
-
-/*************************************************************************/
-//! @brief Convert number to a character string.
-/*!
- Expression function STR().
- \param dIn Input - Number.
- \param ulLen Input - Length.
- \param sOut Output - String.
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbXBase::STR( xbDouble dIn, xbUInt32 ulLen, xbString &sOut) {
- xbString sPadChar = " ";
- return STR( dIn, ulLen, 0, sPadChar, sOut );
-}
-
-/*************************************************************************/
-//! @brief Convert number to a character string.
-/*!
- Expression function STR().
- \param dIn Input - Number.
- \param ulLen Input - Length.
- \param ulDec Input - Number of decimals.
- \param sOut Output - String.
- \returns XB_NO_ERROR.
-*/
-
-xbInt16 xbXBase::STR( xbDouble dIn, xbUInt32 ulLen, xbUInt32 ulDec, xbString &sOut) {
- xbString sPadChar = " ";
- return STR( dIn, ulLen, ulDec, sPadChar, sOut );
-}
-
-/*************************************************************************/
-//! @brief Convert number to a character string.
-/*!
- Expression function STR().
- \param dIn Input - Number.
- \param ulLen Input - Length.
- \param ulDec Input - Number of decimals.
- \param sPadChar Input - Left pad character, typically zero or space.
- \param sOut Output - String.
- \returns XB_NO_ERROR.
-*/
-
-xbInt16 xbXBase::STR( xbDouble dIn, xbUInt32 ulLen, xbUInt32 ulDec, xbString &sPadChar, xbString &sOut) {
-
- xbString sFmt;
- sFmt.Sprintf( "%c%d.%df", '%', ulLen, ulDec );
- sOut.Sprintf( sFmt.Str(), dIn, 0 );
-
- // convert to all "*" if result is too long
- if( sOut.Len() > ulLen ){
- sOut = "*";
- do{
- sOut += "*";
- } while( ulLen > sOut.Len());
- } else if( sPadChar.Len() > 0 && sPadChar != " " ){
- // this logic doesn't make sense when processing negative numbers,
- // but it does behave like the original dbase
- // you could end up with something like 0000-12.17 when you really want -000012.17
- // that is probably why the STRZERO function came into being
- xbUInt32 l = 1;
- while( sOut[l] == ' ' ){
- sOut.PutAt( l, sPadChar[1]);
- l++;
- }
- }
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Convert number to a character string with leading zeroes.
-/*!
- Expression function STRZERO().
- \param dIn Input - Number.
- \param ulLen Input - Length.
- \param ulDec Input - Number of decimals.
- \param sOut Output - String.
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbXBase::STRZERO( xbDouble dIn, xbUInt32 ulLen, xbUInt32 ulDec, xbString &sOut){
-
- xbString sFmt;
- if( dIn < 0 )
- sFmt.Sprintf( "%c+0%d.%df", '%', ulLen, ulDec );
- else
- sFmt.Sprintf( "%c0%d.%df", '%', ulLen, ulDec );
- sOut.Sprintf( sFmt.Str(), dIn );
-
- // convert to all "*" if result is too long
- if( sOut.Len() > ulLen ){
- sOut = "*";
- do{
- sOut += "*";
- } while( ulLen > sOut.Len());
- }
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Extract a portion of a string from another string.
-/*!
- Expression function SUBSTR().
- \param sIn Input - Source string.
- \param ulStartPos Input - Starting position for string extraction.
- \param ulLen Input - Number of characters to extract.
- \param sOut Output - String.
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbXBase::SUBSTR( const xbString &sIn, xbUInt32 ulStartPos, xbUInt32 ulLen, xbString &sOut ){
- sOut = sIn;
- sOut.Mid( ulStartPos, ulLen );
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Trim left and right sides of string.
-/*!
- Expression function TRIM().
- \param sIn Input - string.
- \param sOut Output string result.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbXBase::TRIM( const xbString &sIn, xbString &sOut ){
- return RTRIM( sIn, sOut );
-}
-
-/*************************************************************************/
-//! @brief Convert lower case to upper case.
-/*!
- Expression function UPPER().
- \param sIn Input - string.
- \param sOut Output - string result.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbXBase::UPPER( const xbString &sIn, xbString &sOut ){
- sOut = sIn;
- sOut.ToUpperCase();
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Convert numeric characters to number.
-/*!
- Expression function VAL().
- \param sIn Input - string.
- \param dOut Output - numeric result.
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbXBase::VAL( const xbString &sIn, xbDouble &dOut )
-{
- if( sIn )
- // strtod(nptr,NULL);
- dOut = atof( sIn );
- else
- dOut = 0;
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! @brief Return year for a given date.
-/*!
- Expression function YEAR().
- \param dInDate Input date.
- \param dOutYear - Year.
- \returns XB_NO_ERROR.<br>XB_PARSE_ERROR.
-*/
-
-xbInt16 xbXBase::YEAR( xbDate &dInDate, xbDouble &dOutYear ){
-
- xbInt16 iRc = dInDate.YearOf();
- if( iRc < 0 )
- return XB_PARSE_ERROR;
- else{
- dOutYear = iRc;
- return XB_NO_ERROR;
- }
-}
-/*************************************************************************/
-}; // namespace
-#endif // XB_FUNCTION_SUPPORT
-/*************************************************************************/
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbixbase.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbixbase.cpp
deleted file mode 100755
index e2f929c..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbixbase.cpp
+++ /dev/null
@@ -1,789 +0,0 @@
-/* xbixbase.cpp
-
-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
-
- Base index class
-
-*/
-
-#include "xbase.h"
-#ifdef XB_INDEX_SUPPORT
-
-namespace xb{
-
-/***********************************************************************/
-//! @brief Class constructor.
-/*!
- /param dbf Pointer to dbf instance.
-*/
-xbIx::xbIx( xbDbf *dbf ) : xbFile( dbf->GetXbasePtr()) {
- this->dbf = dbf;
- vpCurTag = NULL;
- cNodeBuf = NULL;
- bLocked = xbFalse;
-}
-/***********************************************************************/
-//! @brief Class Destructor.
-xbIx::~xbIx(){}
-
-
-/***********************************************************************/
-//! @brief Add Keys for record number
-/*!
- For a given a record number, add keys to each tag in the index file
- if it was updated
-
- \param ulRecNo Record number to add keys for
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIx::AddKeys( xbUInt32 ulRecNo ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbInt16 i = 0;
- xbInt16 iKeySts;
-
- try{
- void * vpTag;
- xbInt16 iTagCount = GetTagCount();
-
- for( i = 0; i < iTagCount; i++ ){
- vpTag = GetTag( i );
- iKeySts = GetKeySts( vpTag );
-
- if( iKeySts == 1 || iKeySts == 2 ){
- if(( iRc = UpdateTagKey( 'A', vpTag, ulRecNo )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIx::AddKeys() Exception Caught. Error Stop = [%d] iRc = [%d] Tag=[%d]", iErrorStop, iRc, i );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Allocate memory for index node.
-/*!
- Allocate an index node.
-
- \param ulBufSize Size of buffer to allocate
- \returns null on error<br>Pointer to newly allocated xbIxNode on success
-*/
-xbIxNode * xbIx::AllocateIxNode( xbUInt32 ulBufSize, xbInt16 )
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- xbIxNode * pNode = (xbIxNode *) calloc( 1, sizeof( xbIxNode ));
- if( pNode == NULL ){
- iErrorStop = 100;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- if( ulBufSize == 0 )
- ulBufSize = GetBlockSize();
-
- pNode->ulBufSize = ulBufSize;
- pNode->cpBlockData = (char *) calloc( 1, ulBufSize );
- if( pNode->cpBlockData == NULL ){
- free( pNode );
- iErrorStop = 110;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- return pNode;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIx::AllocateIxNode() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return NULL;
-}
-
-
-/***********************************************************************/
-//! @brief Binary search for given value on an index node.
-/*!
-
- Binary search for key lookups
- \param cKeyType Key type
- \param npNode Pointer to index node for search
- \param lKeyItemLen Lenth of key plus pointer values
- \param vpKey Pointer to key value
- \param lSearchKeyLen length of key to search
- \param iCompRc output return code from the CompareKey routine. CompareKey returns an
- integer value less than, equal to or greater than zero in when comparing values
-
- \param bDescending xbTrue for descending index key lookup.<br>
- xbFalse for ascending index key lookup.
- \return The position in the node the key was found, if multiples it returns the first occurrence.
- If the key is not found, it returns the slot it should be in.
-*/
-
-xbInt16 xbIx::BSearchBlock( char cKeyType, xbIxNode *npNode, xbInt32 lKeyItemLen, const void *vpKey,
- xbInt32 lSearchKeyLen, xbInt16 &iCompRc, xbBool bDescending ) const {
- xbInt32 lLo = 0;
- xbInt32 lHi = 0;
- xbInt32 lMid = 0;
- xbInt32 lKeyCnt = GetKeyCount( npNode );
-
-
- if( !bDescending ){
- lHi = lKeyCnt - 1;
-
- while( lLo <= lHi ){
- lMid = (lLo + lHi) / 2;
- iCompRc = CompareKey( cKeyType, GetKeyData( npNode, lMid, lKeyItemLen ), vpKey, (size_t) lSearchKeyLen );
- if( iCompRc > 0 )
- lHi = lMid - 1;
- else if( iCompRc < 0 )
- lLo = lMid + 1;
- else{ // found match, look for leftmost occurrence
-
- xbInt32 lFoundPos = lMid;
- lMid--;
- while( lMid >= 0 && CompareKey( cKeyType, GetKeyData( npNode, lMid, lKeyItemLen ), vpKey, (size_t) lSearchKeyLen ) == 0 ){
- lFoundPos = lMid;
- lMid--;
- }
- iCompRc = 0;
- lLo = lFoundPos;
- lHi = -1;
- }
- }
- // update the compare key results
- if( lMid != lLo ){
- if( lLo >= lKeyCnt )
- iCompRc = 1;
- else
- iCompRc = CompareKey( cKeyType, GetKeyData( npNode, lLo, lKeyItemLen ), vpKey, (size_t) lSearchKeyLen );
- }
- return (xbInt16) lLo;
-
- } else { // descending key
-
- lLo = lKeyCnt - 1;
- while( lLo >= lHi && lHi != -1 ){
- lMid = (lLo + lHi) / 2;
- iCompRc = CompareKey( cKeyType, GetKeyData( npNode, lMid, lKeyItemLen ), vpKey, (size_t) lSearchKeyLen );
-
- if( iCompRc > 0 ) {
- lHi = lMid + 1;
- }
- else if( iCompRc < 0) {
- lLo = lMid - 1;
- }
- else{ // found match, look for leftmost occurrence
-
- xbInt32 lFoundPos = lMid;
- lMid--;
- while( lMid >= 0 && CompareKey( cKeyType, GetKeyData( npNode, lMid, lKeyItemLen ), vpKey, (size_t) lSearchKeyLen ) == 0 ){
- lFoundPos = lMid;
- lMid--;
- }
- iCompRc = 0;
- lHi = lFoundPos;
- lLo = -1;
- }
- }
-
- // std::cout << "BSB1 lo = " << lLo << " mid = " << lMid << " hi = " << lHi << " keycnt = " << lKeyCnt << " iCompRc = " << iCompRc << "\n"; // key=" << (char *) vpKey << "\n";
- if( lLo < 0 && iCompRc < 0 )
- iCompRc = 1;
- else if( iCompRc != 0 ) {
- iCompRc = CompareKey( cKeyType, GetKeyData( npNode, (lLo < 0 ? 0 : lLo), lKeyItemLen ), vpKey, (size_t) lSearchKeyLen );
- }
- // std::cout << "BSB2 lo = " << lLo << " mid = " << lMid << " hi = " << lHi << " keycnt = " << lKeyCnt << " iCompRc = " << iCompRc << "\n"; // key=" << (char *) vpKey << "\n";
- return (xbInt16) lHi;
- }
-
- // should never get here
- // return (xbInt16) 0;
-}
-
-/***********************************************************************/
-//! @brief Check for duplicate keys.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::CheckForDupKeys(){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbInt16 i = 0;
-
- try{
- void * vpTag;
- xbInt16 iTagCount = GetTagCount();
- for( i = 0; i < iTagCount; i++ ){
- vpTag = GetTag( i );
- if(( iRc = CheckForDupKey( vpTag )) < XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- }
- catch (xbInt16 iRc ){
- if( iRc != XB_KEY_NOT_UNIQUE ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxBase::CheckForDupKeys() Exception Caught. Error Stop = [%d] iRc = [%d] Tag=[%d]", iErrorStop, iRc, i );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Close index file.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIx::Close(){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- if(( iRc = xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIx::Close() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Compare keys.
-/*!
- \param cKeyType C - Character compare.<br>
- N - Numeric BCD compare.<br>
- D - Numeric compare.<br>
- F - Numeric compare.<br>
- \param v1 Left compare.<br>v2 - Right Compare.
- \param iSearchKeyLen Length of key compare.
- \returns 1 - Left operand is greater then right operand.<br>
- 0 - Left operand is equal to right operand.<br>
- -1 - Left operand is less than right operand.
-*/
-inline xbInt16 xbIx::CompareKey( char cKeyType, const void *v1, const void *v2, size_t iSearchKeyLen ) const{
- if( cKeyType == 'C' ){ // character compare
- return memcmp( v1, v2, iSearchKeyLen );
- } else if( cKeyType == 'N' ){ // numeric bcd compare, mdx bcd numeric indices
- xbBcd bcdk1( v1 );
- return bcdk1.Compare( v2 );
- } else if( cKeyType == 'D' || cKeyType == 'F' ){ // julian date compare, ndx float numeric indices
- xbDouble *d1 = (xbDouble *) v1;
- xbDouble *d2 = (xbDouble *) v2;
- if( *d1 < *d2 )
- return -1;
- else if( *d1 > *d2 )
- return 1;
- else
- return 0;
- } else {
-// std::cout << "Unhandled key type [" << cKeyType << "]\n";
- }
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! @brief Create Keys for record number
-/*!
- \param iOpt 0 Build a key for FindKey usage, only rec buf 0.<br>
- 1 Append Mode, Create key for an append, only use rec buf 0, set updated switch.<br>
- 2 Update Mode, Create old version and new version keys, check if different, set update switch appropriately.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::CreateKeys( xbInt16 iOpt ) {
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbInt16 i = 0;
-
- try{
- void * vpTag;
- xbInt16 iTagCount = GetTagCount();
-
- for( i = 0; i < iTagCount; i++ ){
- vpTag = GetTag( i );
- if(( iRc = CreateKey( vpTag, iOpt )) < XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIx::CreateKeys() Exception Caught. Error Stop = [%d] iRc = [%d] Tag=[%d]", iErrorStop, iRc, i );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! @brief Delete keys for record number
-/*!
- Delete keys to each tag in the index file if it was updated as determined
- by CreateKeys function
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-//xbInt16 xbIx::DeleteKeys( xbUInt32 ulRecNo ){
-
-xbInt16 xbIx::DeleteKeys(){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbInt16 i = 0;
-
- try{
- void * vpTag;
- xbInt16 iTagCount = GetTagCount();
-
- for( i = 0; i < iTagCount; i++ ){
- vpTag = GetTag( i );
- if( GetKeySts( vpTag ) > 1 ){ // 0 = no update 1 = add 2 = update, 3 = delete
- if(( iRc = UpdateTagKey( 'D', vpTag )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIx::DeleteKeys() Exception Caught. Error Stop = [%d] iRc = [%d] Tag=[%d]", iErrorStop, iRc, i );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-//! @brief Dump anode for debug purposes.
-/*!
- \param pNode Pointer to node to dump.
- \param iOption 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIx::DumpNode( void *, xbIxNode *pNode, xbInt16 iOption ) const
-{
- xbString s;
- s.Sprintf( "Dump Node Block=[%d] CurKey=[%d]", pNode->ulBlockNo, pNode->iCurKeyNo );
- xbase->WriteLogMessage( s, iOption );
-
- return XB_NO_ERROR;
-}
-#endif // XB_DEBUG_SUPPORT
-
-/***********************************************************************/
-//! @brief Find double key
-/*!
- \param vpTag Pointer to tag to search.
- \param dKey Double value to search for.
- \param iRetrieveSw xbTrue - Retrieve the record if key found.<br>
- xbFalse - Don't retrieve record, check for key existence only.
- \returns XB_NO_ERROR - Key found.<br>
- XB_NOT_FOUND - Key not found.<br>
- <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::FindKey( void *vpTag, xbDouble dKey, xbInt16 iRetrieveSw ){
- return FindKey( vpTag, &dKey, 8, iRetrieveSw );
-}
-/***********************************************************************/
-//! @brief Find string key
-/*!
- \param vpTag Pointer to tag to search.
- \param sKey String data to search for.
- \param iRetrieveSw xbTrue - Retrieve the record if key found.<br>
- xbFalse - Don't retrieve record, check for key existence only.
- \returns XB_NO_ERROR - Key found.<br>
- XB_NOT_FOUND - Key not found.<br>
- <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::FindKey( void *vpTag, const xbString &sKey, xbInt16 iRetrieveSw ){
- return FindKey( vpTag, sKey.Str(), (xbInt32) sKey.Len(), iRetrieveSw );
-}
-/***********************************************************************/
-//! @brief Find character key
-/*!
- \param vpTag Pointer to tag to search.
- \param cKey String data to search for.
- \param lKeyLen Length of key to search for.
- \param iRetrieveSw xbTrue - Retrieve the record if key found.<br>
- xbFalse - Don't retrieve record, check for key existence only.
- \returns XB_NO_ERROR - Key found.<br>
- XB_NOT_FOUND - Key not found.<br>
- <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::FindKey( void *vpTag, const char *cKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw ){
- return FindKey( vpTag, (void *) cKey, lKeyLen, iRetrieveSw );
-}
-/***********************************************************************/
-//! @brief Find bcd key
-/*!
- \param vpTag Pointer to tag to search.
- \param bcd BCD data to search for.
- \param iRetrieveSw xbTrue - Retrieve the record if key found.<br>
- xbFalse - Don't retrieve record, check for key existence only.
-
- \returns XB_NO_ERROR - Key found.<br>
- XB_NOT_FOUND - Key not found.<br>
- <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::FindKey( void *vpTag, const xbBcd &bcd, xbInt16 iRetrieveSw ){
- return FindKey( vpTag, bcd.GetBcd(), 12, iRetrieveSw );
-}
-/***********************************************************************/
-//! @brief Find date key
-/*!
- \param vpTag Pointer to tag to search.
- \param dtKey Date data to search for.
- \param iRetrieveSw xbTrue - Retrieve the record if key found.<br>
- xbFalse - Don't retrieve record, check for key existence only.
- \returns XB_NO_ERROR - Key found.<br>
- XB_NOT_FOUND - Key not found.<br>
- <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::FindKey( void *vpTag, const xbDate &dtKey, xbInt16 iRetrieveSw ){
- xbDouble d = (xbDouble) dtKey.JulianDays();
- return FindKey( vpTag, &d, 8, iRetrieveSw );
-}
-/***********************************************************************/
-//! @brief Free all nodes in a linked list.
-/*!
- \param np Pointer to first node in linked list to free.
- \returns NULL.
-*/
-xbIxNode *xbIx::FreeNodeChain( xbIxNode *np ){
-
- // routine returns NULL
- if( np ){
- // free memory for a given chain of nodes
- xbIxNode * np2;
-
- // Clear the previous node's next pointer
- if( np->npPrev )
- np->npPrev->npNext = NULL;
-
- // Clear out the tree
- while( np ){
- np2 = np->npNext;
- NodeFree( np );
- np = NULL;
- np = np2;
- }
- }
- return NULL;
-}
-/***********************************************************************/
-//! @brief Read block for block number.
-/*!
- Routine to read a node/block out of an index file and store in xbIxNode structure
- \param vpTag Pointer to tag.
- \param ulBlockNo Block number to read off disk.
- \param iOpt
- 0 = Node is read into block buffer, not added to the node chain<br>
- 1 = Node is read into new xbIxNode, then added to the node chain, and sets CurNode with new node<br>
- 2 = Node is read into new xbIxNode, not added to the node chain<br>
- CurNode points to new node<br>
- \param ulAddlBuf Additional buffer size added to memory
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-
-xbInt16 xbIx::GetBlock( void *vpTag, xbUInt32 ulBlockNo, xbInt16 iOpt, xbUInt32 ulAddlBuf ){
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbIxNode *np = NULL;
- try{
-
- if( !vpTag && iOpt == 1 ){
- iErrorStop = 100;
- throw iRc;
- }
-
- // set target location of block read to read
- char *cp;
- if( iOpt == 0 )
- cp = cNodeBuf;
- else{
- if(( np = AllocateIxNode(GetBlockSize() + ulAddlBuf )) == NULL ){
- iErrorStop = 110;
- iRc = XB_NO_MEMORY;
- throw( iRc );
- }
- cp = np->cpBlockData;
- }
- if(( iRc = ReadBlock( ulBlockNo, GetBlockSize(), cp )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if( iOpt == 0 )
- return iRc;
- np->ulBlockNo = ulBlockNo;
- np->iCurKeyNo = 0;
- if( iOpt == 1 )
- AppendNodeChain( vpTag, np );
- else if( iOpt == 2 ){
- std::cout << "Future use stub. xbIxbase::GetBlock() option 2 not coded.\n";
- iErrorStop = 130;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- // SetCurNode( vpTag, np );
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIx::GetBlock() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( np ) NodeFree( np );
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Get pointer to current tag.
-/*!
- \returns Pointer to current tag.
-*/
-
-void *xbIx::GetCurTag() const {
- return vpCurTag;
-}
-/***********************************************************************/
-//! @brief Get pointer to dbf.
-/*!
- \returns Pointer to dbf.
-*/
-xbDbf *xbIx::GetDbf() const {
- return this->dbf;
-}
-/***********************************************************************/
-//! @brief Get the first key for the current tag.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::GetFirstKey(){
- return GetFirstKey( vpCurTag, 0 );
-}
-
-/***********************************************************************/
-//! @brief Get the first key for a given tag.
-/*!
- \param vpTag Tag for get first key operation.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::GetFirstKey( void *vpTag ){
- return GetFirstKey( vpTag, 0 );
-}
-/***********************************************************************/
-//! @brief Get the last key for the current tag.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::GetLastKey(){
- return GetLastKey( 0, vpCurTag, 0 );
-}
-/***********************************************************************/
-//! @brief Get the last key for a given tag.
-/*!
- \param vpTag Tag for get last key operation.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::GetLastKey( void *vpTag ){
- return GetLastKey( 0, vpTag, 0 );
-}
-
-/***********************************************************************/
-//! @brief Get the file lock status.
-/*!
- \returns xbTrue - Index file is locked.<br>xbFalse - Index file is not locked.
-*/
-xbBool xbIx::GetLocked() const {
- return bLocked;
-}
-
-/***********************************************************************/
-//! @brief Get the key count for number of keys on a node.
-/*!
- \param np Given node for key count.
- \returns Number of keys on the node.
-*/
-xbInt32 xbIx::GetKeyCount( xbIxNode *np ) const {
- // assumes the first four bytes of the block is a four byte number
- // representing the number of keys contained on the block
- return eGetInt32( np->cpBlockData );
-}
-/***********************************************************************/
-//! @brief Get key data for a given key number.
-/*!
- \param np Given node for key retrieval.
- \param iKeyNo Which key to pull.
- \param iKeyItemLen Length of key plus pointers.
- \returns Pointer to a given key.
-*/
-char * xbIx::GetKeyData( xbIxNode *np, xbInt16 iKeyNo, xbInt16 iKeyItemLen ) const {
- if( !np ) return NULL;
- char *p = np->cpBlockData;
- xbUInt32 ulKeyCnt = eGetUInt32( p );
- if( iKeyNo < 0 || iKeyNo > (xbInt16) ulKeyCnt ) return NULL;
- xbInt16 iOffset = 12 + (iKeyNo * iKeyItemLen);
- p+=iOffset;
- return p;
-}
-/***********************************************************************/
-//! @brief Get the next key for the current tag.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::GetNextKey(){
- return GetNextKey( vpCurTag, 0 );
-}
-/***********************************************************************/
-//! @brief Get the next key for the given tag.
-/*!
- \param vpTag Tag for next key operation.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::GetNextKey( void *vpTag ){
- return GetNextKey( vpTag, 0 );
-}
-/***********************************************************************/
-//! @brief Get the prev key for the current tag.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::GetPrevKey(){
- return GetPrevKey( vpCurTag, 0 );
-}
-/***********************************************************************/
-//! @brief Get the previous key for the given tag.
-/*!
- \param vpTag Tag for previous key operation.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::GetPrevKey( void *vpTag ){
- return GetPrevKey( vpTag, 0 );
-}
-/***********************************************************************/
-//! @brief Free an index node
-/*!
- \param ixNode Pointer to index node to free.
- \returns void
-*/
-void xbIx::NodeFree( xbIxNode *ixNode ){
- if( ixNode ){
- if( ixNode->cpBlockData ){
- free( ixNode->cpBlockData );
- ixNode->cpBlockData = NULL;
- }
- free( ixNode );
- ixNode = NULL;
- }
-}
-/***********************************************************************/
-//! @brief Open an index file.
-/*!
- MDX files are opened automatically and don't need opened.
- NDX files that are associated with the DBF file are opened automatically.
-
- Non production indexes that haven't been opened will need to be opened to be used.
- \param sFileName Index file name to open.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIx::Open( const xbString & sFileName ){
-
- // There are no locking requirements when opening an NDX index
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- /* copy the file name to the class variable */
- this->SetFileName( sFileName );
-
- if( !FileExists()){
- iErrorStop = 100;
- iRc = XB_FILE_NOT_FOUND;
- throw iRc;
- }
- /* open the file */
- if(( iRc = xbFopen( dbf->GetOpenMode(), dbf->GetShareMode())) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- if(( iRc = ReadHeadBlock()) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- SetCurTag( (xbInt16) 0 ); // default the first tag as the current tag
- }
-
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIx::Open( %s ) Exception Caught. Error Stop = [%d] iRc = [%d]", sFileName.Str(), iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Set the current tag.
-/*!
- \param vpCurTag Pointer to tag to set as current.
- \returns void
-*/
-void xbIx::SetCurTag( void *vpCurTag ){
- this->vpCurTag = vpCurTag;
-}
-/***********************************************************************/
-//! @brief Set the dbf pointer.
-/*!
- \param dbf Dbf pointer to set.
- \returns void
-*/
-void xbIx::SetDbf( xbDbf *dbf ){
- this->dbf = dbf;
-}
-/***********************************************************************/
-//! @brief Set the file lock status.
-/*!
- \param bLocked xbTrue - Set to locked.<br>xbFalse - Set to unlocked.
- \returns void
-*/
-void xbIx::SetLocked( xbBool bLocked ){
- this->bLocked = bLocked;
-}
-/***********************************************************************/
-} /* namespace */
-#endif /* XB_INDEX_SUPPORT */
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbixmdx.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbixmdx.cpp
deleted file mode 100755
index 0eef64b..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbixmdx.cpp
+++ /dev/null
@@ -1,4844 +0,0 @@
-/* xbixmdx.cpp
-
-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
-
-
- MDX indices are comprised of blocks and pages.
- A page is 512 bytes.
- A Block is one or more pages.
- The default block size is two 512 byte pages per block.
- Nodes are used for storing block images in memory
-
-*/
-
-#include "xbase.h"
-
-#ifdef XB_MDX_SUPPORT
-
-namespace xb{
-
-/***********************************************************************/
-xbIxMdx::xbIxMdx( xbDbf *dbf ) : xbIx( dbf ){
- Init();
-}
-/***********************************************************************/
-//void xbIxMdx::Init( xbInt16 iOpt ){
-void xbIxMdx::Init( xbInt16 ){
-
- cVersion = 0;
- cCreateYY = 0;
- cCreateMM = 0;
- cCreateDD = 0;
- sFileName = "";
- iBlockFactor = 0;
- cProdIxFlag = 0;
- cTagEntryCnt = 0;
- iTagLen = 0;
- iTagUseCnt = 0;
- cNextTag = 0;
- c1B = 0x0b;
- ulPageCnt = 0;
- ulFirstFreePage = 0;
- ulNoOfBlockAvail = 0;
- cUpdateYY = 0;
- cUpdateMM = 0;
- cUpdateDD = 0;
- mdxTagTbl = NULL;
- cNodeBuf = NULL;
- bReuseEmptyNodes = xbTrue;
-}
-/***********************************************************************/
-xbIxMdx::~xbIxMdx(){
- if( cNodeBuf )
- free( cNodeBuf );
-
- if( FileIsOpen())
- Close();
-}
-/***********************************************************************/
-//! @brief Add key.
-/*!
- Add key. If this is a unique index, this logic assumes the duplicate
- check logic was already done.
-
- \param vpTag Tag to update.
- \param ulRecNo Record number to add key for.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::AddKey( void * vpTag, xbUInt32 ulRecNo ){
-
- xbMdxTag * npTag = (xbMdxTag *) vpTag;
- if( GetUniqueKeyOpt() == XB_EMULATE_DBASE && npTag->bFoundSts )
- return XB_NO_ERROR;
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbInt16 iHeadNodeUpdateOpt = 2;
- xbIxNode * npRightNode = NULL;
- xbUInt32 ulNewRightChild = 0;
-
- try{
- if(( iRc = xbIxMdx::KeySetPosAdd( npTag, ulRecNo )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- xbInt32 lKeyCnt = GetKeyCount( npTag->npCurNode );
- if( lKeyCnt < npTag->iKeysPerBlock ){
- // Section A - add key to appropriate position if space available
- // std::cout << "AddKey Section A begin\n";
- if(( iRc = InsertNodeL( npTag, npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->cpKeyBuf, ulRecNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- } else {
- // land here with a full leaf node
- iHeadNodeUpdateOpt = 1;
- npRightNode = AllocateIxNode( npTag, GetBlockSize() + (xbUInt32) npTag->iKeyItemLen, npTag->npCurNode->ulBlockNo * (xbUInt32) iBlockFactor );
- if( !npRightNode ){
- iErrorStop = 120;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- if(( npTag->npCurNode->ulBlockNo * (xbUInt32) iBlockFactor ) == npTag->ulRightChild ){
- ulNewRightChild = npRightNode->ulBlockNo * (xbUInt32) iBlockFactor;
- }
-
- if(( iRc = xbIxMdx::SplitNodeL( npTag, npTag->npCurNode, npRightNode, npTag->npCurNode->iCurKeyNo, npTag->cpKeyBuf, ulRecNo )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- xbUInt32 ulTempBlockNo = npRightNode->ulBlockNo;
-
- // section C - go up the tree, splitting nodes as necessary
- xbIxNode * npParent = npTag->npCurNode->npPrev;
- while( npParent && GetKeyCount( npParent ) >= npTag->iKeysPerBlock ){
- //std::cout << "Section C begin interior node is full\n";
- npRightNode = FreeNodeChain( npRightNode );
- npRightNode = AllocateIxNode( npTag, GetBlockSize() + (xbUInt32) npTag->iKeyItemLen, npParent->ulBlockNo * (xbUInt32) iBlockFactor );
- //std::cout << "Section C - B new right node block number for interior node split= " << npRightNode->ulBlockNo << "\n";
-
- if( !npRightNode ){
- iErrorStop = 140;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- //std::cout << "Section C - going to split interior node C\n";
-
- if(( iRc = SplitNodeI( npTag, npParent, npRightNode, npParent->iCurKeyNo, BlockToPage( ulTempBlockNo ))) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- // std::cout << "Section C - interior node split \n";
- ulTempBlockNo = npRightNode->ulBlockNo;
- npTag->npCurNode = npParent;
- npParent = npParent->npPrev;
- }
-
- // section D - if cur node is split root, create new root
- if(( npTag->npCurNode->ulBlockNo * (xbUInt32) iBlockFactor ) == npTag->ulRootPage ){
- if(( iRc = AddKeyNewRoot( npTag, npTag->npCurNode, npRightNode )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if( npRightNode )
- npRightNode = FreeNodeChain( npRightNode );
-
- } else {
-
- // std::cout << "Section E, put key in parent\n";
- if(( iRc = InsertNodeI( (void *) vpTag, (xbIxNode *) npParent, (xbInt16) npParent->iCurKeyNo, BlockToPage( npRightNode->ulBlockNo ))) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- }
- }
-
- // update the header
- if(( iRc = WriteHeadBlock( iHeadNodeUpdateOpt )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
-
- // if adding the first key, set the cHasKeys field
- if( !npTag->cHasKeys ){
- npTag->cHasKeys = 0x01;
- if(( iRc = xbFseek( ((npTag->ulTagHdrPageNo * 512) + 246), SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
- if(( iRc = xbFwrite( &npTag->cHasKeys, 1, 1 )) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw iRc;
- }
- }
-
- if( ulNewRightChild > 0 ){
-
- char cBuf[4];
- ePutUInt32( cBuf, ulNewRightChild );
- if(( iRc = xbFseek( ((npTag->ulTagHdrPageNo * 512) + 252), SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- if(( iRc = xbFwrite( &cBuf, 4, 1 )) != XB_NO_ERROR ){
- iErrorStop = 220;
- throw iRc;
- }
- npTag->ulRightChild = ulNewRightChild;
- }
-
- if( npRightNode )
- npRightNode = FreeNodeChain( npRightNode );
- npTag->npNodeChain = FreeNodeChain( npTag->npNodeChain );
- npTag->npCurNode = NULL;
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::AddKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-void xbIxMdx::AppendNodeChain( void *vpTag, xbIxNode * npNode ){
- xbMdxTag * mdxTag = (xbMdxTag *) vpTag;
- if( mdxTag->npNodeChain == NULL ){
- mdxTag->npNodeChain = npNode;
- mdxTag->npCurNode = npNode;
- } else {
- npNode->npPrev = mdxTag->npCurNode;
- mdxTag->npCurNode->npNext = npNode;
- mdxTag->npCurNode = npNode;
- }
- // time stamp the node chain
- GetFileMtime( mdxTag->tNodeChainTs );
-}
-
-/***********************************************************************/
-//! @brief Add new root node.
-/*!
- \param mpTag Tag to update.
- \param npLeft Left node.
- \param npRight Right node.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxMdx::AddKeyNewRoot( xbMdxTag *npTag, xbIxNode *npLeft, xbIxNode *npRight ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char *pLastKey = NULL;
-
- try{
- xbIxNode *npRoot = AllocateIxNode( npTag, GetBlockSize() + (xbUInt32) npTag->iKeyItemLen, npRight->ulBlockNo * (xbUInt32) iBlockFactor );
- if( !npRoot ){
- iErrorStop = 100;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- npTag->ulRootPage = npRoot->ulBlockNo;
-
- pLastKey = (char *) malloc( (size_t) npTag->iKeyLen );
- if(( iRc = GetLastKeyForBlockNo( npTag, npLeft->ulBlockNo, pLastKey )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- char * pTrg = npRoot->cpBlockData;
-
- // set no of keys to 1
- ePutUInt32( pTrg, 1 );
-
- // set the left node number
- pTrg += 8;
- ePutUInt32( pTrg, npLeft->ulBlockNo * (xbUInt32) iBlockFactor );
-
- // set the key
- pTrg+= 4;
- memcpy( pTrg, pLastKey, (size_t) npTag->iKeyLen );
- pTrg+= npTag->iKeyItemLen - 4;
- ePutUInt32( pTrg, npRight->ulBlockNo * (xbUInt32) iBlockFactor );
-
- // write out the new block
- if(( iRc = WriteBlock( npRoot->ulBlockNo, GetBlockSize(), npRoot->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- // write out the new root node number in the tag header
- // position the file
- xbUInt32 ulPagePos = npTag->ulTagHdrPageNo * 512;
-
- // save the number to a buffer
- char cBuf[4];
- ePutUInt32( cBuf, npRoot->ulBlockNo * ((xbUInt32) iBlockFactor ));
-
- if(( iRc = xbFseek( ulPagePos, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if(( iRc = xbFwrite( &cBuf, 4, 1 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
-
- if( pLastKey )
- free( pLastKey );
-
- npRoot = FreeNodeChain( npRoot );
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::AddKeyNewRoot() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( pLastKey )
- free( pLastKey );
- }
- return iRc;
-}
-
-
-
-/***********************************************************************/
-//! @brief Allocate a node.
-/*!
- \param mpTag Pointer to mdx tag
- \param ulBufSize Buffer size.
- \param ulBlock2 Value to load in ulBlock2 field, bytes 4-7 in the first page of the block
- \returns Pointer to new node.
-*/
-xbIxNode * xbIxMdx::AllocateIxNode( xbMdxTag * mpTag, xbUInt32 ulBufSize, xbUInt32 ulBlock2 ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbIxNode *n = NULL;
-
- try{
- if(( n = xbIx::AllocateIxNode( ulBufSize )) == NULL ){
- iRc = XB_NO_MEMORY;
- iErrorStop = 100;
- throw iRc;
- }
- char *p = n->cpBlockData;
- p += 4;
-
- if( ulFirstFreePage > 0 && bReuseEmptyNodes ){
- // have an empty node we can reuse
- n->ulBlockNo = PageToBlock( ulFirstFreePage );
- if(( iRc = ReadBlock( n->ulBlockNo, GetBlockSize(), n->cpBlockData )) != XB_NO_ERROR ){
- iRc = 110;
- throw iRc;
- }
- // update ulFirstFreePage
- ulFirstFreePage = eGetUInt32( p );
- if(( iRc = xbFseek( 36, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = xbFwrite( p, 4, 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- // memset cpBlockData to zeroes
- memset( n->cpBlockData, 0x00, GetBlockSize());
-
- } else {
- n->ulBlockNo = ulPageCnt / (xbUInt32) iBlockFactor;
- ulPageCnt += (xbUInt32) iBlockFactor;
- }
-
- mpTag->ulTagSize += (xbUInt32) iBlockFactor;
- if( ulBlock2 > 0 ){
- ePutUInt32( p, ulBlock2 );
- }
- }
- catch( xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::AllocateIxNode() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( n )
- n = FreeNodeChain( n );
- }
- return n;
-}
-/***********************************************************************/
-//! @brief Calculate B-tree pointers.
-/*!
- Set binary tree pointer value. The MDX tags are stored with binary
- tree positions. This routine calculates the value in memory.
- \returns void
-*/
-
-void xbIxMdx::CalcBtreePointers(){
-
- xbInt16 iaLeftChild[48];
- xbInt16 iaRightChild[48];
- xbInt16 iaParent[48];
-
- for( xbInt16 i = 0; i < 48; i++ ){
- iaLeftChild[i] = 0;
- iaRightChild[i] = 0;
- iaParent[i] = 0;
- }
-
- // anything to do?
- if( iTagUseCnt > 1 ){
- xbString sBaseTag;
- xbString sThisTag;
- xbString sWorkTag;
- xbInt16 iWorkTagNo;
- xbBool bDone;
- sBaseTag = GetTagName( GetTag( 0 ));
-
- for( xbInt16 iThisTagNo = 1; iThisTagNo < iTagUseCnt; iThisTagNo++ ){
- iWorkTagNo = 0;
- sWorkTag.Set( sBaseTag );
- sThisTag = GetTagName( GetTag( iThisTagNo ));
- bDone = xbFalse;
- while( !bDone ){
- if( sThisTag < sWorkTag ){
- if( iaLeftChild[iWorkTagNo] == 0 ) {
- iaLeftChild[iWorkTagNo] = iThisTagNo + 1;
- iaParent[iThisTagNo] = iWorkTagNo + 1;
- bDone = xbTrue;
- } else {
- iWorkTagNo = iaLeftChild[iWorkTagNo]-1;
- sWorkTag = GetTagName( GetTag( iWorkTagNo));
- }
- } else {
- if( iaRightChild[iWorkTagNo] == 0 ) {
- iaRightChild[iWorkTagNo] = iThisTagNo + 1;
- iaParent[iThisTagNo] = iWorkTagNo + 1;
- bDone = xbTrue;
- } else {
- iWorkTagNo = iaRightChild[iWorkTagNo]-1;
- sWorkTag = GetTagName( GetTag( iWorkTagNo ));
- }
- }
- }
- }
- }
-
- xbString s;
- xbMdxTag *mpTag = mdxTagTbl;
- for( xbInt16 i = 0; i < iTagUseCnt; i++ ){
- mpTag->cLeftChild = (char ) iaLeftChild[i];
- mpTag->cRightChild = (char ) iaRightChild[i];
- mpTag->cParent = (char ) iaParent[i];
- mpTag = mpTag->next;
- }
-}
-
-/**************************************************************************************************************/
-//! @brief Calculate the page number for a given block
-/*!
- This routine is called by any function needing to calculate the page number for a given block.
- Page numbers are stored internally in the physical file, and the library reads and writes in
- blocks of one or more pages.
-
- Assumes valid data input
-
- \param ulBlockNo Block Number
- \returns Calculated page number.
-*/
-
-inline xbUInt32 xbIxMdx::BlockToPage( xbUInt32 ulBlockNo ){
- return ulBlockNo * (xbUInt32) iBlockFactor;
-}
-/***********************************************************************/
-char xbIxMdx::CalcTagKeyFmt( xbExp &exp ){
-
- xbExpNode *n = exp.GetTreeHandle();
- if( n->GetChildCnt() == 0 && n->GetNodeType() == XB_EXP_FIELD )
- return 0x01;
- else
- return 0;
-}
-/***********************************************************************/
-//! @brief Check for duplicate key.
-/*!
- \param vpTag Tag to check.
- \returns XB_KEY_NOT_UNIQUE<br>XB_NO_ERROR
-*/
-
-xbInt16 xbIxMdx::CheckForDupKey( void *vpTag )
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbMdxTag *mpTag = (xbMdxTag *) vpTag;
- mpTag->bFoundSts = xbFalse;
- try{
- if( GetUnique( mpTag )){
- if( mpTag->iKeySts == XB_ADD_KEY || mpTag->iKeySts == XB_UPD_KEY )
- if( KeyExists( mpTag )){
- if( GetUniqueKeyOpt() == XB_EMULATE_DBASE ){
- mpTag->bFoundSts = xbTrue;
- return 0;
- } else {
- return XB_KEY_NOT_UNIQUE;
- }
- }
- }
- return 0;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::CheckForDupKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Check tag integrity.
-/*!
- Check a tag for accuracy.
-
- \param vpTag Tag to create key for.
- \param iOpt Output message destination<br>
- 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxMdx::CheckTagIntegrity( void *vpTag, xbInt16 iOpt ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iRc2;
- xbInt16 iRc3;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulIxCnt = 0;
- xbUInt32 ulThisRecNo = 0;
- xbUInt32 ulPrevRecNo = 0;
- xbBool bDone = false;
- xbString sMsg;
- char cKeyType;
- char *pPrevKeyBuf = NULL;
- xbMdxTag *npTag = (xbMdxTag *) vpTag;
- xbBool bDescending = npTag->cKeyFmt2 & 0x08;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bLocked = xbFalse;
- #endif
-
- try{
-
- #ifdef XB_LOCKING_SUPPORT
- if( dbf->GetAutoLock() && !dbf->GetTableLocked() ){
- if(( iRc = dbf->LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- bLocked = xbTrue;
- }
- #endif
-
- memset( npTag->cpKeyBuf2, 0x00, (size_t) npTag->iKeyLen );
- cKeyType = GetKeyType( vpTag );
-
- pPrevKeyBuf = (char *) calloc( 1, (size_t) npTag->iKeyLen );
- iRc = GetFirstKey( vpTag, 0 );
-
- memcpy( pPrevKeyBuf, GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->iKeyItemLen ), (size_t) npTag->iKeyLen );
-
- // for each key in the index, make sure it is trending in the right direction
- while( iRc == XB_NO_ERROR && !bDone ){
- ulIxCnt++;
-
- iRc = GetNextKey( vpTag, 0 );
- if( iRc == XB_NO_ERROR ){
-
- // compare this key to prev key
- iRc2 = CompareKey( cKeyType, GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->iKeyItemLen ),
- pPrevKeyBuf, (size_t) npTag->iKeyLen );
-
- if(( iRc2 < 0 && !bDescending ) || ( iRc2 > 0 && bDescending )){
- sMsg.Sprintf( "Key sequence error at key number [%ld].", ulIxCnt );
- xbase->WriteLogMessage( sMsg, iOpt );
- iErrorStop = 110;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
-
- ulThisRecNo = 0;
- if(( iRc3 = GetDbfPtr( vpTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulThisRecNo )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc3;
- }
-
- if( iRc2 == 0 && (ulThisRecNo <= ulPrevRecNo )){
- sMsg.Sprintf( "Dbf record number sequence error at key number [%ld].", iOpt );
- xbase->WriteLogMessage( sMsg, iOpt );
- iErrorStop = 130;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
- // save this key info to prev key
- memcpy( pPrevKeyBuf, GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->iKeyItemLen ), (size_t) npTag->iKeyLen );
- ulPrevRecNo = ulThisRecNo;
- }
- }
-
- xbUInt32 ulDbfCnt = 0;
- if(( iRc = dbf->GetRecordCnt( ulDbfCnt )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
-
- xbUInt32 ulFiltCnt = 0;
- xbBool bFiltered = xbTrue;
- // verify each record in the dbf file has a corresponding index entry
- xbUInt32 j = 0;
- while( j < ulDbfCnt ){
-
- if(( iRc = dbf->GetRecord( ++j )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- if( npTag->cHasFilter ){
- if(( iRc = npTag->filter->ProcessExpression( 0 )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if(( iRc = npTag->filter->GetBoolResult( bFiltered )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- }
-
- if( bFiltered ){
- if(( iRc = FindKeyForCurRec( vpTag )) != XB_NO_ERROR ){
- ulThisRecNo = j;
- iErrorStop = 180;
- throw iRc;
- }
- ulFiltCnt++;
- }
- }
-
- if((GetUniqueKeyOpt() == XB_EMULATE_DBASE) && (GetUnique( vpTag ))){
- // can't compare counts if using XB_EMULATE_DBASE and it's a unique index
- } else {
- if( ulIxCnt != ulFiltCnt && GetUniqueKeyOpt() == XB_HALT_ON_DUPKEY ){
- if( npTag->cHasFilter )
- sMsg.Sprintf( "xbIxMdx::CheckTagIntegrity() Filtered index entry count [%ld] does not match dbf record count [%ld] for tag [%s]", ulIxCnt, ulFiltCnt, npTag->cTagName );
- else
- sMsg.Sprintf( "xbIxMdx::CheckTagIntegrity() Index entry count [%ld] does not match dbf record count [%ld] for tag [%s]", ulIxCnt, ulFiltCnt, npTag->cTagName );
-
- xbase->WriteLogMessage( sMsg, iOpt );
- iErrorStop = 190;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
- if( npTag->cHasFilter )
- sMsg.Sprintf( "xbIxMdx::CheckTagIntegrity() Filtered index entry count [%ld] matches dbf record count [%ld] for tag [%s]", ulIxCnt, ulFiltCnt, npTag->cTagName );
- else
- sMsg.Sprintf( "xbIxMdx::CheckTagIntegrity() Index entry count [%ld] matches dbf record count [%ld] for tag [%s]", ulIxCnt, ulFiltCnt, npTag->cTagName );
- xbase->WriteLogMessage( sMsg, iOpt );
- }
-
- if( pPrevKeyBuf )
- free( pPrevKeyBuf );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::CheckTagIntegrity() Exception Caught. Error Stop = [%d] iRc = [%d] Tag = [%s]", iErrorStop, iRc, npTag->cTagName );
- xbase->WriteLogMessage( sMsg, iOpt );
- xbase->WriteLogMessage( GetErrorMessage( iRc ), iOpt );
- if( pPrevKeyBuf )
- free( pPrevKeyBuf );
-
- if( iErrorStop == 160 ){
- sMsg.Sprintf( "xbIxMdx::CheckTagIntegrity() Missing index entry for record [%d]", ulThisRecNo );
- xbase->WriteLogMessage( sMsg, iOpt );
- }
- }
- #ifdef XB_LOCKING_SUPPORT
- if( bLocked ){
- dbf->LockTable( XB_UNLOCK );
- }
- #endif
-
- return iRc;
-}
-
-/***********************************************************************/
-xbMdxTag *xbIxMdx::ClearTagTable(){
-
- // clear the list of tags
- xbMdxTag *tt = mdxTagTbl;
- xbMdxTag *tt2;
- while( tt ){
- tt2 = tt;
- tt = tt->next;
- tt2->npNodeChain = FreeNodeChain( tt2->npNodeChain );
- tt2->npCurNode = NULL;
- if( tt2->cpKeyBuf )
- free( tt2->cpKeyBuf );
- if( tt2->cpKeyBuf2 )
- free( tt2->cpKeyBuf2 );
- if( tt2->exp )
- delete tt2->exp;
- if( tt2->filter )
- delete tt2->filter;
- if( tt2->sKeyExp )
- delete tt2->sKeyExp;
- if( tt2->sTagName )
- delete tt2->sTagName;
- if( tt2->sFiltExp )
- delete tt2->sFiltExp;
- free( tt2 );
- }
- return NULL;
-}
-/***********************************************************************/
-xbInt16 xbIxMdx::Close(){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- mdxTagTbl = ClearTagTable();
- if(( iRc = xbIx::Close()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::Close() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Create key.
-/*!
-
- \param vpTag Tag
- \param iOpt 1 = Append, 2 = Update
- \returns XB_KEY_NOT_UNIQUE<br>XB_NO_ERROR
-
- iKeySts 0 - No Updates
- 1 - Add Key XB_ADD_KEY
- 2 - Update Key XB_UPD_KEY
- 3 - Delete Key XB_DEL_KEY
-
- bKeyFiltered xbFalse - Key filtered out
- xbTrue - Key filtered in
-
- cpKeyBuf - Key buffer for add
- cpKeyBuf2 - Key buffer for delete
-
-*/
-
-xbInt16 xbIxMdx::CreateKey( void *vpTag, xbInt16 iOpt ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- xbBool bFilter0 = xbFalse; // filter against RecBuf, updated record buffer
- xbBool bFilter1 = xbFalse; // filter against recBuf2, original record buffer
-
- try{
-
- xbMdxTag *npTag = (xbMdxTag *) vpTag;
- npTag->iKeySts = 0;
-
- // do tag filter logic
- if( npTag->cHasFilter ){
- if(( iRc = npTag->filter->ProcessExpression( 0 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if(( iRc = npTag->filter->GetBoolResult( bFilter0 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- } else {
- bFilter0 = xbTrue;
- }
-
- // if add request and filtered out, we're done
- if( iOpt == 1 && !bFilter0 )
- return XB_NO_ERROR;
-
- if(( iRc = npTag->exp->ProcessExpression( 0 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if( npTag->exp->GetReturnType() == XB_EXP_CHAR )
- npTag->exp->GetStringResult( npTag->cpKeyBuf, (xbUInt32) npTag->iKeyLen );
- else if( npTag->exp->GetReturnType() == XB_EXP_NUMERIC ){
- xbDouble d;
- npTag->exp->GetNumericResult( d );
- xbBcd bcd( d );
- bcd.ToChar( npTag->cpKeyBuf );
- }
- else if( npTag->exp->GetReturnType() == XB_EXP_DATE ){
- xbDouble d;
- npTag->exp->GetNumericResult( d );
- memcpy( npTag->cpKeyBuf, &d, 8 );
- }
-
- if( iOpt == 1 ) // Append
- npTag->iKeySts = XB_ADD_KEY;
-
- else if( iOpt == 2 ){ // Update
- if( npTag->cHasFilter ){
- if(( iRc = npTag->filter->ProcessExpression( 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if(( iRc = npTag->filter->GetBoolResult( bFilter1 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- } else {
- bFilter1 = xbTrue;
- }
-
- if(( iRc = npTag->exp->ProcessExpression( 1 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
-
- if( npTag->exp->GetReturnType() == XB_EXP_CHAR ){
- npTag->exp->GetStringResult( npTag->cpKeyBuf2, (xbUInt32) npTag->iKeyLen );
-
- } else if( npTag->exp->GetReturnType() == XB_EXP_NUMERIC ){
- xbDouble d;
- npTag->exp->GetNumericResult( d );
- xbBcd bcd( d );
- bcd.ToChar( npTag->cpKeyBuf2 );
-
- } else if( npTag->exp->GetReturnType() == XB_EXP_DATE ){
- xbDouble d;
- npTag->exp->GetNumericResult( d );
- memcpy( npTag->cpKeyBuf2, &d, 8 );
-
- }
-
- if( bFilter1 ){ // original key was indexed
- if( bFilter0 ){ // new key s/b indexed, update it if changed
- if( memcmp( npTag->cpKeyBuf, npTag->cpKeyBuf2, (size_t) npTag->iKeyLen )){
- npTag->iKeySts = XB_UPD_KEY;
- }
- } else { // original key indexed, new key not indexed, delete it
- npTag->iKeySts = XB_DEL_KEY;
- }
- } else { // original key not indexed
- if( bFilter0 )
- npTag->iKeySts = XB_ADD_KEY;
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::CreateKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Create new tag.
-/*!
- This routine creates a new tag. When complete, sets the cur tag pointer to
- the newly created tag.
-
-
- \param sName Tag Name, including .MDX suffix
- \param sKey Key Expression
- \param sFilter Filter expression.
- \param iDescending
- \param iUnique xbtrue - Unique.<br>xbFalse - Not unique.
- \param iOverLay xbTrue - Overlay if file already exists.<br>xbFalse - Don't overlay.
- \param vpTag Output from method Pointer to vptag pointer.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbIxMdx::CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbMdxTag *tte = NULL;
-
- try{
- // verify room for new tag
- if( !( iTagUseCnt < 47 )){
- iErrorStop = 100;
- iRc = XB_LIMIT_REACHED;
- throw iRc;
- }
-
- // verify valid tag name
- xbString sWorker = sName;
- sWorker.Trim();
- if( sWorker.Len() > 10 ){
- iErrorStop = 110;
- iRc = XB_INVALID_TAG;
- throw iRc;
- }
-
- // verify tag not already defined
- if( iTagUseCnt > 0 ){
- if( GetTag( sWorker )){
- iErrorStop = 120;
- iRc = XB_INVALID_TAG;
- throw iRc;
- }
- }
-
- // allocate a tag structure here
- if(( tte = (xbMdxTag *) calloc( 1, (size_t) sizeof( xbMdxTag ))) == NULL ){
- iErrorStop = 130;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- *vpTag = tte;
- tte->sTagName = new xbString( sWorker );
-
- //set up the key expression
- sWorker = sFilter;
- sWorker.Trim();
- if( sWorker.Len() > 0 ){
- if( sWorker.Len() == 0 || sWorker.Len() > 220 ){
- iRc = XB_INVALID_TAG;
- iErrorStop = 140;
- throw iRc;
- }
- tte->sFiltExp = new xbString( sWorker );
- tte->filter = new xbExp( dbf->GetXbasePtr());
- if(( iRc = tte->filter->ParseExpression( dbf, sWorker )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
-
- if((tte->filter->GetReturnType()) != 'L' ){
- iRc = XB_INVALID_TAG;
- iErrorStop = 160;
- throw iRc;
- }
- tte->cHasFilter = 0x01;
- }
-
- //set up the key expression
- sWorker = sKey;
- sWorker.Trim();
- if( sWorker.Len() == 0 || sWorker.Len() > 100 ){
- iRc = XB_INVALID_TAG;
- iErrorStop = 170;
- throw iRc;
- }
- tte->sKeyExp = new xbString( sWorker );
- tte->exp = new xbExp( dbf->GetXbasePtr());
- if(( iRc = tte->exp->ParseExpression( dbf, sWorker )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
-
- xbDate d;
- d.Sysdate();
- if( iTagUseCnt == 0 ){
- // first tag, new mdx file
- // create the file name
- xbString sIxFileName = dbf->GetFqFileName();
- sIxFileName.Trim();
- xbUInt32 lLen = sIxFileName.Len();
- sIxFileName.PutAt( lLen-2, 'M' );
- sIxFileName.PutAt( lLen-1, 'D' );
- sIxFileName.PutAt( lLen, 'X' );
-
- // copy the file name to the class variable
- this->SetFileName( sIxFileName );
- if( FileExists() && !iOverlay ){
- iErrorStop = 190;
- iRc = XB_FILE_EXISTS;
- throw iRc;
- }
-
- // first tag, need to create the file
- if(( iRc = xbFopen( "w+b", dbf->GetShareMode())) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw iRc;
- }
- cVersion = 2;
- cCreateYY = (char) d.YearOf() - 1900;
- cCreateMM = (char) d.MonthOf();
- cCreateDD = (char) d.DayOf( XB_FMT_MONTH );
-
- GetFileNamePart( sFileName );
- sFileName.ToUpperCase();
-
- SetBlockSize( (xbUInt32) dbf->GetCreateMdxBlockSize());
- iBlockFactor = GetBlockSize() / 512;
-
- cProdIxFlag = 1;
- cTagEntryCnt = 48;
- iTagLen = 32;
- ulPageCnt = 4;
- ulFirstFreePage = 0;
- ulNoOfBlockAvail = 0;
- cNextTag = 1;
- c1B = 0x1B;
- cUpdateYY = cCreateYY;
- cUpdateMM = cCreateMM;
- cUpdateDD = cCreateDD;
-
- if(( iRc = WriteHeadBlock( 0 )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- }
-
- // populate the tag table entry structure
- tte->ulTagHdrPageNo = ulPageCnt;
- ulPageCnt += (xbUInt32) iBlockFactor;
- tte->sTagName->strncpy( tte->cTagName, 10 );
-
- // cKeyFmt is always 0x10;
- // tested 2+ZIPCD CITY+STATE or just standalone field - always 0x10
- tte->cKeyFmt = 0x10; // = CalcTagKeyFmt( *tte->exp );
-
- switch( tte->exp->GetReturnType()){
- case XB_EXP_CHAR:
- tte->cKeyType = 'C';
- tte->iKeyLen = tte->exp->GetResultLen();
- tte->iSecKeyType = 0;
- break;
-
- case XB_EXP_NUMERIC:
- tte->cKeyType = 'N';
- tte->iKeyLen = 12;
- tte->iSecKeyType = 0;
- break;
-
- case XB_EXP_DATE:
- tte->cKeyType = 'D';
- tte->iKeyLen = 8;
- tte->iSecKeyType = 1;
- break;
-
- default:
- iErrorStop = 200;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
-
- tte->cpKeyBuf = (char *) malloc( (size_t) tte->iKeyLen + 1 );
- tte->cpKeyBuf2 = (char *) malloc( (size_t) tte->iKeyLen + 1 );
-
- // write the new tte entry here
- char tteBuf[21];
- memset( tteBuf, 0x00, 21 );
-
- ePutUInt32( &tteBuf[0], tte->ulTagHdrPageNo );
- for( xbUInt32 l = 0; l < tte->sTagName->Len() && l < 10; l++ ){
- tteBuf[l+4] = tte->sTagName->GetCharacter(l+1);
- }
- tteBuf[15] = tte->cKeyFmt;
- tteBuf[19] = 0x02; // appears to always be a 0x02
- tteBuf[20] = tte->cKeyType;
-
- if(( iRc = xbFseek( (iTagUseCnt * 32) + 544, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- if(( iRc = xbFwrite( tteBuf, 21, 1 )) != XB_NO_ERROR ){
- iErrorStop = 220;
- throw iRc;
- }
-
- // Begin Tag Header
- tte->ulRootPage = ulPageCnt;
- tte->ulTagSize = (xbUInt32) iBlockFactor;
- ulPageCnt += 2;
- tte->cKeyFmt2 = 0x10;
- if( iDescending )
- tte->cKeyFmt2 += 0x08;
- if( iUnique ){
- tte->cKeyFmt2 += 0x40;
- tte->cUnique = 0x01;
- }
-
- tte->cTag11 = 0x1B; // always 0x1b ?
- tte->cSerialNo = 0x01; // version incremented with each tag update
- tte->ulLeftChild = tte->ulRootPage;
- tte->ulRightChild = tte->ulRootPage;
-
- tte->cTagYY = (char) d.YearOf() - 1900;
- tte->cTagMM = (char) d.MonthOf();
- tte->cTagDD = (char) d.DayOf( XB_FMT_MONTH );
-
- tte->cKeyType2 = tte->cKeyType;
- tte->iKeyItemLen = tte->iKeyLen + 4;
- while(( tte->iKeyItemLen % 4 ) != 0 ) tte->iKeyItemLen++;
-
- tte->iKeysPerBlock = (xbInt16) (GetBlockSize() - 12) / tte->iKeyItemLen;
- tte->cKeyFmt3 = CalcTagKeyFmt( *tte->exp );
-
- char *pBuf;
- if(( pBuf = (char *) calloc( 1, (size_t) GetBlockSize())) == NULL ){
- iErrorStop = 230;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- char *wPtr;
- wPtr = pBuf;
- ePutUInt32( wPtr, tte->ulRootPage );
-
- wPtr += 4;
- ePutUInt32( wPtr, tte->ulTagSize );
-
- wPtr += 4;
- *wPtr = tte->cKeyFmt2;
-
- wPtr++;
- *wPtr = tte->cKeyType2;
-
- wPtr += 2;
- *wPtr = tte->cTag11;
-
- wPtr += 1;
- ePutInt16( wPtr, tte->iKeyLen );
-
- wPtr += 2;
- ePutInt16( wPtr, tte->iKeysPerBlock );
-
- wPtr += 2;
- ePutInt16( wPtr, tte->iSecKeyType );
-
- wPtr += 2;
- ePutInt16( wPtr, tte->iKeyItemLen );
-
- wPtr += 2;
- *wPtr = tte->cSerialNo;
-
- wPtr += 3;
- *wPtr = tte->cUnique;
-
- wPtr++;
- for( xbUInt32 l = 0; l < tte->sKeyExp->Len(); l++ )
- *wPtr++ = tte->sKeyExp->GetCharacter(l+1);
-
- wPtr = pBuf;
-
- tte->cHasKeys = 0x00;
- pBuf[246] = tte->cHasKeys;
-
- wPtr += 248;
- ePutUInt32( wPtr, tte->ulLeftChild );
- wPtr += 4;
- ePutUInt32( wPtr, tte->ulRightChild );
-
- pBuf[257] = tte->cTagYY;
- pBuf[258] = tte->cTagMM;
- pBuf[259] = tte->cTagDD;
- pBuf[480] = tte->cKeyFmt3;
-
- if( sFilter.Len() > 0 ){
- pBuf[245] = tte->cHasFilter;
- wPtr = pBuf;
- wPtr += 762;
- for( xbUInt32 l = 0; l < sFilter.Len(); l++ )
- *wPtr++ = sFilter.GetCharacter(l+1);
- }
-
- if(( iRc = xbFseek( tte->ulTagHdrPageNo * 512, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 240;
- throw iRc;
- }
-
- if(( iRc = xbFwrite( pBuf, GetBlockSize(), 1 )) != XB_NO_ERROR ){
- iErrorStop = 250;
- throw iRc;
- }
-
- memset( pBuf, 0x00, GetBlockSize() );
- if(( iRc = xbFwrite( pBuf, GetBlockSize(), 1 )) != XB_NO_ERROR ){
- iErrorStop = 260;
- throw iRc;
- }
-
- iTagUseCnt++;
- cNextTag++;
-
- if(( iRc = WriteHeadBlock( 1 )) != XB_NO_ERROR ){
- iErrorStop = 270;
- throw iRc;
- }
-
- // update the dbf file if needed - discreet field, has no filter
- // 10/15/22 - dbase 7 does not update this field on index creation
- if( tte->cKeyFmt3 == 0x01 && !tte->cHasFilter ){
- // printf( "cKeyFmt3 = [%x]\n", tte->cKeyFmt3 );
- xbInt16 iFldNo;
- if(( iRc = dbf->GetFieldNo( sKey, iFldNo )) != XB_NO_ERROR ){
- iErrorStop = 280;
- throw iRc;
- }
- xbInt64 lOffset = 31 + ((iFldNo + 1) * 32 );
-
- if(( iRc = dbf->xbFseek( lOffset, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 290;
- iRc = XB_SEEK_ERROR;
- throw iRc;
- }
- char cBuf[2];
- cBuf[0] = 0x01;
- cBuf[1] = 0x00;
-
- if(( iRc = dbf->xbFwrite( cBuf, 1, 1 )) != XB_NO_ERROR ){
- iErrorStop = 300;
- throw iRc;
- }
- dbf->UpdateSchemaIxFlag( iFldNo, 0x01 );
- }
-
- // add the new entry to the end of the list of tags
- if( mdxTagTbl == NULL ){
- mdxTagTbl = tte;
- } else {
- xbMdxTag *tteL = mdxTagTbl;
- while( tteL->next )
- tteL = tteL->next;
- tteL->next = tte;
- }
-
- /* update the btree pointers */
- CalcBtreePointers();
- char bBuf[3];
- xbMdxTag *tteWork = mdxTagTbl;
-
- if(( iRc = xbFseek( 560, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 310;
- throw iRc;
- }
- while( tteWork ){
- bBuf[0] = tteWork->cLeftChild;
- bBuf[1] = tteWork->cRightChild;
- bBuf[2] = tteWork->cParent;
-
- if(( iRc = xbFwrite( bBuf, 3, 1 )) != XB_NO_ERROR ){
- iErrorStop = 320;
- throw iRc;
- }
- if( tteWork->next ){
- if(( iRc = xbFseek( 29, SEEK_CUR )) != XB_NO_ERROR ){
- iErrorStop = 330;
- throw iRc;
- }
- }
- tteWork = tteWork->next;
- }
- free( pBuf );
- }
-
- catch (xbInt16 iRc ){
- if( tte ){
- if( tte->cpKeyBuf )
- free( tte->cpKeyBuf );
- if( tte->cpKeyBuf2 )
- free( tte->cpKeyBuf2 );
- if( tte->exp )
- delete tte->exp;
- if( tte->filter )
- delete tte->filter;
- if( tte->sKeyExp )
- delete tte->sKeyExp;
- if( tte->sFiltExp )
- delete tte->sFiltExp;
- if( tte->sTagName )
- delete tte->sTagName;
- free( tte );
- }
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::CreateTag() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
-
- return iRc;
-};
-
-/***********************************************************************/
-//! @brief Delete a key from a node.
-/*!
- This routine deletes a key from a supplied node.
- \param vpTag Tag to delete key on.
- \param npNode Node to delete key on.
- \param iSlotNo Slot number of key to delete.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxMdx::DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo )
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbMdxTag * npTag = (xbMdxTag *) vpTag;
-
- try{
- xbInt32 lKeyCnt = GetKeyCount( npNode );
- xbInt16 iLen = (lKeyCnt - iSlotNo - 1) * npTag->iKeyItemLen;
- xbBool bLeaf = IsLeaf( vpTag, npNode );
- if( !bLeaf )
- iLen += 4;
-
- char *pTrg = npNode->cpBlockData;
- if( iLen > 0 ){
- pTrg += (8 + (npTag->iKeyItemLen * (iSlotNo)) ); //lTrgPos;
- // std::cout << "TrgSpot = " << (8 + (npTag->iKeyItemLen * (iSlotNo)) ) << "\n";
- char *pSrc = pTrg;
- pSrc += npTag->iKeyItemLen;
- memmove( pTrg, pSrc, (size_t) iLen );
- }
-
- // zap out the right most key
- pTrg = npNode->cpBlockData;
- if( bLeaf ){
- pTrg += (8 + (npTag->iKeyItemLen * ( lKeyCnt-1 )));
-
- } else {
- pTrg += (12 + (npTag->iKeyItemLen * ( lKeyCnt-1 )));
-
- }
-
- for( xbInt16 i = 0; i < npTag->iKeyItemLen; i++ )
- *pTrg++ = 0x00;
-
- // set the new number of keys
- ePutUInt32( npNode->cpBlockData, (xbUInt32) lKeyCnt - 1 );
-
- // if node empty, add it to the free node chain
- if( lKeyCnt < 2 ){
- if( bReuseEmptyNodes ){
- if( bLeaf && lKeyCnt == 1 ){
- if(( iRc = HarvestEmptyNode( npTag, npNode, 0 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- }
- }
-
- // write out the block
- if(( iRc = WriteBlock( npNode->ulBlockNo, GetBlockSize(), npNode->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::DeleteFromNode() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return XB_NO_ERROR;
-}
-
-/***********************************************************************/
-//! @brief Delete a key.
-/*!
- This routine deletes a key. It assumes the key to delete
- is the current key in the node chain.
-
- \param vpTag Tag to delete key on.
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::DeleteKey( void *vpTag ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbMdxTag * npTag = (xbMdxTag *) vpTag;
-
- // save copy of node chain to reset to after delete completed
- xbIxNode *npSaveNodeChain = npTag->npNodeChain;
- npTag->npNodeChain = NULL;
- xbIxNode * npSaveCurNode = npTag->npCurNode;
-
- try{
- xbString sMsg;
-
- if(( iRc = xbIxMdx::KeySetPosDel( npTag )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- // Delete key needs to handle two scenarios
- // 1 - if delete is on the only key of leaf,
- // traverse up tree, trim as needed
- // 2 - if last key on node is deleted, and key value is not the same
- // as prev key, ascend tree looking for an interior node needing
- // updated key value
-
- xbInt32 lOrigKeyCnt = GetKeyCount( npTag->npCurNode );
- if(( iRc = DeleteFromNode( npTag, npTag->npCurNode, npTag->npCurNode->iCurKeyNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- if( lOrigKeyCnt == 1 ){
-
- // scenario 1
- xbBool bDone = xbFalse;
- xbBool bIsLeaf = xbFalse;
- xbInt32 lKeyCnt;
- npTag->npCurNode = npTag->npCurNode->npPrev;
-
- while( npTag->npCurNode && !bDone ){
- lKeyCnt = GetKeyCount( npTag->npCurNode );
- bIsLeaf = IsLeaf( npTag, npTag->npCurNode );
- if( lKeyCnt > 0 ){
- if(( iRc = DeleteFromNode( npTag, npTag->npCurNode, npTag->npCurNode->iCurKeyNo )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- } else if(( iRc = HarvestEmptyNode( npTag, npTag->npCurNode, 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- if( (bIsLeaf && lKeyCnt > 1) || (!bIsLeaf && lKeyCnt > 0) )
- bDone = xbTrue;
- else
- npTag->npCurNode = npTag->npCurNode->npPrev;
- }
-
- } else if( npTag->npCurNode->iCurKeyNo == (xbUInt32) lOrigKeyCnt - 1 ){
-
- // scenario 2
- // if last two keys identical, then nothing to do, else go up looking for a key to change
- if( memcmp( GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->iKeyItemLen ),
- GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo-1, npTag->iKeyItemLen ),
- (size_t) npTag->iKeyLen )){
-
- xbIxNode *pNode = npTag->npCurNode->npPrev;
- char *pSrc = GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo-1, npTag->iKeyItemLen );
-
- while( pNode && pNode->ulBlockNo != npTag->ulRootPage && pNode->iCurKeyNo == (xbUInt32) GetKeyCount( pNode ) )
- pNode = pNode->npPrev;
-
- if( pNode ){
- if( pNode->iCurKeyNo < (xbUInt32) GetKeyCount( pNode )){
- char *pTrg = pNode->cpBlockData;
- pTrg += 12 + (pNode->iCurKeyNo * (xbUInt32) npTag->iKeyItemLen);
- for( xbInt16 i = 0; i < npTag->iKeyLen; i++ )
- *pTrg++ = *pSrc++;
- // write out the block
- if(( iRc = WriteBlock( pNode->ulBlockNo, GetBlockSize(), pNode->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- }
- }
- }
- }
- // restore node chain to pre delete status (which should be post add status)
- npTag->npNodeChain = FreeNodeChain( npTag->npNodeChain );
- npTag->npNodeChain = npSaveNodeChain;
- npTag->npCurNode = npSaveCurNode;
-
- // update the serial number
- if(( iRc = TagSerialNo( 3, npTag )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::DeleteKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( npSaveNodeChain ){
- npTag->npNodeChain = npSaveNodeChain;
- npSaveNodeChain = FreeNodeChain( npSaveNodeChain );
- npTag->npCurNode = npSaveCurNode;
- }
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Delete a given tag
-/*!
- \param vpTag Input tag ptr for tag to be deleted<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a><br>
- 1 = Deleted entire MDX file, only had one tag
-
-*/
-
-xbInt16 xbIxMdx::DeleteTag( void *vpTag ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
- xbIxNode *n = NULL;
- xbBool bLoneTag = xbFalse;
-
- try{
-
- if( !vpTag ){
- iErrorStop = 100;
- iRc = XB_INVALID_TAG;
- throw iRc;
- }
-
- char cSaveHasFilter = mpTag->cHasFilter;
- char cSaveKeyFmt3 = mpTag->cKeyFmt3;
- xbString sSaveKey = mpTag->sKeyExp->Str();
-
- if( iTagUseCnt == 1 ){
- // std::cout << "xbIxMdx::DeleteTag - one tag found, delete the mdx file\n";
-
- // close the mdx file
- if(( iRc = xbIxMdx::Close()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- // delete the file
- xbRemove();
-
- // init variables - needed?
- // Init();
- // iRc > 0 defines this as the only tag in an MDX file, MDX file deleted.
- // signals to the calling process to drop the MDX file from the
- // list of updateable indices.
- bLoneTag = xbTrue;
-
- } else {
-
- // harvest tag nodes
-
- if(( iRc = HarvestTagNodes( mpTag, xbTrue )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- // remove an entry from tag table
- // which tag is this?
- xbInt16 iTagNo = 0;
- xbMdxTag *mp = mdxTagTbl;
- xbMdxTag *mpPrev = NULL;
- while( mp && mp->ulTagHdrPageNo != mpTag->ulTagHdrPageNo ){
- iTagNo++;
- mpPrev = mp;
- mp = mp->next;
- }
-
- // remove it from the linked list of tags
- if( !mpPrev ){
- mdxTagTbl = mp->next;
- } else {
- mpPrev->next = mp->next;
- }
- if( mp ){
- if( mp->cpKeyBuf ) free( mp->cpKeyBuf );
- if( mp->cpKeyBuf2 ) free( mp->cpKeyBuf2 );
- if( mp->exp ) delete mp->exp;
- if( mp->filter ) delete mp->filter;
- if( mp->sKeyExp ) delete mp->sKeyExp;
- if( mp->sFiltExp ) delete mp->sFiltExp;
- if( mp->sTagName ) delete mp->sTagName;
- free( mp );
- }
- xbInt32 iTarg = iTagNo * 32;
- xbInt32 iSrc = iTarg + 32;
- xbInt32 iLen = (iTagUseCnt - iTagNo) * 32;
-
- if(( iRc = xbFseek( 544, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- char Buf[1536]; // 47 tags + 1 in case tag #47 is deleted
- memset( Buf, 0x00, 1536 );
- if(( iRc = xbFread( Buf, 1504, 1 )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- char *pTrg = Buf;
- pTrg += iTarg;
- char *pSrc = Buf;
- pSrc += iSrc;
- for( xbInt32 i = 0; i < iLen; i++ )
- *pTrg++ = *pSrc++;
-
- if(( iRc = xbFseek( 544, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
- if(( iRc = xbFwrite( Buf, 1504, 1 )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
-
- iTagUseCnt--;
- if(( iRc = WriteHeadBlock( 1 )) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw iRc;
- }
-
- /* update the btree pointers */
- CalcBtreePointers();
- char bBuf[3];
- xbMdxTag *tteWork = mdxTagTbl;
-
- if(( iRc = xbFseek( 560, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- while( tteWork ){
- bBuf[0] = tteWork->cLeftChild;
- bBuf[1] = tteWork->cRightChild;
- bBuf[2] = tteWork->cParent;
-
- if(( iRc = xbFwrite( bBuf, 3, 1 )) != XB_NO_ERROR ){
- iErrorStop = 320;
- throw iRc;
- }
- if( tteWork->next ){
- if(( iRc = xbFseek( 29, SEEK_CUR )) != XB_NO_ERROR ){
- iErrorStop = 330;
- throw iRc;
- }
- }
- tteWork = tteWork->next;
- }
- }
-
- // update the dbf file if needed, if discreet field with no filter
- // printf( "cSaveKeyFmt3 = [%x] cSaveHasFilter=[%x] SaveKey = [%s]\n", cSaveKeyFmt3, cSaveHasFilter, sSaveKey.Str());
-
- if( cSaveKeyFmt3 == 0x01 && !cSaveHasFilter ){
- xbInt16 iFldNo;
- if(( iRc = dbf->GetFieldNo( sSaveKey, iFldNo )) != XB_NO_ERROR ){
- iErrorStop = 340;
- throw iRc;
- }
- xbInt64 lOffset = 31 + ((iFldNo + 1) * 32 );
-
- if(( iRc = dbf->xbFseek( lOffset, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 350;
- iRc = XB_SEEK_ERROR;
- throw iRc;
- }
- char cBuf[2];
- cBuf[0] = 0x00;
- cBuf[1] = 0x00;
- if(( iRc = dbf->xbFwrite( cBuf, 1, 1 )) != XB_NO_ERROR ){
- iErrorStop = 360;
- throw iRc;
- }
- dbf->UpdateSchemaIxFlag( iFldNo, 0x00 );
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::DeleteTag() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( n )
- free( n );
- }
- if( bLoneTag && !iRc )
- return 1;
- else
- return iRc;
-}
-
-/***********************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-
-//! @brief Dump a given block for a tag
-/*!
- \param iOpt Output message destination<br>
- 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
- \param ulBlockNo Block number to dump
- \param mpTag Index tag pointer
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-
-xbInt16 xbIxMdx::DumpBlock( xbInt16 iOpt, xbUInt32 ulBlockNo, xbMdxTag *mpTag ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbString s, s2;
- xbBool bLeaf;
- char *p;
-
- try{
- if(( iRc = GetBlock( mpTag, ulBlockNo, 0 )) != XB_NO_ERROR ){
- iErrorStop = 10;
- throw iRc;
- }
- p = cNodeBuf;
- xbInt32 lNoOfKeys = eGetInt32( p );
- p+=4;
- xbUInt32 ulNode2 = eGetUInt32( p );
-
- if( !mpTag ){
- // if no tag info, print what is available without tag info and exit
- s.Sprintf( "--- BlkNo = %ld Page = %ld NoOfKeys = %ld Node2 (opt NextFreePage) = %ld", ulBlockNo, BlockToPage( ulBlockNo ), lNoOfKeys, ulNode2 );
- xbase->WriteLogMessage( s, iOpt );
- return XB_NO_ERROR;
- }
-
- p+=4;
- p+= mpTag->iKeyItemLen * lNoOfKeys;
- if( eGetUInt32( p ) == 0 ){
- bLeaf = xbTrue;
- // std::cout << "No of keys = " << lNoOfKeys << "\n";
- s.Sprintf( "--- Leaf Node KeyCnt %d\t Page %d\t Block %d", lNoOfKeys, BlockToPage( ulBlockNo ), ulBlockNo );
- } else {
- bLeaf = xbFalse;
- s.Sprintf( "--- Interior Node KeyCnt %d\t Page %d\t Block %d", lNoOfKeys, BlockToPage( ulBlockNo ), ulBlockNo );
- }
- if( ulNode2 > 0 )
- s.Sprintf( "%s Node2 (opt NextFreePage) = %d", s.Str(), ulNode2 );
-
- xbase->WriteLogMessage( s, iOpt );
-
- xbInt32 l;
- for( l = 0; l < lNoOfKeys; l++ ){
- p = cNodeBuf + (8 + (l * mpTag->iKeyItemLen ));
- s.Sprintf( "%08ld\t", eGetUInt32( p ));
- p+=4;
- if( mpTag->cKeyType2 == 'C' ){ //CHAR
- for( xbInt32 l = 0; l < (mpTag->iKeyItemLen-4); l++ )
- s += *p++;
- s.Trim();
- } else if( mpTag->cKeyType2 == 'N' ){ // NUMERIC
- xbBcd bcd( p );
- bcd.ToString( s2 );
- s += s2;
- } else if( mpTag->cKeyType2 == 'D' ){ // DATE
- xbInt32 lDate = (xbInt32) eGetDouble( p );
- xbDate d( lDate );
- s.Sprintf( "%s\t%ld\t(%s)", s.Str(), lDate, d.Str());
- } else {
- s.Sprintf( "Unknown key type [%c]", mpTag->cKeyType2 );
- }
- xbase->WriteLogMessage( s, iOpt );
- }
- if( !bLeaf ){
- // interior node has one extra key at the right most position
- p = cNodeBuf + (8 + (l * mpTag->iKeyItemLen ));
- s.Sprintf( "\t%08ld", eGetUInt32( p ));
- xbase->WriteLogMessage( s, iOpt );
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::DumpBlock() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/**************************************************************************************************************/
-//! @brief Dump free blocks.
-/*!
- Dump free blocks for index debugging purposes.
-
- \param iOpt Output message destination<br>
- 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-xbInt16 xbIxMdx::DumpFreeBlocks( xbInt16 iOpt ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbString s;
- char *pBuf = NULL;
- char *pNextPage;
- xbUInt32 ulNextPage;
-
- try{
-
- if(( iRc = ReadHeadBlock( 1 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- xbUInt32 ulLastBlock = PageToBlock( ulPageCnt );
-
- pBuf = (char *) malloc( (size_t) GetBlockSize());
- if( !pBuf ){
- iErrorStop = 110;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- if( ulFirstFreePage > 0 ){
- xbUInt32 ulThisFreePage = ulFirstFreePage;
- xbUInt32 ulNextFreePage = 0;
- xbUInt32 ulCnt = 0;
- xbase->WriteLogMessage( "*** Free Blocks ***", iOpt );
- s.Sprintf( "File Header - FirstFreePage = %ld Block = %ld", ulFirstFreePage, PageToBlock( ulFirstFreePage ));
- xbase->WriteLogMessage( s, iOpt );
- while( ulThisFreePage > 0 ){
- if(( iRc = ReadBlock( PageToBlock( ulThisFreePage ), GetBlockSize(), pBuf )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- pNextPage = pBuf;
- pNextPage+=4;
- ulNextFreePage = eGetUInt32( pNextPage );
- s.Sprintf( "Free Page# = %ld\t(Block# = %ld)\tNext Free Page = %ld\t(Block = %ld)", ulThisFreePage, PageToBlock( ulThisFreePage ), ulNextFreePage, PageToBlock( ulNextFreePage ));
- xbase->WriteLogMessage( s, iOpt );
- ulThisFreePage = ulNextFreePage;
- ulCnt++;
- }
- s.Sprintf( "%ld free blocks (%ld pages)", ulCnt, BlockToPage( ulCnt ));
- xbase->WriteLogMessage( s, iOpt );
- xbase->WriteLogMessage( "*** End Of Free Blocks ***", iOpt );
- }
-
- pNextPage = pBuf;
- pNextPage+=4;
-
- s = "*** Beginning of Block2 Info ***";
- xbase->WriteLogMessage( s, iOpt );
- s = "ulBlock2 info. ulBlock2 is either one of a linked list of free nodes, or the id of the original node that this node was split from.";
- xbase->WriteLogMessage( s, iOpt );
- s = "Stored in physical file as pages, processed in blocks";
- xbase->WriteLogMessage( s, iOpt );
-
- xbUInt32 ulFirstBlock = 3;
-
- for( xbUInt32 ul = ulFirstBlock; ul < ulLastBlock; ul++ ){
- if(( iRc = ReadBlock( ul, GetBlockSize(), pBuf )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- ulNextPage = eGetUInt32( pNextPage );
- if( ulNextPage > 0 ){
- s.Sprintf( " Block# = %ld\tPage# = %ld\tulBlock2 = %ld\tulBlock2(Page) = %ld", ul, BlockToPage( ul ), PageToBlock( ulNextPage ), ulNextPage );
- xbase->WriteLogMessage( s, iOpt );
- }
- }
- s = "*** End of Block2 Info ***";
- xbase->WriteLogMessage( s, iOpt );
-
- if( pBuf ) free( pBuf );
- }
-
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::DumpFreeBlocks() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( pBuf ) free( pBuf );
- }
- return iRc;
-}
-
-/**************************************************************************************************************/
-//! @brief Dump interior and leaf blocks for a given tag.
-/*!
- Dump blocks for given tag for index debugging purposes.
-
- A page is 512 bytes<br>
- A block is one or more pages<br>
- The default mdx block size is 2 pages, or 1024 bytes<br>
- The first four pages or header pages<br>
-
- \param iOpt Output message destination<br>
- 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
- \param vpTag Index tag pointer, defaults to all tags if null.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-
-xbInt16 xbIxMdx::DumpTagBlocks( xbInt16 iOpt, void * vpTag ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbInt16 iCurTag = 0;
- xbString s;
- xbInt16 iBlockCtr = 0;
-
- try{
-
- xbMdxTag * mpTag;
- if( vpTag == NULL )
- mpTag = (xbMdxTag *) GetTag( iCurTag++ );
- else
- mpTag = (xbMdxTag *) vpTag;
-
- if( mpTag == NULL ){
- iErrorStop = 100;
- iRc = XB_INVALID_TAG;
- throw iRc;
- }
-
- xbIxNode *n;
- xbString s;
- xbString s2;
- xbBool bDone = xbFalse;
-
- xbUInt32 ulBlkNo;
- xbLinkListOrd<xbUInt32> ll;
- xbLinkListNode<xbUInt32> * llN;
-
- ll.SetDupKeys( xbFalse );
-
- s.Sprintf( "%s Root Page %ld (Block %ld)", mpTag->cTagName, mpTag->ulRootPage, PageToBlock( mpTag->ulRootPage ) );
- xbase->WriteLogMessage( s, iOpt );
-
- // for each tag
- while( !bDone ){
-
- // clear out any history
- ll.Clear();
- if( mpTag->npNodeChain ){
- mpTag->npNodeChain = FreeNodeChain( mpTag->npNodeChain );
- mpTag->npCurNode = NULL;
- }
-
- while( GetNextKey( mpTag, 0 ) == 0 ){
- n = mpTag->npNodeChain;
-
- while(n){
- ll.InsertKey( n->ulBlockNo, (xbUInt32) n->iCurKeyNo );
- n = n->npNext;
- }
- }
- llN = ll.GetHeadNode();
-
- while( llN ){
-
- ulBlkNo = llN->GetKey();
- xbIxMdx::DumpBlock( iOpt, ulBlkNo, mpTag );
- llN = llN->GetNextNode();
- iBlockCtr++;
- }
-
- if( vpTag || iCurTag >= GetTagCount())
- bDone = xbTrue;
- else
- mpTag = (xbMdxTag *) GetTag( iCurTag++ );
- }
-
- s.Sprintf( "\nTotal Blocks: %d", iBlockCtr );
- xbase->WriteLogMessage( s, iOpt );
-
- if( mpTag->npNodeChain ){
- mpTag->npNodeChain = FreeNodeChain( mpTag->npNodeChain );
- mpTag->npCurNode = NULL;
- }
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::DumpTagBlocks() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Dump index file header.
-/*!
- Dump a index file header for debugging purposes.
- \param iOpt Output message destination<br>
- 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
- \param iFmtOpt Output Format<br>
- 0, 1 = Header info only<br>
- 2 = Tag info<br>
- 3 = Header && Tag info<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxMdx::DumpHeader( xbInt16 iOpt, xbInt16 iFmtOpt )
-{
-
- xbInt16 iRc = XB_NO_ERROR;
- xbString s;
- if(( iRc = ReadHeadBlock( 1 )) != XB_NO_ERROR )
- return iRc;
-
- char c, tfv, cDisplayMask = 1;
- cDisplayMask = cDisplayMask << 7;
- if( iFmtOpt != 2 && iFmtOpt != 4 ){
- s = "*** MDX Index Header ***";
- xbase->WriteLogMessage( s, iOpt );
- s = "Version = ";
- tfv = cVersion;
- for( c = 1; c<= 8; c++ ){
- //std::cout << (tfv & cDisplayMask ? '1' : '0');
- s+= (tfv & cDisplayMask ? '1' : '0');
- tfv <<= 1;
- }
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "Create Date = %d/%d/%d", (int) cCreateMM, (int) cCreateDD, (int) cCreateYY % 100 );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "File Name = %s", sFileName.Str() );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "Block Factor = %d", iBlockFactor );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "Block Size = %d", GetBlockSize() );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "Prod Ix Flag = %d", (xbInt16) cProdIxFlag );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "Tag Entry Cnt = %d", (xbInt16) cTagEntryCnt );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "Tag Len = %d", iTagLen );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "Next Tag = %d", (xbInt16) cNextTag );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "Tag Use Cnt = %d", iTagUseCnt );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "Page Cnt = %d", ulPageCnt );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "First Free Page = %d", ulFirstFreePage );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "No Of Block Avail = %d\n", ulNoOfBlockAvail );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "Last update date = %d/%d/%d", (int) cCreateMM, (int) cCreateDD, (int) cCreateYY % 100 );
- xbase->WriteLogMessage( s, iOpt );
-
- if( ulFirstFreePage > 0 ){
- xbString s;
- xbUInt32 ulNfp = ulFirstFreePage; // next free page
- xbInt16 lc = 0;
- while( ulNfp && lc++ < 5 ){
- if( s.Len() > 0 )
- s += ",";
- s.Sprintf( "%s%ld", s.Str(), ulNfp );
- if(( iRc = GetBlock( NULL, (xbUInt32) (ulNfp / (xbUInt32) iBlockFactor), 0 )) != 0 )
- return iRc;
- ulNfp = eGetUInt32( cNodeBuf+4 );
- }
- xbase->WriteLogMessage( s, iOpt );
- }
- }
- if( iFmtOpt > 1 ){
- xbMdxTag *tt = mdxTagTbl;
- xbString s;
- xbInt16 i = 0;
-
- if( tt ){
- while( tt ){
- i++;
- if(( iRc = LoadTagDetail( 2, tt )) != XB_NO_ERROR )
- return iRc;
-
- s.Sprintf( "TTE (%d)\tName HdrPage\tFormat\tLeftChild\tRightChild\tParent\tKeyType", i );
- xbase->WriteLogMessage( s, iOpt );
- s.Sprintf( "TTE (%d)\t%-12s %d\t\t%d\t%d\t\t%d\t\t%d\t%c\n", i, tt->cTagName, tt->ulTagHdrPageNo, tt->cKeyFmt, tt->cLeftChild, tt->cRightChild, tt->cParent, tt->cKeyType );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "TTH (%d)\tRoot\tTagSize\tKeyFmt2\tType2\tKeyLen\tKeysPerBlock\tSecType\tKeyItemLen\tSerial#\tHasKeys\tFilter\tDesc\tUnique\tLchild\tRchild\tKeyFmt3\tTagDate", i );
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "TTH (%d)\t%d\t%d\t%d\t%c\t%d\t%d\t\t%d\t%d\t\t%x\t%x\t%d\t%d\t%d\t%d\t%d\t%d\t%d/%d/%d",
- i, tt->ulRootPage, tt->ulTagSize, tt->cKeyFmt2, tt->cKeyType2, tt->iKeyLen, tt->iKeysPerBlock, tt->iSecKeyType, tt->iKeyItemLen, tt->cSerialNo, tt->cHasKeys, tt->cHasFilter,
- (((tt->cKeyFmt2 & 0x08) > 0) ? 1 : 0), // descending?
- tt->cUnique, tt->ulLeftChild, tt->ulRightChild, tt->cKeyFmt3, (int) tt->cTagMM, (int) tt->cTagDD, (int) tt->cTagYY % 100 );
-
- xbase->WriteLogMessage( s, iOpt );
-
- s.Sprintf( "Key (%d) %s", i, tt->sKeyExp->Str());
- xbase->WriteLogMessage( s, iOpt );
-
- if( tt->cHasFilter ){
- s.Sprintf( "Flt (%d) %s", i, tt->sFiltExp->Str());
- xbase->WriteLogMessage( s, iOpt );
- }
- xbase->WriteLogMessage( "", iOpt );
- tt = tt->next;
-
- }
- }
- }
- return iRc;
-}
-
-/***********************************************************************/
-xbInt16 xbIxMdx::DumpIxForTag( void *vpTag, xbInt16 iOutputOpt )
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbInt16 iDepth = 0;
- xbUInt32 lKeyCtr = 0;
- xbInt32 iMinDepth = 999999;
- xbInt32 iMaxDepth = 0;
-
- try{
- /*
- get first node
- while interior node
- print the left key
- level++
- go down one on the left
- */
-
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
- if( mpTag->npNodeChain ){
- mpTag->npNodeChain = FreeNodeChain( mpTag->npNodeChain );
- mpTag->npCurNode = NULL;
- }
-
- // Get the root
- if(( iRc = LoadTagDetail( 2, mpTag )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- // lRootBlock is now available
- if(( iRc = GetBlock( vpTag, (mpTag->ulRootPage / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- // if no keys on this node, then the index is empty
- xbUInt32 ulKeyPtr = eGetUInt32( mpTag->npCurNode->cpBlockData );
- if( ulKeyPtr == 0 ){
- iErrorStop = 120;
- iRc = XB_EMPTY;
- throw iRc;
- }
- while( !IsLeaf( vpTag, mpTag->npCurNode )){ // go down the chain looking for a leaf node
- PrintKey( vpTag, mpTag->npCurNode , 0, iDepth++, 'I', iOutputOpt );
- if(( iRc = GetKeyPtr( vpTag, 0, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if(( iRc = GetBlock( vpTag, (ulKeyPtr / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- }
- if(( iRc = GetKeyPtr( vpTag, 0, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- // loop through the leaf entries of left most leaf
- if( iDepth < iMinDepth ) iMinDepth = iDepth;
- if( iDepth > iMaxDepth ) iMaxDepth = iDepth;
- xbUInt32 ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
- for( xbUInt32 ul = 0; ul < ulNoOfKeys; ul++ ){
- PrintKey( vpTag, mpTag->npCurNode , ul, iDepth, 'L', iOutputOpt );
- lKeyCtr++;
- }
-
- // if head node = start node, return
- if( mpTag->npCurNode->ulBlockNo == ( mpTag->ulRootPage / (xbUInt32) iBlockFactor ))
- return XB_NO_ERROR;
-
- xbBool bEof = false;
- while( !bEof ){
-
- // go up the chain, looking for an interior node with more keys on it
- xbIxNode * TempIxNode = mpTag->npCurNode;
- mpTag->npCurNode = mpTag->npCurNode->npPrev;
- mpTag->npCurNode->npNext = NULL;
- TempIxNode->npPrev = NULL;
- TempIxNode = FreeNodeChain( TempIxNode );
- iDepth--;
-
- while( mpTag->npCurNode->iCurKeyNo >= eGetUInt32( mpTag->npCurNode->cpBlockData ) &&
- mpTag->npCurNode->ulBlockNo != ( mpTag->ulRootPage / (xbUInt32) iBlockFactor) ){
- TempIxNode = mpTag->npCurNode;
- mpTag->npCurNode = mpTag->npCurNode->npPrev;
- mpTag->npCurNode->npNext = NULL;
- TempIxNode->npPrev = NULL;
- TempIxNode = FreeNodeChain( TempIxNode );
- iDepth--;
- }
- // if head node && right most key, return
- if( mpTag->npCurNode->ulBlockNo == (mpTag->ulRootPage / (xbUInt32) iBlockFactor) &&
- mpTag->npCurNode->iCurKeyNo == eGetUInt32( mpTag->npCurNode->cpBlockData ))
- bEof = true;
-
- if( !bEof ){
- mpTag->npCurNode->iCurKeyNo++;
- if(( iRc = GetKeyPtr( vpTag, mpTag->npCurNode->iCurKeyNo, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- PrintKey( vpTag, mpTag->npCurNode , mpTag->npCurNode->iCurKeyNo, iDepth++, 'I', iOutputOpt );
-
- if(( iRc = GetBlock( vpTag, (ulKeyPtr / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
-
- // traverse down the left side of the tree
- while( !IsLeaf( vpTag, mpTag->npCurNode )) // go down the chain looking for a leaf node
- {
- PrintKey( vpTag, mpTag->npCurNode , 0, iDepth++, 'I', iOutputOpt );
- if(( iRc = GetKeyPtr( vpTag, 0, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
- if(( iRc = GetBlock( vpTag, (ulKeyPtr / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
- }
- if( iDepth < iMinDepth ) iMinDepth = iDepth;
- if( iDepth > iMaxDepth ) iMaxDepth = iDepth;
- ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
- for( xbUInt32 ul = 0; ul < ulNoOfKeys; ul++ ){
- PrintKey( vpTag, mpTag->npCurNode , ul, iDepth, 'L', iOutputOpt );
- lKeyCtr++;
- }
- }
- }
- xbString s;
- s.Sprintf( "Total keys = [%ld] Min Depth = [%d] Max Depth = [%d]", lKeyCtr, iMinDepth, iMaxDepth );
- xbase->WriteLogMessage( s.Str(), 2 );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::DumpIxForTag() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/**************************************************************************************************************/
-void xbIxMdx::DumpIxNodeChain( void *vpTag, xbInt16 iOutputOpt ) const
-{
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
- xbString s( "Dump Node Chain" );
- xbase->WriteLogMessage( s, 2 );
-
- if( mpTag->npNodeChain ){
- xbIxNode *n = mpTag->npNodeChain;
- xbInt16 iCtr = 0;
- char cLeaf;
- s.Sprintf( "Cnt\tThis Prev Next CurKeyNo BlockNo Page NoOfKeys Type" );
- xbase->WriteLogMessage( s, iOutputOpt );
- while( n ){
- IsLeaf( vpTag, n ) ? cLeaf = 'L' : cLeaf = 'I';
- s.Sprintf( "%d\t%08x %08x %08x %08d %08d %08d %08ld %c",
- iCtr++, n, n->npPrev, n->npNext, n->iCurKeyNo,
- n->ulBlockNo, n->ulBlockNo * (xbUInt32) iBlockFactor,
- eGetUInt32( n->cpBlockData ), cLeaf );
- xbase->WriteLogMessage( s, 2 );
- n = n->npNext;
- }
- } else {
- s = "Empty Node Chain";
- xbase->WriteLogMessage( s, 2 );
- }
-}
-#endif
-
-/***********************************************************************************************/
-xbInt16 xbIxMdx::FindKey( void *vpTag, xbDouble dKey, xbInt16 iRetrieveSw ){
-
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
- if( mpTag->cKeyType2 == 'N' ){ // mdx indices store numeric keys as bcd values
- xbBcd bcd( dKey );
- return xbIx::FindKey( vpTag, bcd, iRetrieveSw );
- } else // this would be a julian date inquiry
- return FindKey( vpTag, &dKey, 8, iRetrieveSw );
-}
-
-/***********************************************************************************************/
-// iRetrieveSw = 1 - position db file to index position
-// 0 - do not position dbf file
-
-xbInt16 xbIxMdx::FindKey( void *vpTag, const void * vpKey,
- xbInt32 lSearchKeyLen, xbInt16 iRetrieveSw ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- // clean up any previous table updates before moving on
- if( iRetrieveSw ){
- if( dbf->GetDbfStatus() == XB_UPDATED ){
- if( dbf->GetAutoCommit() == 1 ){
- if(( iRc = dbf->Commit()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- } else {
- if(( iRc = dbf->Abort()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- }
- }
-
- xbUInt32 ulNoOfKeys;
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
- char cKeyType = GetKeyType( vpTag );
- xbBool bDescending = mpTag->cKeyFmt2 & 0x08;
-
- if( mpTag->npNodeChain ){
-
- // determine if the index has been updated since the last time it was used
- time_t tFileTs;
- if(( iRc = GetFileMtime( tFileTs )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if( mpTag->tNodeChainTs < tFileTs ){
- mpTag->npNodeChain = FreeNodeChain( mpTag->npNodeChain );
- mpTag->npCurNode = NULL;
-
- } else {
- // pop up the chain looking for appropriate starting point
- xbBool bDone = false;
- xbIxNode * TempIxNode;
- while( mpTag->npCurNode && !bDone &&
- (mpTag->npCurNode->ulBlockNo != ( mpTag->ulRootPage / (xbUInt32) iBlockFactor ))){ // not root node
- //if no keys on the node, pop up one
- ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
- if( ulNoOfKeys == 0 ){
- TempIxNode = mpTag->npCurNode;
- mpTag->npCurNode = mpTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
-
- } else {
-
- iRc = CompareKey( cKeyType, vpKey, GetKeyData( mpTag->npCurNode, 0, mpTag->iKeyItemLen ), (size_t) lSearchKeyLen );
- if( (!bDescending && iRc <= 0) || (bDescending && iRc >= 0 )){
- TempIxNode = mpTag->npCurNode;
- mpTag->npCurNode = mpTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
- } else {
- // get the number of keys on the block and compare the key to the rightmost key
- xbUInt32 ulKeyCtr = eGetUInt32( mpTag->npCurNode->cpBlockData ) - 1; // IsLeaf( vpTag, mpTag->npCurNode );
- iRc = CompareKey( cKeyType, vpKey, GetKeyData( mpTag->npCurNode, ulKeyCtr, mpTag->iKeyItemLen), (size_t) lSearchKeyLen );
-
- if( (!bDescending && iRc > 0) || (bDescending && iRc < 0 )){
- TempIxNode = mpTag->npCurNode;
- mpTag->npCurNode = mpTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
- } else {
- bDone = true;
- }
- }
- }
- }
- }
- }
-
- // either started empty, or cleared due to file time diff
- if( !mpTag->npNodeChain ){
- // Get the root
- if(( iRc = LoadTagDetail( 2, mpTag )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- // lRootBlock is now available
- if(( iRc = GetBlock( vpTag, (mpTag->ulRootPage / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- // if this is a leaf node and no keys on this node, then the index is empty
- ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
- if( ulNoOfKeys == 0 && IsLeaf( vpTag, mpTag->npCurNode )){
-// iRc = XB_EMPTY;
- iRc = XB_NOT_FOUND;
- return iRc;
- }
- }
-
- // should be in the appropriate position in the node chain to continue the search from here
- // run down through the interior nodes
- xbInt16 iSearchRc = 0;
- xbUInt32 ulKeyPtr = 0;
-
- while( vpTag && !IsLeaf( vpTag, mpTag->npCurNode ) ){
- // get the number of keys on the block and compare the key to the rightmost key
- ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
-
- if( ulNoOfKeys == 0 ){
- mpTag->npCurNode->iCurKeyNo = 0;
-
- } else {
-
- iRc = CompareKey( cKeyType, vpKey, GetKeyData( mpTag->npCurNode, ulNoOfKeys - 1, mpTag->iKeyItemLen), (size_t) lSearchKeyLen );
- if( (!bDescending && iRc > 0) || (bDescending && iRc < 0)){
- mpTag->npCurNode->iCurKeyNo = ulNoOfKeys;
- }
- else
- {
- mpTag->npCurNode->iCurKeyNo = (xbUInt32) BSearchBlock( cKeyType, mpTag->npCurNode,
- (xbInt32) mpTag->iKeyItemLen, vpKey, (xbInt32) lSearchKeyLen, iSearchRc, bDescending );
- }
- }
-
- if(( iRc = GetKeyPtr( vpTag, mpTag->npCurNode->iCurKeyNo, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
-
- if(( iRc = GetBlock( vpTag, (ulKeyPtr / (xbUInt32)iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- }
-
- ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
- xbInt16 iCompRc = 0;
-
- if( ulNoOfKeys == 0 ){
- // iCompRc = -1;
- // iRc = XB_EMPTY;
- iRc = XB_NOT_FOUND;
- return iRc;
-
- } else {
-
- iRc = BSearchBlock( cKeyType, mpTag->npCurNode, mpTag->iKeyItemLen, vpKey, lSearchKeyLen, iCompRc, bDescending );
- // iCompRc
- // 0 found
- // < 0 eof encountered, search key > last key in file
- // > 0 not found, positioned to next key
-
- if( iCompRc >= 0 ){
- mpTag->npCurNode->iCurKeyNo = (xbUInt32) iRc;
-
-
- if( iRetrieveSw ){
-
- xbUInt32 ulKey = mpTag->npCurNode->iCurKeyNo;
- if( ulKey >= ulNoOfKeys ) // if position past end of keys, need to go back one and position to last key
- ulKey--;
-
- // if(( iRc = GetKeyPtr( vpTag, mpTag->npCurNode->iCurKeyNo, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
-
- if(( iRc = GetKeyPtr( vpTag, ulKey, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
- }
- }
- }
-
- if( iCompRc == 0 )
- return XB_NO_ERROR;
- else if( iCompRc > 0 )
- return XB_NOT_FOUND;
- else
- return XB_EOF;
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::FindKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-xbInt16 xbIxMdx::FindKeyForCurRec( void * vpTag )
-{
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbInt16 i = 0;
-
- try{
- if(( iRc = CreateKey( vpTag, 0 )) < XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::FindKeyForCurRec() Exception Caught. Error Stop = [%d] iRc = [%d] Tag=[%d]", iErrorStop, iRc, i );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return XB_NO_ERROR;
-}
-
-/***********************************************************************/
-//! @brief Get dbf record number for given key number.
-/*!
- \param vpTag Tag to retrieve dbf rec number on.
- \param iKeyNo Key number for retrieval
- \param np Pointer to node
- \param ulDbfPtr- Output dbf record number
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxMdx::GetDbfPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *np, xbUInt32 &ulDbfPtr ) const {
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- #ifdef XB_DEBUG_SUPPORT
- // turn this off in production mode for better performance
- xbUInt32 ulNoOfKeys = eGetUInt32 ( np->cpBlockData );
- if( iKeyNo < 0 || iKeyNo > (xbInt16) --ulNoOfKeys ){
- iErrorStop = 100;
- throw XB_INVALID_KEYNO;
- }
- #endif
-
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
- char *p = ( np->cpBlockData);
- p += (8 + (iKeyNo * mpTag->iKeyItemLen));
- ulDbfPtr = eGetUInt32 ( p );
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::GetDbfPtr() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-/*!
- \param vpTag Tag to retrieve first key on.
- \param iRetrieveSw xbTrue - Retrieve the record on success.<br>
- xbFalse - Don't retrieve record.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::GetFirstKey( void *vpTag, xbInt16 iRetrieveSw = 0 ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- // convert the tag pointer to mdx tag pointer
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
-
-
- try{
- // clear out any history
- if( mpTag->npNodeChain ){
- mpTag->npNodeChain = FreeNodeChain( mpTag->npNodeChain );
- mpTag->npCurNode = NULL;
- }
- // Get the root
- if(( iRc = LoadTagDetail( 2, mpTag )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- // lRootPage is available
- if(( iRc = GetBlock( vpTag, (mpTag->ulRootPage / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- // if no keys on this node, then the index is empty
- // this is not true
-
- xbUInt32 ulKeyPtr = eGetUInt32( mpTag->npCurNode->cpBlockData );
- if( ulKeyPtr == 0 && IsLeaf( vpTag, mpTag->npCurNode )){
- iRc = XB_EMPTY;
- return iRc;
- }
-
- while( !IsLeaf( vpTag, mpTag->npCurNode )){ // go down the chain looking for a leaf node
- if(( iRc = GetKeyPtr( vpTag, 0, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- if(( iRc = GetBlock( vpTag, (ulKeyPtr / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- }
-
- // retrieve record to data buf
- if( iRetrieveSw ){
- if(( iRc = GetKeyPtr( vpTag, 0, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::GetFirstKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//xbBool xbIxMdx::GetIndexUpdated() const {
-// std::cout << "xbIxMdx::GetIndexUpdate() FIX ME \n";
-// return xbFalse;
-//}
-
-/***********************************************************************/
-//! @brief Get the key expression for the given tag.
-/*!
- \param vpTag Tag to retrieve key expression from tag.
- \returns Key expression.
-*/
-
-xbString &xbIxMdx::GetKeyExpression( const void * vpTag ) const{
- xbMdxTag *mpTag = (xbMdxTag *) vpTag;
- return *mpTag->sKeyExp;
-}
-
-/***********************************************************************/
-//! @brief Get the key expression for the given tag.
-/*!
- \param vpTag Tag to retrieve filter expression from tag (if it exists).
- \returns Key filter.
-*/
-
-xbString &xbIxMdx::GetKeyFilter( const void * vpTag ) const{
-
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
-
- if( mpTag->sFiltExp )
- return *mpTag->sFiltExp;
- else
- return sNullString;
-
-}
-/**************************************************************************************************/
-xbInt16 xbIxMdx::GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *np, xbUInt32 &ulKeyPtr ) const {
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
-
- xbMdxTag *mdxTag = (xbMdxTag *) vpTag;
- char *p = np->cpBlockData;
- xbUInt32 ulKeyCnt = eGetUInt32( p );
- if( iKeyNo < 0 || iKeyNo > (xbInt16) ulKeyCnt ){
- iErrorStop = 100;
- iRc = XB_INVALID_KEYNO;
- throw iRc;
- }
- p+=8; // skip past first two four byte numeric fields
- p+= (iKeyNo * mdxTag->iKeyItemLen);
- ulKeyPtr = eGetUInt32( p );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::GetKeyPtr() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Returns key update status.
-/*!
- \param vpTag Tag to check status on.
- \returns XB_UPD_KEY Key updated.<br>
- XB_DEL_KEY Key deleted.<br>
- XB_ADD_KEY Key added.<br>
- 0 No key updates
-
-*/
-inline xbInt16 xbIxMdx::GetKeySts( void *vpTag ) const{
-
- xbMdxTag *mpTag = (xbMdxTag *) vpTag;
- return mpTag->iKeySts;
-}
-
-/***********************************************************************/
-char xbIxMdx::GetKeyType( const void *vpTag ) const {
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
- return mpTag->cKeyType;
-}
-
-/***********************************************************************/
-//! @brief Get the last key for the given tag.
-/*!
- \param vpTag Tag to retrieve last key on.
- \param iRetrieveSw xbTrue - Retrieve the record on success.<br>
- xbFalse - Don't retrieve record.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::GetLastKey( void *vpTag, xbInt16 iRetrieveSw ){
- return GetLastKey( 0, vpTag, iRetrieveSw );
-}
-
-/***********************************************************************/
-//! @brief Get the last key for the given tag and starting node.
-/*!
- \param ulBlockNo Starting node
- \param vpTag Tag to retrieve last key on.
- \param iRetrieveSw xbTrue - Retrieve the record if key found.<br>
- xbFalse - Don't retrieve record.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::GetLastKey( xbUInt32 ulBlockNo, void *vpTag, xbInt16 iRetrieveSw ){
-
- // if UlNodeNo is zero, start at head node, otherwise start at ulNodeNo
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- // convert the tag pointer to mdx tag pointer
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
-
- try{
- xbUInt32 ulNoOfKeys = 0;
- // clear out any history
- if( mpTag->npNodeChain ){
- mpTag->npNodeChain = FreeNodeChain( mpTag->npNodeChain );
- mpTag->npCurNode = NULL;
- }
- // Get the root
- if( ulBlockNo == 0 ){
- if(( iRc = LoadTagDetail( 2, mpTag )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- //if(( iRc = GetBlock( vpTag, (mpTag->ulRootPage / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- if(( iRc = GetBlock( vpTag, PageToBlock( mpTag->ulRootPage ), 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- } else {
- if(( iRc = GetBlock( vpTag, ulBlockNo, 1 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
-
- ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
-
- if( ulNoOfKeys == 0 && IsLeaf( vpTag, mpTag->npCurNode )){
- iRc = XB_EMPTY;
- return iRc;
- }
-
- mpTag->npCurNode->iCurKeyNo = ulNoOfKeys;
- ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
-
- xbUInt32 ulKeyPtr = 0;
- while( !IsLeaf( vpTag, mpTag->npCurNode )){ // go down the chain looking for a leaf node
- // std::cout << "Considered an interior node\n";
- if(( iRc = GetKeyPtr( vpTag, ulNoOfKeys, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if(( iRc = GetBlock( vpTag, (ulKeyPtr / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
-
- ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
- mpTag->npCurNode->iCurKeyNo = ulNoOfKeys;
- }
- // leaf node has one fewer keys than the interior node
- mpTag->npCurNode->iCurKeyNo--;
- ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
-
- // retrieve record to data buf
- if( iRetrieveSw ){
- if(( iRc = GetKeyPtr( vpTag, (ulNoOfKeys-1), mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::GetLastKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Get the last key for a block number.
-/*!
- \param vpTag Tag to retrieve first key on.
- \param ulBlockNo Block number for key retrieval.
- \param cpBuf output buffer for key placement
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::GetLastKeyForBlockNo( void *vpTag, xbUInt32 ulBlockNo, char *cpBuf ){
-
- // returns the last key for a given block number
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- xbMdxTag * npTag = (xbMdxTag *) vpTag;
-
- try{
- xbIxNode * npSaveNodeChain = npTag->npNodeChain;
- xbIxNode * npSaveCurNode = npTag->npCurNode;
- npTag->npNodeChain = NULL;
-
- if(( iRc = GetLastKey( ulBlockNo, npTag, 0 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- memcpy( cpBuf, GetKeyData( npTag->npCurNode, GetKeyCount( npTag->npCurNode ) - 1, npTag->iKeyItemLen ), (size_t) npTag->iKeyLen );
-
- // free memory
- FreeNodeChain( npTag->npNodeChain );
- npTag->npNodeChain = npSaveNodeChain;
- npTag->npCurNode = npSaveCurNode;
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::GetLastKeyForBlockNo() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ) );
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Get the next key for the given tag.
-/*!
- \param vpTag Tag to retrieve next key on.
- \param iRetrieveSw xbTrue - Retrieve the record on success.<br>
- xbFalse - Don't retrieve record.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::GetNextKey( void * vpTag, xbInt16 iRetrieveSw ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- // convert the tag pointer to mdx tag pointer
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
-
- try{
- if( !mpTag->npCurNode )
- return GetFirstKey( vpTag, iRetrieveSw );
-
- // more keys on this node?
- xbUInt32 ulKeyPtr;
- if( (eGetUInt32( mpTag->npCurNode->cpBlockData ) - 1) > mpTag->npCurNode->iCurKeyNo ){
- mpTag->npCurNode->iCurKeyNo++;
-
- if(( iRc = GetKeyPtr( vpTag, mpTag->npCurNode->iCurKeyNo, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if( iRetrieveSw ){
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- } else {
- return iRc;
- }
- } else {
- return iRc;
- }
- }
-
- // if at end head node, then at eof
- if( mpTag->npCurNode->ulBlockNo == ( mpTag->ulRootPage / (xbUInt32) iBlockFactor ))
- return XB_EOF;
-
- // This logic assumes that interior nodes have n+1 left node no's where n is the number of keys in the node
- xbIxNode * TempIxNode = mpTag->npCurNode;
- mpTag->npCurNode = mpTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
-
- // While no more right keys && not head node, pop up one node
- while( mpTag->npCurNode->iCurKeyNo >= eGetUInt32( mpTag->npCurNode->cpBlockData ) &&
- mpTag->npCurNode->ulBlockNo != ( mpTag->ulRootPage / (xbUInt32) iBlockFactor) ){
-
- TempIxNode = mpTag->npCurNode;
- mpTag->npCurNode = mpTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
- }
-
- // if head node && right most key, return eof
- if( mpTag->npCurNode->ulBlockNo == (mpTag->ulRootPage / (xbUInt32) iBlockFactor) &&
- mpTag->npCurNode->iCurKeyNo == eGetUInt32( mpTag->npCurNode->cpBlockData ))
- return XB_EOF;
-
- // move one to the right
- mpTag->npCurNode->iCurKeyNo++;
- if(( iRc = GetKeyPtr( vpTag, mpTag->npCurNode->iCurKeyNo, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- if(( iRc = GetBlock( vpTag, (ulKeyPtr / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- // traverse down the left side of the tree
- while( !IsLeaf( vpTag, mpTag->npCurNode )) // go down the chain looking for a leaf node
- {
- if(( iRc = GetKeyPtr( vpTag, 0, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if(( iRc = GetBlock( vpTag, (ulKeyPtr / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
- // retrieve record to data buf
- if( iRetrieveSw ){
- if(( iRc = GetKeyPtr( vpTag, 0, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- } else {
- return iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::GetNextKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Get the previous key for the given tag.
-/*!
- \param vpTag Tag to retrieve previous key on.
- \param iRetrieveSw xbTrue - Retrieve the record on success.<br>
- xbFalse - Don't retrieve record.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::GetPrevKey( void * vpTag, xbInt16 iRetrieveSw ){
-
- xbString s;
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- // convert the tag pointer to mdx tag pointer
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
-
- try{
- if( !mpTag->npCurNode ){
- return GetLastKey( 0, vpTag, iRetrieveSw );
- }
-
- xbUInt32 ulKeyPtr = 0;
- // more keys on this assumed-leaf node?
-
- if( mpTag->npCurNode->iCurKeyNo > 0 ){
- mpTag->npCurNode->iCurKeyNo--;
-
- if(( iRc = GetKeyPtr( vpTag, mpTag->npCurNode->iCurKeyNo, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- if( iRetrieveSw ){
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- } else {
- return iRc;
- }
- } else {
- return iRc;
- }
- }
-
- //if head node = start node, at eof
- if( mpTag->npCurNode->ulBlockNo == ( mpTag->ulRootPage / (xbUInt32) iBlockFactor ))
- return XB_BOF;
-
- // This logic assumes that interior nodes have n+1 left node no's where n is the number of keys in the node
- xbIxNode * TempIxNode = mpTag->npCurNode;
- mpTag->npCurNode = mpTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
-
- // While no more left keys && not head node, pop up one node
- while( mpTag->npCurNode->iCurKeyNo == 0 &&
- mpTag->npCurNode->ulBlockNo != ( mpTag->ulRootPage / (xbUInt32) iBlockFactor) ){
- TempIxNode = mpTag->npCurNode;
- mpTag->npCurNode = mpTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
- }
-
- //if head node && left most key, return bof
- if( mpTag->npCurNode->ulBlockNo == ( mpTag->ulRootPage / (xbUInt32) iBlockFactor) && mpTag->npCurNode->iCurKeyNo == 0 )
- return XB_BOF;
-
- // move one to the left
- mpTag->npCurNode->iCurKeyNo--;
- if(( iRc = GetKeyPtr( vpTag, mpTag->npCurNode->iCurKeyNo, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- if(( iRc = GetBlock( vpTag, (ulKeyPtr / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- // traverse down the right side of the tree
- xbUInt32 ulNoOfKeys;
- while( !IsLeaf( vpTag, mpTag->npCurNode )) // go down the chain looking for a leaf node
- {
- ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
- mpTag->npCurNode->iCurKeyNo = ulNoOfKeys;
-
- if(( iRc = GetKeyPtr( vpTag, ulNoOfKeys, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if(( iRc = GetBlock( vpTag, (ulKeyPtr / (xbUInt32) iBlockFactor), 1 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
-
- // ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
- mpTag->npCurNode->iCurKeyNo = eGetUInt32( mpTag->npCurNode->cpBlockData ) - 1;
-
- // retrieve record to data buf
- if( iRetrieveSw ){
- if(( iRc = GetKeyPtr( vpTag, mpTag->npCurNode->iCurKeyNo, mpTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- } else {
- return iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::GetPrevKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief GetReuseEmptyNode swuitch setting.
-/*!
- \returns xbFalse - Do not reuse empty MDX index nodes (Dbase 6. behavior).
- xbTrue - Reuse empty MDX index nodes.
-*/
-
-xbBool xbIxMdx::GetReuseEmptyNodesSw() const {
- return bReuseEmptyNodes;
-}
-/***********************************************************************/
-xbBool xbIxMdx::GetSortOrder( void *vpTag ) const {
-
- // return true if descending
- xbMdxTag *mTag = (xbMdxTag *) vpTag;
- if( mTag->cKeyFmt2 & 0x08 )
- return 0x01;
- else
- return 0x00;
-}
-
-/***********************************************************************/
-//! @brief Get tag for tag number.
-/*!
- \param iTagNo - Zero based, which tag to retrieve.
- \returns Pointer to mdx tag for a given tag number.
-*/
-
-void * xbIxMdx::GetTag( xbInt16 iTagNo ) const {
-
- xbMdxTag *tt = mdxTagTbl;
- xbInt16 i = 0;
-
- while( i < iTagNo && tt->next ){
- tt = tt->next;
- i++;
- }
- if( i == iTagNo )
- return (void *) tt;
- else
- return NULL;
-}
-
-/***********************************************************************/
-//! @brief Get tag for tag name.
-/*!
- \sTagName - Tag name to retrieve.
- \returns Pointer to mdx tag for a given tag number.
-*/
-
-void * xbIxMdx::GetTag( xbString &sTagName ) const {
-
- xbMdxTag *tt = mdxTagTbl;
-
- while( sTagName != tt->cTagName && tt->next ){
- tt = tt->next;
- }
-
- if( sTagName == tt->cTagName )
- return (void *) tt;
- else
- return NULL;
-}
-/***********************************************************************/
-xbInt16 xbIxMdx::GetTagCount() const {
- return iTagUseCnt;
-}
-
-/***********************************************************************/
-void xbIxMdx::GetTagName( void *vpTag, xbString &sTagName ){
-
- xbMdxTag *mpTag = (xbMdxTag *) vpTag;
- sTagName = mpTag->sTagName->Str();
-}
-
-/***********************************************************************/
-//const char *xbIxMdx::GetTagName( void *vpTag, xbInt16 iOpt ) const {
-
-const char *xbIxMdx::GetTagName( void *vpTag, xbInt16 ) const {
- xbMdxTag *mpTag = (xbMdxTag *) vpTag;
- return mpTag->cTagName;
-}
-
-/***********************************************************************/
-xbString &xbIxMdx::GetTagName( void *vpTag ) const {
-
- xbMdxTag *mpTag = (xbMdxTag *) vpTag;
- return *mpTag->sTagName;
-}
-
-/***********************************************************************/
-void *xbIxMdx::GetTagTblPtr() const {
- return (void *) mdxTagTbl;
-}
-
-/***********************************************************************/
-xbBool xbIxMdx::GetUnique( void *vpTag ) const {
-//! @brief Determine unique setting for given tag.
-/*!
- \param vpTag Tag to retrieve expression from.
- \returns xbTrue if unique key.
-*/
- xbMdxTag *mTag = (xbMdxTag *) vpTag;
- return mTag->cUnique;
-}
-
-/***********************************************************************/
-//! @brief Harvest Empty Node.
-/*!
- Harvest empty MDX node and add it to the chain of link nodes
-
- \param mpTag Tag to harvest.
- \param iOpt - 0 Don't write the node info to disk, handled elsewhere (don't write it twice)
- 1 Write the update into to disk
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxMdx::HarvestEmptyNode( xbMdxTag *mpTag, xbIxNode *npNode, xbInt16 iOpt, xbBool bHarvestRoot ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbBool bRootPage = xbFalse;
- xbInt32 iOffset = 0;
-
- try{
-
- if( mpTag->ulRootPage == BlockToPage( npNode->ulBlockNo ) && !bHarvestRoot ){
- bRootPage = xbTrue;
- }
- memset( npNode->cpBlockData, 0x00, GetBlockSize());
-
- char *pTrg = npNode->cpBlockData;
- if( !bRootPage ){
- pTrg += 4;
- ePutUInt32( pTrg, ulFirstFreePage );
- }
-
- if( bRootPage ){
- if( mpTag->cHasKeys ){
-
- // std::cout << "setting has keys\n";
-
- mpTag->cHasKeys = 0x00;
- if(( iRc = xbFseek( ((mpTag->ulTagHdrPageNo * 512) + 246), SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if(( iRc = xbFwrite( &mpTag->cHasKeys, 1, 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- // might need to update left sibling and right sibling here.
- // Fields don't seem to be updated consistently by other xbase tools,
- // for now, not updating
- }
-
- } else {
-
- // update header
- // seek to position byte 13
- ulFirstFreePage = BlockToPage( npNode->ulBlockNo );
- if(( iRc = xbFseek( 36, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- // write it
- char c4[4];
- ePutUInt32( c4, ulFirstFreePage );
- if(( iRc = xbFwrite( c4, 4, 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- }
-
- if( iOpt == 1 ){
- if(( iRc = xbFseek( (xbInt64) ((npNode->ulBlockNo * GetBlockSize() )) + iOffset, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- // write out the block
- if(( iRc = xbFwrite( npNode->cpBlockData, GetBlockSize(), 1 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
- }
-
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::HarvestEmptyNodeI() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Harvest Tag Nodes.
-/*!
- Save all nodes for a given tag into the free node chain.
- Used for reindexing or deleting a given tag.
-
- \param mpTag Tag for harvesting nodes
- \param bHarvestRoot Set to True when deleting tag
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::HarvestTagNodes( xbMdxTag *mpTag, xbBool bHarvestRoot ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- xbUInt32 ulBlkNo;
- xbLinkListOrd<xbUInt32> ll;
- xbLinkListNode<xbUInt32> * llN;
- xbIxNode * n;
-
- try{
-
- ll.SetDupKeys( xbFalse );
-
- // clear out any history
- if( mpTag->npNodeChain ){
- mpTag->npNodeChain = FreeNodeChain( mpTag->npNodeChain );
- mpTag->npCurNode = NULL;
- }
-
- while( GetNextKey( mpTag, 0 ) == 0 ){
- n = mpTag->npNodeChain;
- while(n){
- ll.InsertKey( n->ulBlockNo, (xbUInt32) n->iCurKeyNo );
- n = n->npNext;
- }
- }
-
- if( bHarvestRoot )
- ll.InsertKey( PageToBlock( mpTag->ulTagHdrPageNo ), 0 );
-
- llN = ll.GetHeadNode();
- if(( n = xbIx::AllocateIxNode( GetBlockSize())) == NULL ){
- iErrorStop = 100;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- while( llN ){
- ulBlkNo = llN->GetKey();
-
- // read in a block for the block number
- if(( iRc = ReadBlock( ulBlkNo, GetBlockSize(), n->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- // harvest it
- n->ulBlockNo = ulBlkNo;
- if(( iRc = HarvestEmptyNode( mpTag, n, 1, bHarvestRoot )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- llN = llN->GetNextNode();
- }
- n = FreeNodeChain( n );
- mpTag->npNodeChain = FreeNodeChain( mpTag->npNodeChain );
- mpTag->npCurNode = NULL;
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::HarvestTagNodes() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Insert key into interior node.
-/*!
- Insert key into non-full interior node.<br>
- Assumes valid inputs
-
- \param vpTag Tag in play.
- \param npNode Node for insertion.
- \param iSlotNo Slot number to insert key.
- \param ulPtr Page number to insert.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::InsertNodeI( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo, xbUInt32 ulPtr ){
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char *pNewKeyPos;
- char *pTrg;
- char *pLastKey = NULL;
- xbMdxTag * npTag;
- npTag = (xbMdxTag *) vpTag;
- xbInt16 iCopyLen;
- xbInt16 iNewKeyPos = 8;
-
- try{
- xbInt32 lKeyCnt = GetKeyCount( npNode );
- iNewKeyPos += (iSlotNo * npTag->iKeyItemLen);
- char *pSrc = npNode->cpBlockData;
-
- if( iSlotNo < lKeyCnt )
- iCopyLen = ((lKeyCnt - iSlotNo) * npTag->iKeyItemLen) + 4;
- else
- iCopyLen = 0;
-
- xbUInt32 ulRqdBufSize = (xbUInt32) ((lKeyCnt + 1) * npTag->iKeyItemLen) + 12;
- if( ulRqdBufSize > npNode->ulBufSize ){
- npNode->ulBufSize += (xbUInt32) npTag->iKeyItemLen;
- npNode->cpBlockData = (char *) realloc( npNode->cpBlockData, (size_t) npNode->ulBufSize );
- if( !npNode->cpBlockData ){
- iErrorStop = 100;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- }
-
- // if not appending to the end of the node, make some room, move things to the right
- pNewKeyPos = npNode->cpBlockData;
- pNewKeyPos += iNewKeyPos;
-
- if( iSlotNo < lKeyCnt ){
- pTrg = pNewKeyPos;
- pTrg += npTag->iKeyItemLen;
- memmove( pTrg, pNewKeyPos, (size_t) iCopyLen );
- }
-
- // get the right most key for the left part of the split node
- xbUInt32 ulKeyPtr2;
- if(( iRc = GetKeyPtr( vpTag, npNode->iCurKeyNo, npNode, ulKeyPtr2 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- // get the new right key value for the freshly split node
- pLastKey = (char *) malloc((size_t) npTag->iKeyLen);
- if(( iRc = GetLastKeyForBlockNo( vpTag, PageToBlock( ulKeyPtr2 ), pLastKey )) != XB_NO_ERROR ){
- iRc = 120;
- throw iRc;
- }
-
- // write the key values
- pTrg = pNewKeyPos;
- pTrg += 4;
- pSrc = pLastKey;
- for( xbInt16 i = 0; i < npTag->iKeyLen; i++ )
- *pTrg++ = *pSrc++;
-
- pTrg = pNewKeyPos;
- //pTrg+= npTag->iKeyItemLen - 4;
- pTrg+= npTag->iKeyItemLen;
-
- ePutUInt32( pTrg, ulPtr);
- ePutInt32( npNode->cpBlockData, ++lKeyCnt );
-
- // write out the updated block to disk
- if(( iRc = WriteBlock( npNode->ulBlockNo, GetBlockSize(), npNode->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( pLastKey )
- free( pLastKey );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::InsertNodeI() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( pLastKey )
- free( pLastKey );
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Insert key into leaf node.
-/*!
- Insert key into non-full leaf node.<br>
- Assumes valid inputs
-
- \param vpTag Tag in play.
- \param npNode Node for insertion.
- \param iSlotNo Slot number to insert key.
- \param ulPtr Pointer number to insert.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxMdx::InsertNodeL( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo, char * cpKeyBuf, xbUInt32 ulPtr ){
-
- // format of block data is
- // 4 bytes number of keys on block
- // 4 bytes - next free block or split block num
- // repeating
- // 4 bytes record number
- // x bytes key data
-
- // Special processing note: when splitting node, new key is first inserted into full left node before
- // the node is split. This routine will make additional room in the buffer for that scenario
-
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char *pNewKeyPos; // pointer to position in record for new key composite
- char *pTrg;
-
- xbInt16 iNewKeyPos = 8; // position in data block where new key begins.
- // is the position of the record number, where the fmt is
- // [four byte rec number][actual key data] repeats
-
- xbMdxTag * npTag = (xbMdxTag *) vpTag;
- xbInt16 iCopyLen;
-
- try{
- xbInt32 lKeyCnt = GetKeyCount( npNode );
- iNewKeyPos += (iSlotNo * npTag->iKeyItemLen);
-
- // length of number of keys that need to be moved to the right
- if( iSlotNo < lKeyCnt )
- iCopyLen = (lKeyCnt - iSlotNo) * npTag->iKeyItemLen;
- else
- iCopyLen = 0;
-
- // +8 is to include the first two 4 byte fields in the block
- xbUInt32 ulRqdBufSize = (xbUInt32) ((lKeyCnt + 1) * npTag->iKeyItemLen) + 8;
-
- if( ulRqdBufSize > npNode->ulBufSize ){
-
- npNode->ulBufSize += (xbUInt32) npTag->iKeyItemLen;
- npNode->cpBlockData = (char *) realloc( npNode->cpBlockData, (size_t) npNode->ulBufSize );
-
- // init the newly acquired buffer space
- char *p = npNode->cpBlockData;
- p += (npNode->ulBufSize - (xbUInt32) npTag->iKeyItemLen);
- memset( p, 0x00, (size_t) npTag->iKeyItemLen );
-
- if( !npNode->cpBlockData ){
- iErrorStop = 100;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- }
-
- // if not appending to end, move things right
-
- pNewKeyPos = npNode->cpBlockData;
- pNewKeyPos += iNewKeyPos;
-
- if( iSlotNo < lKeyCnt ) {
- pTrg = pNewKeyPos;
- pTrg += npTag->iKeyItemLen;
- memmove( pTrg, pNewKeyPos, (size_t) iCopyLen );
-
- }
-
- // write rec number
- ePutUInt32( pNewKeyPos, ulPtr );
-
- // write the key value
- pTrg = pNewKeyPos;
- pTrg += 4;
- char * pSrc = cpKeyBuf;
- for( xbInt16 i = 0; i < npTag->iKeyLen; i++ )
- *pTrg++ = *pSrc++;
-
- // update number of keys on the node
- ePutInt32( npNode->cpBlockData, ++lKeyCnt );
-
- // determine length of node, zap everything to the right of it
- xbUInt32 iStartPos = 8 + ((xbUInt32) lKeyCnt * (xbUInt32) npTag->iKeyItemLen );
- xbUInt32 iClearLen = npNode->ulBufSize - iStartPos;
-
- char *p = npNode->cpBlockData;
- p += iStartPos;
- memset( p, 0x00, iClearLen );
-
- // write out the updated block to disk
- if(( iRc = WriteBlock( npNode->ulBlockNo, GetBlockSize(), npNode->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::InsertNodeL() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-inline xbBool xbIxMdx::IsLeaf( void *vpTag, xbIxNode *npNode ) const{
-
- // for performance reasons, does no data checking
- // will result in potentially hard to find segfaults if passing invalid npNode
-
- xbMdxTag *mTag = (xbMdxTag *) vpTag;
- char *p = npNode->cpBlockData;
-
- xbInt32 lNoOfKeys = eGetInt32( p );
- // mdx interior nodes have a sibling number to the right of the right most key in the node
- p+=8;
- p+= mTag->iKeyItemLen * lNoOfKeys;
-
- if( eGetUInt32( p ) == 0 ){
- // std::cout << "leaf node\n";
- return true;
- } else {
- // std::cout << "interior node\n";
- return false;
- }
-}
-
-/***********************************************************************/
-xbInt16 xbIxMdx::KeyExists( void * vpTag )
-{
- // this method assumes the key has already been built
-
- xbMdxTag *mpTag = (xbMdxTag *) vpTag;
- xbInt16 iRc = FindKey( vpTag, mpTag->cpKeyBuf, mpTag->iKeyLen, 0 );
-
- if( iRc == 0 )
- return 1;
- else
- return 0;
-
-}
-
-/***********************************************************************/
-//! @brief Set position for key add.
-/*!
- This routine is called by the AddKey() method and is used to position
- the node chain to the position the new key should be added to the index.
-
- \param npTag Pointer to npTag.
- \param ulAddRecNo Record number to add.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxMdx::KeySetPosAdd( xbMdxTag *mpTag, xbUInt32 ulAddRecNo ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- iRc = FindKey( mpTag, mpTag->cpKeyBuf, mpTag->iKeyLen, 0 );
- if( iRc == XB_NOT_FOUND || iRc == XB_EMPTY )
- return XB_NO_ERROR; // good position
- else if( iRc != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- // get here if key was found, get the right most instance of any non unique key for append, find correct spot for update
- if( GetUnique( mpTag ) == 0 ){
-
- xbUInt32 ulCurRecNo;
- if(( iRc = GetDbfPtr( mpTag, mpTag->npCurNode->iCurKeyNo, mpTag->npCurNode, ulCurRecNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- xbBool bKeysMatch = xbTrue;
-
- while( bKeysMatch && ulAddRecNo > ulCurRecNo && iRc == XB_NO_ERROR ){
- if(( iRc = GetNextKey( mpTag, 0 )) == XB_NO_ERROR ){
- if( memcmp( GetKeyData( mpTag->npCurNode, mpTag->npCurNode->iCurKeyNo, mpTag->iKeyItemLen ), mpTag->cpKeyBuf, (size_t) mpTag->iKeyLen ))
- bKeysMatch = xbFalse;
- else{
- if(( iRc = GetDbfPtr( mpTag, mpTag->npCurNode->iCurKeyNo, mpTag->npCurNode, ulCurRecNo )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- }
- }
- }
- if( iRc == XB_EOF ){ // eof condition
- if(( iRc = GetLastKey( 0, mpTag, 0 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- mpTag->npCurNode->iCurKeyNo++;
- return XB_NO_ERROR;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::KeySetPosAdd() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Set position for key delete.
-/*!
- This routine is called by the DeleteKey() method and is used to position
- the node chain to the position the old key should be deleted from the index.
-
- \param npTag Pointer to npTag.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::KeySetPosDel( xbMdxTag *npTag ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbString sMsg;
-
- try{
-
- iRc = FindKey( npTag, npTag->cpKeyBuf2, npTag->iKeyLen, 0 );
- if( iRc == XB_NOT_FOUND || iRc == XB_EMPTY )
- return XB_NO_ERROR; // good pos ition
- else if( iRc != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- xbUInt32 ulIxRecNo;
- if(( iRc = GetDbfPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulIxRecNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- if( ulIxRecNo == dbf->GetCurRecNo())
- return XB_NO_ERROR;
-
- if( GetUnique( npTag ) == 1 ){
- iErrorStop = 120;
- iRc = XB_NOT_FOUND;
- throw iRc;
- }
-
- xbBool bFound = xbFalse;
- xbBool bKeysMatch = xbTrue;
- while( bKeysMatch && !bFound && iRc == XB_NO_ERROR ){
-
- if(( iRc = GetNextKey( npTag, 0 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( memcmp( GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->iKeyItemLen ), npTag->cpKeyBuf2, (size_t) npTag->iKeyLen )){
- bKeysMatch = xbFalse;
- } else {
- if(( iRc = GetDbfPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulIxRecNo )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if( ulIxRecNo == dbf->GetCurRecNo())
- bFound = xbTrue;
- }
- }
-
- if( bFound )
- return XB_NO_ERROR;
- else
- return XB_NOT_FOUND;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::KeySetPosDel() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Returns key update status.
-/*!
- \param vpTag Tag to check status on.
- \returns xbtrue - Key was updated.<br>xbFalse - Key not updated.
-*/
-/*
-inline xbBool xbIxMdx::KeyFiltered( void *vpTag ) const{
-
- xbMdxTag *mpTag = (xbMdxTag *) vpTag;
- return mpTag->bKeyFiltered;
-}
-*/
-/***********************************************************************/
-xbInt16 xbIxMdx::LoadTagDetail( xbInt16 iOption, xbMdxTag *tte ){
-
- // option 1 - Load the entire tag detail
- // option 2 - Load the dynamic variables only
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- size_t iReadSize;
- char *buf = NULL;
- char *p;
-
- try{
- // set the read length based on the option
- if( iOption == 1 )
- iReadSize = 1024;
-
- else if( iOption == 2 )
- // iReadSize = 4;
- iReadSize = 260;
- else{
- iRc = XB_INVALID_OPTION;
- iErrorStop = 100;
- throw iRc;
- }
- if(( buf = (char *) calloc( 1, (size_t) iReadSize )) == NULL ){
- iErrorStop = 110;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- if(( iRc = ReadBlock( tte->ulTagHdrPageNo,(xbUInt32) (GetBlockSize() / (xbUInt16) iBlockFactor),
- iReadSize, buf )) != XB_NO_ERROR ){
- free( buf );
- iErrorStop = 30;
- throw iRc;
- }
-
- p = buf;
- tte->ulRootPage = eGetUInt32( p );
-
- if( iOption == 1 ){
- p+=4;
- tte->ulTagSize = eGetUInt32( p );
- p+=4;
- tte->cKeyFmt2 = *p;
- p++;
- tte->cKeyType2 = *p;
- p+=3;
- tte->iKeyLen = eGetInt16( p );
- p+=2;
- tte->iKeysPerBlock = *p;
- p+=2;
- tte->iSecKeyType = eGetInt16( p );
- p+=2;
- tte->iKeyItemLen = eGetInt16( p );
- p+=2;
- tte->cSerialNo = *p;
- p+=3;
- tte->cUnique = *p;
- p++;
-
- // next line assumes expression is a null terminated string in the block
- tte->sKeyExp = new xbString();
- tte->sKeyExp->Sprintf( "%s", p );
-
- p+=221;
- tte->cHasFilter = *p;
- p+=1;
- tte->cHasKeys = *p;
- p+=2;
- tte->ulLeftChild = eGetUInt32( p );
- p+=4;
- tte->ulRightChild = eGetUInt32( p );
- p+=5;
- tte->cTagYY = *p;
- p++;
- tte->cTagMM = *p;
- p++;
- tte->cTagDD = *p;
- // p+=223;
-
- p+=221;
- tte->cKeyFmt3 = *p;
-
- if( tte->cHasFilter ){
- p+=282;
- tte->sFiltExp = new xbString();
- tte->sFiltExp->Sprintf( "%s", p );
- tte->filter = new xbExp( xbase, dbf );
- if(( iRc = tte->filter->ParseExpression( tte->sFiltExp->Str())) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- tte->npNodeChain = NULL;
- tte->npCurNode = NULL;
- tte->cpKeyBuf = (char *) malloc( (size_t) tte->iKeyLen + 1 );
- tte->cpKeyBuf2 = (char *) malloc( (size_t) tte->iKeyLen + 1 );
- tte->exp = new xbExp( xbase, dbf );
- if(( iRc = tte->exp->ParseExpression( tte->sKeyExp->Str() )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- } else if( iOption == 2 ){
- // refresh the dynamic tag variables
- p+=4;
- tte->ulTagSize = eGetUInt32( p );
- p+= 16;
- tte->cSerialNo = *p;
- p+= 226;
- tte->cHasKeys = *p;
- p+=2;
- tte->ulLeftChild = eGetUInt32( p );
- p+=4;
- tte->ulRightChild = eGetUInt32( p );
- p+=5;
- tte->cTagYY = *p;
- p++;
- tte->cTagMM = *p;
- p++;
- tte->cTagDD = *p;
- }
- if( buf )
- free( buf );
-
- }
- catch (xbInt16 iRc ){
- if( buf )
- free( buf );
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::LoadTagDetail() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-xbInt16 xbIxMdx::LoadTagTable()
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char * buf = NULL;
-
- //std::cout << "xbIxMdx::LoadTagTable() tag use cnt = " << iTagUseCnt << "\n";
-
- try{
-
- if( iTagUseCnt > 46 ){
- iErrorStop = 100;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
-
- xbInt16 iBufSize = (xbInt16) iTagLen * iTagUseCnt;
-
- if(( buf = (char *) malloc( (size_t) iBufSize )) == NULL ){
- iErrorStop = 110;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- if(( iRc = xbFseek( 544, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- if(( iRc = xbFread( buf, (size_t) iBufSize, 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- xbInt16 iPos;
- char *p;
- xbMdxTag *tte;
- xbMdxTag *ttel = NULL;
-
- for( xbInt16 i = 0; i < iTagUseCnt; i++ ){
- iPos = i * iTagLen;
- p = buf + iPos;
-
- if(( tte = (xbMdxTag *) calloc( 1, (size_t) sizeof( xbMdxTag ))) == NULL ){
- iErrorStop = 140;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
-
- // set the current tag to the first tag in the table
- if( !vpCurTag )
- xbIx::SetCurTag( (void *) tte );
-
- if( mdxTagTbl )
- ttel->next = tte;
- else
- mdxTagTbl = tte;
-
- ttel = tte;
- tte->next = NULL;
- tte->ulTagHdrPageNo = eGetUInt32( p );
-
- p += 4;
- for( xbUInt32 i = 0; i < 11; i ++ )
- tte->cTagName[i] = *p++;
-
- tte->cTagName[11] = 0x00;
- tte->cKeyFmt = *p++;
- tte->cLeftChild = *p++;
- tte->cRightChild = *p++;
- tte->cParent = *p++;
- tte->c2 = *p++;
- tte->cKeyType = *p;
- tte->sTagName = new xbString();
- tte->sTagName->Set( tte->cTagName );
- tte->sTagName->Trim();
-
- if(( iRc = LoadTagDetail( 1, tte )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
- if( buf )
- free( buf );
- }
- catch (xbInt16 iRc ){
- if( buf )
- free( buf );
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::LoadTagTable() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- if( iErrorStop == 100 ){
- sMsg.Sprintf( "xbIxMdx::LoadTagTable() Invalid Tag Count: %d", iTagUseCnt );
- xbase->WriteLogMessage( sMsg.Str());
- }
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/**************************************************************************************************************/
-//! @brief Calculate the block number for a given page.
-/*!
- This routine is called by any function needing to calculate the block number for a given page.
- Page numbers are stored internally in the physical file, and the library reads and writes in
- blocks of one or more pages.
-
- Assumes valid data input
-
- \param ulPageNo Page Number
- \returns Calculated block number.
-*/
-
-inline xbUInt32 xbIxMdx::PageToBlock( xbUInt32 ulPageNo ){
- return ulPageNo / (xbUInt32) iBlockFactor;
-}
-
-
-
-/**************************************************************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-xbInt16 xbIxMdx::PrintKey( void *vpTag, xbIxNode *npNode, xbInt16 iKeyNo, xbInt16 iDepth, char cType, xbInt16 iOutputOpt ){
-
- xbString sPre;
- sPre.Sprintf( "%c ", cType );
- for( xbInt16 i = 0; i < iDepth; i++ )
- sPre += "|";
-
- xbString sPost;
- sPost.Sprintf( "\tThisBlock=[%ld] KeyNo=[%d] Depth=[%d]", npNode->ulBlockNo, iKeyNo, iDepth );
-
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
- char *p = npNode->cpBlockData + (8 + (iKeyNo * mpTag->iKeyItemLen ));
-
- xbString sKeyPtr;
- xbUInt32 ulNoOfKeys = 0;
- if( cType == 'I' ) { // interior
- sKeyPtr.Sprintf( " ptr=[%ld]", eGetUInt32( p ));
- ulNoOfKeys = eGetUInt32( mpTag->npCurNode->cpBlockData );
- }
- else if( cType == 'L' ) // leaf
- sKeyPtr.Sprintf( " rec=[%ld]", eGetUInt32( p ));
- p += 4;
-
- xbString s;
- if(( cType == 'I' && iKeyNo < (xbInt16) ulNoOfKeys) || cType == 'L' ){
- if( mpTag->cKeyType2 == 'C' ){ //CHAR
- for( xbInt32 l = 0; l < (mpTag->iKeyItemLen-4); l++ )
- s += *p++;
-
- } else if( mpTag->cKeyType2 == 'N' ){ // NUMERIC
- xbBcd bcd( p );
- xbString s2;
- bcd.ToString( s2 );
- s += s2;
-
- } else if( mpTag->cKeyType2 == 'D' ){ // DATE
- xbInt32 lDate = (xbInt32) eGetDouble( p );
- xbDate d( lDate );
- //xbString s2;
- //d.JulToDate8( lDate, s2 );
- s.Sprintf( "%s%s", s.Str(), d.Str());
- }
- } else {
- s = "Rightmost InteriorNode Pointer";
- }
-
- xbString sOut( sPre );
- sOut += s;
- sOut += sPost;
- sOut += sKeyPtr;
-
- xbase->WriteLogMessage( sOut, iOutputOpt );
- return XB_NO_ERROR;
-}
-#endif
-
-/***********************************************************************/
-//! @brief ReadHeadBlock.
-/*!
- Read values off head block in MDX file
- \param iOpt 0 - Read entire block, initialize as needed.<br>
- 1 - Read in only dynamic section of block<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
-*/
-
-xbInt16 xbIxMdx::ReadHeadBlock( xbInt16 iOpt )
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- if( !FileIsOpen()){
- iRc = XB_NOT_OPEN;
- iErrorStop = 100;
- throw iRc;
- }
- char sBuf[48];
- memset( sBuf, 0x00, 48 );
-
- if( iOpt == 0 ){
- if(( iRc = xbFseek( 0, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- if(( iRc = xbFread( sBuf, 47, 1 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- } else {
-
- if(( iRc = xbFseek( 28, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- if(( iRc = xbFread( sBuf, 19, 1 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- }
-
- char *p = sBuf;
- if( iOpt == 0 ){
- cVersion = *p++;
- cCreateYY = *p++;
- cCreateMM = *p++;
- cCreateDD = *p++;
- sFileName.Assign( p, 1, 16 );
- p+=16;
- iBlockFactor = eGetInt16( p );
- p+=2;
- SetBlockSize( (xbUInt32) eGetInt16( p ));
- p+=2;
- cProdIxFlag = *p++;
- cTagEntryCnt = *p++;
- iTagLen = *p;
- p+=2;
-
- iTagUseCnt = eGetInt16( p );
- //lTagUseCnt = eGetInt32( p );
- //p+=4;
- p+=2;
- cNextTag = *p++;
- c1B = *p++;
-
- ulPageCnt = eGetUInt32( p );
- p+=4;
- ulFirstFreePage = eGetUInt32( p );
- p+=4;
- ulNoOfBlockAvail = eGetUInt32( p );
- p+=4;
- cUpdateYY = *p++;
- cUpdateMM = *p++;
- cUpdateDD = *p;
-
- if( cNodeBuf )
- free( cNodeBuf );
-
- if(( cNodeBuf = (char *) malloc( (size_t) GetBlockSize())) == NULL ){
- iErrorStop = 150;
- throw XB_NO_MEMORY;
- }
-
- if(( iRc = xbIxMdx::LoadTagTable()) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
-
- } else {
- iTagUseCnt = eGetInt16( p );
- p+=4;
- ulPageCnt = eGetUInt32( p );
- p+=4;
- ulFirstFreePage = eGetUInt32( p );
- p+=4;
- ulNoOfBlockAvail = eGetUInt32( p );
- p+=4;
- cUpdateYY = *p++;
- cUpdateMM = *p++;
- cUpdateDD = *p;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::ReadHeadBlock() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( cNodeBuf )
- free( cNodeBuf );
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Reindex
-/*!
- Reindex specifed tag or all tags
- \param **vpTag &tag - Tag to reindex.<br>
- NULL - Reindex all tags<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-
- If this method fails, the index is left in an undefined state
-
-*/
-
-xbInt16 xbIxMdx::Reindex( void **vpTag ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbMdxTag * mpTag;
- #ifdef XB_LOCKING_SUPPORT
- xbBool bLocked = xbFalse;
- #endif
-
- if( vpTag )
- mpTag = (xbMdxTag *) *vpTag;
- else
- mpTag = NULL;
-
- struct tagInfo{
- xbBool bUnique;
- xbBool bDesc;
- char sTagName[11];
- xbString *sKeyExp;
- xbString *sFiltExp;
- tagInfo *next;
- };
- tagInfo *ti = NULL;
-
- try{
-
- #ifdef XB_LOCKING_SUPPORT
- if( dbf->GetAutoLock() && !dbf->GetTableLocked() ){
- if(( iRc = dbf->LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- bLocked = xbTrue;
- }
- #endif
-
- if( mpTag == NULL ){
- // do all tags
- xbMdxTag *tt = mdxTagTbl;
- tagInfo *pHead = NULL;
- tagInfo *pEnd = NULL;
-
- if( tt ){
- while( tt ){
- ti = (tagInfo *) calloc( 1, sizeof( tagInfo ));
- ti->bUnique = tt->cUnique ? 1 : 0;
- ti->bDesc = (((tt->cKeyFmt2 & 0x08) > 0) ? 1 : 0);
- memcpy( ti->sTagName, tt->cTagName, 11 );
- ti->sKeyExp = new xbString( tt->sKeyExp->Str());
- if( tt->cHasFilter )
- ti->sFiltExp = new xbString( tt->sFiltExp->Str());
- else
- ti->sFiltExp = new xbString( "" );
- if( !pHead )
- pHead = ti;
- else
- pEnd->next = ti;
- pEnd = ti;
- tt = tt->next;
- }
- }
-
- // get the file name and save it
- xbString sMdxFileName = GetFqFileName();
-
- // close the mdx file
- if(( iRc = xbIxMdx::Close()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- // delete the file
- xbRemove();
-
- // init variables
- Init();
-
- tagInfo *p = pHead;
- tagInfo *pDel;
-
- // create new file & add the tags
- while( p ){
-
- if(( iRc = CreateTag( p->sTagName, p->sKeyExp->Str(), p->sFiltExp->Str(), p->bDesc, p->bUnique, xbTrue, vpTag )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- delete p->sKeyExp;
- delete p->sFiltExp;
- pDel = p;
- p = p->next;
- free( pDel );
- }
- } else {
- if(( iRc = HarvestTagNodes( mpTag )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- }
-
- xbUInt32 ulRecCnt = 0;
- if(( iRc = dbf->GetRecordCnt( ulRecCnt )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- xbInt16 iCurTag = 0;
- xbBool bDone = xbFalse;
-
- for( xbUInt32 ulRec = 1; ulRec <= ulRecCnt; ulRec++ ){
- if(( iRc = dbf->GetRecord( ulRec )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
-
- bDone = xbFalse;
- iCurTag = 0;
- if( !vpTag )
- mpTag = (xbMdxTag *) GetTag( iCurTag++ );
-
- while( !bDone ){
- // do the tag things
- // CreateKey
- if(( iRc = CreateKey( mpTag, 1 )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if( mpTag->iKeySts == XB_ADD_KEY ){
- if( mpTag->cUnique ){
- if(( iRc = CheckForDupKey( mpTag )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- }
- if(( iRc = AddKey( mpTag, ulRec )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
- }
- if( vpTag || iCurTag >= GetTagCount())
- bDone = xbTrue;
- else
- mpTag = (xbMdxTag *) GetTag( iCurTag++ );
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::ReIndex() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- this->DeleteTag( mpTag );
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( bLocked ){
- dbf->LockTable( XB_UNLOCK );
- }
- #endif
- return iRc;
-}
-
-/***********************************************************************/
-xbInt16 xbIxMdx::SetCurTag( xbString &sTagName ) {
-
- xbMdxTag *tt = (xbMdxTag *) GetTag( sTagName );
- if( tt ){
- xbIx::SetCurTag((void *) tt );
- return XB_NO_ERROR;
- } else
- return XB_INVALID_TAG;
-}
-
-/***********************************************************************/
-xbInt16 xbIxMdx::SetCurTag( xbInt16 iTagNo ) {
-
- xbMdxTag *tt = (xbMdxTag *) GetTag( iTagNo );
- if( tt ){
- xbIx::SetCurTag((void *) tt );
- return XB_NO_ERROR;
- } else
- return XB_INVALID_TAG;
-}
-
-/***********************************************************************/
-//! @brief SetReuseEmptyNode switch setting.
-/*!
- \param bEmptyNodeSw xbFalse - Do not reuse empty MDX index nodes (Dbase 6. behavior).
- xbTrue - Reuse empty MDX index nodes.
-*/
-
-void xbIxMdx::SetReuseEmptyNodesSw( xbBool bEmptyNodesSw ) {
- bReuseEmptyNodes = bEmptyNodesSw;
-}
-
-/***********************************************************************/
-//! @brief Split an interior node
-/*!
-
- This routine splits an interior node into two nodes, divided by dSplitFactor.<br>
- This behaves differently than V7 Dbase. V7 does not balance the nodes.<br>
- For V7, if adding a key to the end of a node, it will create a right node
- with only one key, and the left node is still full.<br><br>
-
- Possible performance improvement options.<br>
- Two modes when splitting:<br>
- a) Split nodes in the middle - good for random access applications<br>
- b) Split off right node with only one key - good for applications with
- expectation of ascending keys added moving forward.<br>
-
- This routine first inserts the key into the left node in the appropriate location
- then splits the node based on the split factor setting.
-
- \param vpTag Tag in play.
- \param npLeft Left node to split.
- \param npRight Right node to split.
- \param iSlotNo Slot number for split.
- \param ulPtr Pointer number to insert.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 ulPtr ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbMdxTag * npTag = (xbMdxTag *) vpTag;
- xbDouble dSplitFactor = .5; // split the nodes 50/50
- xbInt16 iLen;
- char *pSrc;
- char *pTrg;
-
- try{
- xbInt32 lKeyCnt = GetKeyCount( npLeft );
- xbInt32 lNewLeftKeyCnt = (xbInt32) ((lKeyCnt + 1) * dSplitFactor);
- xbInt32 lNewRightKeyCnt = lKeyCnt - lNewLeftKeyCnt;
- if(( iRc = InsertNodeI( vpTag, npLeft, iSlotNo, ulPtr )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- // move the right half of the left node to the right node
- pSrc = npLeft->cpBlockData;
- pSrc += 8 + ((lNewLeftKeyCnt+1) * npTag->iKeyItemLen);
- pTrg = npRight->cpBlockData;
- pTrg += 8;
- iLen = (lNewRightKeyCnt * npTag->iKeyItemLen) + 4;
- memmove( pTrg, pSrc, (size_t) iLen );
-
- // eliminate chattle on the right
- iLen = 12 + (lNewLeftKeyCnt * npTag->iKeyItemLen);
- pSrc = npLeft->cpBlockData;
- pSrc += iLen;
- memset( pSrc, 0x00, npLeft->ulBufSize - (xbUInt32) iLen );
-
- // write the new key counts into the nodes
- pTrg = npLeft->cpBlockData;
- ePutInt32( pTrg, lNewLeftKeyCnt );
- pTrg = npRight->cpBlockData;
- ePutInt32( pTrg, lNewRightKeyCnt );
-
- // write out the block
- if(( iRc = WriteBlock( npLeft->ulBlockNo, GetBlockSize(), npLeft->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- // write out the block
- if(( iRc = WriteBlock( npRight->ulBlockNo, GetBlockSize(), npRight->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::SplitNodeI() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Split a leaf node.
-/*!
- This routine splits an index leaf into two nodes, divided by dSplitFactor.<br>
-
- Possible performance improvement options.<br>
- Two modes when splitting:<br>
- a) Split nodes in the middle - good for random access applications<br>
- b) Split off right node with only one key - good for applications with
- expectation of ascending keys added moving forward.<br>
-
- This routine first inserts the key into the left node in the appropriate location
- then splits the node based on the split factor setting.
-
- \param vpTag Tag in play.
- \param npLeft Left node to split.
- \param npRight Right node to split.
- \param iSlotNo Slot number for split.
- \param ulPtr Pointer number to insert.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight,
- xbInt16 iSlotNo, char * cpKeyBuf, xbUInt32 ulPtr ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbDouble dSplitFactor = .5; // can adjust performance with this number
- xbMdxTag *mpTag = (xbMdxTag *) vpTag;
- xbString sMsg;
-
- xbInt16 iLen;
- char *pSrc;
- char *pTrg;
-
- // std::cout << "In xbIxMdx::SplitNodeL()\n";
- try{
- xbInt32 lKeyCnt = GetKeyCount( npLeft );
- xbInt32 lNewLeftKeyCnt = (xbInt32) ((lKeyCnt + 1) * dSplitFactor) + 1;
- xbInt32 lNewRightKeyCnt = lKeyCnt + 1 - lNewLeftKeyCnt;
-
- if(( iRc = InsertNodeL( vpTag, npLeft, iSlotNo, cpKeyBuf, ulPtr )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- // move right half off of left node to the right node
- pSrc = npLeft->cpBlockData;
- pSrc += 8 + (lNewLeftKeyCnt * mpTag->iKeyItemLen);
- pTrg = npRight->cpBlockData;
- pTrg += 8;
- iLen = lNewRightKeyCnt * mpTag->iKeyItemLen;
- memmove( pTrg, pSrc, (size_t) iLen );
-
- // write the new key counts into the nodes
- pTrg = npLeft->cpBlockData;
- ePutInt32( pTrg, lNewLeftKeyCnt );
- pTrg = npRight->cpBlockData;
- ePutInt32( pTrg, lNewRightKeyCnt );
-
- // zero out the next key number so this node is not confused with interior node
- iLen = 8 + (lNewLeftKeyCnt * mpTag->iKeyItemLen);
- pSrc = npLeft->cpBlockData;
- pSrc += iLen;
- memset( pSrc, 0x00, npLeft->ulBufSize - (xbUInt32) iLen );
-
- // write out the left block
- if(( iRc = WriteBlock( npLeft->ulBlockNo, GetBlockSize(), npLeft->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- // write out the right block
- if(( iRc = WriteBlock( npRight->ulBlockNo, GetBlockSize(), npRight->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::SplitNodeL() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/**************************************************************************************************************/
-//! @brief TagSerialNo.
-/*!
- This routine is used internally for reading or updating the serial number on a given tag when the tag.
-
- \param iOption 1 - Read tag serial number off disk, save in structure<br>
- 2 - Write serial number from memory to disk<br>
- 3 - Read serial number off disk, increment, write updated number to disk<br>
- mpTag - Pointer to tag for serial number update
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::TagSerialNo( xbInt16 iOption, xbMdxTag * mpTag ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- xbInt64 lPos = (mpTag->ulTagHdrPageNo * 512) + 20;
-
- if( iOption != 2 ){
- if(( iRc = xbFseek( lPos, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if(( iRc = xbFgetc( mpTag->cSerialNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- if( iOption == 3 )
- mpTag->cSerialNo++;
-
- if( iOption != 1 ){
- if(( iRc = xbFseek( lPos, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = xbFwrite( &mpTag->cSerialNo, 1, 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::UpdateSerialNo() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief UpdateTagKey
-/*!
- This routine updates a key or a given tag.
- The file header is considered to be the first 2048 bytes in the file.
-
- \param cAction A - Add a key.<br>
- D - Delete a key.<br>
- R - Revise a key.<br>
- \param vpTg - Pointer to tag.<br>
- \param ulRecNo - Record number association with the action.<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxMdx::UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo ){
-
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbMdxTag *npTag = (xbMdxTag *) vpTag;
-
- try{
- // save off any needed fields for updating
- xbUInt32 ulTagSizeSave = npTag->ulTagSize;
-
- if( cAction == 'D' || cAction == 'R' ){
- // std::cout << "UpdateTagKey-delete going to DeleteKey \n";
- if(( iRc = DeleteKey( vpTag )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
-
- if( cAction == 'A' || cAction == 'R' ){
- if(( iRc = AddKey( vpTag, ulRecNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- if( ulTagSizeSave != npTag->ulTagSize ){
- if(( iRc = UpdateTagSize( npTag, npTag->ulTagSize )) != XB_NO_ERROR) {
- iErrorStop = 120;
- throw iRc;
- }
- }
- // update the serial number
- if(( iRc = TagSerialNo( 3, npTag )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::UpdateTagKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/**************************************************************************************************************/
-//! @brief Write head block.
-/*!
- This routine updates the MDX file header and commits changes to disk.
- The file header is considered to be the first 2048 bytes in the file.
-
- \param iOption 0 - Entire 2048 byte header, used for creating a new mdx file.<br>
- 1 - Bytes 28 through 46, used when adding or deleting a tag.<br>
- 2 - Bytes 32 through 46, used after updating keys in the file.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbIxMdx::WriteHeadBlock( xbInt16 iOption ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- xbDate d;
- d.Sysdate(); // set to system date, today
- cUpdateYY = (char) d.YearOf() - 1900;
- cUpdateMM = (char) d.MonthOf();
- cUpdateDD = (char) d.DayOf( XB_FMT_MONTH );
-
- if( iOption > 0 ){
- char buf[48];
- memset( buf, 0x00, 48 );
- xbUInt32 ulStartPos = 0;
- xbUInt32 ulLen = 0;
-
- if( iOption == 1 ){
- ePutInt16( &buf[28], iTagUseCnt );
- buf[30] = cNextTag;
- buf[31] = 0x1b;
- ulStartPos = 28;
- ulLen = 19;
- } else {
- ulStartPos = 32;
- ulLen = 16;
- }
-
- ePutUInt32( &buf[32], ulPageCnt );
- ePutUInt32( &buf[36], ulFirstFreePage );
- ePutUInt32( &buf[40], ulNoOfBlockAvail );
- buf[44] = cUpdateYY;
- buf[45] = cUpdateMM;
- buf[46] = cUpdateDD;
-
- if(( iRc = xbFseek( ulStartPos, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- if(( iRc = xbFwrite( &buf[ulStartPos], ulLen, 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- } else if( iOption == 0 ){
- char buf[2048];
- memset( buf, 0x00, 2048 );
-
- buf[0] = cVersion;
- cCreateYY = cUpdateYY;
- cCreateMM = cUpdateMM;
- cCreateDD = cUpdateDD;
- buf[1] = cCreateYY;
- buf[2] = cCreateMM;
- buf[3] = cCreateDD;
-
-
- for( xbUInt32 l = 0; l < sFileName.Len() && l < 10; l++ ){
- buf[l+4] = sFileName[l+1];
- }
-
- ePutInt16( &buf[20], iBlockFactor );
- ePutInt16( &buf[22], (xbInt16) GetBlockSize() );
-
- buf[24] = cProdIxFlag;
- buf[25] = cTagEntryCnt;
- ePutInt16 ( &buf[26], iTagLen );
- ePutInt16 ( &buf[28], iTagUseCnt );
- buf[30] = cNextTag;
- buf[31] = c1B;
- ePutUInt32( &buf[32], ulPageCnt );
- ePutUInt32( &buf[36], ulFirstFreePage );
- ePutUInt32( &buf[40], ulNoOfBlockAvail );
- buf[44] = cUpdateYY;
- buf[45] = cUpdateMM;
- buf[46] = cUpdateDD;
-
- // not sure what the following "1" is for in a sea of zeroes....
- // maybe it's current tag or default tag or something along those lines?
- buf[529] = 0x01;
-
- xbRewind();
- if(( iRc = xbFwrite( buf, 2048, 1 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- } else {
- iErrorStop = 130;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::WriteHeadBlock() Exception Caught. Error Stop = [%d] iRc = [%d] option = [%d]", iErrorStop, iRc, iOption );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-xbInt16 xbIxMdx::UpdateTagSize( xbMdxTag *mpTag, xbUInt32 ulTagSz ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char buf[4];
- try{
- ePutUInt32( &buf[0], ulTagSz );
- if(( iRc = xbFseek( (xbInt64) ((mpTag->ulTagHdrPageNo *512 )+ 4), SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if(( iRc = xbFwrite( &buf[0], 4, 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxMdx::UpdateTagSize() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-
-/***********************************************************************/
-//void xbIxMdx::TestStub( char *s, void *vpTag ){
-void xbIxMdx::TestStub( char *, void * ){
-}
-/***********************************************************************/
-} /* namespace */
-#endif /* XB_MDX_SUPPORT */
-
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbixndx.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbixndx.cpp
deleted file mode 100755
index b28dd9d..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbixndx.cpp
+++ /dev/null
@@ -1,2834 +0,0 @@
-/* xbixndx.cpp
-
-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 "xbase.h"
-
-#ifdef XB_NDX_SUPPORT
-
-namespace xb{
-
-
-/***********************************************************************/
-//! @brief Class constructor.
-/*!
- \param dbf Pointer to dbf instance.
-*/
-
-xbIxNdx::xbIxNdx( xbDbf *dbf ) : xbIx( dbf ){
- ndxTag = (xbNdxTag *) calloc( 1, sizeof( xbNdxTag ));
- SetBlockSize( XB_NDX_BLOCK_SIZE );
- cNodeBuf = (char *) malloc( XB_NDX_BLOCK_SIZE );
-}
-/***********************************************************************/
-//! @brief Class Destructor.
-xbIxNdx::~xbIxNdx(){
- if( ndxTag ){
- ndxTag->npNodeChain = FreeNodeChain( ndxTag->npNodeChain );
- if( ndxTag->cpKeyBuf )
- free( ndxTag->cpKeyBuf );
- if( ndxTag->cpKeyBuf2 )
- free( ndxTag->cpKeyBuf2 );
- if( ndxTag->exp ){
- delete ndxTag->exp;
- ndxTag->exp = NULL;
- }
- ndxTag->sKeyExpression.Set( NULL );
- ndxTag->sTagName.Set( NULL );
- free( ndxTag );
- ndxTag = NULL;
- }
- if( cNodeBuf )
- free( cNodeBuf );
-}
-/***********************************************************************/
-//! @brief Add key.
-/*!
- Add key. If this is a unique index, this logic assumes the duplicate
- check logic was already done.
-
- \param vpTag Tag to update.
- \param ulRecNo Record number to add key for.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::AddKey( void * vpTag, xbUInt32 ulRecNo ){
-
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
- if( GetUniqueKeyOpt() == XB_EMULATE_DBASE && npTag->bFoundSts )
- return XB_NO_ERROR;
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbInt16 iHeadNodeUpdateOpt = 2;
-
-
- try{
-
- if(( iRc = xbIxNdx::KeySetPosAdd( npTag, ulRecNo )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- xbInt32 lKeyCnt = GetKeyCount( npTag->npCurNode );
- if( lKeyCnt < npTag->iKeysPerBlock ){
- // Section A - add key to appropriate position if space available
- if(( iRc = InsertNodeL( npTag, npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->cpKeyBuf, ulRecNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- } else {
- // land here with a full leaf node
- iHeadNodeUpdateOpt = 1;
- // section B - split the leaf node
- xbIxNode * npRightNode = AllocateIxNode( GetBlockSize() + (xbUInt32) npTag->iKeyItemLen, 1 );
- if( !npRightNode ){
- iErrorStop = 120;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- if(( iRc = SplitNodeL( npTag, npTag->npCurNode, npRightNode, npTag->npCurNode->iCurKeyNo, npTag->cpKeyBuf, ulRecNo )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- xbUInt32 ulTempBlockNo = npRightNode->ulBlockNo;
-
- // section C - go up the tree, splitting nodes as necessary
- xbIxNode * npParent = npTag->npCurNode->npPrev;
- while( npParent && GetKeyCount( npParent ) >= npTag->iKeysPerBlock ){
- npRightNode = FreeNodeChain( npRightNode );
- npRightNode = AllocateIxNode( GetBlockSize() + (xbUInt32) npTag->iKeyItemLen, 1 );
- if( !npRightNode ){
- iErrorStop = 140;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- if(( iRc = SplitNodeI( npTag, npParent, npRightNode, npParent->iCurKeyNo, ulTempBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- ulTempBlockNo = npRightNode->ulBlockNo;
- npTag->npCurNode = npParent;
- npParent = npParent->npPrev;
- }
-
- // section D - if cur node is split root, create new root
- if( npTag->npCurNode->ulBlockNo == npTag->ulRootBlock ){
- // xbase->WriteLogMessage( "Section d" );
- if(( iRc = AddKeyNewRoot( npTag, npTag->npCurNode, npRightNode )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- npRightNode = FreeNodeChain( npRightNode );
-
- } else {
- // else section E, put key in parent
- if(( iRc = InsertNodeI( vpTag, npParent, npParent->iCurKeyNo, npRightNode->ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- npRightNode = FreeNodeChain( npRightNode );
- }
- }
-
- // update the header
- if(( iRc = WriteHeadBlock( iHeadNodeUpdateOpt )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
-
- // ---- free whatever is left of the node chain here, this might not be right, might need to restore it to
- // the point right after SetKeyPosAdd
- npTag->npNodeChain = FreeNodeChain( ndxTag->npNodeChain );
- npTag->npCurNode = NULL;
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::AddKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Add new root node.
-/*!
- \param npTag Tag to update.
- \param npLeft Left node.
- \param npRight Right node.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxNdx::AddKeyNewRoot( xbNdxTag *npTag, xbIxNode *npLeft, xbIxNode *npRight ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbString sMsg;
- char *pLastKey = NULL;
-
- try{
- xbIxNode *npRoot = AllocateIxNode( GetBlockSize() + (xbUInt32) npTag->iKeyItemLen, 1 );
- if( !npRoot ){
- iErrorStop = 100;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- npTag->ulRootBlock = npRoot->ulBlockNo;
- pLastKey = (char *) malloc( (size_t) ndxTag->iKeyLen );
- if(( iRc = GetLastKeyForBlockNo( npTag, npLeft->ulBlockNo, pLastKey )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- char * pTrg = npRoot->cpBlockData;
-
- // set no of keys to 1
- ePutUInt32( pTrg, 1 );
-
- // set the left node number
- pTrg += 4;
- ePutUInt32( pTrg, npLeft->ulBlockNo );
-
- // set the key
- pTrg+= 8;
- memcpy( pTrg, pLastKey, (size_t) npTag->iKeyLen );
-
- // set the right node number
- pTrg+= (npTag->iKeyItemLen - 8);
- ePutUInt32( pTrg, npRight->ulBlockNo );
-
- // write out the block
- if(( iRc = WriteBlock( npRoot->ulBlockNo, GetBlockSize(), npRoot->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if( pLastKey )
- free( pLastKey );
- NodeFree( npRoot );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::AddKeyNewRoot() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( pLastKey )
- free( pLastKey );
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Append node to node chain.
-/*!
- Append a node to the current node chain for a given tag.
-
- \param vpTag Tag to update.
- \param npNode Node to add to node chain.
- \returns void
-*/
-void xbIxNdx::AppendNodeChain( void *vpTag, xbIxNode * npNode ){
-
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- if( npTag->npNodeChain == NULL ){
- npTag->npNodeChain = npNode;
- npTag->npCurNode = npNode;
- } else {
- npNode->npPrev = npTag->npCurNode;
- npTag->npCurNode->npNext = npNode;
- npTag->npCurNode = npNode;
- }
- // time stamp the node chain
- GetFileMtime( npTag->tNodeChainTs );
-}
-
-/***********************************************************************/
-//! @brief Allocate a node.
-/*!
- \param ulBufSize Buffer size.
- \param iOpt 0 - Don't update the node block number on the node.
- 1 - Set node block number to the next available block number.
- \returns Pointer to new node.
-*/
-
-xbIxNode * xbIxNdx::AllocateIxNode( xbUInt32 ulBufSize, xbInt16 iOpt ){
- xbIxNode *n = xbIx::AllocateIxNode( ulBufSize );
- if( n && iOpt == 1 ) n->ulBlockNo = ndxTag->ulTotalBlocks++;
- return n;
-}
-/***********************************************************************/
-//! @brief Check for duplicate key.
-/*!
- \param vpTag Tag to check.
- \returns XB_KEY_NOT_UNIQUE<br>XB_NO_ERROR
-*/
-xbInt16 xbIxNdx::CheckForDupKey( void *vpTag )
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbNdxTag *npTag = (xbNdxTag *) vpTag;
- npTag->bFoundSts = xbFalse;
- try{
- if( GetUnique()){
- if( npTag->iKeySts == XB_ADD_KEY || npTag->iKeySts == XB_UPD_KEY )
- if( KeyExists( vpTag )){
- if( GetUniqueKeyOpt() == XB_EMULATE_DBASE ){
- npTag->bFoundSts = xbTrue;
- return 0;
- } else {
- return XB_KEY_NOT_UNIQUE;
- }
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::CheckForDupKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Check tag integrity.
-/*!
- Check a tag for accuracy.
-
- \param vpTag Tag to create key for.
- \param iOpt Output message destination<br>
- 0 = Syslog<br>
- 1 = Stdout<br>
- 2 = Both<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxNdx::CheckTagIntegrity( void *vpTag, xbInt16 iOpt ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iRc2;
- xbInt16 iRc3;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulIxCnt = 0;
- xbUInt32 ulThisRecNo = 0;
- xbUInt32 ulPrevRecNo = 0;
- xbBool bDone = false;
- xbString sMsg;
- char cKeyType;
- char *pPrevKeyBuf = NULL;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bLocked = xbFalse;
- #endif
-
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- try{
- #ifdef XB_LOCKING_SUPPORT
- if( dbf->GetAutoLock() && !dbf->GetTableLocked() ){
- if(( iRc = dbf->LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- bLocked = xbTrue;
- }
- #endif
-
- memset( npTag->cpKeyBuf2, 0x00, (size_t) npTag->iKeyLen );
- cKeyType = GetKeyType( vpTag );
-
- sMsg.Sprintf( "Checking index type [%c]", cKeyType );
- xbase->WriteLogMessage( sMsg, iOpt );
-
- pPrevKeyBuf = (char *) calloc( 1, (size_t) ndxTag->iKeyLen );
-
- // for each key in the index, make sure it is trending in the right direction
- iRc = GetFirstKey( vpTag, 0 );
- while( iRc == XB_NO_ERROR && !bDone ){
- ulIxCnt++;
- iRc = GetNextKey( vpTag, 0 );
- if( iRc == XB_NO_ERROR ){
- // compare this key to prev key
- iRc2 = CompareKey( cKeyType, GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->iKeyItemLen ),
- pPrevKeyBuf, (size_t) npTag->iKeyLen );
-
- if( iRc2 < 0 ){
- sMsg.Sprintf( "Key sequence error at key number [%ld].", ulIxCnt );
- xbase->WriteLogMessage( sMsg, iOpt );
- iErrorStop = 110;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
-
- ulThisRecNo = 0;
- if(( iRc3 = GetDbfPtr( vpTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulThisRecNo )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc3;
- }
-
- if( iRc2 == 0 && (ulThisRecNo <= ulPrevRecNo )){
- sMsg.Sprintf( "Dbf record number sequence error at key number [%ld].", iOpt );
- xbase->WriteLogMessage( sMsg, iOpt );
- iErrorStop = 130;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
- // save this key info to prev key
- memcpy( pPrevKeyBuf, GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->iKeyItemLen ), (size_t) npTag->iKeyLen );
- ulPrevRecNo = ulThisRecNo;
- }
- }
-
- // verify the index count matches the tag count
- xbUInt32 ulDbfCnt = 0;
- if(( iRc = dbf->GetRecordCnt( ulDbfCnt )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
-
- if( GetUniqueKeyOpt() == XB_EMULATE_DBASE && GetUnique( vpTag )){
- // Can't compare counts if using XB_EMULATE_DBASE and it's a unique index
- } else {
- if( ulDbfCnt != ulIxCnt ){
- sMsg.Sprintf( "CheckTagIntegrity() Index entry count [%ld] does not match dbf record count [%ld]", ulIxCnt, ulDbfCnt );
- xbase->WriteLogMessage( sMsg, iOpt );
- iErrorStop = 150;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
-
- // verify each record in the dbf file has a corresponding index entry
- xbUInt32 j = 0;
- while( j < ulDbfCnt ){
- if(( iRc = dbf->GetRecord( ++j )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if(( iRc = FindKeyForCurRec( vpTag )) != XB_NO_ERROR ){
- ulThisRecNo = j;
- iErrorStop = 170;
- throw iRc;
- }
- }
- sMsg.Sprintf( "CheckTagIntegrity() Index entry count [%ld] matches dbf record count [%ld]", ulIxCnt, ulDbfCnt );
- xbase->WriteLogMessage( sMsg, iOpt );
- }
- if( pPrevKeyBuf )
- free( pPrevKeyBuf );
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::CheckTagIntegrity() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg, iOpt );
- xbase->WriteLogMessage( GetErrorMessage( iRc ), iOpt );
- if( pPrevKeyBuf )
- free( pPrevKeyBuf );
-
- if( iErrorStop == 170 ){
- sMsg.Sprintf( "xbIxNdx::CheckTagIntegrity() Missing index entry for record [%d]", ulThisRecNo );
- xbase->WriteLogMessage( sMsg, iOpt );
- }
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( bLocked ){
- dbf->LockTable( XB_UNLOCK );
- }
- #endif
- return iRc;
-
-}
-/***********************************************************************/
-//! @brief Create key for tag.
-/*!
- Append a node to the current node chain for a given tag.
-
- \param vpTag Tag to create key for.
- \param iOpt 0 = Build a key for FindKey usage, only rec buf 0.<br>
- 1 = Append Mode, Create key for an append, only use rec buf 0, set updated switch.<br>
- 2 = Update Mode, Create old version and new version keys, check if different, set update switch appropriately.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::CreateKey( void * vpTag, xbInt16 iOpt ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- if(( iRc = npTag->exp->ProcessExpression( 0 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if( npTag->exp->GetReturnType() == XB_EXP_CHAR ){
- npTag->exp->GetStringResult( npTag->cpKeyBuf, (xbUInt32) npTag->iKeyLen );
- }
- else if( npTag->exp->GetReturnType() == XB_EXP_NUMERIC ){
- xbDouble d;
- npTag->exp->GetNumericResult( d );
- memcpy( npTag->cpKeyBuf, &d, 8 );
- }
- else if( npTag->exp->GetReturnType() == XB_EXP_DATE ){
- xbDouble d;
- npTag->exp->GetNumericResult( d );
- memcpy( npTag->cpKeyBuf, &d, 8 );
- }
-
- npTag->iKeySts = 0;
- if( iOpt == 1 )
- npTag->iKeySts = XB_ADD_KEY;
-
- else if( iOpt == 2 ){
- if(( iRc = npTag->exp->ProcessExpression( 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- if( npTag->exp->GetReturnType() == XB_EXP_CHAR ){
- npTag->exp->GetStringResult( npTag->cpKeyBuf2, (xbUInt32) npTag->iKeyLen );
- } else if( npTag->exp->GetReturnType() == XB_EXP_NUMERIC || npTag->exp->GetReturnType() == XB_EXP_DATE ){
- xbDouble d;
- npTag->exp->GetNumericResult( d );
- memcpy( npTag->cpKeyBuf2, &d, 8 );
- }
- if( memcmp( npTag->cpKeyBuf, npTag->cpKeyBuf2, (size_t) npTag->iKeyLen ))
- npTag->iKeySts = XB_UPD_KEY;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::CreateKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Create new tag.
-/*!
- This routine creates a new tag. Since NDX files have only one tag,
- this creates a new NDX file.
-
- \param sName Tag Name, including .NDX suffix
- \param sKey Key Expression
- \param sFilter Filter expression. Not supported by NDX indices.
- \param iDescending Not supported by NDX indices.
- \param iUnique xbtrue - Unique.<br>xbFalse - Not unique.
- \param iOverLay xbTrue - Overlay if file already exists.<br>xbFalse - Don't overlay.
- \param vpTag Output from method Pointer to vptag pointer.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::CreateTag( const xbString &sName, const xbString &sKey,
- const xbString &, xbInt16, xbInt16 iUnique, xbInt16 iOverLay, void **vpTag ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbNdxTag *npTag = ndxTag;
- *vpTag = ndxTag;
-
- try{
- //xbString sMsg;
- SetFileName( sName );
-
- if( FileExists() && !iOverLay )
- return XB_FILE_EXISTS;
-
- if( FileIsOpen()){
- if(( iRc = xbTruncate(0)) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if(( iRc = xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- npTag->npNodeChain = FreeNodeChain( npTag->npNodeChain );
- npTag->npCurNode = NULL;
- npTag->sKeyExpression.Set( "" );
-
- if( npTag->cpKeyBuf ){
- free( npTag->cpKeyBuf );
- npTag->cpKeyBuf = NULL;
- }
- if( npTag->cpKeyBuf2 ){
- free( npTag->cpKeyBuf2 );
- npTag->cpKeyBuf2 = NULL;
- }
- }
- if(( iRc = xbFopen( "w+b", dbf->GetShareMode())) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- //set up the key expression
- npTag->exp = new xbExp( dbf->GetXbasePtr());
- if(( iRc = npTag->exp->ParseExpression( dbf, sKey )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- switch( npTag->exp->GetReturnType()){
- case XB_EXP_CHAR:
- npTag->cKeyType = 'C';
- npTag->iKeyType = 0;
- npTag->iKeyLen = npTag->exp->GetResultLen();
- break;
-
- case XB_EXP_NUMERIC:
- npTag->cKeyType = 'F';
- npTag->iKeyType = 1;
- npTag->iKeyLen = 8;
- break;
-
- case XB_EXP_DATE:
- npTag->cKeyType = 'D';
- npTag->iKeyType = 1;
- npTag->iKeyLen = 8;
- break;
-
- default:
- iErrorStop = 140;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
-
- npTag->iUnique = iUnique;
- npTag->ulRootBlock = 1L;
- //npTag->ulTotalBlocks = 2l;
- npTag->ulTotalBlocks = 2L;
- npTag->sKeyExpression = sKey;
-
- GetFileNamePart( npTag->sTagName );
-
- if( npTag->iKeyLen > 100 ){
- iErrorStop = 150;
- throw iRc;
- }
-
- npTag->iKeyItemLen = npTag->iKeyLen + 8;
- while(( npTag->iKeyItemLen % 4 )!= 0 ) npTag->iKeyItemLen++;
-
- npTag->iKeysPerBlock = (xbInt16) (GetBlockSize() - 8 ) / npTag->iKeyItemLen;
- ndxTag->cpKeyBuf = (char *) malloc( (size_t) ndxTag->iKeyLen );
- ndxTag->cpKeyBuf2 = (char *) malloc( (size_t) ndxTag->iKeyLen );
-
- if(( iRc = WriteHeadBlock(0)) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
-
- //write out block binary zeroes
- char buf[512];
- memset( buf, 0x00, 512 );
- if(( iRc = xbFwrite( buf, 1, 512 )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::CreateTag() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Delete a key.
-/*!
- This routine deletes a key from a supplied node.
- \param vpTag Tag to delete key on.
- \param npNode Node to delete key on.
- \param iSlotNo Slot number of key to delete.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo )
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- try{
-
- xbInt32 lKeyCnt = GetKeyCount( npNode );
- xbInt16 iLen = (lKeyCnt - iSlotNo - 1) * npTag->iKeyItemLen;
- if( !IsLeaf( vpTag, npNode ))
- iLen += 4;
-
- if( iLen > 0 ){
- char *pTrg = npNode->cpBlockData;
- pTrg += (4 + (npTag->iKeyItemLen * (iSlotNo)) ); //lTrgPos;
- char *pSrc = pTrg;
- pSrc += npTag->iKeyItemLen;
- memmove( pTrg, pSrc, (size_t) iLen );
- }
-
- // set the new number of keys
- ePutUInt32( npNode->cpBlockData, (xbUInt32) lKeyCnt - 1 );
-
- // write out the block
- if(( iRc = WriteBlock( npNode->ulBlockNo, GetBlockSize(), npNode->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::DeleteFromNode() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return XB_NO_ERROR;
-}
-
-/***********************************************************************/
-//! @brief Delete a key.
-/*!
- This routine deletes a key. It assumes the key to delete
- is the current key in the node chain.
-
- \param vpTag Tag to delete key on.
-
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::DeleteKey( void *vpTag ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- // save copy of node chain to reset to after delete completed
- xbIxNode *npSaveNodeChain = npTag->npNodeChain;
- npTag->npNodeChain = NULL;
- xbIxNode * npSaveCurNode = npTag->npCurNode;
-
- try{
-
- xbString sMsg;
-
- if(( iRc = xbIxNdx::KeySetPosDel( npTag )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- // Delete key needs to handle two scenarios
- // 1 - if the delete is on the only key of a leaf node, then traverse up the tree, trimming as needed
- // 2 - if the last key on a node is deleted, and the key value is not the same as the prev key value
- // go up the tree looking for an interior node needing updated key value
-
- xbInt32 lOrigKeyCnt = GetKeyCount( npTag->npCurNode );
- if(( iRc = DeleteFromNode( npTag, npTag->npCurNode, npTag->npCurNode->iCurKeyNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- if( lOrigKeyCnt == 1 ){
- // scenario 1
- xbBool bDone = xbFalse;
- xbBool bIsLeaf = xbFalse;
- xbInt32 lKeyCnt;
- npTag->npCurNode = npTag->npCurNode->npPrev;
-
- while( npTag->npCurNode && !bDone ){
- lKeyCnt = GetKeyCount( npTag->npCurNode );
- bIsLeaf = IsLeaf( npTag, npTag->npCurNode );
- if( lKeyCnt > 0 ){
- if(( iRc = DeleteFromNode( npTag, npTag->npCurNode, npTag->npCurNode->iCurKeyNo )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- if( (bIsLeaf && lKeyCnt > 1) || (!bIsLeaf && lKeyCnt > 0) )
- bDone = xbTrue;
- else
- npTag->npCurNode = npTag->npCurNode->npPrev;
- }
- } else if( npTag->npCurNode->iCurKeyNo == (xbUInt32) lOrigKeyCnt - 1 ){
-
- // scenario 2
- // if last two keys identical, then nothing to do, else go up looking for a key to change
- if( memcmp( GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->iKeyItemLen ),
- GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo-1, npTag->iKeyItemLen ),
- (size_t) npTag->iKeyLen )){
-
- xbIxNode *pNode = npTag->npCurNode->npPrev;
- char *pSrc = GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo-1, npTag->iKeyItemLen );
-
- while( pNode && pNode->ulBlockNo != npTag->ulRootBlock && pNode->iCurKeyNo == (xbUInt32) GetKeyCount( pNode ) )
- pNode = pNode->npPrev;
- if( pNode ){
- if( pNode->iCurKeyNo < (xbUInt32) GetKeyCount( pNode )){
- char *pTrg = pNode->cpBlockData;
- pTrg += 12 + (pNode->iCurKeyNo * (xbUInt32) npTag->iKeyItemLen);
- for( xbInt16 i = 0; i < npTag->iKeyLen; i++ )
- *pTrg++ = *pSrc++;
-
- // write out the block
- if(( iRc = WriteBlock( pNode->ulBlockNo, GetBlockSize(), pNode->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- }
- }
- }
- }
-
- // restore node chain to pre delete status (which should be post add status)
- npTag->npNodeChain = FreeNodeChain( npTag->npNodeChain );
- npTag->npNodeChain = npSaveNodeChain;
- npTag->npCurNode = npSaveCurNode;
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::DeleteKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( npSaveNodeChain ){
- npTag->npNodeChain = npSaveNodeChain;
- npSaveNodeChain = FreeNodeChain( npSaveNodeChain );
- npTag->npCurNode = npSaveCurNode;
- }
- }
- return iRc;
-}
-
-
-/***********************************************************************/
-//! @brief Delete tag.
-/*!
- In the case of an ndx tag, it deletes the ndx file as it contains
- only one tag.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::DeleteTag( void * ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- //xbNdxTag * npTag;
- //vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- try{
-
- // if open, close it
- if( FileIsOpen()){
- if(( iRc = Close()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- // delete file
- if(( iRc = xbRemove()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::DeleteTag() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-
-//! @brief Dump a block for a given tag.
-/*!
- Dump blocks for given tag for debugging purposes.
- \param iOpt Output message destination<br>
- 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
- \param vpTag - Not required for single tag NDX files.
- \returns void
-*/
-
-xbInt16 xbIxNdx::DumpTagBlocks( xbInt16 iOpt, void * ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbUInt32 lNoOfKeys;
- char *p;
- xbString s;
- xbBool bIsLeaf = false;
-
- try{
- if( !FileIsOpen()){
- iRc = XB_NOT_OPEN;
- iErrorStop = 100;
- throw iRc;
- }
-
- xbUInt32 ulStartBlock;
- xbUInt32 ulEndBlock;
- ulStartBlock = 1;
- ulEndBlock = ndxTag->ulTotalBlocks;
-
- for( xbUInt32 lBlk = ulStartBlock; lBlk < ulEndBlock; lBlk++ ){
-
- memset( cNodeBuf, 0x00, XB_NDX_BLOCK_SIZE );
- if(( iRc = ReadBlock( lBlk, XB_NDX_BLOCK_SIZE, cNodeBuf )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- p = cNodeBuf;
- lNoOfKeys = eGetUInt32( p );
-
- if( eGetUInt32( p + 4 ) > 0 ){
- bIsLeaf = false;
- s.Sprintf( "Node # %ld - Interior Node - Key Type [%c] Key Count [%ld]", lBlk, ndxTag->cKeyType, lNoOfKeys );
- } else {
- bIsLeaf = true;
- s.Sprintf( "Node # %ld - Leaf Node - Key Type [%c] Key count [%ld]", lBlk, ndxTag->cKeyType, lNoOfKeys );
- }
- xbase->WriteLogMessage( s, iOpt );
- xbase->WriteLogMessage( "Key Child Dbf Rec Key", iOpt );
- p += 4;
- xbUInt32 ulLeftBranch;
- xbUInt32 ulRecNo;
- xbString sKey;
- xbDouble d;
-
- xbUInt32 l;
- for( l = 0; l < lNoOfKeys; l++ ){
- ulLeftBranch = eGetUInt32( p );
- p+= 4;
- ulRecNo = eGetUInt32( p );
- p+= 4;
- if( ndxTag->cKeyType == 'C' ){
- sKey.Assign( p, 1, (xbUInt32) ndxTag->iKeyLen );
- } else if( ndxTag->cKeyType == 'D' ){
- xbInt32 lDate = (xbInt32) eGetDouble( p );
- xbDate dt( lDate );
- //xbString s2;
- //dt.JulToDate8( lDate, s2 );
- sKey.Sprintf( "%ld - %s", lDate, dt.Str());
- } else {
- d = eGetDouble( p );
- sKey.Sprintf( "%f", d );
- }
- p+= (ndxTag->iKeyItemLen-8);
-
- s.Sprintf( "%3d %9d %9d %s", l+1, ulLeftBranch, ulRecNo, sKey.Str() );
- xbase->WriteLogMessage( s, iOpt );
- }
- if( !bIsLeaf ){
- ulLeftBranch = eGetUInt32( p );
- s.Sprintf( "%3d %9d", l+1, ulLeftBranch );
- xbase->WriteLogMessage( s, iOpt );
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::DumpTagBlocks() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Dump index file header.
-/*!
- Dump a index file header for debugging purposes.
- \param iOpt Output message destination<br>
- 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::DumpHeader( xbInt16 iOpt, xbInt16 ){
- xbString s;
- xbInt16 iRc;
-
- if(( iRc = ReadHeadBlock( 1 )) != XB_NO_ERROR )
- return iRc;
-
- s.Sprintf( "Index Header Node for %s", GetFileName().Str());
- xbase->WriteLogMessage( s, iOpt );
- s.Sprintf( "--------------------------------" );
- xbase->WriteLogMessage( s, iOpt );
- s.Sprintf( "Root block = %ld", ndxTag->ulRootBlock );
- xbase->WriteLogMessage( s, iOpt );
- s.Sprintf( "Total blocks = %ld", ndxTag->ulTotalBlocks );
- xbase->WriteLogMessage( s, iOpt );
- s.Sprintf( "Key types = %c,%d", ndxTag->cKeyType, ndxTag->iKeyType );
- xbase->WriteLogMessage( s, iOpt );
- s.Sprintf( "Key Length = %d", ndxTag->iKeyLen );
- xbase->WriteLogMessage( s, iOpt );
- s.Sprintf( "Keys Per Block = %d", ndxTag->iKeysPerBlock );
- xbase->WriteLogMessage( s, iOpt );
- s.Sprintf( "Key Item Len = %ld", ndxTag->iKeyItemLen );
- xbase->WriteLogMessage( s, iOpt);
- s.Sprintf( "Serial No = %d", ndxTag->cSerNo );
- xbase->WriteLogMessage( s, iOpt);
- s.Sprintf( "Unique = %d", ndxTag->iUnique );
- xbase->WriteLogMessage( s, iOpt );
- s.Sprintf( "KeyExpression = %s", ndxTag->sKeyExpression.Str() );
- xbase->WriteLogMessage( s, iOpt );
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! @brief Dump the index for a tag.
-/*!
- Stub.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbIxNdx::DumpIxForTag( void *, xbInt16 )
-{
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! @brief Dump the index node chain.
-/*!
- Dump the index node chain for debugging purposes.
- \param vpTag Tag of node chain to dump.
- \param iOpt Output message destination<br>
- 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
- \returns void
-*/
-void xbIxNdx::DumpIxNodeChain( void *vpTag, xbInt16 iOpt ) const
-{
-
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- xbString s( "Dump Node Chain" );
- xbase->WriteLogMessage( s, iOpt );
-
- if( npTag->npNodeChain ){
- xbIxNode *n = npTag->npNodeChain;
- xbInt16 iCtr = 0;
- char cLeaf;
- s.Sprintf( "Cnt\tThis Prev Next CurKeyNo BlockNo NoOfKeys Type" );
- xbase->WriteLogMessage( s, iOpt );
- while( n ){
- IsLeaf( vpTag, n ) ? cLeaf = 'L' : cLeaf = 'I';
- s.Sprintf( "%d\t%08x %08x %08x %08d %08d %08d %c",
- iCtr++, n, n->npPrev, n->npNext, n->iCurKeyNo,
- n->ulBlockNo, eGetUInt32( n->cpBlockData ), cLeaf );
- xbase->WriteLogMessage( s, iOpt );
- n = n->npNext;
- }
- } else {
- s = "Empty Node Chain";
- xbase->WriteLogMessage( s, iOpt );
- }
-}
-/***********************************************************************/
-//! @brief Dump node.
-/*!
- Dump a node for debugging purposes.
- \param vpTag Tag of node chain to dump.
- \param pNode Node to dump.
- \param iOpt Output message destination<br>
- 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
- \returns XB_INVALID_OBJECT<br>XB_NO_ERROR
-*/
-
-xbInt16 xbIxNdx::DumpNode( void *vpTag, xbIxNode *pNode, xbInt16 iOpt ) const
-{
- xbString s;
- xbString sKey;
- xbUInt32 lLeftBranch;
- xbUInt32 lRecNo;
- xbDouble d;
-
- if( !pNode )
- return XB_INVALID_OBJECT;
-
- xbIx::DumpNode( vpTag, pNode, iOpt );
-
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- xbUInt32 lNoOfKeys = eGetUInt32( pNode->cpBlockData );
- xbBool bIsLeaf = IsLeaf( vpTag, pNode );
-
- if( bIsLeaf )
- xbase->WriteLogMessage( "Leaf node", iOpt );
- else
- xbase->WriteLogMessage( "Interior node", iOpt );
-
- s.Sprintf( "Key type = [%c] No Of Keys =[%d] Prev =[%x] Next =[%x]", npTag->cKeyType, lNoOfKeys, pNode->npPrev, pNode->npNext );
- xbase->WriteLogMessage( s, iOpt );
-
- char *p = pNode->cpBlockData;
- p += 4;
-
- xbUInt32 l;
- for( l = 0; l < lNoOfKeys; l++ ){
-
- lLeftBranch = eGetUInt32( p );
- p+= 4;
- lRecNo = eGetUInt32( p );
- p+= 4;
-
- if( npTag->cKeyType == 'C' ){
- sKey.Assign( p, 1, (xbUInt32) npTag->iKeyLen );
- } else if( npTag->cKeyType == 'D' ){
- xbInt32 lDate = (xbInt32) eGetDouble( p );
- xbDate dt( lDate );
- sKey.Sprintf( "%ld - %s", lDate, dt.Str());
- } else {
- d = eGetDouble( p );
- sKey.Sprintf( "%f", d );
- }
- p+= (npTag->iKeyItemLen-8);
- s.Sprintf( "%3d %9d %9d %s", l+1, lLeftBranch, lRecNo, sKey.Str() );
- xbase->WriteLogMessage( s, iOpt );
- }
- if( !bIsLeaf ){
- lLeftBranch = eGetUInt32( p );
- s.Sprintf( "%3d %9d", l+1, lLeftBranch );
- xbase->WriteLogMessage( s.Str(), iOpt );
- }
- return XB_NO_ERROR;
-}
-#endif
-/***********************************************************************/
-//! @brief Find key
-/*!
- \param vpTag Pointer to tag to search.
- \param vpKey Void pointer to key data to search on.
- \param lSearchKeyLen Length of key to search for.
- \param iRetrieveSw xbTrue - Retrieve the record if key found.<br>
- xbFalse - Don't retrieve record, check for key existence only.
- \returns XB_NO_ERROR - Key found.<br>
- XB_NOT_FOUND - Key not found.<br>
- <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxNdx::FindKey( void *vpTag, const void *vpKey, xbInt32 lSearchKeyLen,
- xbInt16 iRetrieveSw ){
-
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbString sMsg;
- // xbInt16 iFindSts;
- try{
- // clean up any previous table updates before moving on
- if( iRetrieveSw ){
- if( dbf->GetDbfStatus() == XB_UPDATED ){
- if( dbf->GetAutoCommit() == 1 ){
- if(( iRc = dbf->Commit()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- } else {
- if(( iRc = dbf->Abort()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- }
- }
-
- xbUInt32 ulNoOfKeys;
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
- char cKeyType = npTag->cKeyType;
-
- if( npTag->npNodeChain ){
-
- // determine if the index has been updated since the last time it was used
- time_t tFileTs;
- if(( iRc = GetFileMtime( tFileTs )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if( npTag->tNodeChainTs < tFileTs ){
- npTag->npNodeChain = FreeNodeChain( npTag->npNodeChain );
- npTag->npCurNode = NULL;
- if(( iRc = ReadHeadBlock( 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if(( iRc = GetBlock( npTag, (npTag->ulRootBlock ), 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- } else {
- // pop up the chain looking for appropriate starting point
- xbBool bDone = false;
- xbIxNode * TempIxNode;
- while( npTag->npCurNode && !bDone && npTag->npCurNode->ulBlockNo != npTag->ulRootBlock ){ // not root node
- iRc = CompareKey( cKeyType, vpKey, GetKeyData( npTag->npCurNode, 0, npTag->iKeyItemLen ), (size_t) lSearchKeyLen );
- if( iRc <= 0 ){
- TempIxNode = npTag->npCurNode;
- npTag->npCurNode = npTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
- } else {
- // get the number of keys on the block and compare the key to the rightmost key
- xbUInt32 ulKeyCtr = eGetUInt32( npTag->npCurNode->cpBlockData ) - 1;
- iRc = CompareKey( cKeyType, vpKey, GetKeyData( npTag->npCurNode, ulKeyCtr, npTag->iKeyItemLen), (size_t) lSearchKeyLen );
-
- if( iRc > 0 ){
- TempIxNode = npTag->npCurNode;
- npTag->npCurNode = npTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
- } else {
- bDone = true;
- }
- }
- }
- }
- } else {
- if(( iRc = GetBlock( npTag, (npTag->ulRootBlock ), 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
-
-
- // if cur node is the base node and no keys on this node, then the index is empty
- if( npTag->ulRootBlock == npTag->npCurNode->ulBlockNo ){
- ulNoOfKeys = eGetUInt32( npTag->npCurNode->cpBlockData );
- if( ulNoOfKeys == 0 && IsLeaf( npTag, npTag->npCurNode )){
- // iRc = XB_EMPTY;
-
- iRc = XB_NOT_FOUND;
- return iRc;
- }
- }
-
- // should be in the appropriate position in the node chain to continue the search from here
- // run down through the interior nodes
- xbInt16 iSearchRc = 0;
- xbUInt32 ulKeyPtr = 0;
-
- while( !IsLeaf( npTag, npTag->npCurNode ) ){
-
- // get the number of keys on the block and compare the key to the rightmost key
- ulNoOfKeys = eGetUInt32( npTag->npCurNode->cpBlockData );
- if( ulNoOfKeys == 0 ) // interior nodes can have zero keys, just a link to the next lower node
- npTag->npCurNode->iCurKeyNo = 0;
- else
- {
- iRc = CompareKey( cKeyType, vpKey, GetKeyData( npTag->npCurNode, ulNoOfKeys - 1, npTag->iKeyItemLen), (size_t) lSearchKeyLen );
- if( iRc > 0 ){
- npTag->npCurNode->iCurKeyNo = ulNoOfKeys;
- } else {
- npTag->npCurNode->iCurKeyNo = (xbUInt32) BSearchBlock( cKeyType, npTag->npCurNode,
- (xbInt32) npTag->iKeyItemLen, vpKey, (xbInt32) lSearchKeyLen, iSearchRc );
- }
- }
-
- if(( iRc = GetKeyPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
-
- if(( iRc = GetBlock( npTag, ulKeyPtr, 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- }
-
- // should be on a the correct leaf node, it may or may not contain the actual key
- ulNoOfKeys = eGetUInt32( npTag->npCurNode->cpBlockData );
- xbInt16 iCompRc = 0;
-
- if( ulNoOfKeys == 0 ){
- iRc = XB_NOT_FOUND;
- return iRc;
- } else {
-
- iRc = BSearchBlock( cKeyType, npTag->npCurNode, npTag->iKeyItemLen, vpKey, lSearchKeyLen, iCompRc );
-
- // iCompRc
- // 0 found
- // < 0 eof encountered, search key > last key in file
- // > 0 not found, positioned to next key
-
-
- // std::cout << "xbIxNdx::FindKey -Rc = " << iRc << " CompRc = " << iCompRc << " NoOfKeys = " << ulNoOfKeys << " blk no = " << npTag->npCurNode->ulBlockNo << "\n";
-
- if( iCompRc >= 0 ){
- npTag->npCurNode->iCurKeyNo = (xbUInt32) iRc;
- if( iRetrieveSw ){
- xbUInt32 ulKey = npTag->npCurNode->iCurKeyNo;
- if( ulKey >= ulNoOfKeys ) // if position past end of keys, need to go back one and position to last key
- ulKey--;
-
- if(( iRc = GetDbfPtr( vpTag, ulKey, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
- }
- }
- }
-
- if( iCompRc == 0 )
- return XB_NO_ERROR;
- else if( iCompRc > 0 )
- return XB_NOT_FOUND;
- else
- return XB_EOF;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::FindKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Find key for current record
-/*!
- This routine is called when updating a key.
-
- \param vpTag Pointer to tag to search.
- XB_NOT_FOUND Key not found.<br>
- <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::FindKeyForCurRec( void * vpTag )
-{
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- try{
- if(( iRc = CreateKey( vpTag, 0 )) < XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- // find key
- iRc = FindKey( vpTag, npTag->cpKeyBuf, npTag->iKeyLen, 0 );
- if( iRc == XB_NOT_FOUND || iRc == XB_EMPTY || iRc == XB_EOF )
- return iRc;
-
- if( iRc != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- // if keys are unique, and the recrd number matches, then we are good
- if( GetUnique() )
- return XB_NO_ERROR;
-
- // get here if key found and not unique, need to move forward looking for correct rec no
- xbUInt32 ulDbfRecNo = dbf->GetCurRecNo();
- xbBool bKeysMatch = true; // keys match?
- xbBool bCurRecsMatch = false; // cur recod number matches?
- xbUInt32 ulIxRecNo = 0;
- char cKeyType = GetKeyType( vpTag );
-
- if(( iRc = GetDbfPtr( vpTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulIxRecNo )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if( ulIxRecNo == ulDbfRecNo )
- bCurRecsMatch = true;
-
- xbInt16 iCompRc;
- while( !bCurRecsMatch && bKeysMatch ){
-
- if(( iRc = GetNextKey( vpTag, 0 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- // do compare key here
- iCompRc = CompareKey( cKeyType, npTag->cpKeyBuf, GetKeyData( npTag->npCurNode, 0, npTag->iKeyItemLen ), (size_t) npTag->iKeyLen );
- if( iCompRc != 0 )
- bKeysMatch = false;
- else{
- if(( iRc = GetDbfPtr( vpTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulIxRecNo )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if( ulIxRecNo == ulDbfRecNo )
- bCurRecsMatch = true;
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::FindKeyForCurRec() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return XB_NO_ERROR;
-}
-
-/***********************************************************************/
-//! @brief Get dbf record number for given key number.
-/*!
- \param vpTag Tag to retrieve dbf rec number on.
- \param iKeyNo Key number for retrieval
- \param np Pointer to node
- \param ulDbfPtr- Output dbf record number
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxNdx::GetDbfPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *np, xbUInt32 &ulDbfPtr ) const {
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- #ifdef XB_DEBUG_SUPPORT
- // turn this off in production mode for better performance
- xbUInt32 ulNoOfKeys = eGetUInt32 ( np->cpBlockData );
- if( iKeyNo < 0 || iKeyNo > (xbInt16) --ulNoOfKeys ){
- iErrorStop = 100;
- throw XB_INVALID_KEYNO;
- }
- #endif
-
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
- char *p = ( np->cpBlockData);
- p += (8 + (iKeyNo * npTag->iKeyItemLen));
- ulDbfPtr = eGetUInt32 ( p );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::GetDbfPtr() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Get the first key for the given tag.
-/*!
- \param vpTag Tag to retrieve first key on.
- \param iRetrieveSw xbTrue - Retrieve the record on success.<br>
- xbFalse - Don't retrieve record.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::GetFirstKey( void *vpTag, xbInt16 iRetrieveSw ){
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- try{
- // clear out any history
- if( npTag->npNodeChain ){
- npTag->npNodeChain = FreeNodeChain( npTag->npNodeChain );
- npTag->npCurNode = NULL;
- }
- if(( iRc = ReadHeadBlock( 1 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- // lRootBlock is now available
- if(( iRc = GetBlock( npTag, npTag->ulRootBlock, 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- // if no keys on this node, and it's a leaf node then the index is empty
- xbUInt32 ulKeyPtr = eGetUInt32( npTag->npCurNode->cpBlockData );
- if( ulKeyPtr == 0 && IsLeaf( npTag, npTag->npCurNode )){
- iRc = XB_EMPTY;
- return iRc;
- }
- while( !IsLeaf( npTag, npTag->npCurNode )) // go down the chain looking for a leaf node
- {
- if(( iRc = GetKeyPtr( npTag, 0, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if(( iRc = GetBlock( npTag, ulKeyPtr, 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- }
- if( iRetrieveSw ){
- if(( iRc = GetDbfPtr( npTag, 0, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
- }
- catch( xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::GetFirstKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Get the key expression for the given tag.
-/*!
- \param vpTag Tag to retrieve expression from.
- \returns Key expression.
-*/
-
-xbString &xbIxNdx::GetKeyExpression( const void * vpTag ) const{
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
- return npTag->sKeyExpression;
-}
-
-
-/***********************************************************************/
-//! @brief Get the key filter for the given tag.
-/*!
- NDX index files do not support filters. This returns NULL.
- \returns NULL.
-*/
-
-xbString &xbIxNdx::GetKeyFilter( const void * ) const{
- return sNullString;
-}
-/***********************************************************************/
-//! @brief Get the key length for the given tag.
-/*!
- \param vpTag Tag to retrieve key length for.
- \returns Length of key.
-*/
-xbInt32 xbIxNdx::GetKeyLen( const void * vpTag ) const{
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
- return npTag->iKeyLen;
-}
-/***********************************************************************/
-//! @brief Get child node number for given key number.
-/*!
- \param vpTag Tag to retrieve dbf rec number on.
- \param iKeyNo Key number for retrieval
- \param np Pointer to node
- \param ulKeyPtr Output node number
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *np, xbUInt32 &ulKeyPtr ) const {
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- try{
- #ifdef XB_DEBUG_SUPPORT
- // turn this off in production mode for better performance
- xbUInt32 ulNoOfKeys = eGetUInt32 ( np->cpBlockData );
- if( iKeyNo < 0 || iKeyNo > (xbInt16) ulNoOfKeys ){
- iErrorStop = 100;
- throw XB_INVALID_KEYNO;
- }
- #endif
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
- char *p = ( np->cpBlockData);
- p += (4 + (iKeyNo * npTag->iKeyItemLen));
- ulKeyPtr = eGetUInt32 ( p );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::GetKeyPtr() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Returns key update status.
-/*!
- \param vpTag Tag to check status on.
- \returns XB_UPD_KEY Key updated.<br>
- XB_DEL_KEY Key deleted.<br>
- XB_ADD_KEY Key added.<br>
- 0 No key updates
-
-*/
-xbInt16 xbIxNdx::GetKeySts( void *vpTag ) const{
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
- return npTag->iKeySts;
-}
-/***********************************************************************/
-//! @brief Get character key type for given tag.
-/*!
- \param vpTag Tag to retrieve key type for.
- \returns Char key type.
-*/
-
-char xbIxNdx::GetKeyType( const void * vpTag ) const{
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
- return npTag->cKeyType;
-}
-
-/***********************************************************************/
-//! @brief Get numeric key type for given tag.
-/*!
- \param vpTag Tag to retrieve first key for.
- \returns Numeric key type.
-*/
-xbInt16 xbIxNdx::GetKeyTypeN( const void * vpTag ) const{
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
- return npTag->iKeyType;
-}
-/***********************************************************************/
-//! @brief Get the last key for the given tag.
-/*!
- \param vpTag Tag to retrieve last key on.
- \param iRetrieveSw xbTrue - Retrieve the record on success.<br>
- xbFalse - Don't retrieve record.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxNdx::GetLastKey( void *vpTag, xbInt16 iRetrieveSw ){
- return GetLastKey( 0, vpTag, iRetrieveSw );
-// return GetLastKey( 0, vpTag, 1 );
-
-}
-/***********************************************************************/
-//! @brief Get the last key for the given tag and starting node.
-/*!
- \param ulNodeNo Starting node
- \param vpTag Tag to retrieve last key on.
- \param iRetrieveSw xbTrue - Retrieve the record if key found.<br>
- xbFalse - Don't retrieve record.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxNdx::GetLastKey( xbUInt32 ulNodeNo, void *vpTag, xbInt16 iRetrieveSw ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulKeyPtr = 0;
- xbUInt32 ulNoOfKeys = 0;
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- try{
- // clear out any history
- if( npTag->npNodeChain ){
- npTag->npNodeChain = FreeNodeChain( npTag->npNodeChain );
- npTag->npCurNode = NULL;
- }
- if( ulNodeNo == 0 ){
- if(( iRc = ReadHeadBlock( 1 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- // lRootBlock is now available
- if(( iRc = GetBlock( npTag, npTag->ulRootBlock, 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- } else {
- if(( iRc = GetBlock( npTag, ulNodeNo, 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- // if no keys on this node, then the index is empty
- ulNoOfKeys = eGetUInt32( npTag->npCurNode->cpBlockData );
- if( ulNoOfKeys == 0 && IsLeaf( npTag, npTag->npCurNode )){
- iRc = XB_EMPTY;
- return iRc;
- }
- npTag->npCurNode->iCurKeyNo = ulNoOfKeys;
- while( !IsLeaf( npTag, npTag->npCurNode ) ){ // go down the chain looking for a leaf node
- npTag->npCurNode->iCurKeyNo = eGetUInt32( npTag->npCurNode->cpBlockData );
- if(( iRc = GetKeyPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if(( iRc = GetBlock( npTag, ulKeyPtr, 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- ulNoOfKeys = eGetUInt32( npTag->npCurNode->cpBlockData );
- npTag->npCurNode->iCurKeyNo = ulNoOfKeys;
- }
- // get here on a leaf node, it has one fewer iCurKeyNo
- npTag->npCurNode->iCurKeyNo--;
- if( iRetrieveSw ){
- ulNoOfKeys = eGetUInt32( npTag->npCurNode->cpBlockData );
- if(( iRc = GetDbfPtr( npTag, ulNoOfKeys - 1, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::GetLastKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Get the last key for a block number.
-/*!
- \param vpTag Tag to retrieve first key on.
- \param ulBlockNo Block number for key retrieval.
- \param cpBuf output buffer for key placement
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::GetLastKeyForBlockNo( void *vpTag, xbUInt32 ulBlockNo, char *cpBuf ){
-
- // returns the last key for a given block number
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- try{
- xbIxNode * npSaveNodeChain = npTag->npNodeChain;
- xbIxNode * npSaveCurNode = npTag->npCurNode;
- npTag->npNodeChain = NULL;
-
- if(( iRc = GetLastKey( ulBlockNo, npTag, 0 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- // set the key
- memcpy( cpBuf, GetKeyData( npTag->npCurNode, GetKeyCount( npTag->npCurNode ) - 1, npTag->iKeyItemLen ), (size_t) npTag->iKeyLen );
-
- // free memory
- npTag->npNodeChain = FreeNodeChain( npTag->npNodeChain );
- npTag->npNodeChain = npSaveNodeChain;
- npTag->npCurNode = npSaveCurNode;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::GetLastKeyForBlockNo() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ) );
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Get the next key for the given tag.
-/*!
- \param vpTag Tag to retrieve next key on.
- \param iRetrieveSw xbTrue - Retrieve the record on success.<br>
- xbFalse - Don't retrieve record.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::GetNextKey( void * vpTag, xbInt16 iRetrieveSw ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- try{
- if( !npTag->npNodeChain )
- return GetFirstKey( vpTag, iRetrieveSw );
-
- // more keys on this node? if yes, get the next one to the right
- xbUInt32 ulKeyPtr;
- if((eGetUInt32( npTag->npCurNode->cpBlockData ) -1) > npTag->npCurNode->iCurKeyNo ){
- npTag->npCurNode->iCurKeyNo++;
- if(( iRc = GetDbfPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if( iRetrieveSw ){
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- } else {
- return iRc;
- }
- } else {
- return iRc;
- }
- }
- // if at end of head node, then eof
- if( npTag->npCurNode->ulBlockNo == npTag->ulRootBlock )
- return XB_EOF;
-
- // This logic assumes that interior nodes have n+1 left node no's where n is he the number of keys in the node
- xbIxNode * TempIxNode = npTag->npCurNode;
- npTag->npCurNode = npTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
-
- while( npTag->npCurNode->iCurKeyNo >= eGetUInt32( npTag->npCurNode->cpBlockData ) &&
- (npTag->npCurNode->ulBlockNo != npTag->ulRootBlock )){
- TempIxNode = npTag->npCurNode;
- npTag->npCurNode = npTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
- }
-
- // head node and at end of head node, then eof
- if( npTag->npCurNode->ulBlockNo == npTag->ulRootBlock &&
- npTag->npCurNode->iCurKeyNo == eGetUInt32( npTag->npCurNode->cpBlockData ))
- return XB_EOF;
-
- // move one to the right
- npTag->npCurNode->iCurKeyNo++;
-
- if(( iRc = GetKeyPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- if(( iRc = GetBlock( npTag, ulKeyPtr, 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- while( !IsLeaf( npTag, npTag->npCurNode )) // go down the chain looking for a leaf node
- {
- if(( iRc = GetKeyPtr( npTag, 0, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if(( iRc = GetBlock( npTag, ulKeyPtr, 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
- if( iRetrieveSw ){
- if(( iRc = GetDbfPtr( npTag, 0, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- }
- }
- catch( xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::GetNextKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Get the previous key for the given tag.
-/*!
- \param vpTag Tag to retrieve previous key on.
- \param iRetrieveSw xbTrue - Retrieve the record on success.<br>
- xbFalse - Don't retrieve record.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxNdx::GetPrevKey( void * vpTag, xbInt16 iRetrieveSw ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- // This method assumes last index call landed on a valid key.
- // If last call resulted in an error, this method will returns XB_BOF
-
- try{
- if( !npTag->npNodeChain )
- return GetLastKey( 0, vpTag, iRetrieveSw );
-
- xbUInt32 ulKeyPtr;
- if( npTag->npCurNode->iCurKeyNo > 0 ){
- npTag->npCurNode->iCurKeyNo--;
-
- if(( iRc = GetDbfPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if( iRetrieveSw ){
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- } else {
- return iRc;
- }
- }
- }
-
- // next two lines might have been an issue
- if( npTag->npCurNode->ulBlockNo == npTag->ulRootBlock && GetKeyCount( npTag->npCurNode ) == 0 && IsLeaf( npTag, npTag->npCurNode ))
- return XB_EMPTY;
-
- if( npTag->npCurNode->ulBlockNo == npTag->ulRootBlock )
- return XB_BOF;
-
- // This logic assumes that interior nodes have n+1 left node no's where n is he the number of keys in the node
- xbIxNode * TempIxNode = npTag->npCurNode;
- npTag->npCurNode = npTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
-
- while( npTag->npCurNode->iCurKeyNo == 0 &&
- (npTag->npCurNode->ulBlockNo != npTag->ulRootBlock )){
- TempIxNode = npTag->npCurNode;
- npTag->npCurNode = npTag->npCurNode->npPrev;
- TempIxNode = FreeNodeChain( TempIxNode );
- }
-
- // head node and at end of head node, then bof
- if( npTag->npCurNode->ulBlockNo == npTag->ulRootBlock &&
- npTag->npCurNode->iCurKeyNo == 0 )
- return XB_BOF;
-
- // move one to the left
- npTag->npCurNode->iCurKeyNo--;
-
- if(( iRc = GetKeyPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- if(( iRc = GetBlock( npTag, ulKeyPtr, 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- while( !IsLeaf( npTag, npTag->npCurNode )){ // go down the chain looking for a leaf node
- npTag->npCurNode->iCurKeyNo = eGetUInt32( npTag->npCurNode->cpBlockData );
- if(( iRc = GetKeyPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if(( iRc = GetBlock( npTag, ulKeyPtr, 1, (xbUInt32) npTag->iKeyItemLen )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
-
- npTag->npCurNode->iCurKeyNo = eGetUInt32( npTag->npCurNode->cpBlockData ) - 1;
- if( iRetrieveSw ){
- if(( iRc = GetDbfPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if(( iRc = dbf->GetRecord( ulKeyPtr )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- }
- }
-
- catch( xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::GetPrevKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Get the sort order for given tag.
-/*!
- Ndx indices only support ascending keys.
- \returns 0
-*/
-xbBool xbIxNdx::GetSortOrder( void * ) const{
- return 0;
-}
-/***********************************************************************/
-//! @brief Get tag for tag number.
-/*!
- \returns Pointer to ndx tag.
-*/
-void * xbIxNdx::GetTag( xbInt16 ) const{
- return ndxTag;
-}
-/***********************************************************************/
-//! @brief Get tag for tag name.
-/*!
- \returns Pointer to ndx tag.
-*/
-void * xbIxNdx::GetTag( xbString & ) const{
- return ndxTag;
-}
-
-/***********************************************************************/
-//! @brief Get tag count.
-/*!
- NDX index files contain one tag.
- \returns 1
-*/
-
-xbInt16 xbIxNdx::GetTagCount() const{
- return 1;
-}
-/***********************************************************************/
-//! @brief Get tag name.
-/*!
- \returns Tag name.
-*/
-xbString &xbIxNdx::GetTagName( void * ) const {
-// char * xbIxNdx::GetTagName( void * ) const {
-
- return ndxTag->sTagName;
-
-}
-/***********************************************************************/
-//! @brief Get tag name.
-/*!
- \returns Tag name.
-*/
-const char * xbIxNdx::GetTagName( void *, xbInt16 ) const {
- return ndxTag->sTagName;
-}
-
-/***********************************************************************/
-//! @brief Get the unique setting for given tag.
-/*!
- \param vpTag Tag to unique setting on.
- \returns xbTrue - Unique index.<br> xbFalse - Not unique index.
-*/
-xbBool xbIxNdx::GetUnique( void * vpTag ) const{
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
- return npTag->iUnique;
-}
-
-/***********************************************************************/
-//! @brief Insert key into interior node.
-/*!
- Insert key into non-full interior node.<br>
- Assumes valid inputs
-
- \param vpTag Tag in play.
- \param npNode Node for insertion.
- \param iSlotNo Slot number to insert key.
- \param ulPtr Pointer number to insert.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::InsertNodeI( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo, xbUInt32 ulPtr ){
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char *pTrg;
- xbInt16 iSrcPos;
- char *pLastKey = NULL;
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- try{
- // update number of keys on the node
- xbInt32 lKeyCnt = GetKeyCount( npNode );
- iSrcPos = 12 + (iSlotNo * npTag->iKeyItemLen);
-
- char *pSrc = npNode->cpBlockData;
- pSrc += iSrcPos;
-
- // if not appending to the end of the node, make some room, move things to the right
- if( iSlotNo < lKeyCnt ) {
- xbInt16 iCopyLen = ((lKeyCnt - iSlotNo) * npTag->iKeyItemLen) - 4;
- pTrg = pSrc;
- pTrg += npTag->iKeyItemLen;
- memmove( pTrg, pSrc, (size_t) iCopyLen );
- }
-
- // get the right most key for the left part of the split node
- xbUInt32 ulKeyPtr2;
- if(( iRc = GetKeyPtr( vpTag, npNode->iCurKeyNo, npNode, ulKeyPtr2 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- // get the new right key value for the freshly split node
- pLastKey = (char *) malloc((size_t) ndxTag->iKeyLen);
- if(( iRc = GetLastKeyForBlockNo( vpTag, ulKeyPtr2, pLastKey )) != XB_NO_ERROR ){
- iRc = 110;
- throw iRc;
- }
- // write the key value
- pTrg = pSrc;
- char *pTrg2 = pSrc;
- pSrc = pLastKey;
- for( xbInt16 i = 0; i < npTag->iKeyLen; i++ )
- *pTrg++ = *pSrc++;
-
- pTrg2 += (npTag->iKeyItemLen - 8);
- ePutUInt32( pTrg2, ulPtr );
- ePutInt32( npNode->cpBlockData, ++lKeyCnt );
-
- // write out the updated block to disk
- if(( iRc = WriteBlock( npNode->ulBlockNo, GetBlockSize(), npNode->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- if( pLastKey )
- free( pLastKey );
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::InsertNodeI() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( pLastKey )
- free( pLastKey );
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Insert key into leaf node.
-/*!
- Insert key into non-full leaf node.<br>
- Assumes valid inputs
-
- \param vpTag Tag in play.
- \param npNode Node for insertion.
- \param iSlotNo Slot number to insert key.
- \param ulPtr Pointer number to insert.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxNdx::InsertNodeL( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo,
- char * cpKeyBuf, xbUInt32 ulPtr ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char *pSrc;
- char *pTrg;
- char *pKeyPos;
- xbString sMsg;
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- try{
- xbInt32 lKeyCnt = GetKeyCount( npNode );
- xbInt16 iKeyPos = 4 + iSlotNo * npTag->iKeyItemLen;
- pKeyPos = npNode->cpBlockData;
- pKeyPos += iKeyPos;
-
- // if not appending to end, make space, move things right
- if( iSlotNo < lKeyCnt ) {
- xbInt16 iCopyLen = (lKeyCnt - iSlotNo) * npTag->iKeyItemLen;
- pTrg = pKeyPos;
- pTrg += npTag->iKeyItemLen;
- memmove( pTrg, pKeyPos, (size_t) iCopyLen );
- }
- // if leaf, write rec number
- pTrg = pKeyPos;
- memset( pTrg, 0x00, 4 );
- pTrg += 4;
- ePutUInt32( pTrg, ulPtr );
- pTrg += 4;
-
- // write the key value
- pSrc = cpKeyBuf;
- for( xbInt16 i = 0; i < npTag->iKeyLen; i++ )
- *pTrg++ = *pSrc++;
-
- // update number of keys on the node
- ePutInt32( npNode->cpBlockData, ++lKeyCnt );
-
- // write out the updated block to disk
- if(( iRc = WriteBlock( npNode->ulBlockNo, GetBlockSize(), npNode->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::InsertNodeL() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Determine node leaf status
-/*!
- \param npNode Node to examine.
- \returns xbTrue - Leaf node.<br> xbFalse - Interior node.
-*/
-xbBool xbIxNdx::IsLeaf( void *, xbIxNode *npNode ) const {
- xbUInt32 ulBlock = eGetUInt32 ( npNode->cpBlockData+4 );
- if( ulBlock > 0 ) // if the second four bytes are a number, it's an interior node
- return false;
- else
- return true;
-}
-/***********************************************************************/
-//! @brief Determine if key exists.
-/*!
- This method assumes the key has already been built and is in either
- cpKeyBuf or dKey.
-
- \param vpTag - Pointer to tag.
- \returns xbTrue - Key exists.<br> xbFalse - Key does not exist.
-*/
-xbInt16 xbIxNdx::KeyExists( void * vpTag ){
-
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- xbInt16 iRc = FindKey( vpTag, npTag->cpKeyBuf, npTag->iKeyLen, 0 );
- if( iRc == 0 )
- return 1;
- else
- return 0;
-}
-
-/***********************************************************************/
-//! @brief Set position for key add.
-/*!
- This routine is called by the AddKey() method and is used to position
- the node chain to the position the new key should be added to the index.
-
- \param npTag Pointer to npTag.
- \param ulAddRecNo Record number to add.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxNdx::KeySetPosAdd( xbNdxTag *npTag, xbUInt32 ulAddRecNo ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
-
- iRc = FindKey( npTag, npTag->cpKeyBuf, npTag->iKeyLen, 0 );
- if( iRc == XB_NOT_FOUND || iRc == XB_EMPTY )
- return XB_NO_ERROR; // good position
-
- else if( iRc != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- // get here if key was found, get the right most instance of any non unique key for append, find correct spot for update
- if( GetUnique() == 0 ){
- xbUInt32 ulCurRecNo;
- if(( iRc = GetDbfPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulCurRecNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- xbBool bKeysMatch = xbTrue;
- while( bKeysMatch && ulAddRecNo > ulCurRecNo && iRc == XB_NO_ERROR ){
- if(( iRc = GetNextKey( npTag, 0 )) == XB_NO_ERROR ){
- if( memcmp( GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->iKeyItemLen ), npTag->cpKeyBuf, (size_t) npTag->iKeyLen ))
- bKeysMatch = xbFalse;
- else{
- if(( iRc = GetDbfPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulCurRecNo )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- }
- }
- }
- if( iRc == XB_EOF ){ // eof condition
- if(( iRc = GetLastKey( 0, npTag, 0 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- npTag->npCurNode->iCurKeyNo++;
- return XB_NO_ERROR;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::KeySetPos() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Set position for key add.
-/*!
- This routine is called by the DeleteKey() method and is used to position
- the node chain to the position the old key should be deleted from the index.
-
- \param npTag Pointer to npTag.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::KeySetPosDel( xbNdxTag *npTag ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbString sMsg;
-
- try{
- iRc = FindKey( NULL, npTag->cpKeyBuf2, npTag->iKeyLen, 0 );
- if( iRc == XB_NOT_FOUND || iRc == XB_EMPTY )
- return XB_NO_ERROR; // good position
- else if( iRc != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- xbUInt32 ulIxRecNo;
- if(( iRc = GetDbfPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulIxRecNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- if( ulIxRecNo == dbf->GetCurRecNo())
- return XB_NO_ERROR;
- if( GetUnique() == 1 ){
- iErrorStop = 120;
- iRc = XB_NOT_FOUND;
- throw iRc;
- }
- xbBool bFound = xbFalse;
- xbBool bKeysMatch = xbTrue;
- while( bKeysMatch && !bFound && iRc == XB_NO_ERROR ){
- if(( iRc = GetNextKey( npTag, 0 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- if( memcmp( GetKeyData( npTag->npCurNode, npTag->npCurNode->iCurKeyNo, npTag->iKeyItemLen ), npTag->cpKeyBuf2, (size_t) npTag->iKeyLen )){
- bKeysMatch = xbFalse;
- } else {
- if(( iRc = GetDbfPtr( npTag, npTag->npCurNode->iCurKeyNo, npTag->npCurNode, ulIxRecNo )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- if( ulIxRecNo == dbf->GetCurRecNo())
- bFound = xbTrue;
- }
- }
- if( bFound )
- return XB_NO_ERROR;
- else
- return XB_NOT_FOUND;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::KeySetPosDel() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Returns key filter status.
-/*!
- \param vpTag Tag to check status on.
- \returns xbtrue - Key was updated.<br>xbFalse - Key not updated.
-
- Always true for NDX style indices.
-*/
-//inline xbBool xbIxNdx::KeyFiltered( void *vpTag ) const{
-// return xbTrue;
-//}
-
-/***********************************************************************/
-//! @brief Read head block of index file.
-/*!
- \param iOpt 0 - Read in entire block
- 1 - Read in only dynamic section of block
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbIxNdx::ReadHeadBlock( xbInt16 iOpt = 0 ) {
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- try{
- if( !FileIsOpen()){
- iRc = XB_NOT_OPEN;
- iErrorStop = 100;
- throw iRc;
- }
- xbInt16 iLen;
- iOpt == 0 ? iLen = 512 : iLen = 21;
-
- if(( iRc = ReadBlock( (xbUInt32) 0, (size_t) iLen, cNodeBuf )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- char *p = cNodeBuf;
- ndxTag->ulRootBlock = eGetUInt32( p ); p+=4;
- ndxTag->ulTotalBlocks = eGetUInt32( p ); p+=5;
- if( iOpt == 0 ){
- ndxTag->cKeyType = *p; p+=3;
- ndxTag->iKeyLen = eGetInt16( p ); p+=2;
- ndxTag->iKeysPerBlock = eGetInt16( p ); p+=2;
- ndxTag->iKeyType = eGetInt16( p ); p+=2;
- ndxTag->iKeyItemLen = eGetInt16( p ); p+=2;
- ndxTag->cSerNo = *p; p+=3;
- ndxTag->iUnique = *p; p++;
- ndxTag->sKeyExpression.Set( p );
-
- if( ndxTag->exp )
- delete ndxTag->exp;
-
- ndxTag->exp = new xbExp( xbase, dbf );
- if(( iRc = ndxTag->exp->ParseExpression( ndxTag->sKeyExpression.Str() )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- if( ndxTag->cpKeyBuf )
- free( ndxTag->cpKeyBuf );
- if( ndxTag->cpKeyBuf2 )
- free( ndxTag->cpKeyBuf2 );
-
- ndxTag->cpKeyBuf = (char *) malloc( (size_t) ndxTag->iKeyLen );
- ndxTag->cpKeyBuf2 = (char *) malloc( (size_t) ndxTag->iKeyLen );
-
- if( ndxTag->sTagName == "" )
- GetFileNamePart( ndxTag->sTagName );
-
- } else {
- p+= 11;
- ndxTag->cSerNo = *p;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::ReadHeadBlock() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Reindex a tag.
-/*!
- \param vpTag Pointer to tag pointer.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::Reindex( void **vpTag ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbNdxTag *npTag = ndxTag;
-
- try{
- xbInt16 iUnique = GetUnique( *vpTag );
-
- npTag->npNodeChain = FreeNodeChain( npTag->npNodeChain );
- npTag->npCurNode = NULL;
- npTag->ulRootBlock = 1L;
- npTag->ulTotalBlocks = 2L;
-
- if(( iRc = xbTruncate( 1024 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- if(( iRc = WriteHeadBlock( 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- char buf[512];
- memset( buf, 0x00, 512 );
-
- if(( iRc = WriteBlock( 1, 0, buf )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- xbUInt32 ulRecCnt = 0;
- if(( iRc = dbf->GetRecordCnt( ulRecCnt )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
-
- for( xbUInt32 l = 1; l <= ulRecCnt; l++ ){
- if(( iRc = dbf->GetRecord( l )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
-
- if(( iRc = CreateKey( npTag, 1 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
-
- if( iUnique ){
- // iRc = CheckForDupKey( vpTag2 );
- iRc = CheckForDupKey( npTag );
- if( iRc != 0 ){
- if( iRc < 0 ){
- iErrorStop = 160;
- throw iRc;
- }
- return XB_KEY_NOT_UNIQUE;
- }
- }
-
- if(( iRc = AddKey( npTag, l )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- }
- *vpTag = npTag;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::Reindex() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- this->DeleteTag( NULL ); // Don't leave the index in an incomplete state
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Set current tag.
-/*!
- For ndx indices, there is only one tag.
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbIxNdx::SetCurTag( xbInt16 ) {
- xbIx::SetCurTag( ndxTag );
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! @brief Set current tag.
-/*!
- For ndx indices, there is only one tag.
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbIxNdx::SetCurTag( xbString & ) {
- xbIx::SetCurTag( ndxTag );
- dbf->SetCurTag( "NDX", this, GetTag(0) );
- return XB_NO_ERROR;
-}
-
-/***********************************************************************/
-//! @brief Split an interior node
-/*!
-
- This routine splits an interior node into two nodes, divided by dSplitFactor.<br>
- This behaves differently than V7 Dbase. V7 does not balance the nodes.<br>
- For V7, if adding a key to the end of a node, it will create a right node
- with only one key, and the left node is still full.<br><br>
-
- Possible performance improvement options.<br>
- Two modes when splitting:<br>
- a) Split nodes in the middle - good for random access applications<br>
- b) Split off right node with only one key - good for applications with
- expectation of ascending keys added moving forward.<br>
-
- This routine first inserts the key into the left node in the appropriate location
- then splits the node based on the split factor setting.
-
- \param vpTag Tag in play.
- \param npLeft Left node to split.
- \param npRight Right node to split.
- \param iSlotNo Slot number for split.
- \param ulPtr Pointer number to insert.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 ulPtr ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbNdxTag * npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
- xbDouble dSplitFactor = .5; // split the nodes 50/50
- xbString sMsg;
-
- try{
- xbInt32 lKeyCnt = GetKeyCount( npLeft );
- xbInt32 lNewLeftKeyCnt = (xbInt32) ((lKeyCnt + 1) * dSplitFactor) + 1;
- xbInt32 lNewRightKeyCnt = lKeyCnt - lNewLeftKeyCnt;
- xbInt16 iSrcPos;
- xbInt16 iCopyLen;
- char *pSrc;
- char *pTrg;
-
- // insert the key into the left node
- if(( iRc = InsertNodeI( vpTag, npLeft, iSlotNo, ulPtr )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- // move the right half of the left node to the right node
- iSrcPos = ((lNewLeftKeyCnt + 1) * npTag->iKeyItemLen) + 4;
- iCopyLen = (lNewRightKeyCnt * npTag->iKeyItemLen) + 4;
- pSrc = npLeft->cpBlockData;
- pSrc += iSrcPos;
- pTrg = npRight->cpBlockData;
- pTrg += 4;
- memmove( pTrg, pSrc, (size_t) iCopyLen );
-
- // write the new key counts into the nodes
- pTrg = npLeft->cpBlockData;
- ePutInt32( pTrg, lNewLeftKeyCnt );
- pTrg = npRight->cpBlockData;
- ePutInt32( pTrg, lNewRightKeyCnt );
-
- // write the new key counts into the nodes
- pTrg = npLeft->cpBlockData;
- ePutInt32( pTrg, lNewLeftKeyCnt );
- pTrg = npRight->cpBlockData;
- ePutInt32( pTrg, lNewRightKeyCnt );
-
- // write out the block
- if(( iRc = WriteBlock( npLeft->ulBlockNo, GetBlockSize(), npLeft->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- // write out the block
- if(( iRc = WriteBlock( npRight->ulBlockNo, GetBlockSize(), npRight->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::SplitNodeI() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Split a leaf node.
-/*!
- This routine splits an index leaf into two nodes, divided by dSplitFactor.<br>
- This behaves differently than V7 Dbase. V7 does not balance the nodes.<br>
- For V7, if adding a key to the end of a node, it will create a right node
- with only one key, and the left node is still full.<br><br>
-
- Possible performance improvement options.<br>
- Two modes when splitting:<br>
- a) Split nodes in the middle - good for random access applications<br>
- b) Split off right node with only one key - good for applications with
- expectation of ascending keys added moving forward.<br>
-
- This routine first inserts the key into the left node in the appropriate location
- then splits the node based on the split factor setting.
-
- \param vpTag Tag in play.
- \param npLeft Left node to split.
- \param npRight Right node to split.
- \param iSlotNo Slot number for split.
- \param ulPtr Pointer number to insert.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight,
- xbInt16 iSlotNo, char * cpKeyBuf, xbUInt32 ulPtr ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbDouble dSplitFactor = .5;
- xbNdxTag *npTag;
- vpTag ? npTag = (xbNdxTag *) vpTag : npTag = ndxTag;
-
- xbString sMsg;
- try{
- xbInt32 lKeyCnt = GetKeyCount( npLeft );
- xbInt32 lNewLeftKeyCnt = (xbInt32) ((lKeyCnt + 1) * dSplitFactor) + 1;
- xbInt32 lNewRightKeyCnt = lKeyCnt + 1 - lNewLeftKeyCnt;
-
- // xbInt16 iSrcPos;
- xbInt16 iLen;
- char *pSrc = npLeft->cpBlockData;
- char *pTrg;
-
- if(( iRc = InsertNodeL( vpTag, npLeft, iSlotNo, cpKeyBuf, ulPtr )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
-
- // move right half off of left node to the right node
- pSrc = npLeft->cpBlockData;
- pSrc += ((lNewLeftKeyCnt * npTag->iKeyItemLen)+4);
- pTrg = npRight->cpBlockData;
- pTrg += 4;
- iLen = lNewRightKeyCnt * npTag->iKeyItemLen;
- memmove( pTrg, pSrc, (size_t) iLen );
-
- // write the new key counts into the nodes
- pTrg = npLeft->cpBlockData;
- ePutInt32( pTrg, lNewLeftKeyCnt );
- pTrg = npRight->cpBlockData;
- ePutInt32( pTrg, lNewRightKeyCnt );
-
- // write out the left block
- if(( iRc = WriteBlock( npLeft->ulBlockNo, GetBlockSize(), npLeft->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- // write out the right block
- if(( iRc = WriteBlock( npRight->ulBlockNo, GetBlockSize(), npRight->cpBlockData )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::SplitNodeL() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief UpdateTagKey
-/*!
- This routine updates a key or a given tag.
- The file header is considered to be the first 2048 bytes in the file.
-
- \param cAction A - Add a key.<br>
- D - Delete a key.<br>
- R - Revise a key.<br>
- \param vpTg - Pointer to tag.<br>
- \param ulRecNo - Record number association with the action.<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbIxNdx::UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo ){
-
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- // ..xbNdxTag *npTag = (xbMdxTag *) vpTag;
-
- try{
- // save off any needed fileds for updating
- // xbUInt32 ulTagSizeSave = mpTag->ulTagSize;
- //xbUInt32 ulLeftChildSave = mpTag->ulLeftChild;
- //xbUInt32 ulRightChildSave = mpTag->ulRightChild;
-
-
- if( cAction == 'D' || cAction == 'R' ){
-// std::cout << "UpdateTagKey delete\n";
- if(( iRc = DeleteKey( vpTag )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- }
-
- if( cAction == 'A' || cAction == 'R' ){
- if(( iRc = AddKey( vpTag, ulRecNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::UpdateTagKey() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-//! @brief Write head block.
-/*!
- Commit the index head node to disk.
- \param iOpt 0 - Entire header.<br>
- 1 - Update root block, number of blocks and seq number.<br>
- 2 - Update sequence number only<br>
- \returns <a href="xbretcod_8h.html">
-*/
-
-xbInt16 xbIxNdx::WriteHeadBlock( xbInt16 iOpt ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- if( iOpt == 2 ){
-
- // increment the serial number
- if( ndxTag->cSerNo >= 0 && ndxTag->cSerNo < 127 )
- ndxTag->cSerNo++;
- else
- ndxTag->cSerNo = 0;
-
- if(( iRc = xbFseek( 20, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if(( iRc = xbFputc( ndxTag->cSerNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- } else if( iOpt == 1 ){
- xbRewind();
- char buf[8];
- ePutUInt32( &buf[0], ndxTag->ulRootBlock );
- ePutUInt32( &buf[4], ndxTag->ulTotalBlocks );
- if(( iRc = xbFwrite( buf, 8, 1 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- return WriteHeadBlock( 2 );
-
- } else if ( iOpt == 0 ){
-
- char buf[512];
- memset( buf, 0x00, 512 );
- ePutUInt32( &buf[0], ndxTag->ulRootBlock );
- ePutUInt32( &buf[4], ndxTag->ulTotalBlocks );
- buf[9] = ndxTag->cKeyType;
- buf[11] = 0x1B;
- ePutInt16( &buf[12], ndxTag->iKeyLen );
- ePutInt16( &buf[14], ndxTag->iKeysPerBlock );
- ePutInt16( &buf[16], ndxTag->iKeyType );
- ePutInt16( &buf[18], ndxTag->iKeyItemLen );
- if( ndxTag-> iUnique ) buf[23] = 0x01;
-
- for( xbUInt32 i = 0; i < ndxTag->sKeyExpression.Len(); i++ )
- buf[i+24] = ndxTag->sKeyExpression.GetCharacter(i+1);
-
- xbRewind();
- if(( iRc = xbFwrite( buf, 512, 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- } else {
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxNdx::WriteHeadBlock() Exception Caught. Error Stop = [%d] iRc = [%d] option = [%d] ser=[%d]", iErrorStop, iRc, iOpt, ndxTag->cSerNo );
- xbase->WriteLogMessage( sMsg );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-} /* namespace */
-#endif /* XB_NDX_SUPPORT */
-
-
-
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbixtdx.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbixtdx.cpp
deleted file mode 100755
index 4137725..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbixtdx.cpp
+++ /dev/null
@@ -1,661 +0,0 @@
-/* xbixtdx.cpp
-
-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 module handles temporary index logic
-
-*/
-
-#include "xbase.h"
-
-
-
-#ifdef XB_TDX_SUPPORT
-
-
-namespace xb{
-
-/************************************************************************/
-xbIxTdx::xbIxTdx( xbDbf *dbf ) : xbIxMdx( dbf ) {
-//xbIxMdx::xbIxMdx( xbDbf *dbf ) : xbIx( dbf ){
-
-// std::cout << "xbIxTdx::Constructor()\n";
-
- // Init(); not needed, called in xbMdx
-
-
-}
-
-/************************************************************************/
-xbIxTdx::~xbIxTdx() {
-
-// std::cout << "xbIxTdx::Destructor()\n";
-
-}
-
-/***********************************************************************/
-xbInt16 xbIxTdx::Close(){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
-std::cout << "xbIxTdx::Close\n";
-
- try{
- if(( iRc = xbIxMdx::Close()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if(( iRc = xbRemove()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxTdx::Close() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Create new tag.
-/*!
- This routine creates a new tag. When complete, sets the cur tag pointer to
- the newly created tag.
-
-
- \param sName Tag Name, including .MDX suffix
- \param sKey Key Expression
- \param sFilter Filter expression.
- \param iDescending
- \param iUnique xbtrue - Unique.<br>xbFalse - Not unique.
- \param iOverLay xbTrue - Overlay if file already exists.<br>xbFalse - Don't overlay.
- \param vpTag Output from method Pointer to vptag pointer.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbIxTdx::CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbMdxTag *tte = NULL;
-
- std::cout << "xbIxTdx::CreateTag()\n";
-
-
- // std::cout << "CreateTag() name=[" << sName.Str() << "] key=[" << sKey.Str() << "] sFilter=[" << sFilter.Str() << "]\n";
- // std::cout << "TagUseCnt = " << iTagUseCnt << std::endl;
-
-
- try{
- // verify room for new tag
- if( !( iTagUseCnt < 47 )){
- iErrorStop = 100;
- iRc = XB_LIMIT_REACHED;
- throw iRc;
- }
-
- // verify valid tag name
- xbString sWorker = sName;
- sWorker.Trim();
- if( sWorker.Len() > 10 ){
- iErrorStop = 110;
- iRc = XB_INVALID_TAG;
- throw iRc;
- }
-
- // verify tag not already defined
- if( iTagUseCnt > 0 ){
- if( GetTag( sWorker )){
- iErrorStop = 120;
- iRc = XB_INVALID_TAG;
- throw iRc;
- }
- }
-
- // allocate a tag structure here
- if(( tte = (xbMdxTag *) calloc( 1, (size_t) sizeof( xbMdxTag ))) == NULL ){
- iErrorStop = 130;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- *vpTag = tte;
- tte->sTagName = new xbString( sWorker );
-
- //set up the key expression
- sWorker = sFilter;
- sWorker.Trim();
- if( sWorker.Len() > 0 ){
- if( sWorker.Len() == 0 || sWorker.Len() > 220 ){
- iRc = XB_INVALID_TAG;
- iErrorStop = 140;
- throw iRc;
- }
- tte->sFiltExp = new xbString( sWorker );
- tte->filter = new xbExp( dbf->GetXbasePtr());
- if(( iRc = tte->filter->ParseExpression( dbf, sWorker )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
-
- // tte->filter->DumpTree( 1 );
-
- if((tte->filter->GetReturnType()) != 'L' ){
- iRc = XB_INVALID_TAG;
- iErrorStop = 160;
- throw iRc;
- }
- tte->cHasFilter = 0x01;
- }
-
- //set up the key expression
- sWorker = sKey;
- sWorker.Trim();
- if( sWorker.Len() == 0 || sWorker.Len() > 100 ){
- iRc = XB_INVALID_TAG;
- iErrorStop = 170;
- throw iRc;
- }
- tte->sKeyExp = new xbString( sWorker );
- tte->exp = new xbExp( dbf->GetXbasePtr());
- if(( iRc = tte->exp->ParseExpression( dbf, sWorker )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
-
- xbDate d;
- d.Sysdate();
- if( iTagUseCnt == 0 ){
- // first tag, new mdx file
- // create the file name
-
- // create temp file
- xbString sIxFileName;
- if(( iRc = CreateUniqueFileName( GetTempDirectory(), "TDX", sIxFileName )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
-
- // copy the file name to the class variable
- this->SetFileName( sIxFileName );
- if( FileExists() && !iOverlay ){
- iErrorStop = 200;
- iRc = XB_FILE_EXISTS;
- throw iRc;
- }
-
- // first tag, need to create the file
- if(( iRc = xbFopen( "w+b", dbf->GetShareMode())) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- cVersion = 2;
- cCreateYY = (char) d.YearOf() - 1900;
- cCreateMM = (char) d.MonthOf();
- cCreateDD = (char) d.DayOf( XB_FMT_MONTH );
-
- GetFileNamePart( sFileName );
- sFileName.ToUpperCase();
-
- SetBlockSize( (xbUInt32) dbf->GetCreateMdxBlockSize());
- iBlockFactor = GetBlockSize() / 512;
-
- cProdIxFlag = 0; // MDX is 1
- cTagEntryCnt = 48;
- iTagLen = 32;
- ulPageCnt = 4;
- ulFirstFreePage = 0;
- ulNoOfBlockAvail = 0;
- cNextTag = 1;
- c1B = 0x1B;
- cUpdateYY = cCreateYY;
- cUpdateMM = cCreateMM;
- cUpdateDD = cCreateDD;
-
- if(( iRc = WriteHeadBlock( 0 )) != XB_NO_ERROR ){
- iErrorStop = 220;
- throw iRc;
- }
- }
-
- // populate the tag table entry structure
- tte->ulTagHdrPageNo = ulPageCnt;
- ulPageCnt += (xbUInt32) iBlockFactor;
- tte->sTagName->strncpy( tte->cTagName, 10 );
-
- // cKeyFmt is always 0x10;
- // tested 2+ZIPCD CITY+STATE or just standalone field - always 0x10
- tte->cKeyFmt = 0x10; // = CalcTagKeyFmt( *tte->exp );
-
- switch( tte->exp->GetReturnType()){
- case XB_EXP_CHAR:
- tte->cKeyType = 'C';
- tte->iKeyLen = tte->exp->GetResultLen();
- tte->iSecKeyType = 0;
- break;
-
- case XB_EXP_NUMERIC:
- tte->cKeyType = 'N';
- tte->iKeyLen = 12;
- tte->iSecKeyType = 0;
- break;
-
- case XB_EXP_DATE:
- tte->cKeyType = 'D';
- tte->iKeyLen = 8;
- tte->iSecKeyType = 1;
- break;
-
- default:
- iErrorStop = 200;
- iRc = XB_INVALID_INDEX;
- throw iRc;
- }
-
- tte->cpKeyBuf = (char *) malloc( (size_t) tte->iKeyLen + 1 );
- tte->cpKeyBuf2 = (char *) malloc( (size_t) tte->iKeyLen + 1 );
-
-// if( 0 ){
-// printf( "ulTagHdrPageNo=[%d] cTagName=[%-11s], cLeftChild=[%d] cRightChild=[%d] cParent=[%d] cKeyType=[%c]\n\n",
-// tte->ulTagHdrPageNo, tte->cTagName, tte->cLeftChild, tte->cRightChild, tte->cParent, tte->cKeyType );
-// }
-
- // write the new tte entry here
- char tteBuf[21];
- memset( tteBuf, 0x00, 21 );
-
- ePutUInt32( &tteBuf[0], tte->ulTagHdrPageNo );
- for( xbUInt32 l = 0; l < tte->sTagName->Len() && l < 10; l++ ){
- tteBuf[l+4] = tte->sTagName->GetCharacter(l+1);
- }
- tteBuf[15] = tte->cKeyFmt;
- tteBuf[19] = 0x02; // appears to always be a 0x02
- tteBuf[20] = tte->cKeyType;
-
- if(( iRc = xbFseek( (iTagUseCnt * 32) + 544, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 230;
- throw iRc;
- }
- if(( iRc = xbFwrite( tteBuf, 21, 1 )) != XB_NO_ERROR ){
- iErrorStop = 240;
- throw iRc;
- }
-
-
- // Begin Tag Header
- tte->ulRootPage = ulPageCnt;
- tte->ulTagSize = (xbUInt32) iBlockFactor;
- ulPageCnt += 2;
- tte->cKeyFmt2 = 0x10;
- if( iDescending )
- tte->cKeyFmt2 += 0x08;
- if( iUnique ){
- tte->cKeyFmt2 += 0x40;
- tte->cUnique = 0x01;
- }
-
- tte->cTag11 = 0x1B; // always 0x1b ?
- tte->cSerialNo = 0x01; // version incremented with each tag update
- tte->ulLeftChild = tte->ulRootPage;
- tte->ulRightChild = tte->ulRootPage;
-
- tte->cTagYY = (char) d.YearOf() - 1900;
- tte->cTagMM = (char) d.MonthOf();
- tte->cTagDD = (char) d.DayOf( XB_FMT_MONTH );
-
- tte->cKeyType2 = tte->cKeyType;
- tte->iKeyItemLen = tte->iKeyLen + 4;
- while(( tte->iKeyItemLen % 4 ) != 0 ) tte->iKeyItemLen++;
-
- tte->iKeysPerBlock = (xbInt16) (GetBlockSize() - 12) / tte->iKeyItemLen;
-
- //std::cout << "-------------- create tag info\n";
- //std::cout << "keylen=" << tte->iKeyLen << " iKeyItemLen = " << tte->iKeyItemLen << " keys per block calc = " << tte->iKeysPerBlock << "\n";
-
- tte->cKeyFmt3 = CalcTagKeyFmt( *tte->exp );
-
-// printf( "ulRootPage=[%d] cKeyFmt2=[%d] cKeyType2=[%d] iKeyLen=[%d]iKeysPerBlock=[%d]\n", tte->ulRootPage, tte->cKeyFmt2, tte->cKeyType2, tte->iKeyLen, tte->iKeysPerBlock );
-// printf( "iSecKeyType=[%d] iKeyItemLen=[%d] cUnique=[%d] \n", tte->iSecKeyType, tte->iKeyItemLen, tte->cUnique );
-
- char *pBuf;
- if(( pBuf = (char *) calloc( 1, (size_t) GetBlockSize())) == NULL ){
- iErrorStop = 230;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- char *wPtr;
- wPtr = pBuf;
- ePutUInt32( wPtr, tte->ulRootPage );
-
- wPtr += 4;
- ePutUInt32( wPtr, tte->ulTagSize );
-
- wPtr += 4;
- *wPtr = tte->cKeyFmt2;
-
- wPtr++;
- *wPtr = tte->cKeyType2;
-
- wPtr += 2;
- *wPtr = tte->cTag11;
-
- wPtr += 1;
- ePutInt16( wPtr, tte->iKeyLen );
-
- wPtr += 2;
- ePutInt16( wPtr, tte->iKeysPerBlock );
-
- wPtr += 2;
- ePutInt16( wPtr, tte->iSecKeyType );
-
- wPtr += 2;
- ePutInt16( wPtr, tte->iKeyItemLen );
-
- wPtr += 2;
- *wPtr = tte->cSerialNo;
-
- wPtr += 3;
- *wPtr = tte->cUnique;
-
- wPtr++;
- for( xbUInt32 l = 0; l < tte->sKeyExp->Len(); l++ )
- *wPtr++ = tte->sKeyExp->GetCharacter(l+1);
-
- wPtr = pBuf;
-
- tte->cHasKeys = 0x00;
- pBuf[246] = tte->cHasKeys;
-
- wPtr += 248;
- ePutUInt32( wPtr, tte->ulLeftChild );
- wPtr += 4;
- ePutUInt32( wPtr, tte->ulRightChild );
-
- pBuf[257] = tte->cTagYY;
- pBuf[258] = tte->cTagMM;
- pBuf[259] = tte->cTagDD;
- pBuf[480] = tte->cKeyFmt3;
-
- if( sFilter.Len() > 0 ){
- pBuf[245] = tte->cHasFilter;
- wPtr = pBuf;
- wPtr += 762;
- for( xbUInt32 l = 0; l < sFilter.Len(); l++ )
- *wPtr++ = sFilter.GetCharacter(l+1);
- }
-
- if(( iRc = xbFseek( tte->ulTagHdrPageNo * 512, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 250;
- throw iRc;
- }
-
- if(( iRc = xbFwrite( pBuf, GetBlockSize(), 1 )) != XB_NO_ERROR ){
- iErrorStop = 260;
- throw iRc;
- }
-
- memset( pBuf, 0x00, GetBlockSize() );
- if(( iRc = xbFwrite( pBuf, GetBlockSize(), 1 )) != XB_NO_ERROR ){
- iErrorStop = 270;
- throw iRc;
- }
-
- iTagUseCnt++;
- cNextTag++;
-
-
- if(( iRc = WriteHeadBlock( 1 )) != XB_NO_ERROR ){
- iErrorStop = 280;
- throw iRc;
- }
-
- // add the new entry to the end of the list of tags
- if( mdxTagTbl == NULL ){
- mdxTagTbl = tte;
- } else {
- xbMdxTag *tteL = mdxTagTbl;
- while( tteL->next )
- tteL = tteL->next;
- tteL->next = tte;
- }
-
- /* update the btree pointers */
- CalcBtreePointers();
- char bBuf[3];
- xbMdxTag *tteWork = mdxTagTbl;
-
- if(( iRc = xbFseek( 560, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 290;
- throw iRc;
- }
- while( tteWork ){
- bBuf[0] = tteWork->cLeftChild;
- bBuf[1] = tteWork->cRightChild;
- bBuf[2] = tteWork->cParent;
-
- if(( iRc = xbFwrite( bBuf, 3, 1 )) != XB_NO_ERROR ){
- iErrorStop = 300;
- throw iRc;
- }
- if( tteWork->next ){
- if(( iRc = xbFseek( 29, SEEK_CUR )) != XB_NO_ERROR ){
- iErrorStop = 310;
- throw iRc;
- }
- }
- tteWork = tteWork->next;
- }
- free( pBuf );
-
- }
-
- catch (xbInt16 iRc ){
- if( tte ){
- if( tte->cpKeyBuf )
- free( tte->cpKeyBuf );
- if( tte->cpKeyBuf2 )
- free( tte->cpKeyBuf2 );
- if( tte->exp )
- delete tte->exp;
- if( tte->filter )
- delete tte->filter;
- if( tte->sKeyExp )
- delete tte->sKeyExp;
- if( tte->sFiltExp )
- delete tte->sFiltExp;
- if( tte->sTagName )
- delete tte->sTagName;
- free( tte );
- }
- xbString sMsg;
- sMsg.Sprintf( "xbIxTdx::CreateTag() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
-
- return iRc;
-};
-
-/***********************************************************************/
-//! @brief Delete a given tag
-/*!
- \param vpTag Input tag ptr for tag to be deleted<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a><br>
- 1 = Deleted entire MDX file, only had one tag
-
-*/
-
-xbInt16 xbIxTdx::DeleteTag( void *vpTag ){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbMdxTag * mpTag = (xbMdxTag *) vpTag;
- xbIxNode *n = NULL;
- xbBool bLoneTag = xbFalse;
-
- try{
-
- if( !vpTag ){
- iErrorStop = 100;
- iRc = XB_INVALID_TAG;
- throw iRc;
- }
-
- // char cSaveHasFilter = mpTag->cHasFilter;
- // char cSaveKeyFmt3 = mpTag->cKeyFmt3;
- // xbString sSaveKey = mpTag->sKeyExp->Str();
-
- if( iTagUseCnt == 1 ){
- // std::cout << "xbIxTdx::DeleteTag - one tag found, delete the mdx file\n";
-
- // close the mdx file
- if(( iRc = xbIxMdx::Close()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
-
- // delete the file
- xbRemove();
-
- // init variables - needed?
- // Init();
- // iRc > 0 defines this as the only tag in an MDX file, MDX file deleted.
- // signals to the calling process to drop the MDX file from the
- // list of updateable indices.
- bLoneTag = xbTrue;
-
- } else {
-
- // harvest tag nodes
-
- if(( iRc = HarvestTagNodes( mpTag, xbTrue )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- // remove an entry from tag table
- // which tag is this?
- xbInt16 iTagNo = 0;
- xbMdxTag *mp = mdxTagTbl;
- xbMdxTag *mpPrev = NULL;
- while( mp && mp->ulTagHdrPageNo != mpTag->ulTagHdrPageNo ){
- iTagNo++;
- mpPrev = mp;
- mp = mp->next;
- }
-
- // remove it from the linked list of tags
- if( !mpPrev ){
- mdxTagTbl = mp->next;
- } else {
- mpPrev->next = mp->next;
- }
- if( mp ){
- if( mp->cpKeyBuf ) free( mp->cpKeyBuf );
- if( mp->cpKeyBuf2 ) free( mp->cpKeyBuf2 );
- if( mp->exp ) delete mp->exp;
- if( mp->filter ) delete mp->filter;
- if( mp->sKeyExp ) delete mp->sKeyExp;
- if( mp->sFiltExp ) delete mp->sFiltExp;
- if( mp->sTagName ) delete mp->sTagName;
- free( mp );
- }
- xbInt32 iTarg = iTagNo * 32;
- xbInt32 iSrc = iTarg + 32;
- xbInt32 iLen = (iTagUseCnt - iTagNo) * 32;
-
- if(( iRc = xbFseek( 544, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- char Buf[1536]; // 47 tags + 1 in case tag #47 is deleted
- memset( Buf, 0x00, 1536 );
- if(( iRc = xbFread( Buf, 1504, 1 )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- char *pTrg = Buf;
- pTrg += iTarg;
- char *pSrc = Buf;
- pSrc += iSrc;
- for( xbInt32 i = 0; i < iLen; i++ )
- *pTrg++ = *pSrc++;
-
- if(( iRc = xbFseek( 544, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
- if(( iRc = xbFwrite( Buf, 1504, 1 )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
-
- iTagUseCnt--;
- if(( iRc = WriteHeadBlock( 1 )) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw iRc;
- }
-
- // update the btree pointers
- CalcBtreePointers();
- char bBuf[3];
- xbMdxTag *tteWork = mdxTagTbl;
-
- if(( iRc = xbFseek( 560, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
- while( tteWork ){
- bBuf[0] = tteWork->cLeftChild;
- bBuf[1] = tteWork->cRightChild;
- bBuf[2] = tteWork->cParent;
-
- if(( iRc = xbFwrite( bBuf, 3, 1 )) != XB_NO_ERROR ){
- iErrorStop = 320;
- throw iRc;
- }
- if( tteWork->next ){
- if(( iRc = xbFseek( 29, SEEK_CUR )) != XB_NO_ERROR ){
- iErrorStop = 330;
- throw iRc;
- }
- }
- tteWork = tteWork->next;
- }
- }
-
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbIxTdx::DeleteTag() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- if( n )
- free( n );
- }
- if( bLoneTag && !iRc )
- return 1;
- else
- return iRc;
-}
-
-/************************************************************************/
-
-
-
-/************************************************************************/
-} /* namespace */
-#endif /* XB_TDX_SUPPORT */ \ No newline at end of file
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xblog.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xblog.cpp
deleted file mode 100755
index 9443006..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xblog.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-/* xblog.cpp
-
-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 "xbase.h"
-//#include <time.h>
-
-#ifdef XB_LOGGING_SUPPORT
-
-namespace xb{
-
-/******************************************************************************/
-//! @brief Constructor.
-xbLog::xbLog() : xbFile( NULL ){
-
-
- // std::cout << "xbLog::xbLog(1) Directory = [" << GetLogDirectory() << "]\n";
- // std::cout << "xbLog::xbLog(1) Name = [" << GetLogFileName() << "]\n";
-
- SetDirectory( GetLogDirectory());
- SetFileName ( GetLogFileName());
-
- bLoggingStatus = xbFalse;
- lLogSize = 100000;
-
- #ifdef XB_LOCKING_SUPPORT
- iShareMode = XB_MULTI_USER;
- #else
- iShareMode = XB_SINGLE_USER;
- #endif
-}
-/******************************************************************************/
-//! @brief Constructor.
-/*!
- \param sLogFileName - Log file name.
-*/
-xbLog::xbLog( const xbString & sLogFileName ) : xbFile( NULL ){
- if( sLogFileName.GetPathSeparator())
- SetFqFileName( sLogFileName ); // file name includes a path
- else
- SetFileName( sLogFileName ); // no file path
-
- bLoggingStatus = xbFalse;
- lLogSize = 100000;
-
- #ifdef XB_LOCKING_SUPPORT
- iShareMode = XB_MULTI_USER;
- #else
- iShareMode = XB_SINGLE_USER;
- #endif
-
-}
-/******************************************************************************/
-//! @brief Deconstructor.
-xbLog::~xbLog(){
- xbFclose();
-}
-/******************************************************************************/
-//! @brief Get the current log status
-/*!
- \returns xbTrue - Logging turned on.<br>xbFalse - Logging turned off.
-*/
-xbBool xbLog::LogGetStatus(){
- return bLoggingStatus;
-}
-/******************************************************************************/
-//! @brief Close the logfile.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbLog::LogClose(){
- return xbFclose();
-}
-/******************************************************************************/
-//! @brief Set maximum log file size.
-/*!
- \param lSize - New maximum log file size.
- \returns void
-*/
-void xbLog::LogSetLogSize( size_t lSize ){
- lLogSize = lSize;
-}
-/******************************************************************************/
-//! @brief Set log status.
-/*!
- \param bStatus xbTrue - Turn logging on.<br>xbFalse - Turn logging off.
- \returns void
-*/
-void xbLog::LogSetStatus( xbBool bStatus ){
- if( bLoggingStatus && !bStatus )
- LogClose();
- bLoggingStatus = bStatus;
-}
-/******************************************************************************/
-//! @brief Open the logfile.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbLog::LogOpen(){
- xbInt16 rc;
-
-// std::cout << "*****\nxbLog::LogOpen(1) GetLogDirectory = " << GetLogDirectory() << "\n";
-// std::cout << "xbLog::LogOpen(1) GetLogFileName = " << GetLogFileName() << "\n";
-// std::cout << "xbLog::GetFqFileName(1) = " << GetFqFileName() << "\n\n";
-
- // 4.1.3 added next two lines for dynamic log file name changing
- SetDirectory( GetLogDirectory());
- SetFileName ( GetLogFileName());
-
-// std::cout << "*****\nxbLog::LogOpen(2) GetLogDirectory = " << GetLogDirectory() << "\n";
-// std::cout << "xbLog::LogOpen(2) GetLogFileName = " << GetLogFileName() << "\n";
-// std::cout << "xbLog::GetFqFileName(2) = " << GetFqFileName() << "\n\n";
-
- if(( rc = xbFopen( "a", iShareMode )) != XB_NO_ERROR )
- return rc;
- xbFTurnOffFileBuffering();
- return XB_NO_ERROR;
-}
-/******************************************************************************/
-//! @brief Write a logfile message.
-/*!
- \param sLogEntryData - Message to write to the logfile.
- \param iOutputOption 0 - Write to logfile.<br>
- 1 - Write to stdout.<br>
- 2 - Write to both logfile and stdout.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbLog::LogWrite( const xbString &sLogEntryData, xbInt16 iOutputOption ){
-
- if( bLoggingStatus == xbFalse ){ // logging turned off
- return XB_NO_ERROR;
- }
- xbInt16 rc = 0;
- if( iOutputOption != 1 && !FileIsOpen() ){
- if(( rc = LogOpen()) != XB_NO_ERROR ){
- fprintf( stderr, "Error - cant write to logfile\n" );
- return rc;
- }
- }
- if( iOutputOption != 1 && lLogSize < xbFtell()){
- xbFputs( "Swapping to next log file" );
- xbFclose();
- xbString sBackupName;
- sBackupName.Sprintf( "%s.bak", GetFqFileName().Str());
- if( FileExists( sBackupName ))
- xbRemove( sBackupName );
-
- xbRename( GetFqFileName(), sBackupName );
- xbFopen( "a", iShareMode );
- }
- xbString sTimeStamp;
- xbString sFled; // formatted log entry data
-
- if( iOutputOption != 1 ){
- #ifdef HAVE__LOCALTIME64_S_F
- __time64_t timer;
- struct tm tb;
- _time64( &timer );
- _localtime64_s( &tb, &timer );
- tb.tm_year += 1900;
- tb.tm_mon++;
- sTimeStamp.Sprintf( "%4d-%02d-%02d %02d:%02d:%02d", tb.tm_year, tb.tm_mon, tb.tm_mday, tb.tm_hour, tb.tm_min, tb.tm_sec );
- #else
- time_t timer;
- struct tm *tb;
- timer = time( NULL );
- tb = localtime( &timer );
- tb->tm_year += 1900;
- tb->tm_mon++;
- sTimeStamp.Sprintf( "%4d-%02d-%02d %02d:%02d:%02d", tb->tm_year, tb->tm_mon, tb->tm_mday, tb->tm_hour, tb->tm_min, tb->tm_sec );
- #endif
- sFled.Sprintf( "%s - %s\n", sTimeStamp.Str(), sLogEntryData.Str() );
- }
-
- switch( iOutputOption ){
- case 0:
- xbFputs( sFled );
- break;
- case 1:
- std::cout << sLogEntryData << std::endl;
- break;
- case 2:
- xbFputs( sFled );
- std::cout << sLogEntryData << std::endl;
- break;
- }
- return XB_NO_ERROR;
-}
-/******************************************************************************/
-//! @brief Write bytes to logfile.
-/*!
- \param ulByteCnt - Number of bytes to write to logfile.
- \param p - Pointer to data to write to logfile.
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbLog::LogWriteBytes( xbUInt32 ulByteCnt, const char *p ){
-
- if( bLoggingStatus == xbFalse ) // logging turned off
- return XB_NO_ERROR;
- const char *p2 = p;
- xbFputc( '[' );
- for( xbUInt32 l = 0; l < ulByteCnt; l++ )
- xbFputc( *p2++ );
- xbFputc( ']' );
- return XB_NO_ERROR;
-}
-/******************************************************************************/
-} // namespace
-#endif // XB_LOGGING_ON
-
-
-
-
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo.cpp
deleted file mode 100755
index 406a77d..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/* xbmemo.cpp
-
-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
-
- Base memo class
-*/
-
-#include "xbase.h"
-
-#ifdef XB_MEMO_SUPPORT
-
-namespace xb{
-
-/***********************************************************************/
-//! @brief Class Constructor.
-/*!
- \param dbf Pointer to dbf construct.
- \param sFileName Memo file name.
-*/
-
-xbMemo::xbMemo( xbDbf * dbf, xbString const &sFileName ) : xbFile( dbf->GetXbasePtr() ) {
- this->dbf = dbf; /* pointer to the associated dbf class instance */
- // xbase = dbf->GetXbasePtr(); /* pointer to the engine */
- SetDirectory( dbf->GetDirectory());
- SetFileName( sFileName );
- mbb = NULL;
- #ifdef XB_LOCKING_SUPPORT
- bFileLocked = xbFalse;
- #endif
-}
-/***********************************************************************/
-//! @brief Class Destructor.
-xbMemo::~xbMemo(){
- if( mbb )
- free( mbb );
-}
-/***********************************************************************/
-//! @brief Calculate the last data block number.
-/*!
- \param ulLastDataBlock Output - Last used block number in the file.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemo::CalcLastDataBlock( xbUInt32 & ulLastDataBlock ){
-
- xbInt16 iRc = XB_NO_ERROR;
- if(( iRc = xbFseek( 0, SEEK_END )) != XB_NO_ERROR )
- return iRc;
-
- ulLastDataBlock = (xbUInt32) xbFtell() / (xbUInt32) GetBlockSize();
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! @brief Close the memo file.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemo::CloseMemoFile(){
-
- if( mbb ){
- free( mbb );
- mbb = NULL;
- }
- return xbFclose();
-}
-
-
-/***********************************************************************/
-//! @brief Get memo file type.
-/*!
- \returns 3 - Version 3 memo file.<br>
- 4 - Version 4 memo file.
-*/
-xbInt16 xbMemo::GetMemoFileType(){
- return iMemoFileType;
-}
-
-/***********************************************************************/
-//! @brief Get next block available from file header.
-/*!
- \param ulBlockNo Output - Next block number for appending data to memo file.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemo::GetHdrNextBlock( xbUInt32 & ulBlockNo ){
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
- if(( iRc = ReadDbtHeader( 0 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- ulBlockNo = ulHdrNextBlock;
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbmemo::GetNextAvailableBlock() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-#ifdef XB_LOCKING_SUPPORT
-//! @brief Lock memo file
-/*!
-
- \param iLockFunction XB_LOCK<br>XB_UNLOCK
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemo::LockMemo( xbInt16 iLockFunction ){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- if( iLockFunction == XB_LOCK ){
-
- if( bFileLocked ) // already locked
- return XB_NO_ERROR;
-
- if( dbf->GetLockFlavor() == LK_DBASE ){
- iRc = xbLock( XB_LOCK, LK4026531838, 1 );
- if( iRc != XB_NO_ERROR ){
- if( iRc == XB_LOCK_FAILED )
- return iRc;
- else {
- iErrorStop = 100;
- throw iRc;
- }
- } else {
- bFileLocked = xbTrue;
- }
- }
- } else if( iLockFunction == XB_UNLOCK ){
-
- if( !bFileLocked ) // already unlocked
- return XB_NO_ERROR;
-
- if( dbf->GetLockFlavor() == LK_DBASE ){
- iRc = xbLock( XB_UNLOCK, LK4026531838, 1 );
- if( iRc != XB_NO_ERROR ){
- if( iRc == XB_LOCK_FAILED )
- return iRc;
- else {
- iErrorStop = 110;
- throw iRc;
- }
- } else {
- bFileLocked = xbFalse;
- }
- }
- } else {
- iErrorStop = 120;
- iRc = XB_INVALID_OPTION;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbmemo::LockMemoFile() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Get memo file lock status.
-/*!
- \returns xbTrue - Memo file is locked.<br>
- xbFalse - Memo file is not locked.
-*/
-xbBool xbMemo::GetMemoLocked() const {
- return bFileLocked;
-}
-#endif
-
-/***********************************************************************/
-//! @brief Update Next Node number in file header
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemo::UpdateHeadNextNode(){
-
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- try{
- char buf[4];
- ePutUInt32( buf, ulHdrNextBlock );
- if(( iRc = xbFseek( 0, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if(( iRc = xbFwrite( &buf, 4, 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbmemo::UpdateHeadeNextNode() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-} /* namespace */
-#endif /* XB_MEMO_SUPPORT */
-
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo3.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo3.cpp
deleted file mode 100755
index 767e9d2..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo3.cpp
+++ /dev/null
@@ -1,585 +0,0 @@
-/* xbmemo3.cpp
-
-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 is used for support dBASE V3 memo files
-
-*/
-
-#include "xbase.h"
-
-#ifdef XB_MEMO_SUPPORT
-#ifdef XB_DBF3_SUPPORT
-
-namespace xb{
-
-/***********************************************************************/
-//! @brief Class Constructor.
-/*!
- \param dbf Pointer to dbf instance.
- \param sFileName Memo file name.
-*/
-xbMemoDbt3::xbMemoDbt3( xbDbf * dbf, xbString const & sFileName ) : xbMemo( dbf, sFileName ){
- iMemoFileType = 3;
- SetBlockSize( 512 );
-}
-
-/***********************************************************************/
-//! @brief Class Deconstructor.
-xbMemoDbt3::~xbMemoDbt3(){}
-
-/***********************************************************************/
-//! @brief Abort.
-/*!
- Abort any pending updates to the memo file.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt3::Abort(){
- return XB_NO_ERROR;
-}/***********************************************************************/
-//! @brief Commit changes to memo file.
-/*!
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbMemoDbt3::Commit(){
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! @brief Create memo file.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt3::CreateMemoFile(){
-
- xbInt16 rc = XB_NO_ERROR;
- char cBuf[4];
- if(( rc = xbFopen( "w+b", dbf->GetShareMode())) != XB_NO_ERROR )
- return rc;
- ulHdrNextBlock = 1L;
- ePutUInt32( cBuf, ulHdrNextBlock );
- if(( rc = xbFwrite( cBuf, 4, 1 ))!= XB_NO_ERROR ){
- xbFclose();
- return rc;
- }
- for(int i = 0; i < 12; i++ )
- xbFputc( 0x00 );
- xbFputc( 0x03 );
- for(int i = 0; i < 495; i++ )
- xbFputc( 0x00 );
- if(( mbb = (void *) malloc( 512 )) == NULL ){
- xbFclose();
- return XB_NO_MEMORY;
- }
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-//! @brief Dump memo file header.
-/*!
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt3::DumpMemoFreeChain() {
- std::cout << "Xbase version 3 file - no free block chain" << std::endl;
- return XB_NO_ERROR;
-}
-#endif // XB_DEBUG_SUPPORT
-
-//! @brief Dump memo file header.
-/*!
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt3::DumpMemoHeader(){
- xbInt16 rc = XB_NO_ERROR;
- xbUInt64 stFileSize;
- if(( rc = ReadDbtHeader( 1 )) != XB_NO_ERROR )
- return rc;
- GetFileSize( stFileSize );
- std::cout << "Version 3 Memo Header Info" << std::endl;
- std::cout << "Memo File Name = " << GetFqFileName() << std::endl;
- std::cout << "Next Available Block = " << ulHdrNextBlock << std::endl;
- std::cout << "Memo File Version = " << (xbInt16) cVersion << " (";
- BitDump( cVersion );
- std::cout << ")" << std::endl;
- std::cout << "Block Size = " << GetBlockSize() << std::endl;
- std::cout << "File Size = " << stFileSize << std::endl;
- std::cout << "Block Count = " << stFileSize / GetBlockSize() << std::endl;
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! @brief Get a memo field for a given field number.
-/*!
- \param iFieldNo Field number to retrieve data for.
- \param sMemoData Output - string containing memo field data.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt3::GetMemoField( xbInt16 iFieldNo, xbString & sMemoData ){
-
- xbInt16 iErrorStop = 0;
- xbInt16 rc = XB_NO_ERROR;
- xbUInt32 ulScnt;
- char *sp, *spp;
- xbUInt32 ulBlockNo;
- xbBool bDone = xbFalse;
- sMemoData = "";
- try{
-
- if(( rc = dbf->GetULongField( iFieldNo, ulBlockNo )) < XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
-
- if( ulBlockNo == 0L ){
- sMemoData = "";
- return XB_NO_ERROR;
- }
- spp = NULL;
-
- while( !bDone ){
- if(( rc = ReadBlock( ulBlockNo++, GetBlockSize(), mbb )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- ulScnt = 0;
- sp = (char *) mbb;
- while( ulScnt < 512 && !bDone ){
- if( *sp == 0x1a && *spp == 0x1a )
- bDone = xbTrue;
- else{
- ulScnt++; spp = sp; sp++;
- }
- }
- sMemoData.Append( (char *) mbb, ulScnt );
- }
- sMemoData.ZapTrailingChar( 0x1a );
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt3::GetMemoField() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Get a memo field length for a given field number.
-/*!
- \param iFieldNo Field number to retrieve data for.
- \param ulFieldLen Output - length of memo field data.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemoDbt3::GetMemoFieldLen( xbInt16 iFieldNo, xbUInt32 & ulFieldLen ){
-
- xbInt16 iErrorStop = 0;
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iScnt;
- char *sp, *spp;
- xbUInt32 ulBlockNo;
- xbInt16 iNotDone;
- try{
- if(( rc = dbf->GetULongField( iFieldNo, ulBlockNo )) < XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if( ulBlockNo == 0 ){
- ulFieldLen = 0;
- return XB_NO_ERROR;
- }
- ulFieldLen = 0L;
- spp = NULL;
- iNotDone = 1;
- while( iNotDone ){
- if(( rc = ReadBlock( ulBlockNo++, GetBlockSize(), mbb )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- iScnt = 0;
- sp = (char *) mbb;
- while( iScnt < 512 && iNotDone ){
- if( *sp == 0x1a && *spp == 0x1a )
- iNotDone = 0;
- else{
- ulFieldLen++; iScnt++; spp = sp; sp++;
- }
- }
- }
- if( ulFieldLen > 0 ) ulFieldLen--;
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt3::GetMemoFieldLen() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Open memo file.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt3::OpenMemoFile() {
- xbInt16 rc = XB_NO_ERROR;
- if(( rc = xbFopen( dbf->GetOpenMode(), dbf->GetShareMode())) != XB_NO_ERROR )
- return rc;
- if(( mbb = (void *) malloc( 512 )) == NULL ){
- xbFclose();
- return XB_NO_MEMORY;
- }
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! @brief Pack memo file.
-/*!
- This routine frees up any unused blocks in the file resulting from field updates.
- Version 3 memo files do not reclaim unused space (Version 4 files do).
- This routine cleans up the unused space.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemoDbt3::PackMemo( void (*memoStatusFunc ) ( xbUInt32 ulItemNum, xbUInt32 ulNumItems ))
-{
- xbInt16 iRc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char * cBlock = NULL;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bTableLocked = xbFalse;
- xbBool bMemoLocked = xbFalse;
- #endif
-
- try{
-
- #ifdef XB_LOCKING_SUPPORT
- if( dbf->GetAutoLock() && !dbf->GetTableLocked() ){
- if(( iRc = dbf->LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- } else {
- bTableLocked = xbTrue;
- }
- if(( iRc = LockMemo( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- } else {
- bMemoLocked = xbTrue;
- }
- }
- #endif
-
- // create temp file
- xbString sTempMemoName;
- //if(( iRc = CreateUniqueFileName( GetDirectory(), "dbt", sTempMemoName )) != XB_NO_ERROR ){
- if(( iRc = CreateUniqueFileName( GetTempDirectory(), "DBT", sTempMemoName )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- xbMemoDbt3 *pMemo = new xbMemoDbt3( dbf, sTempMemoName );
- if(( iRc = pMemo->CreateMemoFile()) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- // for dbase III, block size is always 512, don't need to reset it
- // for each record in dbf
- xbUInt32 ulRecCnt;
- if(( iRc = dbf->GetRecordCnt( ulRecCnt )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- xbInt32 lFldCnt = dbf->GetFieldCnt();
- char cFldType;
- xbString sMemoFldData;
-
- for( xbUInt32 ulI = 1; ulI <= ulRecCnt; ulI++ ){
-
- if(( iRc = dbf->GetRecord( ulI )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
- if( (void *) memoStatusFunc )
- (*memoStatusFunc) ( ulI, ulRecCnt );
-
- // for each memo field
- for( xbInt32 lFc = 0; lFc < lFldCnt; lFc++ ){
- if(( iRc = dbf->GetFieldType( lFc, cFldType )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
-
-
- if( cFldType == 'M' ){
- // copy it to work field
- if(( iRc = dbf->GetMemoField( lFc, sMemoFldData )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- // write it to new field
- if(( iRc = pMemo->UpdateMemoField( lFc, sMemoFldData )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
- }
- }
- }
-
- //copy target back to source
- xbUInt32 ulBlkSize = GetBlockSize();
- xbUInt64 ullFileSize;
- if(( iRc = pMemo->GetFileSize( ullFileSize )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
- // file size should be evenly divisible by block size
- xbUInt32 ulBlkCnt;
-
- if( ullFileSize % ulBlkSize ){
- iErrorStop = 200;
- throw iRc;
- } else {
- ulBlkCnt = (xbUInt32) (ullFileSize / ulBlkSize);
- }
- if(( iRc = xbTruncate( 0 )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
-
- if(( cBlock = (char *) malloc( (size_t) ulBlkSize )) == NULL ){
- iErrorStop = 220;
- throw iRc;
- }
-
- // can't rename files in a multiuser, cross platform environment, causes issues
- // copy work table back to source table
- for( xbUInt32 ulBc = 0; ulBc < ulBlkCnt; ulBc++ ){
- if(( iRc = pMemo->ReadBlock( ulBc, ulBlkSize, cBlock )) != XB_NO_ERROR ){
- iErrorStop = 230;
- throw iRc;
- }
- if(( iRc = WriteBlock( ulBc, ulBlkSize, cBlock )) != XB_NO_ERROR ){
- iErrorStop = 240;
- throw iRc;
- }
- }
-
- //close and delete target
- if(( iRc = pMemo->xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 250;
- throw iRc;
- }
-
- if(( iRc = pMemo->xbRemove()) != XB_NO_ERROR ){
- iErrorStop = 260;
- throw iRc;
- }
- free( cBlock );
- delete pMemo;
- }
- catch (xbInt16 iRc ){
- free( cBlock );
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt3::PackMemo() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
-
- #ifdef XB_LOCKING_SUPPORT
- if( bTableLocked )
- dbf->LockTable( XB_UNLOCK );
- if( bMemoLocked )
- LockMemo( XB_UNLOCK );
- #endif
- return iRc;
-}
-
-/***********************************************************************/
-//! @brief Read dbt header file.
-/*!
- \param iOption 0 --> read only first four bytes<br>
- 1 --> read the entire thing
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt3::ReadDbtHeader( xbInt16 iOption ){
- char *p;
- char MemoBlock[20];
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulReadSize;
-
- try{
- if( !FileIsOpen() ){
- iErrorStop = 100;
- rc = XB_NOT_OPEN;
- throw rc;
- }
- if( iOption == 0 )
- ulReadSize = 4;
- else{
- xbUInt64 stFileSize = 0;
- if(( rc = GetFileSize( stFileSize )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- if( stFileSize < 4 ){
- iErrorStop = 120;
- rc = XB_INVALID_BLOCK_NO;
- throw rc;
- }
- else if( stFileSize > 20 )
- ulReadSize = 130;
- else
- ulReadSize = 4;
- }
- if( xbFseek( 0, SEEK_SET )){
- iErrorStop = 140;
- rc = XB_SEEK_ERROR;
- throw rc;
- }
- if(( xbFread( &MemoBlock, ulReadSize, 1 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- rc = XB_READ_ERROR;
- throw rc;
- }
- p = MemoBlock;
- ulHdrNextBlock = eGetUInt32( p );
-
- if( iOption == 0)
- return XB_NO_ERROR;
-
- if( ulReadSize >= 20 ){
- p+=16;
- cVersion = *p;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt3::ReadDbtHeader() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Update header name.
-/*!
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt3::UpdateHeaderName(){
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! @brief Update a memo field for a given field number.
-/*!
- \param iFieldNo Field number to update data for.
- \param sMemoData Data to update memo field data with.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt3::UpdateMemoField( xbInt16 iFieldNo, const xbString & sMemoData ) {
-
- xbInt16 iErrorStop = 0;
- xbInt16 rc = XB_NO_ERROR;
- try{
- if( sMemoData == "" ){
- if(( rc = dbf->PutField( iFieldNo, "" )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- } else {
- xbUInt32 ulDataLen = sMemoData.Len() + 2;
- xbUInt32 ulBlocksNeeded = (ulDataLen / 512) + 1;
- xbUInt32 ulLastDataBlock;
- if(( rc = CalcLastDataBlock( ulLastDataBlock )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- if(( rc = xbFseek( ((xbInt64) ulLastDataBlock * 512), SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- if(( rc = xbFwrite( sMemoData.Str(), sMemoData.Len(), 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw rc;
- }
- if(( rc = xbFputc( 0x1a, 2 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw rc;
- }
- if(( rc = xbFputc( 0x00, (xbInt32) ( ulBlocksNeeded * 512 ) - (xbInt32) ulDataLen )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw rc;
- }
- if(( rc = dbf->PutULongField( iFieldNo, ulLastDataBlock )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw rc;
- }
- ulHdrNextBlock = ulLastDataBlock + ulBlocksNeeded;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw rc;
- }
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt3::UpdateMemoField() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-
-/***********************************************************************/
-//! @brief Empty the memo file.
-/*!
- This routine clears everything out of the file. It does not address the
- block pointers on the dbf file.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemoDbt3::Zap(){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- char cBuf[4];
-
- try{
- ulHdrNextBlock = 1L;
- ePutUInt32( cBuf, ulHdrNextBlock );
-
- if(( iRc != xbFseek( 0, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if(( iRc != xbFwrite( cBuf, 4, 1 ))!= XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- if(( iRc != xbTruncate( 512 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt3::Zap() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/***********************************************************************/
-} /* namespace */
-#endif /* XB_DBF3_SUPPORT */
-#endif /* XB_MEMO_SUPPORT */
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo4.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo4.cpp
deleted file mode 100755
index 9770806..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbmemo4.cpp
+++ /dev/null
@@ -1,1336 +0,0 @@
-/* xbmemo4.cpp
-
-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 is used for support dBASE V4 memo files
-
-*/
-
-#include "xbase.h"
-
-#ifdef XB_MEMO_SUPPORT
-#ifdef XB_DBF4_SUPPORT
-
-namespace xb{
-
-/***********************************************************************/
-//! @brief Class Constructor.
-/*!
- \param dbf Pointer to dbf instance.
- \param sFileName Memo file name.
-*/
-xbMemoDbt4::xbMemoDbt4( xbDbf * dbf, xbString const & sFileName ) : xbMemo( dbf, sFileName ){
- iMemoFileType = 4;
- SetBlockSize( dbf->GetCreateMemoBlockSize() );
-}
-
-/***********************************************************************/
-//! @brief Class Deconstructor.
-xbMemoDbt4::~xbMemoDbt4(){}
-
-/***********************************************************************/
-//! @brief Abort.
-/*!
- Abort any pending updates to the memo file.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt4::Abort(){
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulBlockNo;
-
- try{
- xbUInt32 ulNodeCnt = llNewBlocks.GetNodeCnt();
- for( xbUInt32 l = 0; l < ulNodeCnt; l++ ){
- if(( rc = llNewBlocks.RemoveFromFront( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if(( rc = FreeMemoBlockChain( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- }
- llOldBlocks.Clear();
- }
-
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::Abort() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-
-/***********************************************************************/
-//! @brief Commit changes to memo file.
-/*!
- Commit any pending updates to the memo file.
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbMemoDbt4::Commit(){
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulBlockNo;
-
- try{
- xbUInt32 ulNodeCnt = llOldBlocks.GetNodeCnt();
- for( xbUInt32 l = 0; l < ulNodeCnt; l++ ){
- if(( rc = llOldBlocks.RemoveFromFront( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if(( rc = FreeMemoBlockChain( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- }
- llNewBlocks.Clear();
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::Commit() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Create memo file.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::CreateMemoFile(){
-
- xbInt16 iErrorStop = 0;
- xbInt16 rc = XB_NO_ERROR;
- char cBuf[4];
-
- try{
- if(( rc = xbFopen( "w+b", dbf->GetShareMode() )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
-
- ulHdrNextBlock = 1L;
- ePutUInt32( cBuf, ulHdrNextBlock );
- if(( rc = xbFwrite( cBuf, 4, 1 ))!= XB_NO_ERROR ){
- iErrorStop = 110;
- xbFclose();
- throw rc;
- }
- for(int i = 0; i < 4; i++ )
- xbFputc( 0x00 );
- GetFileNamePart( sDbfFileNameWoExt );
- sDbfFileNameWoExt.PadRight( ' ', 8 ); // need at least eight bytes of name
- sDbfFileNameWoExt = sDbfFileNameWoExt.Mid( 1, 8 ); // need no more than eight bytes of name
- for( int i = 1; i < 9; i++ )
- xbFputc( sDbfFileNameWoExt[i] );
-
- for(int i = 0; i < 4; i++ )
- xbFputc( 0x00 );
-
- ePutInt16( cBuf, GetBlockSize());
- if(( rc = xbFwrite( cBuf, 2, 1 ))!= XB_NO_ERROR ){
- iErrorStop = 120;
- xbFclose();
- throw rc;
- }
- for( xbUInt32 i = 0; i < (GetBlockSize() - 22); i++ )
- xbFputc( 0x00 );
- if(( mbb = (void *) malloc( GetBlockSize())) == NULL ){
- rc = XB_NO_MEMORY;
- iErrorStop = 130;
- return XB_NO_MEMORY;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::CreateMemoFile() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- xbFclose();
- }
- return rc;
-}
-/***********************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-//! @brief Dump memo file header.
-/*!
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbMemoDbt4::DumpMemoFreeChain()
-{
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulCurBlock, ulLastDataBlock;
-
- try{
- if(( rc = ReadDbtHeader(1)) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if(( rc = CalcLastDataBlock( ulLastDataBlock )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
-
- ulCurBlock = ulHdrNextBlock;
- std::cout << "**********************************" << std::endl;
- std::cout << "Head Node Next Block = " << ulCurBlock << std::endl;;
- std::cout << "Total blocks in file = " << ulLastDataBlock << std::endl;
-
- while( ulCurBlock < ulLastDataBlock ){
- if(( rc = ReadBlockHeader( ulCurBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- std::cout << "**********************************" << std::endl;
- std::cout << "This Free Block = [" << ulCurBlock << "] contains [" << ulFreeBlockCnt << "] block(s)" << std::endl;
- std::cout << "Next Free Block = [" << ulNextFreeBlock << "]" << std::endl;
- ulCurBlock = ulNextFreeBlock;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::UpdateMemoField() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return XB_NO_ERROR;
-}
-
-//! @brief Dump memo internals.
-/*!
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbMemoDbt4::DumpMemoInternals() {
-
- xbLinkListNode<xbUInt32> *llPtr;
- xbInt16 iNodeCnt;
-
- llPtr = llOldBlocks.GetHeadNode();
- iNodeCnt = llOldBlocks.GetNodeCnt();
-
- std::cout << "Link List Old Blocks - " << iNodeCnt << " nodes" << std::endl;
- for( xbInt16 i = 0; i < iNodeCnt; i++ ){
- std::cout << llPtr->GetKey() << ",";
- llPtr = llPtr->GetNextNode();
- }
- std::cout << std::endl;
-
- llPtr = llNewBlocks.GetHeadNode();
- iNodeCnt = llNewBlocks.GetNodeCnt();
- std::cout << "Link List New Blocks - " << iNodeCnt << " nodes" << std::endl;
- for( xbInt16 i = 0; i < iNodeCnt; i++ ){
- std::cout << llPtr->GetKey() << ",";
- llPtr = llPtr->GetNextNode();
- }
- std::cout << std::endl;
-
- return XB_NO_ERROR;
-}
-#endif // XB_DEBUG_SUPPORT
-
-/***********************************************************************/
-//! @brief Dump memo file header.
-/*!
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt4::DumpMemoHeader(){
-
- xbInt16 rc = XB_NO_ERROR;
- xbUInt32 ulLastDataBlock;
- CalcLastDataBlock( ulLastDataBlock );
-
- if(( rc = ReadDbtHeader( 1 )) != XB_NO_ERROR )
- return rc;
- std::cout << "Version 4 Memo Header Info" << std::endl;
- std::cout << "Memo File Name = " << GetFqFileName() << std::endl;
- std::cout << "Hdr Next Avail Block = " << ulHdrNextBlock << std::endl;
- std::cout << "Block Size = " << GetBlockSize() << std::endl;
- std::cout << "Dbf File Name wo Ext = " << sDbfFileNameWoExt.Str() << std::endl;
- std::cout << "Last Data Block = " << ulLastDataBlock << std::endl;
- return rc;
-}
-
-/************************************************************************/
-//! @brief Find an empty set of blocks in the free block chain
-/*!
- This routine searches thruugh the free node chain in a dbase IV type
- memo file searching for a place to grab some free blocks for reuse
-
- \param ulBlocksNeeded The size to look in the chain for.
- \param ulLastDataBlock is the last data block in the file, enter 0
- for the routine to calculate it.
- \param ulLocation The location it finds.
- \param ulPreviousNode Block number of the node immediately previous to this node in the chain.<br>
- 0 if header node
- \param bFound Output xbFalse - Spot not found in chain.<br>
- xbTrue - Spot found in chain.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemoDbt4::FindBlockSetInChain( xbUInt32 ulBlocksNeeded,
- xbUInt32 &ulLastDataBlock, xbUInt32 &ulLocation, xbUInt32 &ulPrevNode, xbBool &bFound ){
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulCurNode;
-
- try{
- ulPrevNode = 0L;
- if( ulLastDataBlock == 0 ){
- /* Determine last good data block */
- if(( rc = CalcLastDataBlock( ulLastDataBlock )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- }
- if( ulHdrNextBlock < ulLastDataBlock ){
- ulCurNode = ulHdrNextBlock;
-
- if(( rc = ReadBlockHeader( ulHdrNextBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- while( ulBlocksNeeded > ulFreeBlockCnt && ulNextFreeBlock < ulLastDataBlock ){
- ulPrevNode = ulCurNode;
- ulCurNode = ulNextFreeBlock;
- if(( rc = ReadBlockHeader( ulNextFreeBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- }
- if( ulBlocksNeeded <= ulFreeBlockCnt ){
- ulLocation = ulCurNode;
- // PreviousNode = lPrevNode;
- bFound = xbTrue;
- } else { // no data found and at end of chain
- ulPrevNode = ulCurNode;
- bFound = xbFalse;
- }
- } else {
- bFound = xbFalse;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::FindBlockSetInChain() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Free a block.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::FreeMemoBlockChain( xbUInt32 ulBlockNo ){
- xbUInt32 ulLastDataBlock;
- return FreeMemoBlockChain( ulBlockNo, ulLastDataBlock );
-}
-
-/***********************************************************************/
-//! @brief Free a block.
-/*!
- \param ulBlockNo The block number being deleted.
- \param ulLastDataBlock Output - Last free block number,prior to this block.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemoDbt4::FreeMemoBlockChain( xbUInt32 ulBlockNo, xbUInt32 &ulLastDataBlock )
-{
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulNoOfFreedBlocks;
- xbUInt32 ulLastFreeBlock = 0;
- xbUInt32 ulLastFreeBlockCnt = 0;
- xbUInt32 ulSaveNextFreeBlock;
-
- // iFieldNo - The field no m\bing deleted
- // iBlockNo - The block number being deleted
- // iNoOfFreeBlocks - The number of blocks being freed with this delete
- // iLastDataBlock - The next block number to allocate if more blocks needed
- // iHdrNextBlock - The head pointer in the main header block
- // iNextFreeBlock - The block that is immediately following the current free block to be added
- // iLastFreeBlock - Last free block number,prior to this block
- // iLastFreeBlockCnt - Last free block number of blocks
-
- try{
-
- if( ulBlockNo <= 0 ){
- iErrorStop = 100;
- rc =XB_INVALID_BLOCK_NO;
- throw rc;
- }
-
- /* Load the first block */
- if(( rc = ReadBlockHeader( ulBlockNo, 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
-
- if( (ulFieldLen) % GetBlockSize() )
- ulNoOfFreedBlocks = ((ulFieldLen) / GetBlockSize()) + 1L;
- else
- ulNoOfFreedBlocks = (ulFieldLen) / GetBlockSize();
-
- /* Determine last good data block */
- if(( rc = CalcLastDataBlock( ulLastDataBlock )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
-
- if(( rc = ReadDbtHeader( 0 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw rc;
- }
-
- // Not an empty node chain, position to correct location in chain
- ulNextFreeBlock = ulHdrNextBlock;
- while( ulBlockNo > ulNextFreeBlock && ulBlockNo < ulLastDataBlock ){
- ulLastFreeBlock = ulNextFreeBlock;
-
- if(( rc = ReadBlockHeader( ulNextFreeBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- return rc;
- }
- ulLastFreeBlockCnt = ulFreeBlockCnt;
- }
-
- // One of two outcomes at this point
- // A) This block is combined with the next free block chain, and points to the free chain after the next free block
- // B) This block is not combined with the next free block chain, and points to the next block
- // (which could be the last block
-
- // should next block should be concatonated onto the end of this set?
- ulSaveNextFreeBlock = ulNextFreeBlock;
- if(( ulBlockNo + ulNoOfFreedBlocks ) == ulNextFreeBlock && ulNextFreeBlock < ulLastDataBlock ){
- if(( rc = ReadBlockHeader( ulNextFreeBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw rc;
- }
- ulNoOfFreedBlocks += ulFreeBlockCnt;
- ulSaveNextFreeBlock = ulNextFreeBlock;
- }
-
- // if this is the first set of free blocks
- if( ulLastFreeBlock == 0 ){
- // 1 - write out the current block
- // 2 - update header block
- // 3 - write header block
- // 4 - update data field
-
- ePutUInt32( (char *) mbb, ulSaveNextFreeBlock );
- ePutUInt32( (char *) mbb+4, ulNoOfFreedBlocks );
- if(( rc = WriteBlock( ulBlockNo, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw rc;
- }
-
- ulHdrNextBlock = ulBlockNo;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw rc;
- }
- return XB_NO_ERROR;
- }
-
- /* determine if this block set should be added to the previous set */
- if(( ulLastFreeBlockCnt + ulLastFreeBlock ) == ulBlockNo ){
- if(( rc = ReadBlockHeader( ulLastFreeBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw rc;
- }
- ulFreeBlockCnt += ulNoOfFreedBlocks;
-
- ePutUInt32( (char *) mbb, ulSaveNextFreeBlock );
- ePutUInt32( (char *) mbb+4, ulFreeBlockCnt );
- if(( rc = WriteBlock( ulLastFreeBlock, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw rc;
- }
- return XB_NO_ERROR;
- }
-
- /* insert into the chain */
- /* 1 - set the next bucket on the current node */
- /* 2 - write this node */
- /* 3 - go to the previous node */
- /* 4 - insert this nodes id into the previous node set */
- /* 5 - write previous node */
-
- ePutUInt32( (char *) mbb, ulSaveNextFreeBlock );
- ePutUInt32( (char *) mbb+4, ulNoOfFreedBlocks );
- if(( rc = WriteBlock( ulBlockNo, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw rc;
- }
-
- if(( rc = ReadBlockHeader( ulLastFreeBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw rc;
- }
-
- ePutUInt32( (char *) mbb, ulBlockNo );
- if(( rc = WriteBlock( ulLastFreeBlock, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 220;
- throw rc;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::DeleteMemoField() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/************************************************************************/
-//! @brief Get a set of blocks from the free block chain.
-/*!
- This routine grabs a set of blocks out of the free block chain.
-
- \param ulBlocksNeeded The number of blocks requested.
- \param ulLocation
- \param ulPrevNode
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbMemoDbt4::GetBlockSetFromChain( xbUInt32 ulBlocksNeeded,
- xbUInt32 ulLocation, xbUInt32 ulPrevNode )
-{
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulNextFreeBlock2;
- xbUInt32 ulNewFreeBlocks;
- xbUInt32 ulSaveNextFreeBlock;
-
- try{
- if(( rc = ReadBlockHeader( ulLocation, 2 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
-
- if( ulBlocksNeeded == ulFreeBlockCnt ){ // grab this whole set of blocks
- if( ulPrevNode == 0 ){ // first in the chain
- ulHdrNextBlock = ulNextFreeBlock;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- }
- else // remove out of the middle or end
- {
- ulNextFreeBlock2 = ulNextFreeBlock;
- if(( rc = ReadBlockHeader( ulPrevNode, 2 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- ulNextFreeBlock = ulNextFreeBlock2;
- if(( rc = WriteBlockHeader( ulPrevNode, 2 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw rc;
- }
- }
- } else { // only take a portion of this set
- if( ulPrevNode == 0 ){ // first in the set
- ulHdrNextBlock = ulLocation + ulBlocksNeeded;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw rc;
- }
- ulFreeBlockCnt -= ulBlocksNeeded;
- if(( rc = WriteBlockHeader( ulHdrNextBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw rc;
- }
- }
- else { // remove out of the middle or end
- ulNewFreeBlocks = ulFreeBlockCnt - ulBlocksNeeded;
- ulSaveNextFreeBlock = ulNextFreeBlock;
- ulNextFreeBlock2 = ulLocation + ulBlocksNeeded;
-
- if(( rc = ReadBlockHeader( ulPrevNode, 2 )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw rc;
- }
- ulNextFreeBlock = ulNextFreeBlock2;
- if(( rc = WriteBlockHeader( ulPrevNode, 2 )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw rc;
- }
- ulFreeBlockCnt = ulNewFreeBlocks;
- ulNextFreeBlock = ulSaveNextFreeBlock;
- if(( rc = WriteBlockHeader( ulNextFreeBlock2, 2 )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw rc;
- }
- }
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::GetBlockSetFromChain() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Get a memo field for a given field number.
-/*!
- \param iFieldNo Field number to retrieve data for.
- \param sMemoData Output - string containing memo field data.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::GetMemoField( xbInt16 iFieldNo, xbString & sMemoData ){
-
- xbUInt32 ulBlockNo;
- xbUInt32 ulMemoFieldLen;
- xbUInt32 ulMemoFieldDataLen;
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char *p = NULL;
-
- try{
- if(( rc = GetMemoFieldLen( iFieldNo, ulMemoFieldLen, ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
-
- if( ulBlockNo == 0L || ulMemoFieldLen == 0L )
- sMemoData = "";
- else{
- ulMemoFieldDataLen = ulMemoFieldLen - 8;
-
- if(( p = (char *)calloc(1, ulMemoFieldDataLen+1)) == NULL ){
- iErrorStop = 110;
- rc = XB_NO_MEMORY;
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::GetMemoField() lBlockNo = %ld Data Len = [%ld]", ulBlockNo, ulMemoFieldDataLen + 1 );
- xbase->WriteLogMessage( sMsg.Str() );
- throw rc;
- }
-
- // go to the first block of the memo field, skip past the first 8 bytes
- if(( xbFseek( ( ulBlockNo * GetBlockSize() + 8 ), SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 120;
- rc = XB_SEEK_ERROR;
- throw rc;
- }
-
- // read the memo file data into buffer pointed to by "p"
- if(( rc = xbFread( p, ulMemoFieldDataLen, 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- rc = XB_READ_ERROR;
- throw rc;
- }
- // null terminate the string
- char *p2;
- p2 = p + ulMemoFieldDataLen;
- *p2 = 0x00;
-
- // save it to the string
- sMemoData.Set( p, ulMemoFieldDataLen + 1 );
- free( p );
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::GetMemoField() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- if( p )
- free( p );
- }
- return rc;
-}
-
-/***********************************************************************/
-//! @brief Get a memo field length for a given field number.
-/*!
- \param iFieldNo Field number to retrieve data for.
- \param ulMemoFieldLen Output - length of memo field data.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemoDbt4::GetMemoFieldLen( xbInt16 iFieldNo, xbUInt32 &ulMemoFieldLen ){
- xbUInt32 ulBlockNo;
- return GetMemoFieldLen( iFieldNo, ulMemoFieldLen, ulBlockNo );
-}
-
-/***********************************************************************/
-//! @brief Get a memo field length for a given field number.
-/*!
- \param iFieldNo Field number to retrieve data for.
- \param ulMemoFieldLen Output - length of memo field data.
- \param ulBlockNo Output - Starting block number.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::GetMemoFieldLen( xbInt16 iFieldNo, xbUInt32 &ulMemoFieldLen, xbUInt32 &ulBlockNo ){
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char cFieldType;
-
- try{
-
- if(( rc = dbf->GetFieldType( iFieldNo, cFieldType )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if( cFieldType != 'M' ){
- iErrorStop = 110;
- rc = XB_INVALID_MEMO_FIELD;
- throw rc;
- }
- if(( rc = dbf->GetULongField( iFieldNo, ulBlockNo )) < XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- if( ulBlockNo < 1 ){
- ulMemoFieldLen = 0;
- return XB_NO_ERROR;
- }
- if(( rc = ReadBlockHeader( ulBlockNo, 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw rc;
- }
- ulMemoFieldLen = ulFieldLen;
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::GetMemoFieldLen() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Open memo file.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::OpenMemoFile() {
-
- xbInt16 iErrorStop = 0;
- xbInt16 rc = XB_NO_ERROR;
-
- try{
- if(( rc = xbFopen( dbf->GetOpenMode(), dbf->GetShareMode())) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if(( rc = ReadDbtHeader( 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- if(( mbb = (void *) malloc( GetBlockSize())) == NULL ){
- xbFclose();
- iErrorStop = 120;
- rc = XB_NO_MEMORY;
- throw rc;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::OpenMemoFile() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Pack memo file.
-/*!
- This routine frees up any unused blocks in the file resulting from field updates.
- Version 3 memo files do not reclaim unused space (Version 4 files do).
- This routine cleans up the unused space.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::PackMemo( void (*memoStatusFunc ) ( xbUInt32 ulItemNum, xbUInt32 ulNumItems )){
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- char * cBlock = NULL;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bTableLocked = xbFalse;
- xbBool bMemoLocked = xbFalse;
- #endif
-
- try{
- #ifdef XB_LOCKING_SUPPORT
- if( dbf->GetAutoLock() && !dbf->GetTableLocked() ){
- if(( iRc = dbf->LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- } else {
- bTableLocked = xbTrue;
- }
- if(( iRc = LockMemo( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- } else {
- bMemoLocked = xbTrue;
- }
- }
- #endif
-
- // create temp file
- xbString sTempMemoName;
- //if(( iRc = CreateUniqueFileName( GetDirectory(), "dbt", sTempMemoName )) != XB_NO_ERROR ){
- if(( iRc = CreateUniqueFileName( GetTempDirectory(), "DBT", sTempMemoName )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- xbMemoDbt4 *pMemo = new xbMemoDbt4( dbf, sTempMemoName );
- if(( iRc = pMemo->CreateMemoFile()) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- // for dbase III, block size is always 512, don't need to reset it
- // for each record in dbf
- xbUInt32 ulRecCnt;
- if(( iRc = dbf->GetRecordCnt( ulRecCnt)) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- xbInt32 lFldCnt = dbf->GetFieldCnt();
- char cFldType;
- xbString sMemoFldData;
-
- for( xbUInt32 ulI = 1; ulI <= ulRecCnt; ulI++ ){
- if(( iRc = dbf->GetRecord( ulI )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
-
- if( (void *) memoStatusFunc)
- (*memoStatusFunc)(ulI, ulRecCnt );
-
- // for each memo field
- for( xbInt32 lFc = 0; lFc < lFldCnt; lFc++ ){
- if(( iRc = dbf->GetFieldType( lFc, cFldType )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if( cFldType == 'M' ){
- // copy it to work field
- if(( iRc = dbf->GetMemoField( lFc, sMemoFldData )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- // write it to new field
- if(( iRc = pMemo->UpdateMemoField( lFc, sMemoFldData )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
- }
- }
- }
-
- //copy target back to source
- xbUInt32 ulBlkSize = GetBlockSize();
- xbUInt64 ullFileSize;
- if(( iRc = pMemo->GetFileSize( ullFileSize )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
- // file size should be evenly divisible by block size
- xbUInt32 ulBlkCnt;
-
- if( ullFileSize % ulBlkSize ){
- iErrorStop = 200;
- throw iRc;
- } else {
- ulBlkCnt = (xbUInt32) (ullFileSize / ulBlkSize);
- }
- if(( iRc = xbTruncate( 0 )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
-
- if(( cBlock = (char *) malloc( ulBlkSize )) == NULL ){
- iErrorStop = 220;
- throw iRc;
- }
-
- // can't rename files in a multiuser, cross platform environment, causes issues
- // copy work table back to source table
-
- for( xbUInt32 ulBc = 0; ulBc < ulBlkCnt; ulBc++ ){
- if(( iRc = pMemo->ReadBlock( ulBc, ulBlkSize, cBlock )) != XB_NO_ERROR ){
- iErrorStop = 230;
- throw iRc;
- }
- if(( iRc = WriteBlock( ulBc, ulBlkSize, cBlock )) != XB_NO_ERROR ){
- iErrorStop = 240;
- throw iRc;
- }
- }
-
- if(( xbFseek( 8, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 250;
- iRc = XB_SEEK_ERROR;
- throw iRc;
- }
-
- for( int i = 1; i < 9; i++ )
- xbFputc( sDbfFileNameWoExt[i] );
-
- //close and delete target
- if(( iRc = pMemo->xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 260;
- throw iRc;
- }
- if(( iRc = pMemo->xbRemove()) != XB_NO_ERROR ){
- iErrorStop = 270;
- throw iRc;
- }
- free( cBlock );
- delete pMemo;
-
- }
- catch (xbInt16 iRc ){
- free( cBlock );
-
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::PackMemo() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- #ifdef XB_LOCKING_SUPPORT
- if( bTableLocked )
- dbf->LockTable( XB_UNLOCK );
- if( bMemoLocked )
- LockMemo( XB_UNLOCK );
- #endif
- return iRc;
-}
-/***********************************************************************/
-//! @brief Read block header.
-/*!
- \param ulBlockNo Block to read
- \param iOption 1 - Read fields option 1
- 2 - Read fields option 2
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::ReadBlockHeader( xbUInt32 ulBlockNo, xbInt16 iOption ) {
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
-
- if(( rc = ReadBlock( ulBlockNo, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 100;
- rc = XB_READ_ERROR;
- }
- if( iOption == 1 ){
- iField1 = eGetInt16((char *) mbb );
- iStartPos = eGetInt16((char *) mbb+2);
- ulFieldLen = eGetUInt32((char *) mbb+4);
- }
- else if( iOption == 2 ){
- ulNextFreeBlock = eGetUInt32((char *) mbb );
- ulFreeBlockCnt = eGetUInt32((char *) mbb+4 );
- }
- else{
- iErrorStop = 110;
- rc = XB_INVALID_OPTION;
- throw rc;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::ReadBlockHeader() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Read dbt header file.
-/*!
- \param iOption 0 --> read only first four bytes<br>
- 1 --> read the entire thing
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::ReadDbtHeader( xbInt16 iOption ) {
-
- xbInt16 iErrorStop = 0;
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iReadLen = 0;
- char *p;
- char MemoBlock[22];
-
- try{
- if( !FileIsOpen() ){
- iErrorStop = 100;
- rc = XB_NOT_OPEN;
- throw rc;
- }
- if( xbFseek( 0, SEEK_SET )){
- iErrorStop = 110;
- rc = XB_SEEK_ERROR;
- throw rc;
- }
- if( iOption )
- iReadLen = 22;
- else
- iReadLen = 4;
-
- if(( xbFread( &MemoBlock, (size_t) iReadLen, 1 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- rc = XB_READ_ERROR;
- throw rc;
- }
-
- p = MemoBlock;
- ulHdrNextBlock = eGetUInt32( p );
- if( iOption == 0)
- return XB_NO_ERROR;
-
- p += 8;
- sDbfFileNameWoExt = "";
- for( int i = 0; i < 8; i++ )
- sDbfFileNameWoExt += *p++;
-
- p += 4;
- SetBlockSize( (xbUInt32) eGetInt16( p ));
-
- cVersion = MemoBlock[16];
-
- }
- catch (xbInt16 rc ){
-
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::ReadDbtHeader() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-
-/***********************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-//! @brief Read free block information from header.
-/*!
- This routing pulls any reusable block information for file header.
- Not used with version 3 memo files - stub.
-
- \param ulBlockNo
- \param ulNextBlock
- \param ulFreeBlockCnt
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt4::ReadFreeBlockHeader( xbUInt32 ulBlockNo, xbUInt32 &ulNextBlock, xbUInt32 &ulFreeBlockCount ){
-
- xbInt16 rc = XB_NO_ERROR;
- rc = ReadBlockHeader( ulBlockNo, 2 );
- ulNextBlock = ulNextFreeBlock;
- ulFreeBlockCount = ulFreeBlockCnt;
- return rc;
-}
-#endif
-/***********************************************************************/
-//! @brief Update header name.
-/*!
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt4::UpdateHeaderName() {
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- GetFileNamePart( sDbfFileNameWoExt );
- sDbfFileNameWoExt.PadRight( ' ', 8 ); // need at least eight bytes of name
- sDbfFileNameWoExt = sDbfFileNameWoExt.Mid( 1, 8 ); // need no more than eight bytes of name
-
- try{
- if(( rc = xbFseek( 8, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
-
- for( int i = 1; i < 9; i++ ){
- if(( rc = xbFputc( sDbfFileNameWoExt[i] )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::UpdateHeaderName() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Update a memo field length for a given field number.
-/*!
- \param iFieldNo Field number to update data for.
- \param sMemoData Data to update memo field data with.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::UpdateMemoField( xbInt16 iFieldNo, const xbString & sMemoData ) {
-
- xbInt16 iErrorStop = 0;
- xbInt16 rc = XB_NO_ERROR;
- xbUInt32 ulBlockNo;
-
- try{
-
- if(( rc = dbf->GetULongField( iFieldNo, ulBlockNo )) < XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
-
- if( sMemoData == "" ){
- if( ulBlockNo == 0 ){
- /* if nothing to do, return */
- return XB_NO_ERROR;
- } else {
-
- // if this is in the new blocks link list already, then this is not the first update for this memo field
- // this would be second or third update on the field since the original change and not commited
- // Since it won't be needed in either a Commmit() or Abort(), can be freed immediately
- if( llNewBlocks.SearchFor( ulBlockNo ) > 0 ){
- if(( rc = FreeMemoBlockChain( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- if(( llNewBlocks.RemoveByVal( ulBlockNo )) < XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- } else {
- // first revision, save what it was in case of Abort() command
- if(( llOldBlocks.InsertAtFront( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw rc;
- }
- }
- if(( rc = dbf->PutField( iFieldNo, "" )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw rc;
- }
- }
- } else {
- // free up the old space
- xbUInt32 ulLastDataBlock = 0L;
-
- if( ulBlockNo > 0 ){
- if( llNewBlocks.SearchFor( ulBlockNo ) > 0 ){
-
- if(( rc = FreeMemoBlockChain( ulBlockNo, ulLastDataBlock )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw rc;
- }
- } else {
- // first revision, save what it was in case of Abort() command
- if(( rc = llOldBlocks.InsertAtFront( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw rc;
- }
- }
- }
- // should next line be unsigned 32 bit int?
- xbUInt32 ulTotalLen = 8 + sMemoData.Len();
- xbUInt32 ulBlocksNeeded;
- if( ulTotalLen % GetBlockSize())
- ulBlocksNeeded = ulTotalLen / GetBlockSize() + 1;
- else
- ulBlocksNeeded = ulTotalLen / GetBlockSize();
-
- xbBool bUsedBlockFound;
- xbUInt32 ulHeadBlock;
- xbUInt32 ulPrevNode;
- if(( rc = FindBlockSetInChain( ulBlocksNeeded, ulLastDataBlock, ulHeadBlock, ulPrevNode, bUsedBlockFound )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw rc;
- }
- iField1 = -1;
- iStartPos = 8;
- ulFieldLen = sMemoData.Len() + 8;
-
- if( bUsedBlockFound ){
-
- if(( rc = GetBlockSetFromChain( ulBlocksNeeded, ulHeadBlock, ulPrevNode )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw rc;
- }
-
- if(( rc = WriteBlockHeader( ulHeadBlock, 1 )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw rc;
- }
-
- if(( rc = xbFwrite( sMemoData.Str(), sMemoData.Len(), 1 )) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw rc;
- }
- } else { // append to the end
-
- if(( rc = WriteBlockHeader( ulLastDataBlock, 1 )) != XB_NO_ERROR ){
- iErrorStop = 220;
- throw rc;
- }
-
- if(( rc = xbFwrite( sMemoData.Str(), sMemoData.Len(), 1 )) != XB_NO_ERROR ){
- iErrorStop = 230;
- throw rc;
- }
-
- if(( rc = xbFputc( 0x00, (xbInt32)((ulBlocksNeeded * GetBlockSize()) - (sMemoData.Len() + 8)))) != XB_NO_ERROR ){
- iErrorStop = 240;
- throw rc;
- }
-
- if( ulLastDataBlock == ulHdrNextBlock ){ // this is first node to be added to the node chain
- ulHdrNextBlock += ulBlocksNeeded;
- ulHeadBlock = ulLastDataBlock;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR ){
- iErrorStop = 250;
- throw rc;
- }
-
- } else { // adding memo data to the end of the file, but chain exists
-
- ulNextFreeBlock = ulLastDataBlock + ulBlocksNeeded;
- ulHeadBlock = ulLastDataBlock;
- if(( rc = WriteBlockHeader( ulPrevNode, 2 )) != XB_NO_ERROR ){
- iErrorStop = 260;
- throw rc;
- }
- }
- }
-
- if(( rc = llNewBlocks.InsertAtFront( ulHeadBlock )) != XB_NO_ERROR ){ // In case of Abort(), this block needs to be freed
- iErrorStop = 270;
- throw rc;
- }
- if(( rc = dbf->PutLongField( iFieldNo, (xbInt32) ulHeadBlock )) != XB_NO_ERROR ){
- iErrorStop = 280;
- throw rc;
- }
- }
- }
-
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::UpdateMemoField() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Write block header.
-/*!
- \param ulBlockNo Block to read
- \param iOption 1 - Read fields option 1
- 2 - Read fields option 2
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::WriteBlockHeader( xbUInt32 ulBlockNo, xbInt16 iOption ) {
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- if( iOption == 1 ){
- ePutInt16 ((char *) mbb, iField1 );
- ePutInt16 ((char *) mbb+2, iStartPos );
- ePutUInt32((char *) mbb+4, ulFieldLen );
- }
- else if( iOption == 2 ){
- ePutUInt32((char *) mbb, ulNextFreeBlock );
- ePutUInt32((char *) mbb+4, ulFreeBlockCnt );
- }
- else{
- iErrorStop = 100;
- rc = XB_INVALID_OPTION;
- throw rc;
- }
-
- if(( rc = WriteBlock( ulBlockNo, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 110;
- rc = XB_READ_ERROR;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::WriteHeader() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Empty the memo file.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemoDbt4::Zap(){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- char cBuf[4];
- try{
- ulHdrNextBlock = 1L;
- ePutUInt32( cBuf, ulHdrNextBlock );
-
- if(( iRc != xbFseek( 0, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if(( iRc != xbFwrite( cBuf, 4, 1 ))!= XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- if(( iRc != xbTruncate( GetBlockSize())) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
-
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::Zap() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}/***********************************************************************/
-} /* namespace */
-#endif /* XB_DBF4_SUPPORT */
-#endif /* XB_MEMO_SUPPORT */
-
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbssv.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbssv.cpp
deleted file mode 100755
index 532f942..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbssv.cpp
+++ /dev/null
@@ -1,658 +0,0 @@
-/* xbssv.cpp
-
-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 "xbase.h"
-
-namespace xb{
-
-const xbErrorMessage xbErrorMessages[] = {
- { XB_NO_ERROR, "No Error" },
- { XB_NO_MEMORY, "No Memory" },
- { XB_INVALID_OPTION, "Invalid Option" },
- { XB_INVALID_PARAMETER, "Invalid Parameter" },
- { XB_DUP_TABLE_OR_ALIAS, "Duplicate Alias/Table Name" },
- { XB_INVALID_NODELINK, "Invalid Node Link" },
- { XB_KEY_NOT_UNIQUE, "Key Not Unique" },
- { XB_MEMCPY_ERROR, "Memory copy failure" },
- { XB_FILE_EXISTS, "File Already Exists" },
- { XB_ALREADY_OPEN, "Database already open" },
- { XB_DBF_FILE_NOT_OPEN, "DBF File Not Open" },
- { XB_FILE_NOT_FOUND, "File not found" },
- { XB_FILE_TYPE_NOT_SUPPORTED, "Not an Xbase type database" },
- { XB_RENAME_ERROR, "Unable to rename file" },
- { XB_INVALID_OBJECT, "Invalid Object" },
- { XB_NOT_OPEN, "Database not open" },
- { XB_NOT_FOUND, "Not Found" },
- { XB_OPEN_ERROR, "Open Error" },
- { XB_CLOSE_ERROR, "Close Error" },
- { XB_SEEK_ERROR, "Seek Error" },
- { XB_READ_ERROR, "Read Error" },
- { XB_WRITE_ERROR, "Error writing to disk drive" },
- { XB_EOF, "End Of File" },
- { XB_BOF, "Beginning Of File" },
- { XB_INVALID_BLOCK_SIZE, "Invalid Block Size" },
- { XB_INVALID_BLOCK_NO, "Invalid Block Number" },
- { XB_INVALID_RECORD, "Invalid Record Number" },
- { XB_DELETE_FAILED, "Delete Failed" },
- { XB_INVALID_TABLE_NAME, "Invalid Table Name" },
- { XB_EMPTY, "Empty Table or Index" },
- { XB_LIMIT_REACHED, "Limit Reached" },
- { XB_BLOCKREAD_NOT_ENABLED, "Block Read Mode is not enabled" },
- { XB_DIRECTORY_ERROR, "Directory Read/Write error" },
- { XB_INVALID_FIELD_TYPE, "Unknown Field Type" },
- { XB_INVALID_FIELD_NO, "Invalid Field Number" },
- { XB_INVALID_DATA, "Invalid Data" },
- { XB_INVALID_FIELD_NAME, "Invalid Field Name" },
- { XB_INVALID_MEMO_FIELD, "Not a Memo field" },
- { XB_INVALID_FIELD, "Invalid Field" },
- { XB_INVALID_FIELD_LEN, "Invalid Field Length" },
- { XB_INVALID_DATE, "Invalid Date" },
- { XB_INVALID_LOCK_OPTION, "Invalid Lock Option" },
- { XB_LOCK_FAILED, "Lock Failed" },
- { XB_TABLE_NOT_LOCKED, "Table Not Locked" },
- { XB_PARSE_ERROR, "Parse Error" },
- { XB_INVALID_FUNCTION, "Invalid or Undefined Function" },
- { XB_INVALID_PARM, "Invalid Parm" },
- { XB_INCONSISTENT_PARM_LENS, "Inconsistent parm lengths" },
- { XB_INCOMPATIBLE_OPERANDS, "Incompatible operands" },
- { XB_UNBALANCED_PARENS, "Unbalanced Parens" },
- { XB_UNBALANCED_QUOTES, "Unbalanced Quotes" },
- { XB_INVALID_EXPRESSION, "Invalid expression" },
- { XB_INVALID_KEYNO, "Invalid Key Number" },
- { XB_INVALID_INDEX, "Index File Error" },
- { XB_INVALID_TAG, "Invalid index tag" },
- { XB_SYNTAX_ERROR, "Invalid SQL Syntax" },
- { XB_MAX_ERROR_NO, "End of Error List" }
-};
-// see also xbretcod.h
-
-xbInt16 xbSsv::iEndianType = 0;
-xbString xbSsv::sDefaultDateFormat = "MM/DD/YY";
-
-xbInt16 xbSsv::iDefaultFileVersion = 4;
-xbString xbSsv::sNullString = "";
-xbBool xbSsv::bDefaultAutoCommit = xbTrue;
-
-xbString xbSsv::sDataDirectory = PROJECT_DATA_DIR;
-xbString xbSsv::sTempDirectory = PROJECT_TEMP_DIR;
-
-#ifdef XB_LOGGING_SUPPORT
-xbString xbSsv::sLogDirectory = PROJECT_LOG_DIR;
-xbString xbSsv::sLogFileName = PROJECT_DFLT_LOGFILE;
-#endif // XB_LOGGING_SUPPORT
-
-#ifdef XB_LOCKING_SUPPORT
-xbInt32 xbSsv::lDefaultLockWait = 100;
-xbInt16 xbSsv::iDefaultLockRetries = 3;
-xbBool xbSsv::bDefaultAutoLock = xbTrue;
-xbInt16 xbSsv::iDefaultLockFlavor = 1;
-xbBool xbSsv::bMultiUser = xbTrue;
-#else
-xbBool xbSsv::bMultiUser = xbFalse;
-#endif // XB_LOCKING_SUPPORT
-
-#if defined (XB_NDX_SUPPORT) || defined (XB_MDX_SUPPORT)
-xbInt16 xbSsv::iUniqueKeyOpt = XB_HALT_ON_DUPKEY;
- // is one of XB_HALT_ON_DUPKEY || XB_EMULATE_DBASE
-#endif // defined (XB_NDX_SUPPORT) || defined (XB_MDX_SUPPORT)
-
-
-#ifdef XB_MDX_SUPPORT
-xbInt16 xbSsv::iCreateMdxBlockSize = 1024; // 1024 is DBase 7 default size for MDX index blocks
-#endif // XB_MDX_SUPPORT
-
-#ifdef XB_BLOCKREAD_SUPPORT
-xbUInt32 xbSsv::ulDefaultBlockReadSize = 32768; // 32K buffer for block DBF datafile reads
-#endif // XB_BLOCKREAD_SUPPORT
-
-/*************************************************************************/
-//! @brief Class Constructor.
-xbSsv::xbSsv(){}
-/*************************************************************************/
-void xbSsv::BitDump( unsigned char c ) const {
- for( int i = 7; i >= 0; i-- )
- std::cout << (BitSet( c, i ) ? 1 : 0);
-}
-void xbSsv::BitDump( char c ) const {
- BitDump( (unsigned char) c );
-}
-/*************************************************************************/
-//! @brief Check a bit in a one byte field and see if it is set.
-/*!
- \param c One byte char field to examine.
- \param iBitNo which bit to examine.
- \returns xbTrue Bit is set<br>
- xbFalse Bit is not set
-*/
-xbBool xbSsv::BitSet( unsigned char c, xbInt16 iBitNo ) const {
- return c & 1 << iBitNo;
-}
-/*************************************************************************/
-//! @brief Display error message on console for a given error number.
-/*!
- \param iErrorCode Error number to reference
-*/
-void xbSsv::DisplayError( xbInt16 iErrorCode ) const {
- std::cout << (const char *) GetErrorMessage( iErrorCode ) << std::endl;
-}
-/*************************************************************************/
-//! @brief Get the default auto commit setting.
-/*!
-
- When auto commit is enabled, the library will automatically post any updates
- when moving off an updated record or closing files.
- If auto commit is disabled, the application program will need to explicitly
- update the tables using using dbf->Put() and dbf->AppendRecord().
-
- \returns xbTrue if auto commit is turned on<br>
- xbFalse is auto commit is turned off
-*/
-
-xbBool xbSsv::GetDefaultAutoCommit() const {
- return bDefaultAutoCommit;
-}
-/*************************************************************************/
-//! @brief Get the current data directory.
-/*!
- \returns xbString containing the current data directory
- where the database files are stored.
-*/
-
-xbString &xbSsv::GetDataDirectory() const {
- return sDataDirectory;
-}
-/*************************************************************************/
-//! @brief Get the default date format.
-/*!
- \returns xbString containing the default date format.
-*/
-
-xbString & xbSsv::GetDefaultDateFormat() const {
- return sDefaultDateFormat;
-}
-/*************************************************************************/
-//! @brief Get the Endian type.
-/*!
- \returns B - Big endian<br>
- L - Little endian<br>
-*/
-xbInt16 xbSsv::GetEndianType() const {
- return iEndianType;
-}
-/*************************************************************************/
-//! @brief Get an error message.
-/*!
- \param iErrorCode ErrorCode is the error number of description to be returned.
- \returns Returns a pointer to a string containing a text description for the error code.
-*/
-
-const char * xbSsv::GetErrorMessage( xbInt16 iErrorCode ) const{
-
- if( iErrorCode > 0 || iErrorCode <= XB_MAX_ERROR_NO )
- return "";
-
- xbBool bFound = xbFalse;
- xbInt16 iCtr = 0;
- while( !bFound ){
- if( xbErrorMessages[iCtr].iErrorNo == XB_MAX_ERROR_NO )
- return "Unknown Error";
- if( xbErrorMessages[iCtr].iErrorNo == iErrorCode )
- return xbErrorMessages[iCtr].sErrorText;
- iCtr++;
- }
- return "";
-}
-/*************************************************************************/
-//! @brief Get home directory.
-/*!
- \param sHomeDirOut - Output home directory for current user.
-*/
-
-void xbSsv::GetHomeDir( xbString &sHomeDirOut ){
-
- #ifdef HAVE_GETENV_S_F
-
- char sPath[MAX_PATH];
- size_t lSize;
-
- sHomeDirOut = "";
- memset( sPath, 0x00, MAX_PATH );
-
- getenv_s( &lSize, NULL, 0, "HOMEDRIVE" );
- if( lSize > 0 ){
- getenv_s( &lSize, sPath, lSize, "HOMEDRIVE" );
- sHomeDirOut = sPath;
- memset( sPath, 0x00, MAX_PATH );
- }
-
- getenv_s( &lSize, NULL, 0, "HOMEPATH" );
- if( lSize > 0 ){
- getenv_s( &lSize, sPath, lSize, "HOMEPATH" );
- sHomeDirOut += sPath;
- }
- if( sHomeDirOut == "" )
- sHomeDirOut = "C:\xbase64";
-
- #elif defined(WIN32)
- sHomeDirOut.Sprintf( "%s%s", getenv( "HOMEDRIVE" ), getenv( "HOMEPATH" ));
-
- #else
- sHomeDirOut.Sprintf( "%s", getenv( "HOME" ));
- sHomeDirOut.Trim();
- if( sHomeDirOut == "" )
- sHomeDirOut.Sprintf( "%s", getpwuid( getuid())->pw_dir );
- #endif
-
- sHomeDirOut.Trim();
-}
-
-
-/*************************************************************************/
-//! @brief Set the data directory.
-/*!
- \param sDataDirectory Set the data directory.
-*/
-
-void xbSsv::SetDataDirectory( const xbString &sDataDirectory ){
- this->sDataDirectory = sDataDirectory;
-
- #ifdef WIN32
- this->sDataDirectory.SwapChars( '/', '\\' );
- #else
- this->sDataDirectory.SwapChars( '\\', '/' );
- #endif
-
-}
-
-/*************************************************************************/
-//! @brief Set the default date format.
-/*!
- \param sDefaultDateFormat Set the default date format.
-*/
-
-void xbSsv::SetDefaultDateFormat( const xbString &sDefaultDateFormat ) {
- this->sDefaultDateFormat = sDefaultDateFormat;
-}
-
-/*************************************************************************/
-//! @brief Set the default auto commit.
-/*!
-
- Disabling auto commit requires the application execute explicit updates
- using dbf->Put() and dbf->AppendRecord(). With auto commit on, the library
- posts updates automatically when moving off the current record or closing
- a file.
-
- \param bDefaultAutoCommit xbTrue - Enable default auto commit.<br>
- xbFalse - Disable default auto commit.<br>
-*/
-
-void xbSsv::SetDefaultAutoCommit( xbBool bDefaultAutoCommit ) {
- this->bDefaultAutoCommit = bDefaultAutoCommit;
-}
-/*************************************************************************/
-//! @brief Set the endian type
-/*!
- This routine determines the Endian-ness at run time instead of
- compile time as some processers (ie; Sparc,ARM) can be switched either way.
- This routine is called automatically by the library at startup and does not
- need to be called in an application program.
-
-*/
-
-void xbSsv::SetEndianType() {
- xbInt16 e = 1;
- iEndianType = *(char *) &e;
- if( iEndianType )
- iEndianType = 'L';
- else
- iEndianType = 'B';
- return;
-}
-
-/*************************************************************************/
-//! @brief Set the temp directory.
-/*!
- \param sTempDirectory Set the data direcroty.
-*/
-
-void xbSsv::SetTempDirectory( const xbString &sTempDirectory ){
- this->sTempDirectory = sTempDirectory;
-
- #ifdef WIN32
- this->sTempDirectory.SwapChars( '/', '\\' );
- #else
- this->sTempDirectory.SwapChars( '\\', '/' );
- #endif
-
-}
-
-/*************************************************************************/
-//! @brief Get the OS dependent path separator.
-/*!
- \returns Returns '\' for windows environment, otherwise returns '/'.
-*/
-
-char xbSsv::GetPathSeparator() const {
- #ifdef WIN32
- return '\\';
- #else
- return '/';
- #endif
-}
-
-/*************************************************************************/
-//! @brief Get the current temp directory.
-/*!
- \returns xbString containing the current data directory
- where the database files are stored.
-*/
-
-xbString &xbSsv::GetTempDirectory() const {
- return sTempDirectory;
-}
-
-/*************************************************************************/
-#ifdef XB_LOGGING_SUPPORT
-
-//! @brief Get the default log file name.
-/*!
- \returns Returns the log file name.
-*/
-
-xbString & xbSsv::GetLogFileName() const {
- return sLogFileName;
-}
-
-/*************************************************************************/
-//! @brief Get the default log directory.
-/*!
- \returns Returns the log directory.
-*/
-
-
-xbString & xbSsv::GetLogDirectory() const {
- return sLogDirectory;
-}
-/*************************************************************************/
-//! @brief Set the default log directory name.
-/*!
- \param sLogDirectory Name of desired log directory.
-
-*/
-
-void xbSsv::SetLogDirectory( const xbString &sLogDirectoryIn ){
-
- this->sLogDirectory = sLogDirectoryIn;
- #ifdef WIN32
- this->sLogDirectory.SwapChars( '/', '\\' );
- #else
- this->sLogDirectory.SwapChars( '\\', '/' );
- #endif
-
-}
-
-//! @brief Set the log file name.
-/*!
- \param sLogFileName - Log File Name.
- \return void
-*/
-
-void xbSsv::SetLogFileName( const xbString & sLogFileName ){
-
- this->sLogFileName = sLogFileName;
-}
-
-
-#else
-
-xbString & xbSsv::GetLogFileName() const {
- return sNullString;
-}
-
-
-xbString & xbSsv::GetLogDirectory() const {
-
-std::cout << "xbSsv::GetLogDirectory() returning null\n";
-
- return sNullString;
-}
-
-void xbSsv::SetLogDirectory( const xbString &sLogDirectory ){
- return;
-}
-
-void xbSsv::SetLogFileName( const xbString & sLogFileName ){
- return;
-}
-
-#endif
-
-/*************************************************************************/
-
-#ifdef XB_LOCKING_SUPPORT
-
-//! @brief Get the default lock retries.
-/*!
- This is the number of lock attempts the libary will make before returning
- failure if the file can not be locked.
- \returns Default lock retry count.
-*/
-xbInt16 xbSsv::GetDefaultLockRetries() const {
- return iDefaultLockRetries;
-}
-
-//! @brief Set the default lock retries.
-/*!
- \param iDefaultLockRetries - Number of lock attempts before returning failure.
-*/
-void xbSsv::SetDefaultLockRetries( xbInt16 iDefaultLockRetries ) {
- this->iDefaultLockRetries = iDefaultLockRetries;
-}
-
-//! @brief Get the default auto lock setting.
-/*!
- When auto locking is turned on, the library automatically locks and unlocks
- files and indices as needed in a multi user environment.
- \returns Number of lock attempt settings.
-*/
-xbBool xbSsv::GetDefaultAutoLock() const {
- return bDefaultAutoLock;
-}
-
-
-//! @brief Set the default auto lock setting.
-/*!
- When auto locking is turned on, the library automatically locks and unlocks
- files and indices as needed in a multi user environment. Locking is not required
- in single a single user environment.
-
- \param bDefaultAutoLock xbTrue - Turn autolocking on<br>
- xbFalse - Turn autolocking off<br>
-*/
-void xbSsv::SetDefaultAutoLock( xbBool bDefaultAutoLock ) {
- this->bDefaultAutoLock = bDefaultAutoLock;
-}
-
-//! @brief Enable default auto locking.
-/*!
- When auto locking is turned on, the library automatically locks and unlocks
- files and indices as needed in a multi user environment.
-*/
-void xbSsv::EnableDefaultAutoLock() {
- this->bDefaultAutoLock = xbTrue;
-}
-
-//! @brief Disable defalt auto locking.
-/*!
- When auto locking is turned off, the library does not automatically lock
- and unlock files and indices as needed in a multi user environment.
- Locking is not needed in a single user environment.
-
-*/
-void xbSsv::DisableDefaultAutoLock() {
- this->bDefaultAutoLock = xbFalse;
-}
-/***************************************************************************/
-//! @brief Get default lock flavor
-/*!
- Currently one flavor. This routine is part of the structure to support
- future additional locking scenarios for Clipper and Foxpro.
- \returns 1
-*/
-xbInt16 xbSsv::GetDefaultLockFlavor() const {
- return iDefaultLockFlavor;
-}
-
-/***************************************************************************/
-//! @brief Set default lock flavor
-/*!
- Currently one flavor. This routine is part of the structure to support
- future additional locking scenarios for Clipper and Foxpro.
-*/
-void xbSsv::SetDefaultLockFlavor( xbInt16 iDefaultLockFlavor ) {
- this->iDefaultLockFlavor = iDefaultLockFlavor;
-}
-
-/***************************************************************************/
-//! @brief Set default lock wait
-/*!
- \param lLockWait Set default lock wait in milliseconds.
-*/
-void xbSsv::SetDefaultLockWait( xbInt32 lLockWait ) {
- this->lDefaultLockWait = lLockWait;
-}
-
-/***************************************************************************/
-//! @brief Get default lock wait
-/*!
- \returns Lock wait time in milliseconds.
-
-*/
-xbInt32 xbSsv::GetDefaultLockWait() const {
- return lDefaultLockWait;
-}
-#endif
-
-/***************************************************************************/
-//! @brief Get the multi user setting.
-/*!
- \returns xbTrue - Multi user mode turned on.<br>
- xbFalse - Multi user mode turned off.<br>
-*/
-xbBool xbSsv::GetMultiUser() const {
- return bMultiUser;
-}
-
-//! @brief Get the multi user setting.
-/*!
- \param bMultiUser xbTrue - Turn on Multi user mode.<br>
- xbFalse - Turn off Multi user mode.<br>
-*/
-void xbSsv::SetMultiUser( xbBool bMultiUser ) {
- this->bMultiUser = bMultiUser;
-}
-
-
-
-/************************************************************************/
-#ifdef XB_MDX_SUPPORT
-//! @brief Get the mdx file block size used when creating a memo file.
-/*!
- \returns system default setting for MDX block size.
-*/
-xbInt16 xbSsv::GetCreateMdxBlockSize() const {
- return iCreateMdxBlockSize;
-}
-
-/************************************************************************/
-//! @brief Create mdx block size.
-/*!
- This routine sets the mdx file block size at the system level. This value is
- used when the mdx index file is initially created so if you want to change it,
- this must be called before creating the table.
-
- \param iBlockSize - Block size, must be evenly divisible by 512 and <= 16384
- \returns XB_INVALID_BLOCK_SIZE<br>XB_NO_ERROR
-*/
-
-xbInt16 xbSsv::SetCreateMdxBlockSize( xbInt16 iBlockSize ){
-
- if( iBlockSize < 512 || iBlockSize > 16384 || iBlockSize % 512 )
- return XB_INVALID_BLOCK_SIZE;
- else
- iCreateMdxBlockSize = iBlockSize;
-
- return XB_NO_ERROR;
-}
-#endif
-
-/************************************************************************/
-#if defined (XB_NDX_SUPPORT) || defined (XB_MDX_SUPPORT)
-//! @brief Get Unique Key Opt
-/*!
- This routine returns the Unique Key Processing Option which is one of:
- XB_HALT_ON_DUPKEY
- XB_EMULATE_DBASE
-*/
-
-xbInt16 xbSsv::GetUniqueKeyOpt() const {
- return iUniqueKeyOpt;
-}
-
-//! @brief Set Unique Key Opt
-/*! @brief Set Unique Key Opt
- This routine Sets the Unique Key Processing Option which is one of:
- XB_HALT_ON_DUPKEY
- XB_EMULATE_DBASE
-*/
-xbInt16 xbSsv::SetUniqueKeyOpt( xbInt16 iOpt ){
- if( iOpt == XB_HALT_ON_DUPKEY || iOpt == XB_EMULATE_DBASE ){
- iUniqueKeyOpt = iOpt;
- return XB_NO_ERROR;
- } else {
- return XB_INVALID_OPTION;
- }
-}
-#endif
-/************************************************************************/
-#ifdef XB_BLOCKREAD_SUPPORT
-
-//! @brief Get Default Read Block Size
-/*!
- This routine returns the default read block size used when allocating
- buffer space for block reads of table data. Initial setting is 32768 bytes.
-*/
-xbUInt32 xbSsv::GetDefaultBlockReadSize() const {
- return ulDefaultBlockReadSize;
-}
-
-
-//! @brief Set Default Read Block Size
-/*!
- This routine sets the default read block size used when allocating
- buffer space for block reads of table data. Initial setting is 32768 bytes.
-*/
-void xbSsv::SetDefaultBlockReadSize( xbUInt32 ulDfltBlockReadSize ){
- ulDefaultBlockReadSize = ulDfltBlockReadSize;
-}
-
-#endif // XB_BLOCKREAD_SUPPORT
-/************************************************************************/
-
-
-
-
-} /* namespace */ \ No newline at end of file
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbstring.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbstring.cpp
deleted file mode 100755
index 89cefb6..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbstring.cpp
+++ /dev/null
@@ -1,2000 +0,0 @@
-/* xbstring.cpp
-
-XBase64 Software Library
-
-Copyright (c) 1997,2003,2014,2021,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
-
-*/
-
-//#ifdef __GNU LesserG__
-// #pragma implementation "xbstring.h"
-//#endif
-
-#include "xbase.h"
-
-
-namespace xb{
-
-XBDLLEXPORT const char * xbString::NullString = "";
-XBDLLEXPORT char xbString::cJunkBuf;
-
-/************************************************************************/
-//! @brief Destructor
-
-xbString::~xbString(){
- if (data != NULL)
- free(data);
-
-}
-
-/************************************************************************/
-//! @brief Constructor
-/*!
- \param ulSize - Allocation size. The allocation size is normally handled internally
- by the class, but it can be set in this constructor.
-*/
-xbString::xbString(xbUInt32 ulSize) {
- data = (char *)calloc(1, ulSize);
- this->size = ulSize;
-// memset( data, 0x00, ulSize ); - redundant, initialized by calloc
-}
-/************************************************************************/
-//! @brief Constructor
-/*!
- \param c - Initialize string to c.
-*/
-xbString::xbString(char c) {
- data = (char *)calloc(1, 2);
- data[0] = c;
- data[1] = 0;
- size = 2;
-}
-/************************************************************************/
-//! @brief Constructor
-/*!
- \param s - Initialize string to s.
-*/
-xbString::xbString( const char *s ) {
-
- if( s == NULL ){
- size = 0;
- data = NULL;
- } else {
- size = (xbUInt32) (strlen(s) + 1 );
- data = (char *) calloc( 1, size );
- xb_strcpy( data, s );
- }
- // ctor(s);
-}
-/************************************************************************/
-//! @brief Constructor
-/*!
- \param d - Initiailize string to d.
-*/
-xbString::xbString( xbDouble d ) {
- data = NULL;
- size = 0;
- Sprintf("%f", d);
-}
-/************************************************************************/
-//! @brief Constructor
-/*!
- \param s Initialize string to s.
- \param ulMaxLen Maximum length of string. Truncate any characters greater than ulMaxLen.
-*/
-xbString::xbString( const char *s, xbUInt32 ulMaxLen ) {
- xbUInt32 sSize = (xbUInt32) strlen( s );
- if( sSize < ulMaxLen )
- size = sSize;
- else
- size = ulMaxLen;
- data = (char *)calloc(1, size+1);
- for( xbUInt32 i = 0; i < size; i++ )
- data[i] = s[i];
- data[size] = '\0';
- size++; // account for null trailing byte
- return;
-}
-/************************************************************************/
-//! @brief Constructor
-/*!
- \param s Initialize string to s.
-*/
-xbString::xbString( const xbString &s ) {
- ctor(s.Str());
-}
-
-/************************************************************************/
-//! @brief Operator const char *
-/*!
- \returns Pointer to string data.
-*/
-xbString::operator const char *() const {
- return data ? data : NullString;
-}
-
-/************************************************************************/
-//! @brief Set operator =
-/*!
- \param s - Set the string to the string on the right of the equal sign.
-*/
-xbString &xbString::operator=( const xbString &s ) {
- return Set(s);
-}
-/************************************************************************/
-//! @brief Set operator =
-/*!
- \param s - Set the string to the string on the right of the equal sign.
-*/
-xbString &xbString::operator=( const char *s ) {
- return Set(s);
-}
-
-/************************************************************************/
-//! @brief Stream insertion operator <<
-/*!
- std::cout << MyString << std::endl;
-
- \param os Output stream
- \param s String to send to output stream
-*/
-std::ostream& operator<< ( std::ostream& os, const xbString & s ) {
- return os << s.Str();
-}
-/************************************************************************/
-//! @brief Append operator +=
-/*!
- \param s - Append s to the string.
-*/
-xbString &xbString::operator+=( const xbString &s ) {
-
- if (s.IsNull())
- return (*this);
-
- xbUInt32 Len = s.Len();
- xbUInt32 oldLen = this->Len();
- xbUInt32 newLen = Len + oldLen;
-
- data = (char *)realloc(data, newLen+1);
- if( !data )
- return (*this);
-
- if(oldLen == 0)
- data[0] = 0;
-
- char *t = data;
- t+= oldLen;
- for( xbUInt32 i = 0; i < Len; i++ )
- *t++ = s.GetCharacter(i+1);
-
- data[newLen] = '\0';
- size == 0 ? size += (Len + 1) : size += Len;
-
- return (*this);
-}
-/************************************************************************/
-//! @brief Append operator +=
-/*!
- \param s - Append s to the string.
-*/
-xbString &xbString::operator+=( const char *s ) {
-
- if (s == NULL)
- return (*this);
- xbUInt32 Len = (xbUInt32) strlen(s);
- xbUInt32 oldLen = this->Len();
- xbUInt32 newLen = Len + oldLen;
- data = (char *)realloc(data, newLen+1);
- if(oldLen == 0)
- data[0] = 0;
- for( xbUInt32 i = 0; i < Len; i++ )
- data[i+oldLen] = s[i];
- data[newLen] = '\0';
- // size += Len;
- size == 0 ? size+= (Len + 1) : size += Len;
- return (*this);
-}
-/************************************************************************/
-//! @brief Append operator +=
-/*!
- \param c - Append c to the string.
-*/
-xbString &xbString::operator+=( char c ) {
- xbUInt32 Len = 1;
- xbUInt32 oldLen = this->Len();
- data = (char *)realloc(data, oldLen+Len+1);
- data[oldLen] = c;
- data[oldLen+1] = 0;
- // size++;
- size == 0 ? size += 2 : size++;
- return (*this);
-}
-/************************************************************************/
-//! @brief Append operator -=
-/*!
- Append s to the right of this string, right trimming both strings.
- \param s - Append s to the right of the string value.
-*/
-xbString &xbString::operator-=( const xbString &s ) {
-
- Rtrim();
- if (s.IsNull())
- return (*this);
- xbUInt32 Len = s.Len();
- xbUInt32 oldLen = this->Len();
- xbUInt32 newLen = Len + oldLen;
-
- data = (char *)realloc(data, newLen+1);
- if(oldLen == 0)
- data[0] = 0;
-
- for( xbUInt32 i = 0; i < Len; i++ )
- data[i+oldLen] = s.GetCharacter(i+1);
-
- data[newLen] = '\0';
- //size += Len;
- size == 0 ? size += (Len+1) : size += Len;
- Rtrim();
- return (*this);
-}
-/************************************************************************/
-//! @brief Append operator -=
-/*!
- Append s to the right of this string, right trimming both strings.
- \param s - Append s to the right of the string value.
-*/
-xbString &xbString::operator-=(const char *s) {
-
- Rtrim();
- if (s == NULL)
- return (*this);
- xbUInt32 Len = (xbUInt32) strlen(s);
- xbUInt32 oldLen = this->Len();
- xbUInt32 newLen = Len + oldLen;
-
- data = (char *)realloc(data, newLen+1);
-
- if(oldLen == 0)
- data[0] = 0;
-
- for( xbUInt32 i = 0; i < Len; i++ )
- data[i+oldLen] = s[i];
- data[newLen] = '\0';
-
- //size += Len;
- size == 0 ? size += (Len+1) : size += Len;
-
- Rtrim();
- return (*this);
-}
-/************************************************************************/
-//! @brief Append operator -=
-/*!
- Append c to the right of this string, trimming right space on this string first.
- \param c - Append s to the right of the string value.
-*/
-xbString &xbString::operator-=(const char c) {
- Rtrim();
- xbUInt32 oldSize = size;
-
- // size += 1;
- size == 0 ? size += 2 : size += 1;
-
- data = (char *)realloc( data, size );
- if( oldSize == 0 ) data[0] = 0;
- data[size-2] = c;
- data[size-1] = 0;
- Trim();
- return (*this);
-}
-/************************************************************************/
-//! @brief Concatonate operator -
-/*!
- Concatonate left string with right string returning reference to new string.
- Both strings are trimmed.
-
- \param s1 Right string operator.
-*/
-xbString xbString::operator-(const xbString &s1) {
- xbString tmp( data );
- tmp -= s1;
- return tmp;
-}
-/************************************************************************/
-//! @brief Concatonate operator +
-/*!
- Concatonate left string with right string returning reference to new string.
-
- \param s1 Right string operator.
-*/
-xbString xbString::operator+( const char *s1) {
- xbString tmp( data );
- tmp += s1;
- return tmp;
-}
-/************************************************************************/
-//! @brief Concatonate operator +
-/*!
- Concatonate left string with right string returning reference to new string.
-
- \param s1 Right string operator.
-*/
-xbString xbString::operator+( const xbString &s1) {
- xbString tmp( data );
- tmp += s1;
- return tmp;
-}
-/************************************************************************/
-//! @brief Concatonate operator +
-/*!
- Concatonate left string with right string returning reference to new string.
-
- \param c Right string operator.
-*/
-
-xbString xbString::operator+( const char c) {
- xbString tmp( data );
- tmp += c;
- return tmp;
-}
-/************************************************************************/
-//! @brief operator []
-/*!
- \param n - Offset into the string of the byte to retrieve.
- \returns c - The character to return from the offset within the [] brackets.
-*/
-char &xbString::operator[]( xbUInt32 n ) const {
- if( n > 0 && n <= size )
- return data[n-1];
- else
- return cJunkBuf;
-}
-/************************************************************************/
-//! @brief operator []
-/*!
- \param n - Offset into the string of the byte to retrieve.
- \returns c - The character to return from the offset within the [] brackets.
-*/
-char &xbString::operator[]( xbInt32 n ) const {
- if( n > 0 && n <= (xbInt32) size )
- return data[n-1];
- else
- return cJunkBuf;
-}
-/************************************************************************/
-//! @brief operator ==
-/*!
- \param s String to compare
- \returns xbTrue - Strings match.<br>
- zbFalse - Strings don't match.<br>
-
-*/
-xbBool xbString::operator==( const xbString &s ) const {
-
- if( data == NULL || data[0] == 0 ) {
- if( s.data == NULL || s.data[0] == 0 )
- return true;
- return false;
- } else {
- if( s.data == NULL || s.data[0] == 0 )
- return false;
- return( strcmp(data,s.data) == 0 ? xbTrue : xbFalse );
- }
-}
-/************************************************************************/
-//! @brief operator ==
-/*!
- \param s String to compare
- \returns xbTrue - Strings match.<br>
- zbFalse - Strings don't match.<br>
-*/
-xbBool xbString::operator==( const char *s ) const {
-
- if (s == NULL) {
- if ( data == NULL)
- return true;
- return false;
- }
- if ((s[0] == 0) && data == NULL)
- return true;
- if ( data == NULL)
- return false;
- return( strcmp( data, s) == 0 ? xbTrue : xbFalse );
-}
-/************************************************************************/
-//! @brief operator !=
-/*!
- \param s String to compare
- \returns xbTrue - Strings don't match.<br>
- xbFalse - Strings match.<br>
-*/
-xbBool xbString::operator!=( const xbString &s ) const {
- if( data == NULL || data[0] == 0 ) {
- if( s.data == NULL || s.data[0] == 0 )
- return xbFalse; // NULL != NULL
- return xbTrue; // NULL != !NULL
- } else {
- if( s.data == NULL || s.data[0] == 0 )
- return xbTrue; // !NULL != NULL
- return( strcmp( data, s.data ) != 0 ? xbTrue : xbFalse ); // !NULL != !NULL
- }
-}
-/************************************************************************/
-//! @brief operator !=
-/*!
- \param s String to compare
- \returns xbTrue - Strings don't match.<br>
- zbFalse - Strings match.<br>
-*/
-xbBool xbString::operator!=( const char *s ) const {
- if( s == NULL || s[0] == 0 ) {
- if( data == NULL || data[0] == 0 )
- return xbFalse; // NULL != NULL
- return xbTrue; // NULL != !NULL
- } else {
- if( s == NULL || s[0] == 0 )
- return xbTrue; // !NULL != NULL
- return( strcmp( data, s ) != 0 ? xbTrue : xbFalse ); // !NULL != !NULL
- }
-}
-/************************************************************************/
-//! @brief operator <
-/*!
- \param s String to compare
- \returns xbTrue - Left string is less than the right string.<br>
- zbFalse - Left string is not less than the right string.<br>
-*/
-xbBool xbString::operator< ( const xbString &s ) const {
-
- if( data == NULL || data[0] == 0 ) {
- if( s.data == NULL || s.data[0] == 0 )
- return false;
- return true;
- } else {
- if( s.data == NULL || s.data[0] == 0 )
- return false;
- return ( strcmp(data, s.data) < 0 ? xbTrue : xbFalse );
- }
-}
-/************************************************************************/
-//! @brief operator >
-/*!
- \param s String to compare
- \returns xbTrue - Left string is greater than the right string.<br>
- zbFalse - Left string is not greater than the right string.<br>
-*/
-xbBool xbString::operator> ( const xbString &s ) const {
- if( data == NULL || data[0] == 0 ) {
- if( s.data == NULL || s.data[0] == 0 )
- return false;
- return false;
- } else {
- if( s.data == NULL || s.data[0] == 0 )
- return true;
- return( strcmp(data,s.data) > 0 ? xbTrue : xbFalse );
- }
-}
-/************************************************************************/
-//! @brief operator <=
-/*!
- \param s String to compare
- \returns xbTrue - Left string is less than or equal to the right string.<br>
- zbFalse - Left string is not less than or equal to the right string.<br>
-*/
-xbBool xbString::operator<=( const xbString &s ) const {
- if( data == NULL || data[0] == 0 ) {
- if( s.data == NULL || s.data[0] == 0 )
- return true;
- return true;
- } else {
- if( s.data == NULL || s.data[0] == 0 )
- return false;
- return( strcmp(data,s.data) <= 0 ? xbTrue : xbFalse );
- }
-}
-/************************************************************************/
-//! @brief operator >=
-/*!
- \param s String to compare
- \returns xbTrue - Left string is greater than or equal to the right string.<br>
- zbFalse - Left string is not greater than or equal to the right string.<br>
-*/
-xbBool xbString::operator>=( const xbString &s ) const {
- if( data == NULL || data[0] == 0 ) {
- if( s.data == NULL || s.data[0] == 0 )
- return true;
- return false;
- } else {
- if( s.data == NULL || s.data[0] == 0 )
- return true;
- return( strcmp(data, s.data) >= 0 ? xbTrue : xbFalse );
- }
-}
-
-/************************************************************************/
-//! @brief Add a prefixing back slash to specified characters in the string.
-/*!
- \param c Character to prefix with a backslash.
- \returns Reference to this string.
-*/
-xbString &xbString::AddBackSlash( char c ) {
-
- xbUInt32 lCnt = CountChar( c );
- if( lCnt == 0 )
- return *this;
- char *p;
- if(( p = (char *)calloc( 1, size + lCnt )) == NULL )
- return *this;
-
- char *p2 = p;
- for( xbUInt32 lS = 0; lS < size; lS++ ){
- if( data[lS] == c )
- *p2++ = '\\';
- *p2++ = data[lS];
- }
- if( data )
- free( data );
- data = p;
-
- // size += lCnt;
- size == 0 ? size += (lCnt+1) : size += lCnt;
-
- return *this;
-}
-/************************************************************************/
-//! @brief Append data to string.
-/*!
- \param s String data to append.
- \returns Reference to this string.
-*/
-xbString &xbString::Append( const xbString &s ) {
- *this += s;
- return *this;
-}
-
-/************************************************************************/
-//! @brief Append data to string.
-/*!
- \param s String data to append.
- \returns Reference to this string.
-*/
-xbString &xbString::Append( const char *s ) {
- *this += s;
- return *this;
-}
-/************************************************************************/
-//! @brief Append data to string.
-/*!
- \param c String data to append.
- \returns Reference to this string.
-*/
-xbString &xbString::Append( char c ) {
- *this += c;
- return *this;
-}
-/************************************************************************/
-//! @brief Append data to string.
-/*!
- \param s String data to append.
- \param ulByteCount Maximum number of bytes to append.
- \returns Reference to this string.
-*/
-xbString &xbString::Append( const char *s, xbUInt32 ulByteCount ) {
-
- if ( s == NULL || !*s || ulByteCount == 0)
- return (*this);
-
- xbUInt32 ulOrigLen = this->Len();
-
- // s might not be null byte at the end, can't use strlen
- // xbUInt32 ulAddLen = strlen( s );
- xbUInt32 ulAddLen = 0;
- const char *p = s;
-
- while( ulAddLen < ulByteCount && *p ){
- p++;
- ulAddLen++;
- }
-
- if( ulAddLen > ulByteCount )
- ulAddLen = ulByteCount;
-
- size = ulOrigLen + ulAddLen + 1;
- data = (char *) realloc( data, size );
-
- for( xbUInt32 i = 0; i < ulAddLen; i++ )
- data[i+ulOrigLen] = s[i];
-
- data[size-1] = 0x00;
- return (*this);
-}
-
-/************************************************************************/
-//! @brief Assign portion of string.
-/*!
- \param sStr - Source string for copy operation. sStr needs to be a Null terminated string.
- \param ulStartPos - Starting position within source string.
- \param ulCopyLen - Length of data to copy.
- \returns Reference to this string.
-*/
-xbString &xbString::Assign(const char * sStr, xbUInt32 ulStartPos, xbUInt32 ulCopyLen){
- if(data){
- free(data);
- data = 0;
- size = 0;
- }
- xbUInt32 lLen = (xbUInt32) strlen( sStr );
- if( ulStartPos > lLen ){
- size = 0;
- return( *this );
- }
- if((( ulCopyLen - 1) + ulStartPos ) > lLen )
- ulCopyLen = lLen - ulStartPos + 1;
- data = (char *)calloc(1, ulCopyLen + 1);
-
- //size = ulCopyLen + 1;
- size == 0 ? size += (ulCopyLen+1) : size += ulCopyLen;
-
- for( xbUInt32 i = 0; i < ulCopyLen; i++ )
- data[i] = sStr[i + ulStartPos - ((xbUInt32) 1)];
- data[ulCopyLen] = '\0';
- return (*this);
-}
-/************************************************************************/
-//! @brief Assign portion of string.
-/*!
- \param sStr - Source string for copy operation. sStr needs to be a Null terminated string.
- \param ulStartPos - Starting position within source string.
- \returns Reference to this string.
-*/
-xbString &xbString::Assign(const char * sStr, xbUInt32 ulStartPos){
- if(data){
- free(data);
- data = 0;
- size = 0;
- }
- xbUInt32 ulSrcLen = (xbUInt32) strlen( sStr );
- if( ulStartPos > ulSrcLen ){
- size = 0;
- return( *this );
- }
- xbUInt32 ulCopyLen;
- ulCopyLen = ulSrcLen - ulStartPos + 1;
- data = (char *)calloc(1, ulCopyLen + 1);
-
- size = ulCopyLen + 1;
-
- for( xbUInt32 i = 0; i < ulCopyLen; i++ )
- data[i] = sStr[i + ulStartPos - ((xbUInt32) 1)];
- data[ulCopyLen] = '\0';
- return (*this);
-}
-
-/************************************************************************/
-//! @brief Assign portion of string.
-/*!
- \param sStr - Source string for copy operation. sStr needs to be a Null terminated string.
- \param ulStartPos - Starting position within source string.
- \param ulCopyLen - Length of data to copy.
- \returns Reference to this string.
-*/
-xbString &xbString::Assign(const xbString& sStr, xbUInt32 ulStartPos, xbUInt32 ulCopyLen){
- if(data){
- free(data);
- data = 0;
- size = 0;
- }
- xbUInt32 ulSrcLen = sStr.Len();
- if( ulStartPos > ulSrcLen ){
- size = 0;
- return( *this );
- }
- if((( ulCopyLen - 1) + ulStartPos ) > ulSrcLen )
- ulCopyLen = ulSrcLen - ulStartPos + 1;
- data = (char *)calloc(1, ulCopyLen + 1);
- size = ulCopyLen + 1;
- for( xbUInt32 i = 0; i < ulCopyLen; i++ )
- data[i] = sStr[i + ulStartPos];
- data[ulCopyLen] = '\0';
- return (*this);
-}
-/************************************************************************/
-//! @brief Assign portion of string.
-/*!
- \param sStr - Source string for copy operation. sStr needs to be a Null terminated string.
- \param ulStartPos - Starting position within source string.
- \returns Reference to this string.
-*/
-xbString &xbString::Assign(const xbString& sStr, xbUInt32 ulStartPos){
- if(data){
- free(data);
- data = 0;
- size = 0;
- }
- xbUInt32 ulSrcLen = sStr.Len();
- if( ulStartPos > ulSrcLen ){
- size = 0;
- return( *this );
- }
- xbUInt32 ulCopyLen;
- ulCopyLen = ulSrcLen - ulStartPos + 1;
- data = (char *)calloc(1, ulCopyLen + 1);
- size = ulCopyLen;
- for( xbUInt32 i = 0; i < ulCopyLen; i++ )
- data[i] = sStr[i + ulStartPos];
- data[ulCopyLen] = '\0';
- size++;
- return (*this);
-}
-/************************************************************************/
-//! @brief Copy a string
-/*!
- \returns xbString.
-*/
-xbString xbString::Copy() const {
- return( *this );
-}
-/************************************************************************/
-//! @brief Count the number of characters in the string.
-/*!
- \param c Character to count.
- \param iOpt 0 - Count the number of characters.<br>
- 1 - Count the number of characters not between single or double quotes.
- \returns The number of characters.
-*/
-xbUInt32 xbString::CountChar( char c, xbInt16 iOpt ) const {
- if( iOpt == 0 )
- return CountChar( c );
- else{
- xbBool bSingleQuote = xbFalse;
- xbBool bDoubleQuote = xbFalse;
- char cPrevChar = 0x00;
- xbUInt32 i,j;
- for( i = 0, j = 0; i < size; i++ ){
- if( bSingleQuote && data[i] == '\'' && cPrevChar != '\\' ){
- bSingleQuote = xbFalse;
- }
- else if( bDoubleQuote && data[i] == '"' && cPrevChar != '\\' ){
- bDoubleQuote = xbFalse;
- }
- else if( data[i] == '\'' && cPrevChar != '\\' && !bDoubleQuote ){
- bSingleQuote = xbTrue;
- }
- else if( data[i] == '"' && cPrevChar != '\\' && !bSingleQuote ){
- bDoubleQuote = xbTrue;
- }
- else if( !bDoubleQuote && !bSingleQuote && data[i] == c ){
- j++;
- }
- cPrevChar = data[i];
- }
- return j;
- }
-}
-/************************************************************************/
-//! @brief Count the number of characters in the string.
-/*!
- \param c Character to count.
- \returns The number of characters.
-*/
-xbUInt32 xbString::CountChar( char c ) const {
- xbUInt32 i,j;
- for( i = 0,j = 0; i < size; i++ )
- if( data[i] == c )
- j++;
- return j;
-}
-/************************************************************************/
-void xbString::ctor( const char *s ) {
-
- // this routine assumes it was called by one of the constructors.
-
- if (s == NULL) {
- data = NULL;
- size = 0;
- return;
- }
-
- size = (xbUInt32) (strlen(s) + 1);
- data = (char *) calloc( 1, size);
-
- xb_strcpy(data, s);
-}
-/************************************************************************/
-//! @brief Convert hex character to string.
-/*!
- This routine converts a four byte string in the format of 0x00 to a one byte char value.
- The first four bytes of the string must be in the format 0x00.
- Anything past the first four bytes is disregarded.
-
- \param cOut Output character.
- \returns XB_INVALID_PARM on error<br>
- XB_NO_ERROR on success.
-*/
-xbInt16 xbString::CvtHexChar( char &cOut ){
-
- int j, k;
- char c;
-
- if( Len() < 4 || data[0] != '0' || (data[1]!='X' && data[1]!='x' ))
- return XB_INVALID_PARM;
-
- c = (char) toupper( data[2] );
- j = ( c > '9' ? c - 'A' + 10 : c - '0' );
- c = (char)toupper( data[3] );
- k = ( c > '9' ? c - 'A' + 10 : c - '0' );
- j = ( j << 4 ) + k;
-
- cOut = ( char ) j;
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! @brief Convert string of hex characters to string.
-/*!
-
- This routine converts a string of four byte format of 0x00 to a string of one byte chars.
-
- \param sOut Output string of converted characters.
- \returns XB_INVALID_PARM on error<br>
- XB_NO_ERROR on success.
-*/
-xbInt16 xbString::CvtHexString( xbString &sOut ){
- char c;
- xbString ws;
- ws = data;
- sOut = "";
- xbInt16 iRc;
- while( ws.Len()){
- if(( iRc= ws.CvtHexChar( c )) != XB_NO_ERROR )
- return iRc;
- sOut += c;
- ws.Ltrunc( 4 );
- }
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! @brief Convert string to xbUInt64 number
-/*!
- \param ullOut - output unsigned long long.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbString::CvtULongLong( xbUInt64 &ullOut ){
-
- // version 1 - fast, but no data checking
- ullOut = 0;
- char *s = data;
- int i = 0;
- while( *s ){
- ullOut *= 10;
- ullOut += (xbUInt64) *s - '0';
- s++;
- i++;
- }
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! @brief Convert string to xbInt64 number
-/*!
- \param llOut - output long long.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbString::CvtLongLong( xbInt64 &llOut ){
-
- // version 1 - fast, but no data checking
- llOut = 0;
- char *s = data;
- int i = 0;
- while( *s ){
- llOut *= 10;
- llOut += (xbInt64) *s - '0';
- s++;
- i++;
- }
- return XB_NO_ERROR;
-}
-
-/************************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-void xbString::Dump( const char * title, xbInt16 iHexOption ) const {
- fprintf(stdout, "%s StringSize[%d] DataLen=[%d] data=[%s]\n", title, size, Len(), data );
- if( iHexOption ){
- std::cout << "Hex values" << std::endl;
- for( xbUInt32 i = 0; i < strlen( data ); i++ )
- printf( " %x", data[i] );
- std::cout << std::endl;
- }
-}
-void xbString::Dump( const char * title ) const {
- Dump( title, 0 );
-}
-
-void xbString::DumpHex( const char * title ) const {
- Dump( title, 1 );
-}
-#endif
-
-/************************************************************************/
-//! @brief Extract an element out of a delimited string.
-/*!
- \param sSrc Source string.
- \param cDelim Delimiter.
- \param lSkipCnt Number of delimiters to skip.
- \param iOpt 0 - ignore single and double quotes.<br>
- 1 - ignore delimiters between single or double quotes.
- \returns Reference to string extracted from element.
-*/
-xbString &xbString::ExtractElement( xbString &sSrc, char cDelim, xbUInt32 lSkipCnt, xbInt16 iOpt )
-{
- return ExtractElement( sSrc.Str(), cDelim, lSkipCnt, iOpt );
-}
-
-/************************************************************************/
-//! @brief Extract an element out of a delimited string.
-/*!
- \param pSrc Source string.
- \param cDelim Delimiter.
- \param lSkipCnt Number of delimiters to skip.
- \param iOpt 0 - ignore single and double quotes.<br>
- 1 - ignore delimiters between single or double quotes.
- \returns Reference to string extracted from element.
-*/
-xbString &xbString::ExtractElement( const char *pSrc, char cDelim, xbUInt32 lSkipCnt, xbInt16 iOpt )
-{
- /* opt values
- 0 - ignore single and double quotes
- 1 - ignore delimiters between single or double quotes
- */
-
- xbUInt32 lLen;
- xbUInt32 lCurCnt = 0;
- xbBool bInSingleQuotes = xbFalse;
- xbBool bInDoubleQuotes = xbFalse;
- char cPrevChar = 0x00;
- const char *s = pSrc;
- const char *pAnchor;
-
- /* skip past skipcnt delimiters */
- while( *s && lCurCnt < (lSkipCnt-1) ){
- if( iOpt == 0 ){
- if( *s == cDelim )
- lCurCnt++;
- } else {
- if( *s == cDelim && !bInSingleQuotes && !bInDoubleQuotes ){
- lCurCnt++;
- } else if( *s == '\'' && !bInDoubleQuotes && cPrevChar != '\\' ){
- if( bInSingleQuotes == xbTrue )
- bInSingleQuotes = xbFalse;
- else
- bInSingleQuotes = xbTrue;
- } else if( *s == '"' && !bInSingleQuotes && cPrevChar != '\\' ){
- if( bInDoubleQuotes == xbTrue )
- bInDoubleQuotes = xbFalse;
- else
- bInDoubleQuotes = xbTrue;
- }
- }
- cPrevChar = *s;
- s++;
- }
-
- /* at the beginning of the field */
- pAnchor = s;
- xbBool bDone = xbFalse;
- while( *s && !bDone ){
- if( iOpt == 0 ){
- if( *s == cDelim )
- bDone = xbTrue;
- } else {
- if( *s == cDelim && !bInSingleQuotes && !bInDoubleQuotes ){
- bDone = xbTrue;
- } else if( *s == '\'' && !bInDoubleQuotes && cPrevChar != '\\' ){
- if( bInSingleQuotes == xbTrue )
- bInSingleQuotes = xbFalse;
- else
- bInSingleQuotes = xbTrue;
- } else if( *s == '"' && !bInSingleQuotes && cPrevChar != '\\' ){
- if( bInDoubleQuotes == xbTrue )
- bInDoubleQuotes = xbFalse;
- else
- bInDoubleQuotes = xbTrue;
- }
- }
- cPrevChar = *s;
- s++;
- }
-
- // if at end of string, go back one and drop the delimiter
- if( *s ) s--;
-
- lLen = (xbUInt32)(s - pAnchor);
-
- /* copy data */
- data = (char *) realloc( data, lLen+1 );
- memcpy( data, pAnchor, lLen );
- data[lLen] = 0;
- this->size = lLen+1;
- return *this;
-}
-
-/************************************************************************/
-//! @brief Get a character by position
-/*!
- \param n - Position in string to extract. First position is 1 (not 0).
- \returns Character from position n, or null.
-*/
-char xbString::GetCharacter( xbUInt32 n ) const {
- if( n > 0 && n <= size )
- return data[n-1];
- else
- return 0x00;
-}
-/************************************************************************/
-//! @brief Get the position of the last occurrence of a given character.
-/*!
- \param c - Character to search for.
- \returns Last position of character in the string.
-*/
-xbUInt32 xbString::GetLastPos(char c) const {
-
- if (data == NULL)
- return 0;
-
- char *p = data;
- xbUInt32 iPos = 0;
- xbUInt32 hPos = 0;
- while( *p && iPos++ < ( size - 1 )){
- if( *p == c )
- hPos = iPos;
- p++;
- }
- if( hPos )
- return hPos;
- else
- return 0;
-}
-/************************************************************************/
-//! @brief Get the position of the last occurrence of a given string.
-/*!
- \param s - String to search for.
- \returns Last position of character in the string.
-*/
-xbUInt32 xbString::GetLastPos(const char* s) const{
-
- if (data == NULL)
- return 0;
-
- char *p = data;
- char *saveP = NULL;
- while( p ){
- p = strstr( p, s);
- if( p ){
- saveP = p;
- p++;
- }
- }
- if (saveP == NULL)
- return 0;
- return (xbUInt32)(saveP - data) + 1;
-}
-/************************************************************************/
-//! @brief Get the path separator out of the string.
-/*!
- This method assumes the string is a valid path name.
- If it is, it returns either / or \.
- \returns Char value containing either / or \ depending on OS.
-*/
-char xbString::GetPathSeparator() const {
-
- if (data == NULL)
- return 0x00;
- char *p = data;
- while( *p ){
- if( *p == '\\' || *p == '/' )
- return *p;
- else
- p++;
- }
- return 0x00;
-}
-
-/************************************************************************/
-//! @brief Retrieve the size of the string buffer.
-/*!
- \returns Size of string buffer including the null terminating byte.
-*/
-xbUInt32 xbString::GetSize() const {
- return size;
-}
-
-/************************************************************************/
-//! @brief Determine if the string has any alpha characters
-/*!
- \returns xbTrue - String contains one or more aloha characters.<br>
- xbFalse - String contains no alpha characters.
-*/
-xbBool xbString::HasAlphaChars() const {
- for( xbUInt32 i = 0; i < size; i++ )
- if( isalpha( data[i] ))
- return xbTrue;
- return xbFalse;
-}
-
-
-/************************************************************************/
-//! @brief Determine if string is empty
-/*!
- \returns xbTrue if string is empty.<br>
- xbFalse if string is not empty.
-*/
-xbBool xbString::IsEmpty() const {
- if( data == NULL )
- return true;
- if( data[0] == 0 )
- return xbTrue;
- return xbFalse;
-}
-
-/************************************************************************/
-//! @brief Determine if string is NULL
-/*!
- \returns xbTrue if string is NULL.<br>
- xbFalse if string is not NULL.
-*/
-xbBool xbString::IsNull() const {
- return( data == NULL );
-}
-
-
-/************************************************************************/
-//! @brief Retain left part of string, drop rightmost characters.
-/*!
- \param ulLen New string length, truncate rightmost excess.
- \returns Reference to string.
-*/
-xbString &xbString::Left( xbUInt32 ulLen ) {
- return Mid( 1, ulLen );
-}
-
-/************************************************************************/
-//! @brief Retrieve length of current string.
-/*!
- \returns String length, excluding the terminating null byte.
-*/
-// return length of string
-xbUInt32 xbString::Len() const {
- return( data ? (xbUInt32) strlen(data) : 0 );
-}
-
-/************************************************************************/
-//! @brief Left trim white space from string.
-/*!
- \returns Reference to this string.
-*/
-xbString &xbString::Ltrim(){
-
- if( !data )
- return *this;
-
- char *p = data;
- if( !*p || (*p && *p != ' ') )
- return *this; /* nothing to do */
-
- xbUInt32 s = 0;
- while( *p && *p == ' ' ){
- p++;
- s++;
- size--;
- }
-
- xbUInt32 i;
- for( i = 0; i < size; i++ )
- data[i] = data[i+s];
- data[i] = 0x00;
- data = (char *) realloc( data, size );
-
- return *this;
-
-}
-
-/************************************************************************/
-//! @brief Left truncate string
-/*!
- \param ulCnt Number of bytes to remove from the left.
- \returns Reference to this string.
-*/
-xbString &xbString::Ltrunc( xbUInt32 ulCnt ){
- if( ulCnt >= size ){
- if( size > 0 ){
- free( data );
- data = NULL;
- size = 0;
- }
- return *this;
- }
-
- char * ndata;
- char * p;
- ndata = (char *) calloc( 1, size - ulCnt );
- p = data;
- p += ulCnt;
- xb_strcpy( ndata, p );
- free( data );
- data = ndata;
- size = size - ulCnt;
- return *this;
-}
-
-/************************************************************************/
-//! @brief Extract portion of data from string
-/*!
- \param ulStartPos Starting position
- \param ulTargLen Length
- \returns Reference to string
-*/
-xbString &xbString::Mid( xbUInt32 ulStartPos, xbUInt32 ulTargLen ){
-
- // this is a 1 based routine
- if( ulStartPos == 0 )
- return *this;
-
- if( data == NULL )
- return( *this );
- if( data[0] == 0 )
- return( *this );
- if( ulStartPos > Len() )
- return( *this );
-/*
- // Resize( ulTargLen + 1 );
- char *pTarg = data;
- char *pSrc = data + ulStartPos - 1;
- for( xbUInt32 l = 0; l < ulTargLen; l++ )
- *pTarg++ = *pSrc++;
- *pTarg = 0x00;
- // Resize( ulTargLen + 1 );
- */
-
- char * newData = (char *) calloc( 1, ulTargLen + 1 );
- char *pTarg = newData;
- char *pSrc = data + ulStartPos - 1;
- for( xbUInt32 l = 0; l < ulTargLen; l++ )
- *pTarg++ = *pSrc++;
- *pTarg = 0x00;
-
- free( data );
- data = newData;
- size = ulTargLen + 1;
-
- return *this;
-}
-
-/************************************************************************/
-//! @brief Left pad string
-/*!
- \param c Padding character.
- \param ulNewLen New string length.
- \returns Reference to this string.
-*/
-xbString &xbString::PadLeft( char c, xbUInt32 ulNewLen ){
-
- xbUInt32 srcLen;
- if( data )
- srcLen = (xbUInt32) strlen( data );
- else
- srcLen = 0;
-
- if( srcLen >= ulNewLen )
- return *this;
-
- char * newData = (char *) calloc( 1, ulNewLen + 1 );
- xbUInt32 i;
- for( i = 0; i < ulNewLen - srcLen; i++ )
- newData[i] = c;
-
- char *targ = &newData[i];
- xb_strcpy( targ, data );
- free( data );
- data = newData;
- size = ulNewLen + 1;
- return *this;
-}
-
-/************************************************************************/
-//! @brief Right pad string
-/*!
- \param c Padding character.
- \param ulNewLen New string length.
- \returns Reference to this string.
-*/
-xbString &xbString::PadRight( char c, xbUInt32 ulNewLen ){
- xbUInt32 srcLen = (xbUInt32) strlen( data );
- if( srcLen >= ulNewLen )
- return *this;
- data = (char *) realloc( data, ulNewLen + 1 );
- xbUInt32 i;
- for( i = srcLen; i < ulNewLen; i++ )
- data[i] = c;
- data[i] = 0x00;
- size = ulNewLen + 1;
- return *this;
-}
-
-/************************************************************************/
-//! @brief Determine position of a given character
-/*!
- \param c Seek character
- \param ulStartPos starting position for search, first position is 1
- \returns Position within string. Returns 0 if not found.
-*/
-xbUInt32 xbString::Pos(char c, xbUInt32 ulStartPos ) const {
-
- if (data == NULL)
- return 0;
- char *p = data;
-
- if( ulStartPos >= size )
- return 0;
-
- xbUInt32 iPos = 0;
- while( (iPos+1) < ulStartPos ){
- p++;
- iPos++;
- }
- xbBool bFound = 0;
- while( *p && !bFound && iPos < ( size - 1 )){
- if( *p == c )
- bFound = 1;
- else {
- iPos++;
- p++;
- }
- }
-
- if( bFound )
- return iPos + 1;
- else
- return 0;
-}
-
-/************************************************************************/
-//! @brief Determine position of a given character
-/*!
- \param c Seek character
- \returns Position within string. Returns 0 if not found.
-*/
-xbUInt32 xbString::Pos(char c) const {
-
- if (data == NULL)
- return 0;
- char *p = data;
- xbUInt32 iPos = 0;
- int iFound = 0;
- while( *p && !iFound && iPos < ( size - 1 )){
- if( *p == c )
- iFound = 1;
- else {
- iPos++;
- p++;
- }
- }
- if( iFound )
- return iPos + 1;
- else
- return 0;
-}
-
-/************************************************************************/
-//! @brief Determine position of a given substring
-/*!
- \param s Substring
- \returns Position within string. Returns 0 if not found.
-*/
-xbUInt32 xbString::Pos(const char* s) const{
-
- if (data == NULL)
- return 0;
-
- char *p = strstr(data, s);
- if ( p == NULL)
- return 0;
-
- return (xbUInt32)(p - data + 1);
-}
-
-/************************************************************************/
-//! @brief Insert character into string
-/*!
- \param ulPos Insertion position.
- \param c Character to insert.
- \returns Reference to this string.
-*/
-xbString &xbString::PutAt(xbUInt32 ulPos, char c){
- if((ulPos-1) > Len() )
- return *this;
- data[ulPos-1] = c;
- return *this;
-}
-
-/************************************************************************/
-//! @brief Remove portion of string.
-/*!
- \param ulStartPos Starting position for removal operation.
- \param ulDelSize Size of deletion.
- \returns Reference to string.
-*/
-xbString &xbString::Remove(xbUInt32 ulStartPos, xbUInt32 ulDelSize ) {
- if( data == NULL )
- return( *this );
- if( data[0] == 0 )
- return( *this );
- xbUInt32 srcLen = Len();
-
- if( ulStartPos > srcLen || ulStartPos < 1 || ulDelSize < 1 )
- return( *this );
-
- if(( ulStartPos + ulDelSize - 1) >= size ){
- data[ulStartPos-1] = 0x00;
- size = ulStartPos;
- return( *this );
- }
-
- char *t;
- char *s;
- t = data + (ulStartPos - 1);
- s = t + ulDelSize;
- size -= ulDelSize;
- while( *s )
- *t++ = *s++;
- *t = 0x00;
- return( *this );
-}
-
-/************************************************************************/
-//! @brief Replace a value within a string with another value
-/*!
- \param sReplace - Character string to replace.
- \param sReplaceWith - Character string to replace with
- \param iOption - 0 = All occurrences, 1 = first occurrence
- \returns Reference to this string.
-*/
-
-//the new size includes the null termination byte
-xbString &xbString::Replace( const char *sReplace, const char *sReplaceWith, xbInt16 iOption ){
-
- xbBool bDone = xbFalse;
- xbUInt32 ulPos;
- xbUInt32 ulNewLen;
- xbUInt32 ulReplaceWithLen;
- xbUInt32 ulRsLen; // size of right side of string after replaced data
- xbUInt32 ulSp2;
- char *sBuf2;
-
- const char *s; // source ptr
- char *t; // target ptr
-
- while( !bDone ){
- ulPos = Pos( sReplace );
- if( ulPos == 0 ){
- bDone = xbTrue;
- } else {
-
- ulReplaceWithLen = (xbUInt32) strlen( sReplaceWith );
- ulNewLen = this->size + ulReplaceWithLen - (xbUInt32) strlen( sReplace );
- sBuf2 = (char *) calloc( 1, ulNewLen );
-
- // copy part1
- t = sBuf2;
- s = data;
- for( xbUInt32 ul = 0; ul < ulPos-1; ul++ )
- *t++ = *s++;
-
- // copy part2
- s = sReplaceWith;
- for( xbUInt32 ul = 0; ul < ulReplaceWithLen; ul++ )
- *t++ = *s++;
-
- // copy part3
- ulSp2 = ulPos + (xbUInt32) strlen( sReplace );
- s = data;
- s+= (ulSp2 - 1);
- ulRsLen = (xbUInt32) strlen( s );
- for( xbUInt32 ul = 0; ul < ulRsLen; ul++ )
- *t++ = *s++;
-
- if( iOption )
- bDone = xbTrue;
-
- free(data);
- data = sBuf2;
- size = ulNewLen;
- }
- }
- return *this;
-}
-
-/************************************************************************/
-//! @brief Resize a string
-/*!
- \param ulSize - New string size, including null termination byte.
- \returns Reference to this string.
-*/
-//the new size includes the null termination byte
-xbString &xbString::Resize(xbUInt32 ulSize) {
-
-// data = (char *) realloc( data, ulSize );
-
-
-// original
- data = (char *) realloc( data, ulSize );
-
- if( ulSize > 0 )
- data[ulSize-1] = 0;
- this->size = ulSize;
- return *this;
-}
-/************************************************************************/
-//! @brief Right trim the string.
-/*!
- This routine removes any trailing white space on the string.
-
- \returns Reference to string.
-*/
-xbString &xbString::Rtrim(){
-
- xbUInt32 l = Len();
- if( l == 0 )
- return *this;
-
- xbUInt32 ulOrigSize = size;
- l--;
-
- for(;;) {
- if( data[l] != ' ' )
- break;
- data[l] = 0;
- size--;
- if( l == 0 )
- break;
- l--;
- }
-
- if( ulOrigSize != size )
- data = (char * ) realloc( data, size );
- return *this;
-}
-
-/************************************************************************/
-//! @brief Set the value of the string.
-/*!
-
- Note: This routine fails if you try to set the string to itself or some part of itself.
-
- \param s Value to set the string.
- \returns Reference to string.
-
-*/
-xbString &xbString::Set( const char *s ) {
-
- if(data != NULL){
- free(data);
- data = NULL;
- }
- if( s == NULL || !*s ) {
- if( data )
- free( data );
- data = NULL;
- size = 0;
- } else {
- //data = (char *)calloc(1, strlen(s) + 1 );
- data = (char *) realloc( data, strlen(s) + 1 );
- xb_strcpy(data, s);
- size = (xbUInt32) (strlen(data) + 1);
- }
- return (*this);
-}
-/************************************************************************/
-//! @brief Set the value of the string.
-/*!
- \param s Value to set the string.
- \returns Reference to string.
-*/
-xbString &xbString::Set( const xbString &s ) {
-
-// if( s.Str() == NULL || s.Len() == 0 ){
-
- if( s.Str() == NULL ){
- if( data ) free( data );
- data = NULL;
- size = 0;
- } else {
- xbUInt32 ulLen = s.Len();
- char *p = (char *) calloc( 1, ulLen + 1 );
- xb_strcpy( p, s.Str());
- size = ulLen + 1;
- if( data ) free( data );
- data = p;
- }
- return (*this );
-}
-
-/************************************************************************/
-//! @brief Set the value of the string.
-/*!
-
- Note: This routine fails if you try to set the string to itself or some part of itself.
-
- \param s Value to set the string.
- \param ulSize Maximum size of resultant string.
- \returns Reference to string.
-*/
-
-xbString &xbString::Set(const char *s, xbUInt32 ulSize) {
-
- if( data != NULL )
- free( data );
-
- if(s == NULL) {
- data = NULL;
- size = 0;
- return (*this);
- }
-
- data = (char *) calloc( 1, ulSize+1 );
- char *pTarget = data;
- for( xbUInt32 i = 0; i < ulSize; i++ ){
- *pTarget = *s;
- pTarget++;
- s++;
- }
- this->size = ulSize + 1;
- return *this;
-}
-
-
-/************************************************************************/
-//! @brief Set the string to long integer numeric value.
-/*!
- \param lNum Value to set the string
- \returns Reference to this string.
-*/
-xbString &xbString::SetNum(xbInt32 lNum) {
- Sprintf("%ld", lNum);
- return *this;
-}
-
-/************************************************************************/
-//! @brief Printf routine for formatting a string.
-/*!
- See documentation on the standard C printf function for how to use this.
-
- MyString.Sprintf( "a number %d some text %s", 100, "test text data" );
-
- \param sFormat A format specifier
- \returns Reference to a formatted string
-*/
-xbString &xbString::Sprintf( const char *sFormat, ...) {
-
- xbInt32 iRc;
- va_list ap;
- char *t;
-
-#ifdef HAVE__VSNPRINTF_S_F
-
- va_start( ap, sFormat );
- size = (xbUInt32) _vsnprintf_s( NULL, 0, sFormat, ap ) + 1;
- va_end( ap );
-
- t = (char *) malloc( size );
- if( !t ){
- size = 0;
- return( *this );
- }
-
- va_start( ap, sFormat );
- iRc = _vsnprintf_s( t, size, sFormat, ap );
- va_end( ap );
-
-#else
-#ifdef HAVE_VSPRINTF_S_F
-
- va_start( ap, sFormat );
- // size = (xbUInt32) vsprintf_s( NULL, 0, sFormat, ap ) + 1;
- size = (xbUInt32) _vscprintf( sFormat, ap ) + 1;
- va_end( ap );
-
- t = (char *) malloc( size );
- if( !t ){
- size = 0;
- return( *this );
- }
-
- va_start( ap, sFormat );
- iRc = vsprintf_s( t, size, sFormat, ap );
- va_end( ap );
-
-#else
-#ifdef HAVE_VSNPRINTF_F
-
- va_start( ap, sFormat );
- size = (xbUInt32) vsnprintf( NULL, 0, sFormat, ap) + 1;
- va_end( ap );
-
- t = (char *) calloc( 1, size );
- if( !t ){
- size = 0;
- return( *this );
- }
- va_start( ap, sFormat );
- iRc = vsnprintf( t, size, sFormat, ap );
- va_end( ap );
-
-# else
-# error "Fatal error building [xbstring.cpp] - You have neither _vsnprintf_s nor vsnprintf_s."
-# endif
-#endif
-#endif
-
- if( iRc < 0 ){
- if( data )
- free( data );
- data = NULL;
- size = 0;
- } else {
- if( data )
- free( data );
- data = t;
- }
- return( *this );
-}
-
-/************************************************************************/
-//! @brief Return string data
-/*!
- \returns char * to string data or NULL if string is empty
-*/
-const char *xbString::Str() const {
- return data ? data : NullString;
-}
-
-/************************************************************************/
-//! @brief Copy all or part of string to character array
-/*!
- \param cDest pointer to destination buffer.
- \param n Number of bytest to copy. It is the responsibility of the application
- to verify the buffer is large enough to hold the string contents.
- \returns char * to result
-
-*/
-char *xbString::strncpy( char * cDest, xbUInt32 n ) const {
- xbUInt32 i;
- xbUInt32 ulLen;
- n > (size-1) ? ulLen = size-1 : ulLen = n;
- memset( cDest, 0x00, ulLen );
- for( i = 0; i < ulLen; i++ )
- cDest[i] = data[i];
-// cDest[i] = 0x00;
- return cDest;
-}
-/************************************************************************/
-//! @brief Swap characters
-/*!
- \param cFrom character to replace.
- \param cTo character to replace with.
- \returns Reference to this string.
-*/
-xbString &xbString::SwapChars( char cFrom, char cTo ){
- xbUInt32 i;
- for( i = 0; i < size; i++ )
- if( data[i] == cFrom )
- data[i] = cTo;
- return *this;
-}
-
-
-/************************************************************************/
-//! @brief Replace all upper case charaters with lower case characters
-/*!
- \returns Reference to this string.
-*/
-xbString &xbString::ToLowerCase(){
- xbUInt32 Len = this->Len();
- for (xbUInt32 i=0; i<Len; i++)
- data[i] = (char)tolower(data[i]);
- return *this;
-}
-
-/************************************************************************/
-//! @brief Replace all lower case charaters with lower case characters
-/*!
- \returns Reference to this string.
-*/
-xbString &xbString::ToUpperCase(){
- xbUInt32 Len = this->Len();
- for (xbUInt32 i=0;i<Len;i++)
- data[i] = (char)toupper(data[i]);
- return *this;
-}
-/************************************************************************/
-//! @brief Trim all leading and trailing white space from string.
-/*!
- \returns Reference to string.
-*/
-xbString &xbString::Trim(){
- Rtrim();
- Ltrim();
- return *this;
-}
-
-/************************************************************************/
-//! @brief Private function used for reallocateing memory
-/*!
- This function is designed to be a drop in replacement for the realloc
- function call.
-*/
-/*
-char * xbString::xb_realloc( char * pIn, xbUInt32 iLen ){
-
- if( iLen == 0 ){
- if( pIn ){
- free( pIn );
- return NULL;
- }
- }
-
- char *pNew = (char *) calloc( 1, (size_t) iLen );
- if( !pNew ) return NULL;
- char *s = pIn;
- char *t = pNew;
- xbUInt32 iCnt = 0;
- while( *s && iCnt++ < iLen )
- *t++ = *s++;
- return pNew;
-}
-*/
-/************************************************************************/
-//! @brief Private function used for copying a string
-/*!
- For performance reasons, this is an internal function that does no
- memory checking and assumes a valid buffer area is available to be copied.
-
- This function is marked as private because of the above reason and
- is used by "stronger" calling functions.
-
- \param sTarget Target destination of copied string
- \param sSource Source string to copy
- \returns Reference to string.
-*/
-
-char * xbString::xb_strcpy( char *sTarget, const char *sSource ){
-
- char *temp = sTarget;
- while( *sSource != '\0')
- *sTarget++ = *sSource++;
- *sTarget= '\0';
- return temp;
-}
-
-/************************************************************************/
-//! @brief Check for valid logical field data
-/*!
- Valid logical data is one 'T', 'F', 'N' or 'Y'.<br>
-
- \returns xbTrue if the data is valid logical data.<br>
- xbFalse if not valid logical data.
-*/
-
-xbBool xbString::ValidLogicalValue() const {
- if( Len() == 1 )
- if( data[0] == 'T' || data[0] == 'F' || data[0] == 'Y' || data[0] == 'N' || data[0] == '?' )
- return xbTrue;
- return xbFalse;
-}
-/************************************************************************/
-//! @brief This function returns true if the data is valid numeric data
-/*!
- \returns xbTrue if valid numeric data.<br>
- xbFalse if not valid numeric daata.
-*/
-
-xbBool xbString::ValidNumericValue() const {
- const char *p;
- p = data;
- while( *p ){
- if( *p != '+' && *p != '-' && *p != '.' && *p != '0' && *p != '1' &&
- *p != '2' && *p != '3' && *p != '4' && *p != '5' && *p != '6' &&
- *p != '7' && *p != '8' && *p != '9' )
- return xbFalse;
- else
- p++;
- }
- return xbTrue;
-}
-
-
-/************************************************************************/
-//! @brief Remove every instance of a character from a string.
-/*!
- \param c character to remove from string.
- \returns Reference to this stirng.void
-*/
-
-xbString &xbString::ZapChar( char c ){
-
- if( data == NULL )
- return *this;
- if( data[0] == 0 )
- return *this;
-
- char *s;
- char *t;
-
- s = data;
- t = data;
- while( *s ){
- if( *s == c ){
- s++;
- size--;
- } else {
- *t++ = *s++;
- }
- }
- *t = 0x00;
-
- data = (char *) realloc( data, size );
- return *this;
-}
-
-/************************************************************************/
-//! @brief Remove leading character from a string.
-/*!
- \param c character to remove from beginning of string.
- \returns Reference to this string.
-*/
-xbString &xbString::ZapLeadingChar( char c ){
- /* left truncate all of character c */
- xbUInt32 iLen = 0;
- char *p;
- p = data;
- while( *p && *p == c ){
- iLen++;
- p++;
- }
- if( iLen )
- Ltrunc( iLen );
- return *this;
-}
-
-/************************************************************************/
-//! @brief Remove trailing character from a string.
-/*!
- \param c character to remove from ending of string.
- \returns Reference to this string.
-*/
-xbString &xbString::ZapTrailingChar( char c ){
-
- xbUInt32 l = Len();
- if( l == 0 )
- return *this;
- xbUInt32 ulOrigSize = size;
- l--;
- for(;;) {
- if( data[l] != c )
- break;
- data[l] = 0;
- size--;
- if( l == 0 )
- break;
- l--;
- }
- if( ulOrigSize != size )
- data = (char *) realloc( data, size );
- return *this;
-}
-
-} /* namespace */ \ No newline at end of file
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbtag.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbtag.cpp
deleted file mode 100755
index 621d44b..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbtag.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/* xbtag.cpp
-
-
-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 "xbase.h"
-
-#ifdef XB_INDEX_SUPPORT
-
-
-namespace xb{
-
-/************************************************************************/
-//! @brief Constructor
-/*!
- \param pIx Pointer to index file instance.
- \param vpTag Pointer to tag structure within file instance.
- \param sType NDX or MDX
- \param sTagName Name of tag.
- \param sExpression Tag key definition.
- \param sFilter MDX only - tag qualification expression.
- \param bUnique xbTrue - Index is unique.<br>xbFalse - Index is not unique.
- \param bSort MDX only<br>xbTrue - Descending.<br>xbFalse - Ascending.
-*/
-
-xbTag::xbTag( xbIx *pIx, void *vpTag, xbString &sType, xbString &sTagName, xbString &sExpression, xbString &sFilter,
-xbBool bUnique, xbBool bSort )
-{
- this->pIx = pIx;
- this->vpTag = vpTag;
- this->sType = sType;
- this->sTagName = sTagName;
- this->sExpression = sExpression;
- this->sFilter = sFilter;
- this->bUnique = bUnique;
- this->bSort = bSort;
-}
-
-
-/************************************************************************/
-//! @brief Get tag key expression.
-/*!
- \returns Tag key expression.
-*/
-const xbString &xbTag::GetExpression() const {
- return sExpression;
-}
-/************************************************************************/
-//! @brief Get tag filter expression.
-/*!
- \returns Tag filter expression (mdx only).
-*/
-
-const xbString &xbTag::GetFilter() const {
- return sFilter;
-}
-/************************************************************************/
-//! @brief Get index file pointer.
-/*!
- \returns Pointer to index file instance.
-*/
-xbIx *xbTag::GetIx() const {
- return pIx;
-}
-/************************************************************************/
-//! @brief Get tag ascending setting.
-/*!
- \returns Tag sort setting - MDX only.<br>xbTrue - Descending.<br>xbFalse - Ascending.
-*/
-xbBool xbTag::GetSort() const {
- return bSort;
-}
-/************************************************************************/
-//! @brief Get tag name.
-/*!
- \returns Tag name.
-*/
-
-const xbString &xbTag::GetTagName() const {
- return sTagName;
-}
-/************************************************************************/
-//! @brief Get tag type.
-/*!
- \returns Tag type.
-*/
-const xbString &xbTag::GetType() const {
- return sType;
-}
-
-/************************************************************************/
-//! @brief Get tag unique setting.
-/*!
- \returns Tag unique setting.<br>xbTrue - Unique.<br>xbFalse - Not unique.
-*/
-
-xbBool xbTag::GetUnique() const {
- return bUnique;
-}
-/************************************************************************/
-//! @brief Get tag pointer for tag within index file.
-/*!
- \returns Pointer to tag within index file instance.
-*/
-void *xbTag::GetVpTag() const {
- return vpTag;
-}
-/************************************************************************/
-} /* namespace */
-#endif /* XB_INDEX_SUPPORT */ \ No newline at end of file
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbtblmgr.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbtblmgr.cpp
deleted file mode 100755
index 53b6dd9..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbtblmgr.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-/* xbtblmgr.cpp
-
-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 "xbase.h"
-
-//#ifdef HAVE_STRING_H
-//#include <string.h>
-//#endif
-
-namespace xb{
-
-/*************************************************************************/
-xbTblMgr::xbTblMgr(){
- TblList = NULL;
- iOpenTableCount = 0;
-}
-
-/*************************************************************************/
-xbTblMgr::~xbTblMgr(){
- xbTblList *l;
- if( TblList ){
- while( TblList ){
- l = TblList;
- TblList = TblList->pNext;
- delete l->psFqTblName;
- delete l->psTblName;
- delete l->psTblAlias;
- free( l );
- }
- }
-}
-
-/*************************************************************************/
-xbInt16 xbTblMgr::AddTblToTblList( xbDbf *d, const xbString & sFqTblName ){
- return AddTblToTblList( d, sFqTblName, "" );
-}
-
-/*************************************************************************/
-xbInt16 xbTblMgr::AddTblToTblList( xbDbf *d, const xbString & sFqTblName, const xbString & sTblAlias ) {
-
- // Set the Fq (fully qualified name)
- // Pull the table name from the FQ name
- // Set the Alias to the table name if the alias name is not provided
-
-
- xbTblList *i, *s, *t;
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbString sTblName;
- xbString sAlias;
- xbString sTemp;
- xbString sFqTemp;
- xbUInt32 iSlashPos;
-
- // std::cout << "AddTblToTblList fq in = [" << sFqTblName.Str() << "] alias in =[" << sTblAlias.Str() << "]\n";
-
- try{
-
- if( sFqTblName.Len() == 0 ){
- iErrorStop = 100;
- iRc = XB_INVALID_TABLE_NAME;
- throw iRc;
- }
-
- sTblName = sFqTblName;
- sTblName.SwapChars( '\\', '/' );
- iSlashPos = sTblName.GetLastPos( '/' );
-
- // std::cout << "slashpos = " << iSlashPos << "\n";
-
-
- if( iSlashPos > 0 ){
- sTblName.Ltrunc( iSlashPos ); // remove the directory part from the table name
- sFqTemp = sFqTblName;
- } else{
- sFqTemp.Sprintf( "%s%s", GetDataDirectory().Str(), sFqTblName.Str()); // add the dir part to the FQ name
- }
-
- xbUInt32 iDbfPos = sFqTemp.Pos( ".DBF" );
- if( iDbfPos == 0 )
- sFqTemp += ".DBF";
- else
- sTblName.Resize( sTblName.Len() - 3 );
-
- if( sTblAlias.Len() == 0 )
- sAlias = sTblName;
- else
- sAlias = sTblAlias;
-
- //std::cout << "fq=[" << sFqTemp.Str() << "] tblname = [" << sTblName.Str() << "] alias = [" << sAlias.Str() << "]\n";
-
- if((i = (xbTblList *) calloc(1, sizeof(xbTblList))) == NULL){
- iErrorStop = 110;
- iRc = XB_NO_MEMORY;
- throw iRc;
- }
- i->psFqTblName = new xbString( sFqTemp );
- i->psTblName = new xbString( sTblName );
- i->psTblAlias = new xbString( sAlias );
- i->pDbf = d;
- i->pNext = NULL;
-
- // insert new table into the list of open tables, sorted by table name
- s = NULL;
- t = TblList;
-
- while(t && (strcmp( t->psTblAlias->Str(), sAlias.Str()) < 0 )){
- s = t;
- t = t->pNext;
- }
-
- if( t && (strcmp( t->psTblAlias->Str(), sAlias.Str()) == 0 )){
- iErrorStop = 120;
- delete i->psFqTblName;
- delete i->psTblName;
- delete i->psTblAlias;
- free( i );
- iRc = XB_DUP_TABLE_OR_ALIAS;
- throw iRc;
- }
- i->pNext = t;
- if (s == NULL)
- TblList = i;
- else
- s->pNext = i;
- }
- catch (xbInt16 iRc ){
- if( iErrorStop != 120 ){
- xbString sMsg;
- sMsg.Sprintf( "xbTblMgr::AddTblToTblList() Exception Caught. Error Stop = [%d] iRc = [%d] Tbl Name = [%s] Alias = [%s]", iErrorStop, iRc, sTblName.Str(), sTblAlias.Str() );
- std::cout << sMsg << std::endl;
- }
- }
- if( iRc == XB_NO_ERROR )
- iOpenTableCount++;
- return iRc;
-}
-
-/*************************************************************************/
-xbInt16 xbTblMgr::DisplayTableList() const {
- xbInt16 iTblCnt = 0;
- xbTblList * l = TblList;
- std::cout << "-- Open Table List --" << std::endl;
- if( l == NULL )
- std::cout << "Table list is empty" << std::endl;
- else{
- while( l ){
- iTblCnt++;
- std::cout << iTblCnt << " FqFileName=[" << l->psFqTblName->Str() << "] TableName=[" << l->psTblName->Str() << "] Alias=[" << l->psTblAlias->Str() << "]" << std::endl;
- l = l->pNext;
- }
- }
- return iTblCnt;
-}
-/*************************************************************************/
-/* Get pointer to named dbf.
- Looks up an open DBF file by Name.
-
- returns A pointer to the xbDbf class instance if found or NULL if not found.
-
- // looks for a match as an alias first, if not found as an alias, looks at the name
-
-*/
-
-xbDbf *xbTblMgr::GetDbfPtr(const xbString& sTblAlias) const {
-
-
- xbTblList *t;
- t = TblList;
- xbString s;
- xbUInt32 ui = sTblAlias.Pos( ".DBF" );
- if( ui > 0 )
- s.Assign( sTblAlias.Str(), 1, ui - 1 );
- else
- s.Set( sTblAlias );
-
- while( t ){
- if( s == t->psTblAlias->Str()){
- return t->pDbf;
- }
- t = t->pNext;
- }
-
- t = TblList;
- while( t ){
- // std::cout << "s = [" << s.Str() << "] tbl name = [" << t->psTblName->Str() << "]\n";
- if( s == t->psTblName->Str()){
- std::cout << "found\n";
- return t->pDbf;
- }
- t = t->pNext;
- }
-
-
- t = TblList;
- while( t ){
- if( sTblAlias == t->psFqTblName->Str())
- return t->pDbf;
- t = t->pNext;
- }
- return NULL;
-}
-/*************************************************************************/
-/* Get pointer to named dbf.
- Looks up an open DBF file by Name.
-
- returns pointer to the xbDbf class instance if found or NULL if not found.
-*/
-
-xbDbf *xbTblMgr::GetDbfPtr(xbInt16 iItemNo ) const {
-
- xbTblList *t;
- t = TblList;
- xbInt16 iCnt = 1;
-
- if( iItemNo < 1 || iItemNo > iOpenTableCount )
- return NULL;
-
- while( t && iCnt < iItemNo ){
- t = t->pNext;
- iCnt++;
- }
- if( t )
- return t->pDbf;
- else
- return NULL;
-}
-/*************************************************************************/
-xbInt16 xbTblMgr::GetOpenTableCount() const {
- return iOpenTableCount;
-}
-/*************************************************************************/
-xbTblList * xbTblMgr::GetTblListEntry( xbDbf *pTbl ){
-
- xbTblList * i = TblList;
- while( i ){
- if( i->pDbf == pTbl )
- return i;
- i = i->pNext;
- }
- return NULL;
-}
-/*************************************************************************/
-xbInt16 xbTblMgr::RemoveTblFromTblList( const xbString & sTblAlias ) {
- xbTblList *i, *s;
-
- i = TblList;
- s = NULL;
-
- while( i ){
-
- if( strcmp( i->psTblAlias->Str(), sTblAlias.Str()) == 0 ) {
- if(s)
- s->pNext = i->pNext;
- else
- TblList = i->pNext;
-
- delete i->psFqTblName;
- delete i->psTblName;
- delete i->psTblAlias;
- free( i );
- iOpenTableCount--;
- return XB_NO_ERROR;
- } else {
- s = i;
- i = i->pNext;
- }
- }
- return XB_NOT_FOUND;
-}
-/*************************************************************************/
-xbInt16 xbTblMgr::RemoveTblFromTblList( xbDbf *pTbl ) {
- xbTblList *i, *s;
-
- i = TblList;
- s = NULL;
-
- while( i ){
-
- if( i->pDbf == pTbl ) {
- if(s)
- s->pNext = i->pNext;
- else
- TblList = i->pNext;
-
- delete i->psFqTblName;
- delete i->psTblName;
- delete i->psTblAlias;
- free( i );
- iOpenTableCount--;
- return XB_NO_ERROR;
- } else {
- s = i;
- i = i->pNext;
- }
- }
- return XB_NOT_FOUND;
-}
-/*************************************************************************/
-} /* namespace */
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbuda.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbuda.cpp
deleted file mode 100755
index 5db7aec..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbuda.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/* xbuda.cpp
-
-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 module handles uda (user data area) methods
-
-*/
-
-#include "xbase.h"
-
-
-// might need to change thisto XB_EXPRESSION_SUPPORT
-#ifdef XB_EXPRESSION_SUPPORT
-
-
-namespace xb{
-
-/************************************************************************/
-xbUda::xbUda() {
- llOrd. SetDupKeys( xbFalse );
-}
-/************************************************************************/
-xbUda::~xbUda() {}
-/************************************************************************/
-void xbUda::Clear() {
- llOrd.Clear();
-}
-/************************************************************************/
-xbInt16 xbUda::GetTokenCnt() const {
- return llOrd.GetNodeCnt();
-}
-/************************************************************************/
-
-xbInt16 xbUda::GetTokenForKey( const xbString &sKey, xbString &sToken ) {
- return llOrd.GetDataForKey( sKey, sToken );
-}
-
-/************************************************************************/
-xbInt16 xbUda::AddTokenForKey( const xbString &sKey, const xbString &sToken ) {
- return llOrd.InsertKey( sKey, sToken );
-}
-/************************************************************************/
-
-xbInt16 xbUda::UpdTokenForKey( const xbString &sKey, const xbString &sData ) {
- return llOrd.UpdateForKey( sKey, sData );
-}
-
-/************************************************************************/
-xbInt16 xbUda::DelTokenForKey( const xbString &sKey ) {
- return llOrd.RemoveKey( sKey ); //, sToken );
-}
-
-
-/************************************************************************/
-
-void xbUda::DumpUda() const{
-
- xbLinkListNode<xbString> *lln = llOrd.GetHeadNode();
-
- xbInt32 l = 0;
- while( lln ){
- std::cout << ++l << " Key=[" << lln->GetKey() << "] Data=[" << lln->GetData() << "]" << std::endl;
- lln = lln->GetNextNode();
- }
-}
-
-/************************************************************************/
-} /* namespace */
-#endif /* XB_EXPRESSION_SUPPORT */ \ No newline at end of file
diff --git a/1Tdata/xbase/xbase64-4.1.4/src/core/xbxbase.cpp b/1Tdata/xbase/xbase64-4.1.4/src/core/xbxbase.cpp
deleted file mode 100755
index 7267f98..0000000
--- a/1Tdata/xbase/xbase64-4.1.4/src/core/xbxbase.cpp
+++ /dev/null
@@ -1,803 +0,0 @@
-/* xbxbase.cpp
-
-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 "xbase.h"
-
-namespace xb{
-
-/*************************************************************************/
-//! @brief Class Constructor.
-xbXBase::xbXBase() {
- SetEndianType();
-
- xbFile f( this );
- f.SetHomeFolders();
- xbDate d( (xbUInt16) 1); // initialize xbDate static variables
- #ifdef XB_LOGGING_SUPPORT
- xLog = new xbLog();
- #endif
-}
-/*************************************************************************/
-//! @brief Class Deconstructor.
-xbXBase::~xbXBase(){
- CloseAllTables();
- #ifdef XB_LOGGING_SUPPORT
- delete xLog;
- #endif
-}
-/*************************************************************************/
-//! @brief Close all tables / files.
-/*!
- This closes everything and deletes references to the associated xbDbf objects.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::CloseAllTables(){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- xbInt16 iOpenTableCnt = GetOpenTableCount();
- try{
- xbDbf *d;
- for( xbInt16 i = 0; i < iOpenTableCnt; i++ ){
- d = (xbDbf *) GetDbfPtr( 1 );
- if( d ){
- if(( iRc = d->Close()) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- delete d;
- } else {
- iRc = XB_INVALID_OBJECT;
- iErrorStop = 110;
- throw iRc;
- }
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbxbase::CloseAllTables() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc );
- WriteLogMessage( sMsg.Str() );
- WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-
-/************************************************************************/
-//! @brief Fully qualified file name from a directory, filename and extension.
-/*!
- Given a directory, file name and file extension as inputs, create a fully qualified file name.
-
- \param sDirIn Directory
- \param sFileIn File Name
- \param sExtIn File Extension
- \param sFqnOut A fully qualifed unique file name as output
- \returns XB_INVALIED_PARAMETER or XB_NO_ERROR
-*/
-xbInt16 xbXBase::CreateFqn( const xbString &sDirIn, const xbString &sNameIn, const xbString &sExtIn, xbString &sFqnOut ){
-
- if( sNameIn == "" || sExtIn == "" )
- return XB_INVALID_PARAMETER;
-
- sFqnOut = sDirIn;
- #ifdef WIN32
- sFqnOut.SwapChars( '/', '\\' );
- if( sFqnOut[sFqnOut.Len()] != '\\' )
- sFqnOut += '\\';
- #else
- sFqnOut.SwapChars( '\\', '/' );
- if( sFqnOut[sFqnOut.Len()] != '/' )
- sFqnOut += '/';
- #endif
- sFqnOut += sNameIn;
- if( sExtIn != "" ){
- sFqnOut += '.';
- sFqnOut += sExtIn;
- }
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-//! @brief Parse commmand line options for a given parm request
-/*!
- \param lArgc Value passed from main( argc, argv[] )
- \param sArgv Valued passed from main
- \param sOptRqst Option to search for in the arguments list
- \param sParmOut String token immediately to the right of the the option request, if found
- \returns 0 - paramater request not found<br> 1 - Parameter found
-*/
-
-xbInt16 xbXBase::GetCmdLineOpt( xbInt32 lArgc, char **sArgv, const char *sOptRqst, xbString &sParmOut ){
- xbString sOpt( sOptRqst );
- return GetCmdLineOpt( lArgc, sArgv, sOpt, sParmOut );
-}
-
-/*************************************************************************/
-//! @brief Parse commmand line options for a given parm request
-/*!
- \param lArgc Value passed from main( argc, argv[] )
- \param sArgv Valued passed from main
- \param sOptRqst Option to search for in the arguments list
- \param sParmOut String token immediately to the right of the the option request, if found
- \returns 0 - paramater request not found<br> 1 - Parameter found
-*/
-
-xbInt16 xbXBase::GetCmdLineOpt( xbInt32 lArgc, char **sArgv, xbString &sOptRqst, xbString &sParmOut ){
-
- xbInt16 iFound = 0;
- sParmOut = "";
- if( lArgc < 2 ) // first string is the program name
- return iFound;
-
- xbInt32 i = 1;
- while( iFound == 0 && i < lArgc ){
- if( sOptRqst == sArgv[i] ){
- iFound = 1;
- if( i < (lArgc-1))
- sParmOut = sArgv[i+1];
- }
- i++;
- }
- return iFound;
-}
-
-/*************************************************************************/
-#ifdef XB_LOGGING_SUPPORT
-//! @brief Get fully qualified log file name.
-/*!
- \returns Returns the fully qualified log file name.
-*/
-const xbString & xbXBase::GetLogFqFileName() const {
- return xLog->GetFqFileName();
-}
-
-//! @brief Get the log file name.
-/*!
- \returns Returns the log file name.
-*/
-/*
-const xbString & xbXBase::GetLogFileName() const {
- return xLog->GetFileName();
-}
-*/
-
-//! @brief Get the log directory.
-/*!
- \returns Returns the log directory.
-*/
-/*
-const xbString & xbXBase::GetLogDirectory() const {
- return GetLogDirectory();
-}
-*/
-//! @brief Get the log directory.
-/*!
- \returns xbTrue - Logging enabled.<br>xbFalse - Logging disables.
-*/
-xbBool xbXBase::GetLogStatus() const {
- return xLog->LogGetStatus();
-}
-
-//! @brief Set the log file name.
-/*!
- \param sLogFileName - Log File Name.
- \return void
-*/
-/*
-void xbXBase::SetLogFileName( const xbString & sLogFileName ){
-
- xLog->SetFileName( sLogFileName );
-}
-*/
-//! @brief Set the log directory.
-/*!
- \param sLogDirectory - Log File Directory.
- \return void
-*/
-/*
-void xbXBase::SetLogDirectory( const xbString & sLogDirectory ){
- xLog->SetDirectory( sLogDirectory );
-}
-*/
-
-
-//! @brief Set the logfile size.
-/*!
- \param lSize - Log File Size.
- \return void
-*/
-void xbXBase::SetLogSize( size_t lSize ) {
- xLog->LogSetLogSize( lSize );
-}
-
-//! @brief Get the logfile size.
-/*!
- \return log file size
-*/
-size_t xbXBase::GetLogSize() const {
- return xLog->LogGetLogSize();
-}
-
-
-//! @brief Write message to logfile.
-/*!
- \param sLogMessage - Message to write.
- \param iOpt 0 = stdout<br>
- 1 = Syslog<br>
- 2 = Both<br>
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbXBase::WriteLogMessage( const xbString & sLogMessage, xbInt16 iOpt ){
- return xLog->LogWrite( sLogMessage, iOpt );
-}
-
-//! @brief Write message to logfile.
-/*!
- \param lCnt - Number of bytes to write.
- \param p - Pointer to bytes to write to log file.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbXBase::WriteLogBytes( xbUInt32 lCnt, const char *p ){
- return xLog->LogWriteBytes( lCnt, p );
-}
-
-//! @brief Enable message logging.
-void xbXBase::EnableMsgLogging() {
- xLog->LogSetStatus( xbTrue );
-}
-
-//! @brief Disable message logging.
-void xbXBase::DisableMsgLogging() {
- xLog->LogSetStatus( xbFalse );
-}
-
-//! @brief Flush log file updates to disk.
-xbInt16 xbXBase::FlushLog() {
- return xLog->xbFflush();
-}
-#else
-
-// if logging not compiled in, these stubs are called with no effect
-const xbString & xbXBase::GetLogFqFileName() const {
- return sNullString;
-}
-/*
-const xbString & xbXBase::GetLogFileName() const {
- return sNullString;
-}
-const xbString & xbXBase::GetLogDirectory() const {
- return sNullString;
-}
-*/
-/*
-void xbXBase::SetLogFileName( const xbString & sLogFileName ){
- return;
-}
-void xbXBase::SetLogDirectory( const xbString & sLogDirectory ){
- return;
-}
-*/
-xbBool xbXBase::GetLogStatus() const {
- return xbFalse;
-}
-xbInt16 xbXBase::WriteLogMessage( const xbString & sLogMessage, xbInt16 ){
- return XB_NO_ERROR;
-}
-xbInt16 xbXBase::WriteLogBytes( xbUInt32 lCnt, const char *p ){
- return XB_NO_ERROR;
-}
-void xbXBase::EnableMsgLogging() {
- return;
-}
-void xbXBase::DisableMsgLogging() {
- return;
-}
-xbInt16 xbXBase::FlushLog() {
- return XB_NO_ERROR;
-}
-void xbXBase::SetLogSize( size_t lSize ) {
- return;
-}
-
-#endif // XB_LOGGING_SUPPORT
-
-/*************************************************************************/
-#ifdef XB_FUNCTION_SUPPORT
-
-//! @brief Get information regarding expression functions.
-/*!
- \param sExpLine An expression beginning with function name.
- \param cReturnType Output - return type of function.
- \param iCalc Used to calculate the function return value is<br>
- 1 = use value specified in lReturnLenVal<br>
- 2 = use length of operand specified in col 4<br>
- 3 = use valued of numeric operand specified in col 4<br>
- 4 = length of parm 1 * numeric value parm<br>
- 5 = larger length of parm 2 or length of parm 3<br>
- 6 = if two or more parms, use numeric value from second parm, otherwise use col4 value
- \param lReturnLenVal Used in combination with iReturnLenCalc.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbXBase::GetFunctionInfo( const xbString &sExpLine, char &cReturnType, xbInt16 &iCalc, xbInt32 &lReturnLenVal ) const{
-
- xbUInt32 iLen;
- const char *s;
- if( sExpLine.Len() == 0 )
- return XB_INVALID_FUNCTION;
-
- s = sExpLine;
- iLen = 0;
- while( *s && *s != '(' && *s != ' ' ) { s++; iLen++; }
- xbString sFunction( sExpLine, iLen );
- cReturnType = 0x00;
- char cFunc1 = sFunction[1];
-
- if( cFunc1 < 'L' ){
- // std::cout << "less than L\n";
- if( cFunc1 < 'D' ){
- // std::cout << "less than D\n";
- if( sFunction == "ABS" ){
- // { "ABS", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "ALLTRIM" ){
- // { "ALLTRIM", 'C', 2, 1 },
- cReturnType = 'C';
- iCalc = 2;
- lReturnLenVal = 1;
- } else if( sFunction == "ASC" ){
- // { "ASC", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "AT" ){
- // { "AT", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "CDOW" ){
- // { "CDOW", 'C', 1, 9 },
- cReturnType = 'C';
- iCalc = 1;
- lReturnLenVal = 9;
- } else if( sFunction == "CHR" ){
- // { "CHR", 'C', 1, 1 },
- cReturnType = 'C';
- iCalc = 1;
- lReturnLenVal = 1;
- } else if( sFunction == "CMONTH" ){
- // { "CMONTH", 'C', 1, 9 },
- cReturnType = 'C';
- iCalc = 1;
- lReturnLenVal = 9;
- } else if( sFunction == "CTOD" ){
- // { "CTOD", 'D', 1, 8 },
- cReturnType = 'D';
- iCalc = 1;
- lReturnLenVal = 8;
- }
- } else {
- // std::cout << ">= D\n";
- if( sFunction == "DATE" ){
- // { "DATE", 'D', 1, 8 },
- cReturnType = 'D';
- iCalc = 1;
- lReturnLenVal = 8;
- } else if( sFunction == "DAY" ){
- // { "DAY", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "DEL" ){
- // { "DEL", 'C', 1, 1 },
- cReturnType = 'C';
- iCalc = 1;
- lReturnLenVal = 1;
- } else if( sFunction == "DELETED" ){
- // { "DELETED", 'L', 1, 1 },
- cReturnType = 'L';
- iCalc = 1;
- lReturnLenVal = 1;
- } else if( sFunction == "DESCEND" ){
- // { "DESCEND", '1', 2, 1 },
- cReturnType = '1';
- iCalc = 2;
- lReturnLenVal = 1;
- } else if( sFunction == "DOW" ){
- // { "DOW", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "DTOC" ){
- // { "DTOC", 'C', 1, 8 },
- cReturnType = 'C';
- iCalc = 1;
- lReturnLenVal = 8;
- } else if( sFunction == "DTOS" ){
- // { "DTOS", 'C', 1, 8 },
- cReturnType = 'C';
- iCalc = 1;
- lReturnLenVal = 8;
- } else if( sFunction == "EXP" ){
- // { "EXP", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "IIF" ){
- // { "IIF", 'C', 5, 0 },
- cReturnType = 'C';
- iCalc = 5;
- lReturnLenVal = 0;
- } else if( sFunction == "INT" ){
- // { "INT", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "ISALPHA" ){
- // { "ISALPHA", 'L', 1, 1 },
- cReturnType = 'L';
- iCalc = 1;
- lReturnLenVal = 1;
- } else if( sFunction == "ISLOWER" ){
- // { "ISLOWER", 'L', 1, 1 },
- cReturnType = 'L';
- iCalc = 1;
- lReturnLenVal = 1;
- } else if( sFunction == "ISUPPER" ){
- // { "ISUPPER", 'L', 1, 1 },
- cReturnType = 'L';
- iCalc = 1;
- lReturnLenVal = 1;
- }
- }
- } else {
- // std::cout << ">= L\n";
- if( cFunc1 < 'R' ) {
- // std::cout << " < R\n";
- if( sFunction == "LEFT" ){
- // { "LEFT", 'C', 3, 2 },
- cReturnType = 'C';
- iCalc = 3;
- lReturnLenVal = 2;
- } else if( sFunction == "LEN" ){
- // { "LEN", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 3;
- } else if( sFunction == "LOG" ){
- // { "LOG", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "LOWER" ){
- // { "LOWER", 'C', 2, 1 },
- cReturnType = 'C';
- iCalc = 2;
- lReturnLenVal = 1;
- } else if( sFunction == "LTRIM" ){
- // { "LTRIM", 'C', 2, 1 },
- cReturnType = 'C';
- iCalc = 2;
- lReturnLenVal = 1;
- } else if( sFunction == "MAX" ){
- // { "MAX", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "MIN" ){
- // { "MIN", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "MONTH" ){
- // { "MONTH", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- }
- } else if( cFunc1 == 'R' ){
- // std::cout << "==R\n";
- if( sFunction == "RECNO" ){
- // { "RECNO", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "RECCOUNT" ){
- // { "RECCOUNT", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "REPLICATE" ){
- // { "REPLICATE", 'C', 4, 0 },
- cReturnType = 'C';
- iCalc = 4;
- lReturnLenVal = 0;
- } else if( sFunction == "RIGHT" ){
- // { "RIGHT", 'C', 3, 2 },
- cReturnType = 'C';
- iCalc = 3;
- lReturnLenVal = 2;
- } else if( sFunction == "RTRIM" ){
- // { "RTRIM", 'C', 2, 1 },
- cReturnType = 'C';
- iCalc = 2;
- lReturnLenVal = 1;
- }
- } else if( cFunc1 == 'S' ){
- // std::cout << "==S\n";
- if( sFunction == "SPACE" ){
- // { "SPACE", 'C', 3, 1 },
- cReturnType = 'C';
- iCalc = 3;
- lReturnLenVal = 1;
- } else if( sFunction == "SQRT" ){
- // { "SQRT", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- } else if( sFunction == "STOD" ){
- // { "STOD", 'D', 1, 8 },
- cReturnType = 'D';
- iCalc = 1;
- lReturnLenVal = 8;
- } else if( sFunction == "STR" ){
- // { "STR", 'C', 6, 10 },
- cReturnType = 'C';
- iCalc = 6;
- lReturnLenVal = 10;
- } else if( sFunction == "STRZERO" ){
- // { "STRZERO", 'C', 3, 2 },
- cReturnType = 'C';
- iCalc = 3;
- lReturnLenVal = 2;
- } else if( sFunction == "SUBSTR" ){
- // { "SUBSTR", 'C', 3, 3 },
- cReturnType = 'C';
- iCalc = 3;
- lReturnLenVal = 3;
- }
- } else {
- // std::cout << ">S\n";
- if( sFunction == "TRIM" ){
- // { "TRIM", 'C', 2, 1 },
- cReturnType = 'C';
- iCalc = 2;
- lReturnLenVal = 1;
- } else if( sFunction == "UPPER" ){
- // { "UPPER", 'C', 2, 1 },
- cReturnType = 'C';
- iCalc = 2;
- lReturnLenVal = 1;
- } else if( sFunction == "VAL" ){
- // { "VAL", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 3;
- } else if( sFunction == "YEAR" ){
- // { "YEAR", 'N', 1, 4 },
- cReturnType = 'N';
- iCalc = 1;
- lReturnLenVal = 4;
- }
- }
- }
- if( cReturnType == 0x00 )
- return XB_INVALID_FUNCTION;
- else
- return XB_NO_ERROR;
-}
-#endif
-/*************************************************************************/
-//! @brief Cross platform sleep function.
-/*!
- \param lMillisecs Milliseconds to sleep.
-*/
-void xbXBase::xbSleep( xbInt32 lMillisecs ){
- #ifdef WIN32
- Sleep( (xbUInt32) lMillisecs );
- #else
- usleep( (xbInt64) lMillisecs * 1000 );
- #endif
-
-}
-/***********************************************************************/
-//! @brief Cross memcmp function.
-/*!
- \param s1 Left operand to compare.
- \param s2 Right operand to compare.
- \param n Number of bytes to compare.
- \returns 1 s1 > s2<br>
- 0 s1 == s2<br>
- -1 s1 < s2
-*/
-xbInt16 xbXBase::xbMemcmp( const unsigned char *s1, const unsigned char *s2, size_t n ){
- // The standard memcmp function was found not to behave the same across all platforms
- for( size_t i = 0; i < n; i++ ){
- if( s1[i] > s2[i] )
- return 1;
- else if( s1[i] < s2[i] )
- return -1;
- }
- return 0;
-}
-
-/***********************************************************************/
-//! @brief Open highest qualified class available for dbf file.
-/*!
- This routine opens the highest available version of the dbf file.
- Defaults to XB_READ_WRITE and XB_MULTI_USER mode.
- \returns param dbf - Output pointer to dbf file opened or null if error
-*/
-xbDbf* xbXBase::Open( const xbString &sTableName, xbInt16 &iRc ){
- return Open( sTableName, "", XB_READ_WRITE, XB_MULTI_USER, 0, iRc );
-}
-/***********************************************************************/
-//! @brief Open highest qualified class available for dbf file.
-/*!
- This routine can open various versions of the dbf file dependent on the iVersion field
-
- \param sTableName - Table name to open.
- \param sAlias - Optional alias name.
- \param iOpenMode - XB_READ_WRITE or XB_READ
- \param iShareMode - XB_SINGLE_USER or XB_MULTI_USER
- \param iRequestVersion 0 - Highest available
- 4 - Version four dbf
- 3 - Version three dbf
- \param iRc - Return code from open request
- \returns param dbf - Output pointer to dbf file opened or null if error
-*/
-
-
-xbDbf* xbXBase::Open( const xbString &sTableName, const xbString &sAlias, xbInt16 iOpenMode,
- xbInt16 iShareMode, xbInt16 iRequestVersion, xbInt16 &iRc ){
-
- xbInt16 iErrorStop = 0;
- xbDbf * pDbf = 0;
- iRc = 0;
- xbString sFqFileName;
-
- try{
-
- if( sTableName.Len() == 0 ){
- iErrorStop = 100;
- iRc = XB_FILE_NOT_FOUND;
- throw iRc;
- }
- xbFile *f = new xbFile(this);
- f->SetFileName( sTableName );
- if(( iRc = f->FileExists( f->GetFqFileName())) != xbTrue ){
- iErrorStop = 110;
- iRc = XB_FILE_NOT_FOUND;
- throw iRc;
- }
- unsigned char cFileTypeByte;
- if(( iRc = f->GetXbaseFileTypeByte( f->GetFqFileName(), cFileTypeByte )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- xbInt16 iTblVsn = f->DetermineXbaseTableVersion( cFileTypeByte );
- f->xbFclose();
- sFqFileName.Set( f->GetFqFileName() );
- delete f;
-
- if( iTblVsn == 4 && ( iRequestVersion == 0 || iRequestVersion == 4 )){
- #ifdef XB_DBF4_SUPPORT
- pDbf = new xbDbf4( this );
- iRc = pDbf->Open( sFqFileName, sAlias, iOpenMode, iShareMode );
- #else
- // std::cout << "Dbase IV file support not build into library. See XB_DBF4_SUPPORT" << std::endl;
- iErrorStop = 130;
- iRc = XB_FILE_TYPE_NOT_SUPPORTED;
- throw iRc;
- #endif
- }
- else if( iTblVsn == 3 && ( iRequestVersion == 0 || iRequestVersion == 3 )){
-
- #ifdef XB_DBF3_SUPPORT
- pDbf = new xbDbf3( this );
- iRc = pDbf->Open( sFqFileName, sAlias, iOpenMode, iShareMode );
- #else
- //std::cout << "Dbase III file support not build into library. See XB_DBF3_SUPPORT" << std::endl;
- iErrorStop = 140;
- iRc = XB_FILE_TYPE_NOT_SUPPORTED;
- throw iRc;
- #endif
-
- } else {
- iErrorStop = 150;
- iRc = XB_FILE_TYPE_NOT_SUPPORTED;
- throw iRc;
- }
-
- if( iRc != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbxbase::Open() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc );
- WriteLogMessage( sMsg.Str() );
- WriteLogMessage( GetErrorMessage( iRc ));
- }
- return pDbf;
-}
-
-xbInt16 xbXBase::OpenHighestVersion( const xbString &sTableName, const xbString &sAlias,
- xbDbf **dbf )
-{
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
-
- try{
- xbFile f(this);
- if( sTableName.Len() == 0 ){
- iErrorStop = 100;
- iRc = XB_FILE_NOT_FOUND;
- throw iRc;
- }
- f.SetFileName( sTableName );
- if(( iRc = f.FileExists( f.GetFqFileName() )) != xbTrue ){
- iErrorStop = 110;
- iRc = XB_FILE_NOT_FOUND;
- throw iRc;
- }
-
- unsigned char cFileTypeByte;
- if(( iRc = f.GetXbaseFileTypeByte( f.GetFqFileName(), cFileTypeByte )) != XB_NO_ERROR ){
- iErrorStop = 120;
- return iRc;
- }
- if( f.DetermineXbaseTableVersion( cFileTypeByte ) == 4 ){
- #ifdef XB_DBF4_SUPPORT
- xbDbf *pwDbf = new xbDbf4( this );
- pwDbf->Open( f.GetFqFileName(), sAlias );
- *dbf = pwDbf;
- pwDbf = 0;
- #else
- // std::cout << "Dbase IV file support not build into library. See XB_DBF4_SUPPORT" << std::endl;
- iErrorStop = 130;
- iRc = XB_FILE_TYPE_NOT_SUPPORTED;
- throw iRc;
- #endif
-
- } else if( f.DetermineXbaseTableVersion( cFileTypeByte ) == 3 ){
- #ifdef XB_DBF3_SUPPORT
- *dbf = new xbDbf3( this );
- #else
- //std::cout << "Dbase III file support not build into library. See XB_DBF3_SUPPORT" << std::endl;
- iErrorStop = 140;
- iRc = XB_FILE_TYPE_NOT_SUPPORTED;
- throw iRc;
- #endif
-
- } else {
- iErrorStop = 150;
- iRc = XB_FILE_TYPE_NOT_SUPPORTED;
- throw iRc;
- }
- }
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbxbase::OpenHighestVersion() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc );
- WriteLogMessage( sMsg.Str() );
- WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}
-/***********************************************************************/
-} /* namespace */