⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbf.cpp

📁 一个通讯管理机的源代码。比较好用。推荐
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      MemoHeader.Version = 0x03;#endif   }   else if( Version == 4 || Version == (char)0x8B )    /* dBASE IV */   {      XFV = 4;#ifdef XB_MEMO_FIELDS      MemoHeader.Version = 0x00;#endif   }   else   {     InitVars();      xb_error(XB_NOT_XBASE);   }   // it would seem that dBASE III+ generates an UpdateYY value   // of 0 for 2000 and dBASE IV uses 100, so I have removed the   // check for UpdateYY being 0 (which might be valid).  DTB         if (/*UpdateYY == 0 ||*/ UpdateMM == 0 || UpdateDD == 0 )   {     InitVars();      xb_error(XB_NOT_XBASE);   }   /* calculate the number of fields */   NoOfFields = ( HeaderLen - 33 ) / 32;   if(( RecBuf = (char *) malloc( RecordLen )) == NULL ) {      fclose( fp );      InitVars();       xb_memory_error;   }   if(( RecBuf2 = (char *) malloc( RecordLen )) == NULL ) {      fclose( fp );      free( RecBuf );      InitVars();       xb_memory_error;   }   if((SchemaPtr=(xbSchemaRec *)malloc(NoOfFields*sizeof(xbSchemaRec)))==NULL){      free( RecBuf );      free( RecBuf2 );      fclose( fp );      InitVars();       xb_memory_error;   }   memset( SchemaPtr, 0x00, ( NoOfFields * sizeof(xbSchemaRec)));   /* copy field info into memory */   for( i = 0, j = 1; i < NoOfFields; i++ ){      fseek( fp, i*32+32, 0 );      //      fread( &SchemaPtr[i].FieldName, 1, 18, fp );      fread( &buf, 1, 32, fp );      p = buf;      strncpy( SchemaPtr[i].FieldName, p, 10 );      p += 11;      SchemaPtr[i].Type = *p++;      SchemaPtr[i].Address  = RecBuf + j;      SchemaPtr[i].Address2 = RecBuf2 + j;            SchemaPtr[i].FieldLen = *( p + 4 );      SchemaPtr[i].NoOfDecs = *( p + 5 );            if( SchemaPtr[i].Type == 'C' && SchemaPtr[i].NoOfDecs > 0 )      {        SchemaPtr[i].LongFieldLen = xbase->GetShort( p + 4 );      j += SchemaPtr[i].LongFieldLen;      }      else        j += SchemaPtr[i].FieldLen;#ifdef XB_MEMO_FIELDS      if( !MemoSw && (SchemaPtr[i].Type == 'M' ||           SchemaPtr[i].Type == 'B' || SchemaPtr[i].Type == 'O' ))         MemoSw++;#endif   }    CurRec = 0L;   DbfStatus = XB_OPEN;   BlankRecord();#ifdef XB_MEMO_FIELDS   if( MemoSw )   /* does this table have memo fields ? */      if(( rc = OpenMemoFile()) != XB_NO_ERROR )      {         free( RecBuf );         free( RecBuf2 );         free( SchemaPtr );         fclose( fp );         InitVars();          return rc;      }#endif#ifdef XB_LOCKING_ON   if( AutoLock )      LockDatabase( F_SETLK, F_UNLCK, 0L );#endif               /* XB_LOCKING_ON */   return xbase->AddDbfToDbfList( this, DatabaseName );}/************************************************************************///! Blank the record buffer./*!  Sets the record to spaces.*/xbShort xbDbf::BlankRecord( void ){   if( DbfStatus == XB_CLOSED )      xb_error(XB_NOT_OPEN);   memset( RecBuf, 0x20, RecordLen );   return XB_NO_ERROR;}/************************************************************************///! 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 XDB DBF file and updates the file date and number of  records in the file.  Also updates any open indexes associated with  this data file.    \returns One of the following:    \htmlonly      <p>      <table border=2><tr><th>Return Code</th><th>Description</th></tr>        <tr><td>XB_NO_ERROR</td><td>No error</td></tr>        <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>        <tr><td>XB_WRITE_ERROR</td><td>Error writing to file</td></tr>      </table>    \endhtmlonly    \latexonly      \\      \\      \begin{tabular}{|l|l|} \hline        \textbf{Return Code} & \textbf{Description} \\ \hline \hline        XB\_NO\_ERROR & No error \\ \hline   XB\_LOCK\_FAILED & Couldn't lock file \\ \hline   XB\_WRITE\_ERROR & Error writing to file \\ \hline      \end{tabular}    \endlatexonly*/xbShort xbDbf::AppendRecord( void ){   xbShort       rc = 0;         xbULong     nextRecNo;#if defined(XB_INDEX_ANY)   xbIxList *i;#endif/* lock the database */#ifdef XB_LOCKING_ON   if( AutoLock )      if(( rc = LockDatabase( F_SETLKW, F_WRLCK, 0L )) != XB_NO_ERROR)          return rc;         if((rc = ReadHeader(1)) != XB_NO_ERROR)   {      if(AutoLock)         LockDatabase( F_SETLK, F_UNLCK, 0L );      return rc;   }#endif/* lock any indexes */#if defined(XB_INDEX_ANY)#ifdef XB_LOCKING_ON   i = NdxList;   while( i && AutoLock )   {      if(( rc = i->index->LockIndex( F_SETLKW, F_WRLCK )) != XB_NO_ERROR )          return rc;      i = i->NextIx;   }#endif               /* XB_LOCKING_ON */#endif// if there are no duplicates, and no records set the CurRec to the// last record + 1.  This is for EXP::RECNO()/* check for any duplicate keys */#if defined(XB_INDEX_ANY)   i = NdxList;   while( i )   {      if( i->index->UniqueIndex() )      {         i->index->CreateKey( 0, 0 );         if( i->index->FindKey() == XB_FOUND )           xb_error(XB_KEY_NOT_UNIQUE);      }      i = i->NextIx;   }#endif#ifdef XB_REAL_DELETE   if(RealDelete && FirstFreeRec)     nextRecNo = FirstFreeRec;   else     nextRecNo = NoOfRecs + 1;#else   nextRecNo = NoOfRecs + 1;#endif   CurRec = NoOfRecs + 1;#if defined(XB_INDEX_ANY)/* update the indexes */   i = NdxList;   while( i )   {      if( !i->index->UniqueIndex() )          /* if we didn't prepare the key */         if(( rc = i->index->CreateKey( 0, 0 )) != XB_NO_ERROR ) /* then do it before the add    */            return rc;      if(( rc =  i->index->AddKey(nextRecNo)) != XB_NO_ERROR )   return rc;      i->index->TouchIndex();      i = i->NextIx;   }#endif              /* XB_INDEX_ANY */#ifdef XB_REAL_DELETE   char     buf[4];        if(RealDelete && FirstFreeRec)   {     /*     **  Grab the next free rec no and put it in FirstFreeRec     */     if(fseek(fp, ((long) HeaderLen + ((FirstFreeRec - 1) * RecordLen) + 1), 0) != 0)       xb_error(XB_SEEK_ERROR);            if(fread(buf, 4, 1, fp) != 1)       xb_error(XB_READ_ERROR);            FirstFreeRec = xbase->GetULong(buf);   }      /*   **  Okay, seek and write the record out   */   if(fseek(fp, ((long) HeaderLen + ((nextRecNo - 1) * RecordLen)), 0) != 0)     xb_error(XB_SEEK_ERROR);        if(fwrite( RecBuf, RecordLen, 1, fp) != 1)     xb_error(XB_WRITE_ERROR);   /*   **  If we just appended the record to the file, then write the EOF char   */   if(nextRecNo == NoOfRecs + 1)   {//     if(fwrite( EofChar, 1, 1, fp ) != 1 )     if( fputc( XB_CHAREOF, fp ) != XB_CHAREOF )       xb_error(XB_WRITE_ERROR);   }#else   /* write the last record */   if( fseek( fp, ((long) HeaderLen + ( NoOfRecs * RecordLen )), 0 ) != 0 )     xb_error(XB_SEEK_ERROR);   if( fwrite( RecBuf, RecordLen, 1, fp ) != 1 )     xb_error(XB_WRITE_ERROR);   /* write the end of file marker *///   if( fwrite( "\x0d", 1, 1, fp ) != 1 )//   if( fwrite( EofChar, 1, 1, fp ) != 1 )   if( fputc( XB_CHAREOF, fp ) != XB_CHAREOF )     xb_error(XB_WRITE_ERROR);#endif   /* calculate the latest header information */   xbDate d;    UpdateYY = d.YearOf() - 1900;   if(XFV == 3)      UpdateYY %= 100;  // dBASE III seems to do this, IV does not.  DTB   UpdateMM = d.MonthOf();   UpdateDD = d.DayOf( XB_FMT_MONTH );#ifndef XB_REAL_DELETE   NoOfRecs++;#else   if(RealDelete)   {     if(nextRecNo == NoOfRecs + 1)       NoOfRecs++;     RealNumRecs++;   }   else     NoOfRecs++;#endif   CurRec = nextRecNo;//   CurRec = NoOfRecs;   /* rewrite the header record */   if(( rc = WriteHeader( 1 )) != XB_NO_ERROR )      return rc;#ifdef XB_LOCKING_ON   if( AutoLock )      LockDatabase( F_SETLK, F_UNLCK, 0L );#if defined(XB_INDEX_ANY)   i = NdxList;   while( i && AutoLock ){      i->index->LockIndex( F_SETLK, F_UNLCK );      i = i->NextIx;   }#endif               /* XB_INDEX_ANY  */#endif               /* XB_LOCKING_ON */   DbfStatus = XB_OPEN;   return XB_NO_ERROR;}/************************************************************************///! Get a record from the data file/*!  This method attempts to retrieve the record specified by RecNo from the  data file into the record buffer.      \param RecNo Record number to retrieve  \returns One of the following:    \htmlonly      <p>      <table border=2><tr><th>Return Code</th><th>Description</th></tr>        <tr><td>XB_NO_ERROR</td><td>No error</td></tr>        <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>        <tr><td>XB_NOT_OPEN</td><td>File is not open</td></tr>        <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>        <tr><td>XB_WRITE_ERROR</td><td>Error writing to file</td></tr>      </table>    \endhtmlonly    \latexonly      \\      \\      \begin{tabular}{|l|l|} \hline        \textbf{Return Code} & \textbf{Description} \\ \hline \hline        XB\_NO\_ERROR & No error \\ \hline   XB\_LOCK\_FAILED & Couldn't lock file \\ \hline   XB\_NOT\_OPEN & File is not open \\ \hline   XB\_INVALID\_RECORD & Invalid record number \\ \hline   XB\_WRITE\_ERROR & Error writing to file \\ \hline      \end{tabular}    \endlatexonly*/xbShort xbDbf::GetRecord( xbULong RecNo ){/* 4/16/2000 - gk - made mods to record locking logic */   int rc;   if( DbfStatus == XB_CLOSED )    xb_error(XB_NOT_OPEN); #ifndef XB_LOCKING_ON   if( DbfStatus == XB_UPDATED /*&& AutoUpdate*/ )   /* update previous rec if necessary */      if(( rc = PutRecord( CurRec )) != 0 )         return rc;#endif         #ifdef XB_LOCKING_ON   if( AutoLock )      if(( rc = LockDatabase( F_SETLKW, F_RDLCK, RecNo )) != 0 ) return rc;         if((rc = ReadHeader(1)) != XB_NO_ERROR)   {      if(AutoLock)         LockDatabase( F_SETLK, F_UNLCK, RecNo );      return rc;   }#endif   if( RecNo > NoOfRecs || RecNo == 0L )     xb_error(XB_INVALID_RECORD);   /* michael - modified code to avoid unecessary fseek work */   /* commented out this code because it doesn't work in DOS/Win environments *///   if( !CurRec || RecNo != CurRec+1 )//   {      if( fseek( fp, (long) HeaderLen+((RecNo-1L)*RecordLen), SEEK_SET ))      {#ifdef XB_LOCKING_ON         LockDatabase( F_SETLK, F_UNLCK, RecNo );#endif         xb_error(XB_SEEK_ERROR);      }//   }   if( fread( RecBuf, RecordLen, 1, fp ) != 1 )   {#ifdef XB_LOCKING_ON      LockDatabase( F_SETLK, F_UNLCK, RecNo );#endif      xb_error(XB_READ_ERROR);   }#ifdef XB_LOCKING_ON   if( AutoLock )      LockDatabase( F_SETLKW, F_UNLCK, RecNo );#endif   DbfStatus = XB_OPEN;   CurRec = RecNo;   return XB_NO_ERROR;}/************************************************************************///! Get the first physical record in the data file/*!  Attempts to retrieve the first physical record from the data file into  the record buffer.    \returns One of the following:    \htmlonly      <p>      <table border=2><tr><th>Return Code</th><th>Description</th></tr>        <tr><td>XB_NO_ERROR</td><td>No error</td></tr>        <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>        <tr><td>XB_NOT_OPEN</td><td>File is not open</td></tr>        <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>        <tr><td>XB_SEEK_ERROR</td><td>Error seeking file</td></tr>        <tr><td>XB_WRITE_ERROR</td><td>Error writing to file</td></tr>      </table>    \endhtmlonly    \latexonly      \\      \\      \begin{tabular}{|l|l|} \hline        \textbf{Return Code} & \textbf{Description} \\ \hline \hline        XB\_NO\_ERROR & No error \\ \hline   XB\_LOCK\_FAILED & Couldn't lock file \\ \hline   XB\_NOT\_OPEN & File is not open \\ \hline   XB\_INVALID\_RECORD & Invalid record number \\ \hline   XB\_SEEK\_ERROR & Error seeking file \\ \hline   XB\_WRITE\_ERROR & Error writing to file \\ \hline      \end{tabular}    \endlatexonly*/xbShort xbDbf::GetFirstRecord( void ){   xbShort rc = 0;   if( NoOfRecs == 0 )     xb_error(XB_INVALID_RECORD);#ifndef XB_LOCKING_ON   if( DbfStatus == XB_UPDATED /*&& AutoUpdate*/ )  /* updatfe previous rec if necessary */      if(( rc = PutRecord( CurRec )) != 0 )         return rc;#endif            rc = GetRecord( 1L );#ifdef XB_REAL_DELETE   if(!rc && RealDelete && RecordDeleted())     rc = GetNextRecord();#endif   return rc;}/************************************************************************///! Get the last phyiscal record in the data file/*!  Attempts to retrieve the last physical record from the data file into  the record buffer.    \returns One of the following:    \htmlonly      <p>      <table border=2><tr><th>Return Code</th><th>Description</th></tr>        <tr><td>XB_NO_ERROR</td><td>No error</td></tr>        <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -