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

📄 ntx.cpp

📁 一个通讯管理机的源代码。比较好用。推荐
💻 CPP
📖 第 1 页 / 共 5 页
字号:
   if( !TempNode ) return 0;   if( TempNode->Type == 'd' ) return TempNode->ResultLen;   if( TempNode->Type == 'D' )   {      memset( FieldName, 0x00, 11 );      memcpy( FieldName, TempNode->NodeText, TempNode->Len );      Type = dbf->GetFieldType( dbf->GetFieldNo( FieldName ));      if( Type == 'N' || Type == 'F' )         return TempNode->ResultLen;   }   if(( rc = dbf->xbase->ProcessExpression( ExpressionTree )) != XB_NO_ERROR )      return 0;   TempNode = (xbExpNode *) dbf->xbase->Pop();   if( !TempNode ) return 0;   rc = TempNode->DataLen;//   if( !TempNode->InTree ) dbf->xbase->FreeExpNode( TempNode );   if( !TempNode->InTree ) delete TempNode;   return rc;}/***********************************************************************///! Short description./*!  \param IxName  \param Exp  \param Unique  \param Overlay*/xbShort xbNtx::CreateIndex(const char * IxName, const char * Exp, xbShort Unique, xbShort Overlay ){   xbShort i, NameLen, KeyLen, rc;   IndexStatus = XB_CLOSED;   if( strlen( Exp ) > 255 ) xb_error( XB_INVALID_KEY_EXPRESSION);   if( dbf->GetDbfStatus() == 0 ) xb_error( XB_NOT_OPEN);   /* Get the index file name and store it in the class */   NameLen = strlen( IxName ) + 1;   if(( rc = dbf->NameSuffixMissing( 4, IxName )) > 0 )      NameLen +=4;/*   if(( IndexName = (char *) malloc( NameLen )) == NULL )   {#ifdef HAVE_EXCEPTIONS       throw xbOutOfMemoryException();#else      return XB_NO_MEMORY;#endif   }*/                             /* copy the name to the class variable */   IndexName = IxName;      if( rc == 1 )       IndexName += ".ntx";   else if( rc == 2 )       IndexName += ".NTX";   /* check if the file already exists */   if (((indexfp = fopen( IndexName, "r" )) != NULL ) && !Overlay )   {      fclose( indexfp );      xb_io_error(XB_FILE_EXISTS, IndexName);   }   else if( indexfp ) fclose( indexfp );   if(( indexfp = fopen( IndexName, "w+b" )) == NULL ){      return XB_OPEN_ERROR;   }#ifdef XB_LOCKING_ON      /*   **  Must turn off buffering when multiple programs may be accessing   **  index files.   */   setbuf( indexfp, NULL );#endif   #ifdef XB_LOCKING_ON   if( dbf->GetAutoLock() )      if((rc = LockIndex(F_SETLKW, F_WRLCK)) != 0)         return rc;#endif   /* parse the expression */   if(( rc = dbf->xbase->BuildExpressionTree( Exp, strlen( Exp ), dbf )) != XB_NO_ERROR )      return rc;   ExpressionTree = dbf->xbase->GetTree();   dbf->xbase->SetTreeToNull();    /* build the header record */   memset( &HeadNode, 0x00, sizeof( NtxHeadNode ));   HeadNode.Signature = 0x6;   // Clipper 5.x   HeadNode.Version = 1;   HeadNode.StartNode  = 1024L;   KeyLen = CalcKeyLen();   // TODO   // What is the Clipper key length limit?   if( KeyLen == 0 || KeyLen > 100 )       /* 100 byte key length limit */   {#ifdef XB_LOCKING_ON      if( dbf->GetAutoLock() )         LockIndex(F_SETLKW, F_UNLCK);#endif       xb_error(XB_INVALID_KEY);   }   else   {       HeadNode.KeyLen = KeyLen;    }   // This is not the algorithm that Clipper uses. I cant figure out   // what they use from looking at the examples.   // This is correct tho.   HeadNode.KeysPerNode = (xbUShort)       (( XB_NTX_NODE_SIZE - (2 * sizeof( xbUShort ))) / (HeadNode.KeyLen + 10 )) - 1;   if (HeadNode.KeysPerNode % 2)       HeadNode.KeysPerNode--;   HeadNode.HalfKeysPerNode = (xbUShort) HeadNode.KeysPerNode / 2;   HeadNode.KeySize = HeadNode.KeyLen + 8;//   while(( HeadNode.KeySize % 4 ) != 0 ) HeadNode.KeySize++;  /* multiple of 4*/   HeadNode.Unique = Unique;   strncpy( HeadNode.KeyExpression, Exp, 255 );   rc=AllocKeyBufs();   if(rc) {      fclose(indexfp);      return rc;        };   if(( rc = PutHeadNode( &HeadNode, indexfp, 0 )) != 0 )   {#ifdef XB_LOCKING_ON      if( dbf->GetAutoLock() )         LockIndex(F_SETLKW, F_UNLCK);#endif      return rc;   }   /* write node #1 all 0x00 */   for( i = 0; i < XB_NTX_NODE_SIZE; i++ )   {      if(( fwrite( "\x00", 1, 1, indexfp )) != 1 )      {#ifdef XB_LOCKING_ON         if( dbf->GetAutoLock() )            LockIndex(F_SETLKW, F_UNLCK);#endif         fclose( indexfp );         xb_io_error(XB_WRITE_ERROR, IndexName);      }   }   IndexStatus = XB_OPEN;   if ((rc = GetLeafNode(HeadNode.StartNode, 1)) != 0)   {#ifdef XB_LOCKING_ON      if( dbf->GetAutoLock() )         LockIndex(F_SETLKW, F_UNLCK);#endif       return rc;   }      for (i = 0; i < HeadNode.KeysPerNode + 1; i++)   {       CurNode->offsets[i] = (i * HeadNode.KeySize) +           2 + (2 * (HeadNode.KeysPerNode + 1));   }      if ((rc = PutLeafNode(HeadNode.StartNode, CurNode )) != 0)   {#ifdef XB_LOCKING_ON      if( dbf->GetAutoLock() )         LockIndex(F_SETLKW, F_UNLCK);#endif       return rc;   }#ifdef XB_LOCKING_ON   if( dbf->GetAutoLock() )      LockIndex(F_SETLKW, F_UNLCK);#endif   return dbf->AddIndexToIxList( index, IndexName );  }/***********************************************************************///! Short description./*!  \param RecNo  \param n  \param NodeNo*/xbShort xbNtx::PutLeftNodeNo( xbShort RecNo, xbNodeLink *n, xbLong NodeNo ){   /* This routine sets n node's leftnode number */   NtxLeafNode *temp;   char *p;   xbUShort itemOffset;   if( !n ) xb_error( XB_INVALID_NODELINK);   temp = &n->Leaf;   if( RecNo < 0 || RecNo > HeadNode.KeysPerNode)       xb_error(XB_INVALID_KEY);   p = temp->KeyRecs;   itemOffset = GetItemOffset(RecNo, n, 1);   p += itemOffset;   dbf->xbase->PutLong( p, NodeNo );   return XB_NO_ERROR;}/***********************************************************************///! Short description./*!  \param RecNo  \param n  \param DbfNo*/xbShort xbNtx::PutDbfNo( xbShort RecNo, xbNodeLink *n, xbLong DbfNo ){   /* This routine sets n node's dbf number */   NtxLeafNode *temp;   char *p;   xbUShort itemOffset;   if( !n ) xb_error( XB_INVALID_NODELINK);   temp = &n->Leaf;   if( RecNo < 0 || RecNo > (HeadNode.KeysPerNode))       xb_error(XB_INVALID_KEY);   itemOffset = GetItemOffset(RecNo, n, 1);   p = temp->KeyRecs;   p += itemOffset;   p += 4;   dbf->xbase->PutLong( p, DbfNo );   return XB_NO_ERROR;}/************************************************************************///! Short description./*!  \param l  \param n*/xbShort xbNtx::PutLeafNode( xbLong l, xbNodeLink *n ){    NtxLeafNode *temp;    char *p;        if(( fseek( indexfp, l , SEEK_SET )) != 0 )    {        fclose( indexfp );        xb_io_error( XB_SEEK_ERROR, IndexName );    }    temp = &n->Leaf;    p = temp->KeyRecs;    dbf->xbase->PutShort( p, temp->NoOfKeysThisNode );    // The offsets at the head of each leaf are not necessarly in order.    p += 2;    for (int i = 0; i < HeadNode.KeysPerNode + 1; i++)    {        dbf->xbase->PutShort( p, n->offsets[i] );        p += 2;    }           if(( fwrite( &n->Leaf.KeyRecs, XB_NTX_NODE_SIZE, 1, indexfp )) != 1 )    {        fclose( indexfp );        xb_io_error(XB_WRITE_ERROR, IndexName);    }    PutHeadNode(&HeadNode, indexfp, 1);    return 0;   }/************************************************************************///! Short description./*!  \param Head  \param f  \param UpdateOnly*/xbShort xbNtx::PutHeadNode( NtxHeadNode * Head, FILE * f, xbShort UpdateOnly ){    char buf[4];    char *p;     if(( fseek( f, 0L, SEEK_SET )) != 0 )    {        fclose( f );        xb_io_error( XB_SEEK_ERROR, IndexName );    }    memset( buf, 0x00, 2 );    dbf->xbase->PutUShort( buf, Head->Signature );    if(( fwrite( &buf, 2, 1, f )) != 1 )    {        fclose( f );        xb_io_error(XB_WRITE_ERROR, IndexName);    }    memset( buf, 0x00, 2 );    dbf->xbase->PutUShort( buf, Head->Version );    if(( fwrite( &buf, 2, 1, f )) != 1 )    {        fclose( f );        xb_io_error( XB_WRITE_ERROR, IndexName );    }    memset( buf, 0x00, 4 );    dbf->xbase->PutULong( buf, Head->StartNode );    if(( fwrite( &buf, 4, 1, f )) != 1 )    {        fclose( f );        xb_io_error( XB_WRITE_ERROR, IndexName );    }        memset( buf, 0x00, 4 );    dbf->xbase->PutULong( buf, Head->UnusedOffset );    if(( fwrite( &buf, 4, 1, f )) != 1 )    {        fclose( f );        xb_io_error( XB_WRITE_ERROR, IndexName );    }    if( UpdateOnly )    {        fflush(indexfp);        xb_io_error( XB_NO_ERROR, IndexName );    }    memset( buf, 0x00, 2 );    dbf->xbase->PutUShort( buf, Head->KeySize );    if(( fwrite( &buf, 2, 1, f )) != 1 )    {        fclose( f );        xb_io_error( XB_WRITE_ERROR, IndexName );    }    memset( buf, 0x00, 2 );    dbf->xbase->PutUShort( buf, Head->KeyLen );    if(( fwrite( &buf, 2, 1, f )) != 1 )    {        fclose( f );        xb_io_error( XB_WRITE_ERROR, IndexName );    }    memset( buf, 0x00, 2 );    dbf->xbase->PutUShort( buf, Head->DecimalCount );    if(( fwrite( &buf, 2, 1, f )) != 1 )    {        fclose( f );        xb_io_error( XB_WRITE_ERROR, IndexName );    }    memset( buf, 0x00, 2 );    dbf->xbase->PutUShort( buf, Head->KeysPerNode );    if(( fwrite( &buf, 2, 1, f )) != 1 )    {        fclose( f );        xb_io_error( XB_WRITE_ERROR, IndexName );    }    memset( buf, 0x00, 2 );    dbf->xbase->PutUShort( buf, Head->HalfKeysPerNode );    if(( fwrite( &buf, 2, 1, f )) != 1 )    {        fclose( f );        xb_io_error( XB_WRITE_ERROR, IndexName );    }    p = HeadNode.KeyExpression;    while (*p)    {        *p = tolower(*p);        p++;    }    if(( fwrite( &Head->KeyExpression, 256, 1, f )) != 1 )    {        fclose( f );        xb_io_error( XB_WRITE_ERROR, IndexName );    }        memset( buf, 0x00, 1 );    buf[0] = Head->Unique;    if(( fwrite( &buf, 1, 1, f )) != 1 )    {        fclose( f );        xb_io_error( XB_WRITE_ERROR, IndexName );    }    if(( fwrite( &Head->NotUsed, 745, 1, f )) != 1 )    {        fclose( f );        xb_io_error( XB_WRITE_ERROR, IndexName );    }    return 0;   }xbShort xbNtx::TouchIndex( void ){    xbShort rc;    if (( rc = GetHeadNode()) != XB_NO_ERROR) return rc;    HeadNode.Version++;    if (( rc = PutHeadNode(&HeadNode, indexfp, 1)) != XB_NO_ERROR) return rc;    return XB_NO_ERROR;}/************************************************************************///! Short description./*!  \param RecNo  \param n*/xbShort xbNtx::PutKeyData( xbShort RecNo, xbNodeLink *n ){   /* This routine copies the KeyBuf data into xbNodeLink n */   NtxLeafNode *temp;   char *p;   xbShort i;   xbUShort itemOffset;   if( !n ) xb_error( XB_INVALID_NODELINK );   temp = &n->Leaf;   if( RecNo < 0 || RecNo > (HeadNode.KeysPerNode))       xb_error( XB_INVALID_KEY );   itemOffset = GetItemOffset(RecNo, n, 1);   p = temp->KeyRecs;   p += itemOffset;   p += 8;   for( i = 0; i < HeadNode.KeyLen; i++ )   {      *p = KeyBuf[i];      p++;   }   return XB_NO_ERROR;}/************************************************************************///! Short description./*!  \param n  \param pos  \param d  \param l  \param w*/xbShort xbNtx::PutKeyInNode( xbNodeLink * n, xbShort pos, xbLong d, xbLong l, xbShort w ){    /* check the node */    if( !n ) xb_error( XB_INVALID_NODELINK );    if( pos < 0 || pos > HeadNode.KeysPerNode ) xb_error( XB_INVALID_RECORD );    if( n->Leaf.NoOfKeysThisNode >= HeadNode.KeysPerNode ) xb_error( XB_NODE_FULL );    InsertKeyOffset(pos, n);    PutKeyData( pos, n );    PutDbfNo( pos, n, d );    PutLeftNodeNo( pos, n, l );    n->Leaf.NoOfKeysThisNode++;    if( w )        return PutLeafNode( n->NodeNo, n );    else        return 0;}/************************************************************************///! Short description./*!  \param n1  \param n2  \param pos  \param d*/xbShort xbNtx::SplitLeafNode( xbNodeLink *n1, xbNodeLink *n2, xbShort pos, xbLong d ){   xbShort i,j,rc;   xbShort temp;   xbShort start;   xbShort end;   xbShort length;   if( !n1 || !n2 ) xb_error( XB_INVALID_NODELINK );   if( pos < 0 || pos > HeadNode.KeysPerNode ) xb_error( XB_INVALID_RECORD );   length = strlen(KeyBuf);   // If the new key goes in the first node.   if (pos < HeadNode.HalfKeysPerNode)   {       // Setup key to insert into parent       memcpy(PushItem.Key,              GetKeyData(HeadNode.HalfKeysPerNode -1, n1),              HeadNode.KeyLen);       PushItem.RecordNumber = GetDbfNo(HeadNode.HalfKeysPerNode -1, n1);       PushItem.Node =  0L;        start = pos;       end = HeadNode.HalfKeysPerNode - 1;

⌨️ 快捷键说明

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