summaryrefslogtreecommitdiff
path: root/src/core/xbxbase.cpp
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2022-12-07 13:17:14 +0100
committerJörg Frings-Fürst <debian@jff-webhosting.net>2022-12-07 13:17:14 +0100
commit4875a3dd9b183dcd2256e2abfc4ccf7484c233b4 (patch)
tree0abbea881ded030851014ffdd60fbf71fead8f65 /src/core/xbxbase.cpp
parentdaf17154bf13139d9375f48525d19d6aaba08155 (diff)
New upstream version 4.0.2upstream/4.0.2
Diffstat (limited to 'src/core/xbxbase.cpp')
-rwxr-xr-xsrc/core/xbxbase.cpp712
1 files changed, 712 insertions, 0 deletions
diff --git a/src/core/xbxbase.cpp b/src/core/xbxbase.cpp
new file mode 100755
index 0000000..7dd3ac7
--- /dev/null
+++ b/src/core/xbxbase.cpp
@@ -0,0 +1,712 @@
+/* xbxbase.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+#include "xbase.h"
+
+namespace xb{
+
+/*************************************************************************/
+//! @brief Class Constructor.
+xbXBase::xbXBase() {
+ SetEndianType();
+ #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.
+ \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 = 10;
+ throw iRc;
+ }
+ } else {
+ iRc = XB_INVALID_OBJECT;
+ iErrorStop = 20;
+ 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;
+}
+/*************************************************************************/
+#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 xLog->GetDirectory();
+}
+
+//! @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 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 ){
+ 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;
+}
+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( 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 = 10;
+ iRc = XB_FILE_NOT_FOUND;
+ throw iRc;
+ }
+ xbFile *f = new xbFile(this);
+ f->SetFileName( sTableName );
+ if(( iRc = f->FileExists( f->GetFqFileName())) != xbTrue ){
+ iErrorStop = 20;
+ iRc = XB_FILE_NOT_FOUND;
+ throw iRc;
+ }
+ unsigned char cFileTypeByte;
+ if(( iRc = f->GetXbaseFileTypeByte( f->GetFqFileName(), cFileTypeByte )) != XB_NO_ERROR ){
+ iErrorStop = 30;
+ 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 = 40;
+ 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 = 50;
+ iRc = XB_FILE_TYPE_NOT_SUPPORTED;
+ throw iRc;
+ #endif
+
+ } else {
+ iErrorStop = 60;
+ iRc = XB_FILE_TYPE_NOT_SUPPORTED;
+ throw iRc;
+ }
+
+ if( iRc != XB_NO_ERROR ){
+ iErrorStop = 70;
+ throw iRc;
+ }
+ }
+ catch (xbInt16 iRc ){
+
+ std::cout << "Openerror\n";
+
+ 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;
+
+ xbDbf * pwDbf;
+
+ try{
+ xbFile f(this);
+ if( sTableName.Len() == 0 ){
+ iErrorStop = 10;
+ iRc = XB_FILE_NOT_FOUND;
+ throw iRc;
+ }
+ f.SetFileName( sTableName );
+ if(( iRc = f.FileExists( f.GetFqFileName() )) != xbTrue ){
+ iErrorStop = 20;
+ iRc = XB_FILE_NOT_FOUND;
+ throw iRc;
+ }
+ unsigned char cFileTypeByte;
+ if(( iRc = f.GetXbaseFileTypeByte( f.GetFqFileName(), cFileTypeByte )) != XB_NO_ERROR ){
+ iErrorStop = 30;
+ return iRc;
+ }
+ if( f.DetermineXbaseTableVersion( cFileTypeByte ) == 4 ){
+ #ifdef XB_DBF4_SUPPORT
+ 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 = 40;
+ 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 = 50;
+ iRc = XB_FILE_TYPE_NOT_SUPPORTED;
+ throw iRc;
+ #endif
+
+ } else {
+ iErrorStop = 60;
+ iRc = XB_FILE_TYPE_NOT_SUPPORTED;
+ throw iRc;
+ }
+
+ }
+ catch (xbInt16 iRc ){
+
+ std::cout << "OpenHighestVersion error\n";
+
+ xbString sMsg;
+ sMsg.Sprintf( "xbxbase::OpenHighestVersion() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc );
+ WriteLogMessage( sMsg.Str() );
+ WriteLogMessage( GetErrorMessage( iRc ));
+
+ }
+ return iRc;
+}
+/***********************************************************************/
+} /* namespace */