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

📄 ntx.cpp

📁 一个通讯管理机的源代码。比较好用。推荐
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************                          ntx.cpp  -  description                             -------------------    begin                : Thu Jan 17 2002    copyright            : (C) 2002 by     email                :  ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//*  $Id: ntx.cpp,v 1.6 2000/11/10 19:04:17 dbryson Exp $    Xbase project source code    NTX (Clipper) indexing routines for X-Base    Copyright (C) 1999 SynXis Corp., Bob Cotton    email - bob@synxis.com    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Lesser General Public    License as published by the Free Software Foundation; either    version 2.1 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public    License along with this library; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    Contact:      Mail:        Technology Associates, Inc.        XBase Project        1455 Deming Way #11        Sparks, NV 89434        USA      Email:        xbase@techass.com      See our website at:        xdb.sourceforge.net    V 1.0   10/10/97   - Initial release of software*/#ifdef __GNUG__  #pragma implementation "ntx.h"#endif#ifdef __WIN32__#include "xbconfigw32.h"#else#include "xbconfig.h"#endif#include "xbase.h"#ifdef XB_INDEX_NTX#ifdef HAVE_IO_H#include <io.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <sys/stat.h>/* FIXME?   Why <unistd.h> is there?  Nothing bad happens if it isn't.   -- willy */#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include "xbexcept.h"/*! \file ntx.cpp*//***********************************************************************///! Short description./*!*/xbShort xbNtx::CloneNodeChain( void ){   xbNodeLink * TempNodeS;   xbNodeLink * TempNodeT;   xbNodeLink * TempNodeT2;   xbUShort *sp;   if( CloneChain ) ReleaseNodeMemory( CloneChain );   CloneChain = NULL;   if( !NodeChain ) return XB_NO_ERROR;   TempNodeS = NodeChain;   TempNodeT2 = NULL;   while( TempNodeS )   {      if(( TempNodeT = GetNodeMemory()) == NULL )#ifdef HAVE_EXCEPTIONS      throw xbOutOfMemoryException();#else      return XB_NO_MEMORY;#endif      sp = TempNodeT->offsets;      memcpy( TempNodeT, TempNodeS, sizeof( struct xbNodeLink ));      TempNodeT->offsets = sp;      TempNodeT->NextNode = NULL;      TempNodeT->PrevNode = TempNodeT2;      if( !CloneChain )      {         TempNodeT2 = TempNodeT;         CloneChain = TempNodeT;      }      else      {         TempNodeT2->NextNode = TempNodeT;         TempNodeT2 = TempNodeT2->NextNode;      }      TempNodeS = TempNodeS->NextNode;   }   return XB_NO_ERROR;}/***********************************************************************///! Short description./*!*/xbShort xbNtx::UncloneNodeChain( void ){   if( NodeChain )      ReleaseNodeMemory( NodeChain );   NodeChain = CloneChain;   CloneChain = NULL;   CurNode = NodeChain;   while( CurNode->NextNode )      CurNode = CurNode->NextNode;   return XB_NO_ERROR;}/***********************************************************************///! Short description./*!*//* This routine dumps the node chain to stdout                         */#ifdef XBASE_DEBUGvoid xbNtx::DumpNodeChain( void ){   xbNodeLink  *n;   cout << "\n*************************\n";   cout <<   "NodeLinkCtr = " << NodeLinkCtr;   cout << "\nReused      = " << ReusedNodeLinks << "\n";   n = NodeChain;   while(n)   {      cout << "xbNodeLink Chain" << n->NodeNo << "\n";      n = n->NextNode;   }   n = FreeNodeChain;   while(n)   {      cout << "FreeNodeLink Chain" << n->NodeNo << "\n";      n = n->NextNode;   }   n = DeleteChain;   while(n)   {      cout << "DeleteLink Chain" << n->NodeNo << "\n";      n = n->NextNode;   }}#endif/***********************************************************************///! Short description./*!  \param n*//* This routine returns a chain of one or more index nodes back to the *//* free node chain                                                     */void xbNtx::ReleaseNodeMemory( xbNodeLink * n ){   xbNodeLink * temp;   if( !FreeNodeChain )      FreeNodeChain = n;   else    /* put this list at the end */   {      temp = FreeNodeChain;      while( temp->NextNode )         temp = temp->NextNode;      temp->NextNode = n;   }   return;}/***********************************************************************///! Short description./*!*//* This routine returns a node from the free chain if available,       *//* otherwise it allocates new memory for the requested node             */xbNodeLink * xbNtx::GetNodeMemory( void ){   xbNodeLink * temp;   if( FreeNodeChain )   {      temp = FreeNodeChain;      temp->offsets = FreeNodeChain->offsets;      FreeNodeChain = temp->NextNode;      ReusedNodeLinks++;            memset( temp->Leaf.KeyRecs, 0x00, XB_NTX_NODE_SIZE );      temp->Leaf.NoOfKeysThisNode = 0;      temp->PrevNode = 0x00;      temp->NextNode = 0x00;      temp->CurKeyNo = 0L;      temp->NodeNo = 0L;      for (int i = 0; i < HeadNode.KeysPerNode + 1; i++)      {          temp->offsets[i] = 2 + ((HeadNode.KeysPerNode + 1) * 2) + (HeadNode.KeySize * i);      }                     }   else   {      temp = (xbNodeLink *) malloc( sizeof( xbNodeLink ));      if(temp==NULL) return NULL;      memset( temp, 0x00, sizeof( xbNodeLink ));      temp->offsets = (xbUShort *)malloc( (HeadNode.KeysPerNode + 1) * sizeof(xbUShort));     if (temp->offsets==NULL) {      free(temp);      return NULL;     };      NodeLinkCtr++;   }   return temp;}/***********************************************************************///! Short description./*!*/#ifdef XBASE_DEBUGvoid xbNtx::DumpHdrNode( void ){    cout << "\nSignature          = " << HeadNode.Signature;    cout << "\nVersion            = " << HeadNode.Version;    cout << "\nStartPahe          = " << HeadNode.StartNode;    cout << "\nUnusedOffset       = " << HeadNode.UnusedOffset;    cout << "\nKeySize            = " << HeadNode.KeySize;    cout << "\nKeyLen             = " << HeadNode.KeyLen;    cout << "\nDecimalCount       = " << HeadNode.DecimalCount;    cout << "\nKeysPerNode        = " << HeadNode.KeysPerNode;    cout << "\nHalfKeysPerPage    = " << HeadNode.HalfKeysPerNode;    cout << "\nKeyExpression      = " << HeadNode.KeyExpression;    cout << "\nUnique             = " << HeadNode.Unique;    cout << "\n";}#endif/***********************************************************************///! Short description./*!  \param pdbf*/xbNtx::xbNtx( xbDbf * pdbf )  : xbIndex (pdbf){   memset( Node, 0x00, XB_NTX_NODE_SIZE );   memset( &HeadNode, 0x00, sizeof( NtxHeadNode ));    NodeChain       = NULL;   CloneChain      = NULL;   FreeNodeChain   = NULL;   DeleteChain     = NULL;   CurNode         = NULL;   NodeLinkCtr     = 0L;   ReusedNodeLinks = 0L;}/***********************************************************************///! Short description./*!*/xbShortxbNtx::AllocKeyBufs(void){   KeyBuf  = (char *) malloc( HeadNode.KeyLen + 1 );    if(KeyBuf==NULL) {       return XB_NO_MEMORY;       };   KeyBuf2 = (char *) malloc( HeadNode.KeyLen + 1);   if(KeyBuf2==NULL) {      free(KeyBuf);      return XB_NO_MEMORY;       };   memset( KeyBuf,  0x00, HeadNode.KeyLen + 1 );   memset( KeyBuf2, 0x00, HeadNode.KeyLen + 1 );   return XB_NO_ERROR;}/***********************************************************************///! Short description./*!  \param FileName*/xbShort xbNtx::OpenIndex( const char * FileName ){   int NameLen, rc;   NameLen = strlen( FileName ) + 1;   if (( rc = dbf->NameSuffixMissing( 4, FileName )) > 0)       NameLen += 4;   IndexName = FileName;      if( rc == 1 )       IndexName += ".ntx";   else if ( rc == 2 )       IndexName += ".NTX";   /* open the file */   if(( indexfp = fopen( IndexName, "r+b" )) == NULL ){     xb_open_error(IndexName);   }   #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_RDLCK)) != 0)        return rc;#endif          IndexStatus = 1;    if(( rc = GetHeadNode()) != 0)    { #ifdef XB_LOCKING_ON      if( dbf->GetAutoLock() )         LockIndex(F_SETLKW, F_UNLCK);#endif      fclose( indexfp );      return rc;   }   /* parse the expression */   if(( rc = dbf->xbase->BuildExpressionTree( HeadNode.KeyExpression,       strlen( HeadNode.KeyExpression ), dbf )) != XB_NO_ERROR )   {#ifdef XB_LOCKING_ON      if( dbf->GetAutoLock() )         LockIndex(F_SETLKW, F_UNLCK);#endif      fclose( indexfp );      return rc;   }   ExpressionTree = dbf->xbase->GetTree();   dbf->xbase->SetTreeToNull();    rc=AllocKeyBufs();   if(rc)    {#ifdef XB_LOCKING_ON      if( dbf->GetAutoLock() )         LockIndex(F_SETLKW, F_UNLCK);#endif      fclose(indexfp);      return rc;        }#ifdef XBASE_DEBUG//   CheckIndexIntegrity( 0 );#endif#ifdef XB_LOCKING_ON   if( dbf->GetAutoLock() )      LockIndex(F_SETLKW, F_UNLCK);#endif   return dbf->AddIndexToIxList( index, IndexName );  }/***********************************************************************///! Short description./*!*/xbShort xbNtx::CloseIndex( void ){   if( KeyBuf )    { free ( KeyBuf );    KeyBuf = NULL;    }   if( KeyBuf2 )   { free ( KeyBuf2 );   KeyBuf2 = NULL;   }   dbf->RemoveIndexFromIxList( index );   fclose( indexfp );   IndexStatus = 0;   return 0;}/***********************************************************************///! Short description./*!*/xbShort xbNtx::GetHeadNode( void ){   char *p;   if( !IndexStatus )       xb_error(XB_NOT_OPEN);   if( fseek( indexfp, 0, SEEK_SET ))       xb_io_error(XB_SEEK_ERROR, IndexName);   if(( fread( Node, XB_NTX_NODE_SIZE, 1, indexfp )) != 1 )       xb_io_error(XB_READ_ERROR, IndexName);   /* load the head node structure */   p = Node;   HeadNode.Signature = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);   HeadNode.Version = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);   HeadNode.StartNode = dbf->xbase->GetULong( p ); p += sizeof(xbULong);   HeadNode.UnusedOffset = dbf->xbase->GetULong( p ); p += sizeof(xbULong);   HeadNode.KeySize = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);   HeadNode.KeyLen = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);   HeadNode.DecimalCount = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);   HeadNode.KeysPerNode = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);   HeadNode.HalfKeysPerNode = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);   strncpy(HeadNode.KeyExpression, p, 256); p+= 256;   HeadNode.Unique = *p++;   p = HeadNode.KeyExpression;   while (*p)   {       *p = toupper(*p);       p++;   }   return 0;}/***********************************************************************///! Short description./*!  \param NodeNo  \param SetNodeChain*//* This routine reads a leaf node from disk                            *//*                                                                     *//*  If SetNodeChain 2, then the node is not appended to the node chain *//*                     but the CurNode pointer points to the node read *//*  If SetNodeChain 1, then the node is appended to the node chain     *//*  If SetNodeChain 0, then record is only read to Node memory         */xbShort xbNtx::GetLeafNode( xbLong NodeNo, xbShort SetNodeChain ){   xbNodeLink *n;   char *p;   if( !IndexStatus )       xb_error(XB_NOT_OPEN);   if( fseek( indexfp, NodeNo, SEEK_SET ))       xb_io_error(XB_SEEK_ERROR, IndexName);   if(( fread( Node, XB_NTX_NODE_SIZE, 1, indexfp )) != 1 )       xb_io_error(XB_READ_ERROR, IndexName);   if( !SetNodeChain ) return 0;   if(( n = GetNodeMemory()) == NULL )       xb_memory_error;   n->NodeNo = NodeNo;   n->CurKeyNo = 0L;   n->NextNode = NULL;   // The offsets at the head of each leaf are not necessarly in order.   p = Node + 2;   for (int i = 0; i < HeadNode.KeysPerNode + 1; i++)   {      n->offsets[i] = dbf->xbase->GetShort( p );      p += 2;   }      // Do the edian translation correctly   n->Leaf.NoOfKeysThisNode = dbf->xbase->GetShort( Node );   memcpy( n->Leaf.KeyRecs,           Node,           XB_NTX_NODE_SIZE);

⌨️ 快捷键说明

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