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

📄 memo.cpp

📁 一个通讯管理机的源代码。比较好用。推荐
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   if((  rc = ReadMemoBlock( BlockNo, Vswitch )) != 0 )   {#ifdef XB_LOCKING_ON      if( LockOpt != -1 )         LockMemoFile( F_SETLK, F_UNLCK );#endif      return rc;   }   tp = Buf;   sp = (char *) mbb;   if( IsType4Dbt() )   {      sp+=8;      Scnt = 8L;     }   else      Scnt = 0L;   Tcnt = 0L;   while( Tcnt < len )   {      *tp++ = *sp++;      Scnt++;      Tcnt++;      if( Scnt >= MemoHeader.BlockSize )      {         BlockNo++;         if((  rc = ReadMemoBlock( BlockNo, 1 )) != 0 )            return rc;         Scnt = 0;         sp = (char *) mbb;      }   } #ifdef XB_LOCKING_ON   if( LockOpt != -1 )      LockMemoFile( F_SETLK, F_UNLCK );#endif   return XB_NO_ERROR;}/***********************************************************************///! Short description/*!  \param FieldNo*/xbLong xbDbf::GetMemoFieldLen( const xbShort FieldNo ) {   xbLong  BlockNo, ByteCnt;   xbShort scnt, NotDone;   char *sp, *spp;   if(( BlockNo = GetLongField( FieldNo )) == 0L )      return 0L;   if( IsType4Dbt())   /* dBASE IV */   {      if( BlockNo == CurMemoBlockNo && CurMemoBlockNo != -1 )         return MFieldLen - MStartPos;      if( ReadMemoBlock( BlockNo, 0 ) != XB_NO_ERROR )         return 0L;      return MFieldLen - MStartPos;   }   else  /* version 0x03 dBASE III+ */   {      ByteCnt = 0L;      sp = spp = NULL;      NotDone = 1;      while( NotDone )      {         if( ReadMemoBlock( BlockNo++, 1 ) != XB_NO_ERROR )            return 0L;         scnt = 0;         sp = (char *) mbb;         while( scnt < 512 && NotDone )         {            if( *sp == 0x1a && *spp == 0x1a )               NotDone = 0;            else            {               ByteCnt++; scnt++; spp = sp; sp++;            }         }      }      if( ByteCnt > 0 ) ByteCnt--;      return ByteCnt;   }}/***********************************************************************///! Short description/*!*/xbShort xbDbf::MemoFieldsPresent( void ) const{   xbShort i;   for( i = 0; i < NoOfFields; i++ )      if( GetFieldType( i ) == 'M' )          return 1;   return 0;}/***********************************************************************///! Short description/*!  \param FieldNo*/xbShort xbDbf::DeleteMemoField( const xbShort FieldNo ){   xbLong SBlockNo, SNoOfBlocks = 0L, SNextBlock;   xbLong LastFreeBlock, LastFreeBlockCnt, LastDataBlock;   xbShort rc;   NextFreeBlock    = 0L;   LastFreeBlockCnt = 0L;   LastFreeBlock    = 0L;   SNextBlock       = 0L;   if( IsType3Dbt() )    /* type III */   {      PutField( FieldNo, "          " );      return XB_NO_ERROR;   }   /* Get Block Number */   if(( SBlockNo = GetLongField( FieldNo )) == 0 )     xb_error(XB_INVALID_BLOCK_NO);   /* Load the first block */   if(( rc = ReadMemoBlock( SBlockNo, 4 )) != XB_NO_ERROR )     return rc;   if( (MFieldLen+2) % MemoHeader.BlockSize )     SNoOfBlocks = (MFieldLen+2)/MemoHeader.BlockSize+1L;   else     SNoOfBlocks = (MFieldLen+2)/MemoHeader.BlockSize;   /* Determine last good data block */   LastDataBlock = CalcLastDataBlock();      /* position to correct location in chain */   NextFreeBlock = MemoHeader.NextBlock;   while( SBlockNo > NextFreeBlock && SBlockNo < LastDataBlock )   {      LastFreeBlock    = NextFreeBlock;      if(( rc = ReadMemoBlock( NextFreeBlock, 2 )) != XB_NO_ERROR )        return rc;      LastFreeBlockCnt = FreeBlockCnt;   }   /* if next block should be concatonated onto the end of this set */   if((SBlockNo+SNoOfBlocks) == NextFreeBlock && NextFreeBlock < LastDataBlock )   {      if(( rc = ReadMemoBlock( NextFreeBlock, 2 )) != XB_NO_ERROR )         return XB_NO_ERROR;      SNoOfBlocks += FreeBlockCnt;      SNextBlock = NextFreeBlock;   }   else if( LastFreeBlock == 0L )      SNextBlock = MemoHeader.NextBlock;   else      SNextBlock = NextFreeBlock;    /* if this is the first set of free blocks */   if( LastFreeBlock == 0L )   {      /* 1 - write out the current block */      /* 2 - update header block         */      /* 3 - write header block          */      /* 4 - update data field           */      NextFreeBlock = SNextBlock;      FreeBlockCnt = SNoOfBlocks;      if(( rc = WriteMemoBlock( SBlockNo, 2 )) != XB_NO_ERROR )         return rc;            MemoHeader.NextBlock = SBlockNo;      if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR )        return rc;      PutField( FieldNo, "          " );      return XB_NO_ERROR;   }   /* determine if this block set should be added to the previous set */   if(( LastFreeBlockCnt + LastFreeBlock ) == SBlockNo )   {      if(( rc = ReadMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR )           return rc;      NextFreeBlock = SNextBlock;      FreeBlockCnt += SNoOfBlocks;      if(( rc = WriteMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR )         return rc;      PutField( FieldNo, "          " );      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                             */   FreeBlockCnt = SNoOfBlocks;   if(( rc = WriteMemoBlock( SBlockNo, 2 )) != XB_NO_ERROR )      return rc;   if(( rc = ReadMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR )      return rc;   NextFreeBlock = SBlockNo;   if(( rc = WriteMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR )      return rc;   PutField( FieldNo, "          " );   return XB_NO_ERROR;}/***********************************************************************///! Short description/*!  \param FieldNo  \param DataLen  \param Buf*/xbShort xbDbf::AddMemoData( const xbShort FieldNo, const xbLong DataLen,     const char * Buf ){   xbShort rc;   xbLong  BlocksNeeded, LastDataBlock;    xbLong  PrevNode, HeadBlock;   xbLong  TotalLen;       /* total length of needed area for memo field */   TotalLen = DataLen+2;   LastDataBlock = CalcLastDataBlock();   if( IsType3Dbt() ||                          /* always append to end */     ( LastDataBlock == MemoHeader.NextBlock )) /* no free space */   {      if( TotalLen % MemoHeader.BlockSize )        BlocksNeeded = TotalLen / MemoHeader.BlockSize + 1;      else        BlocksNeeded = TotalLen / MemoHeader.BlockSize;      MemoHeader.NextBlock = LastDataBlock + BlocksNeeded;  /* reset to eof */      if(( rc = PutMemoData( LastDataBlock, BlocksNeeded, DataLen, Buf ))            != XB_NO_ERROR )        return rc;      HeadBlock = LastDataBlock;      if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR )        return rc;   }   else   {      TotalLen += 8;      if( TotalLen % MemoHeader.BlockSize )        BlocksNeeded = TotalLen / MemoHeader.BlockSize + 1;      else        BlocksNeeded = TotalLen / MemoHeader.BlockSize;      if(( rc = FindBlockSetInChain( BlocksNeeded, LastDataBlock,                   HeadBlock, PrevNode )) == 1 )      {        if(( rc = GetBlockSetFromChain( BlocksNeeded, HeadBlock, PrevNode ))                != XB_NO_ERROR )          return rc;        if(( rc = PutMemoData( HeadBlock, BlocksNeeded, DataLen, Buf )) !=                  XB_NO_ERROR )          return rc;      }      else /* append to the end */      {         /* if header block needed updated, already done by here */         if(( rc = PutMemoData( LastDataBlock, BlocksNeeded, DataLen, Buf ))               != XB_NO_ERROR )      return rc;         HeadBlock = LastDataBlock;         if(( rc = ReadMemoBlock( PrevNode, 2 )) != XB_NO_ERROR )           return rc;         NextFreeBlock += BlocksNeeded;         if(( rc = WriteMemoBlock( PrevNode, 2 )) != XB_NO_ERROR )           return rc;      }                  }   PutLongField( FieldNo, HeadBlock );   return XB_NO_ERROR;}/***********************************************************************///! Short description/*!*/xbShort xbDbf::UpdateHeadNextNode( void ) const{         char buf[4];   memset( buf, 0x00, 4 );   xbase->PutLong( buf, MemoHeader.NextBlock );   if(( fseek( mfp, 0L, SEEK_SET )) != 0 )     xb_error(XB_SEEK_ERROR);   if(( fwrite( &buf, 4, 1, mfp )) != 1 )     xb_error(XB_WRITE_ERROR);   return XB_NO_ERROR;}/***********************************************************************///! Short description/*!  \param StartBlock  \param BlocksNeeded  \param DataLen  \param Buf*/xbShort xbDbf::PutMemoData( const xbLong StartBlock,    const xbLong BlocksNeeded, const xbLong DataLen, const char *Buf ){   xbShort i, rc, Qctr, Tctr, wlen;   xbLong  CurBlock;   char *tp;   const char *sp;     wlen = DataLen + 2;   CurBlock = StartBlock;   tp = (char *) mbb;   sp = Buf;   Qctr = 0;   /* total length processed */   if( IsType3Dbt() )      Tctr = 0;   else  /* dBASE IV */   {      tp += 8;      Tctr = 8;   }   for( i = 0; i < BlocksNeeded; i++ )   {      while( Tctr < MemoHeader.BlockSize && Qctr < wlen )      {         if( Qctr >= DataLen )            *tp++ = 0x1a;    /* end of data marker */         else            *tp++ = *sp++;           Tctr++; Qctr++;      }      if( i == 0 && IsType4Dbt() )      {         mfield1 = -1;         MStartPos = 8;         MFieldLen = DataLen + MStartPos;         if(( rc = WriteMemoBlock( CurBlock++, 0 )) != XB_NO_ERROR )            return rc;      }      else       {         if(( rc = WriteMemoBlock( CurBlock++, 1 )) != XB_NO_ERROR )            return rc;      }      Tctr = 0;      tp = (char *) mbb;   }   return XB_NO_ERROR;}/***********************************************************************///! Short description/*!  \param FieldNo  \param DataLen  \param Buf  \param LockOpt*/xbShort xbDbf::UpdateMemoData( const xbShort FieldNo, const xbLong DataLen,      const char * Buf, const xbShort LockOpt ){   xbShort rc;   xbLong  TotalLen;   xbLong  BlocksNeeded, BlocksAvailable;   #ifdef XB_LOCKING_ON   if( LockOpt != -1 )      if(( rc = LockMemoFile( LockOpt, F_WRLCK )) != XB_NO_ERROR )      return XB_LOCK_FAILED;   #endif   if( DataLen ){     TotalLen = DataLen + 2;              //  add 2 eod 0x1a chars     if( IsType4Dbt()) TotalLen += 8;     //  leading fields for dbase iv   }   else     TotalLen = 0;   if( DataLen == 0L )   /* handle delete */   {      if( MemoFieldExists( FieldNo ) )       {         if(( rc = DeleteMemoField( FieldNo )) != XB_NO_ERROR )         {            #ifdef XB_LOCKING_ON            LockMemoFile( F_SETLK, F_UNLCK );            #endif            return rc;         }      }   }   else if((IsType3Dbt() || GetMemoFieldLen(FieldNo)==0L))   {      if(( rc = AddMemoData( FieldNo, DataLen, Buf )) != XB_NO_ERROR )      {         #ifdef XB_LOCKING_ON         LockMemoFile( F_SETLK, F_UNLCK );         #endif         return rc;      }   }   else   /* version IV type files, reuse unused space */   {      if( TotalLen % MemoHeader.BlockSize )        BlocksNeeded = TotalLen / MemoHeader.BlockSize + 1;      else        BlocksNeeded = TotalLen / MemoHeader.BlockSize;      if(( rc = ReadMemoBlock( GetLongField( FieldNo ), 4 )) != XB_NO_ERROR )       {         #ifdef XB_LOCKING_ON         LockMemoFile( F_SETLK, F_UNLCK );         #endif         return rc;      }      if( (MFieldLen+2) % MemoHeader.BlockSize )        BlocksAvailable = (MFieldLen+2) / MemoHeader.BlockSize + 1;      else        BlocksAvailable = (MFieldLen+2) / MemoHeader.BlockSize;      if( BlocksNeeded == BlocksAvailable )      {         if(( rc = PutMemoData( GetLongField( FieldNo ), BlocksNeeded,           DataLen, Buf )) != XB_NO_ERROR )         {             #ifdef XB_LOCKING_ON             LockMemoFile( F_SETLK, F_UNLCK );             #endif             return rc;         }      }      else      {         if(( rc = DeleteMemoField( FieldNo )) != XB_NO_ERROR )           {             #ifdef XB_LOCKING_ON             LockMemoFile( F_SETLK, F_UNLCK );             #endif             return rc;         }         if(( rc = AddMemoData( FieldNo, DataLen, Buf )) != XB_NO_ERROR )         {            #ifdef XB_LOCKING_ON            LockMemoFile( F_SETLK, F_UNLCK );            #endif            return rc;         }      }   }   #ifdef XB_LOCKING_ON   if( LockOpt != -1 )      if(( rc = LockMemoFile( F_SETLK, F_UNLCK )) != XB_NO_ERROR )         xb_error(XB_LOCK_FAILED);   #endif   return XB_NO_ERROR;}/***********************************************************************///! Short description/*!  \param FieldNo*/xbShort xbDbf::MemoFieldExists( const xbShort FieldNo ) const{   if( GetLongField( FieldNo ) == 0L )      return 0;   else      return 1;}/***********************************************************************///! Short description/*!*/#ifdef XBASE_DEBUGvoid xbDbf::DumpMemoHeader( void ) const{   xbShort i;   cout << "\n*********************************";   cout << "\nMemo header data...";   cout << "\nNext Block " << MemoHeader.NextBlock;   if( IsType4Dbt() )   {      cout << "\nFilename   ";      for( i = 0; i < 8; i++ )         cout << MemoHeader.FileName[i];   }   cout << "\nBlocksize  " << MemoHeader.BlockSize;   return;}/***********************************************************************///! Short description/*!*/xbShort xbDbf::DumpMemoFreeChain( void ) {   xbShort rc;   xbLong  CurBlock, LastDataBlock;   if(( rc = GetDbtHeader(1)) != XB_NO_ERROR )      return rc;   LastDataBlock = CalcLastDataBlock();   CurBlock = MemoHeader.NextBlock;   cout << "\nTotal blocks in file = " << LastDataBlock;   cout << "\nHead Next Block = " << CurBlock;   while( CurBlock < LastDataBlock )   {      if(( rc = ReadMemoBlock( CurBlock, 2 )) != XB_NO_ERROR )         return rc;      cout << "\n**********************************";      cout << "\nThis Block = " << CurBlock;      cout << "\nNext Block = " << NextFreeBlock;      cout << "\nNo Of Blocks = " << FreeBlockCnt << "\n";      CurBlock = NextFreeBlock;   }   return XB_NO_ERROR;}/***********************************************************************///! Short description/*!*/void xbDbf::DumpMemoBlock( void ) const{   xbShort i;   char  *p;   p = (char *) mbb;   if( IsType3Dbt() )   {      for( i = 0; i < 512; i++ )         cout << *p++;   }   else   {      cout << "\nField1     => " << mfield1;      cout << "\nStart Pos  => " << MStartPos;      cout << "\nField Len  => " << MFieldLen;      cout << "\nBlock data => ";      p += 8;      for( i = 8; i < MemoHeader.BlockSize; i++ )         cout << *p++;   }   return;}#endif  /* XBASE_DEBUG *//***********************************************************************/#endif  /* MEMO_FIELD */

⌨️ 快捷键说明

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