dbfntx

  Previous topic Next topic JavaScript is required for the print function Mail us feedback on this topic! Mail us feedback on this topic!  
c:\harbour\source\rdd\dbfntx
dbfntx1.c
TypeFunctionSourceLine
STATIC USHORThb_ntxGetKeyCount( LPPAGEINFO pPage )
static USHORT hb_ntxGetKeyCount( LPPAGEINFO pPage )
{
   char * ptr = hb_ntxPageBuffer( pPage );
   return HB_GET_LE_UINT16( ptr );
}
dbfntx1.c191
STATIC VOIDhb_ntxSetKeyCount( LPPAGEINFO pPage, USHORT uiKeys )
static void hb_ntxSetKeyCount( LPPAGEINFO pPage, USHORT uiKeys )
{
   char * ptr = hb_ntxPageBuffer( pPage );
   HB_PUT_LE_UINT16( ptr, uiKeys );
}
dbfntx1.c197
STATIC USHORThb_ntxGetKeyOffset( LPPAGEINFO pPage, SHORT iKey )
static USHORT hb_ntxGetKeyOffset( LPPAGEINFO pPage, SHORT iKey )
{
   char * ptr = hb_ntxPageBuffer( pPage ) + 2 + ( iKey << 1 );
   return HB_GET_LE_UINT16( ptr );
}
dbfntx1.c203
STATIC VOIDhb_ntxSetKeyOffset( LPPAGEINFO pPage, SHORT iKey, USHORT uiOffset )
static void hb_ntxSetKeyOffset( LPPAGEINFO pPage, SHORT iKey, USHORT uiOffset )
{
   char * ptr = hb_ntxPageBuffer( pPage ) + 2 + ( iKey << 1 );
   HB_PUT_LE_UINT16( ptr, uiOffset );
}
dbfntx1.c209
STATIC CHAR *hb_ntxGetKeyPtr( LPPAGEINFO pPage, SHORT iKey )
static char * hb_ntxGetKeyPtr( LPPAGEINFO pPage, SHORT iKey )
{
   return hb_ntxPageBuffer( pPage ) + hb_ntxGetKeyOffset( pPage, iKey );
}
dbfntx1.c215
STATIC ULONGhb_ntxGetKeyPage( LPPAGEINFO pPage, SHORT iKey )
static ULONG hb_ntxGetKeyPage( LPPAGEINFO pPage, SHORT iKey )
{
   char * ptr = hb_ntxGetKeyPtr( pPage, iKey );
   return HB_GET_LE_UINT32( ptr );
}
dbfntx1.c220
STATIC VOIDhb_ntxSetKeyPage( LPPAGEINFO pPage, SHORT iKey, ULONG ulPage )
static void hb_ntxSetKeyPage( LPPAGEINFO pPage, SHORT iKey, ULONG ulPage )
{
   char * ptr = hb_ntxGetKeyPtr( pPage, iKey );
   HB_PUT_LE_UINT32( ptr, ulPage );
}
dbfntx1.c226
STATIC CHAR *hb_ntxGetKeyVal( LPPAGEINFO pPage, SHORT iKey )
static char * hb_ntxGetKeyVal( LPPAGEINFO pPage, SHORT iKey )
{
   return hb_ntxGetKeyPtr( pPage, iKey ) + 8;
}
dbfntx1.c232
STATIC VOIDhb_ntxSetKeyRec( LPPAGEINFO pPage, SHORT iKey, ULONG ulRec )
static void hb_ntxSetKeyRec( LPPAGEINFO pPage, SHORT iKey, ULONG ulRec )
{
   char * ptr = hb_ntxGetKeyPtr( pPage, iKey ) + 4;
   HB_PUT_LE_UINT32( ptr, ulRec );
}
dbfntx1.c237
STATIC ULONGhb_ntxGetKeyRec( LPPAGEINFO pPage, SHORT iKey )
static ULONG hb_ntxGetKeyRec( LPPAGEINFO pPage, SHORT iKey )
{
   char * ptr = hb_ntxGetKeyPtr( pPage, iKey ) + 4;
   return HB_GET_LE_UINT32( ptr );
}
dbfntx1.c243
STATIC ERRCODEhb_ntxErrorRT( NTXAREAP pArea, USHORT uiGenCode, USHORT uiSubCode, char * szFileName, USHORT uiOsCode, USHORT uiFlags )
static ERRCODE hb_ntxErrorRT( NTXAREAP pArea, USHORT uiGenCode, USHORT uiSubCode, char * szFileName, USHORT uiOsCode, USHORT uiFlags )
{
   PHB_ITEM pError;
   ERRCODE iRet = FAILURE;

   if( hb_vmRequestQuery() == 0 )
   {
      pError = hb_errNew();
      hb_errPutGenCode( pError, uiGenCode );
      hb_errPutSubCode( pError, uiSubCode );
      hb_errPutOsCode( pError, uiOsCode );
      hb_errPutDescription( pError, hb_langDGetErrorDesc( uiGenCode ) );
      if( szFileName )
         hb_errPutFileName( pError, szFileName );
      if( uiFlags )
         hb_errPutFlags( pError, uiFlags );
      iRet = SELF_ERROR( ( AREAP ) pArea, pError );
      hb_errRelease( pError );
   }
   return iRet;
}
dbfntx1.c251
STATIC CHAR *hb_ntxNumToStr( PHB_ITEM pItem, char* szBuffer, USHORT length, USHORT dec )
static char * hb_ntxNumToStr( PHB_ITEM pItem, char* szBuffer, USHORT length, USHORT dec )
{
   char *ptr = szBuffer;

   hb_itemStrBuf( szBuffer, pItem, length, dec );

   while( *ptr == ' ' )
      *ptr++ = '0';

   if( *ptr == '-' )
   {
      *ptr = '0';
      for( ptr = &szBuffer[0]; *ptr; ptr++ )
      {
         if( *ptr >= '0' && *ptr <= '9' )
            *ptr = (char) ( '0' - ( *ptr - '0' ) - 4 );
            /*
             * I intentionally used the above formula to avoid problems on
             * non ASCII machines though many of other xHarbour codes is
             * hard coded to ASCII values and should be fixed. Druzus.
             */
      }
   }

   return szBuffer;
}
dbfntx1.c276
STATIC PHB_ITEMhb_ntxStrToNum( PHB_ITEM pItem, char* szKeyVal, USHORT length, USHORT dec )
static PHB_ITEM hb_ntxStrToNum( PHB_ITEM pItem, char* szKeyVal, USHORT length, USHORT dec )
{
   char szBuffer[ NTX_MAX_KEY + 1 ];
   char *ptr = szKeyVal, *ptr2, c;
   int iLen, iDec;
   HB_LONG lValue;
   double dValue;

   HB_SYMBOL_UNUSED( dec );

   if( *ptr == '0' - 4 ) /* negative number */
   {
      ptr2 = szBuffer;
      while( ( c = *ptr++ ) != 0 )
      {
         if( c != '.' )
            c = '0' - ( c - '0' + 4 );
         *ptr2++ = c;
      }
      szBuffer[ 0 ] = '-';
      *ptr2 = '\0';
      ptr = szBuffer;
   }
   if( hb_valStrnToNum( ptr, length, &lValue, &dValue, &iDec, &iLen ) )
      return hb_itemPutNDLen( pItem, dValue, iLen, iDec );
   else
      return hb_itemPutNIntLen( pItem, lValue, length );
}
dbfntx1.c306
STATIC LPKEYINFOhb_ntxKeyNew( LPKEYINFO pKeyFrom, int keylen )
static LPKEYINFO hb_ntxKeyNew( LPKEYINFO pKeyFrom, int keylen )
{
   LPKEYINFO pKey;

   pKey = ( LPKEYINFO ) hb_xgrab( sizeof( KEYINFO ) + keylen );
   if( pKeyFrom )
   {
      memcpy( pKey->key, pKeyFrom->key, keylen + 1 );
      pKey->Tag = pKeyFrom->Tag;
      pKey->Xtra = pKeyFrom->Xtra;
   }
   else
   {
      pKey->key[ keylen ] = '\0';
      pKey->Tag = pKey->Xtra = 0;
   }
   return pKey;
}
dbfntx1.c338
STATIC LPKEYINFOhb_ntxKeyCopy( LPKEYINFO pKeyDest, LPKEYINFO pKey, int keylen )
static LPKEYINFO hb_ntxKeyCopy( LPKEYINFO pKeyDest, LPKEYINFO pKey, int keylen )
{
   if( !pKeyDest )
      pKeyDest = hb_ntxKeyNew( NULL, keylen );

   memcpy( pKeyDest->key, pKey->key, keylen + 1 );
   pKeyDest->Tag = pKey->Tag;
   pKeyDest->Xtra = pKey->Xtra;

   return pKeyDest;
}
dbfntx1.c360
STATIC BYTEhb_ntxItemType( PHB_ITEM pItem )
static BYTE hb_ntxItemType( PHB_ITEM pItem )
{
   switch( hb_itemType( pItem ) )
   {
      case HB_IT_STRING:
      case HB_IT_STRING | HB_IT_MEMO:
         return 'C';

      case HB_IT_INTEGER:
      case HB_IT_LONG:
      case HB_IT_DOUBLE:
         return 'N';

      case HB_IT_DATE:
         return 'D';

      case HB_IT_LOGICAL:
         return 'L';

      default:
         return 'U';
   }
}
dbfntx1.c375
STATIC LPKEYINFOhb_ntxKeyPutItem( LPKEYINFO pKey, PHB_ITEM pItem, ULONG ulRecNo, LPTAGINFO pTag, BOOL fTrans, USHORT *puiLen )
static LPKEYINFO hb_ntxKeyPutItem( LPKEYINFO pKey, PHB_ITEM pItem, ULONG ulRecNo,
                                   LPTAGINFO pTag, BOOL fTrans, USHORT *puiLen )
{
   ULONG len;

   if( !pKey )
      pKey = hb_ntxKeyNew( NULL, pTag->KeyLength );

   if( puiLen )
      *puiLen = pTag->KeyLength;

   switch( hb_ntxItemType( pItem ) )
   {
      case 'C':
         len = hb_itemGetCLen( pItem );
         if( len < ( ULONG ) pTag->KeyLength )
         {
            memcpy( pKey->key, hb_itemGetCPtr( pItem ), len );
            memset( pKey->key + len, ' ', pTag->KeyLength - len );
            if( puiLen )
               *puiLen = ( USHORT ) len;
         }
         else
         {
            memcpy( pKey->key, hb_itemGetCPtr( pItem ), pTag->KeyLength );
         }
         pKey->key[ pTag->KeyLength ] = '\0';
#ifndef HB_CDP_SUPPORT_OFF
         if( fTrans )
            hb_cdpnTranslate( pKey->key, hb_vmCDP(), pTag->Owner->Owner->cdPage, pTag->KeyLength );
#else
         HB_SYMBOL_UNUSED( fTrans );
#endif
         break;
      case 'N':
         hb_ntxNumToStr( pItem, pKey->key, pTag->KeyLength, pTag->KeyDec );
         break;
      case 'D':
         hb_itemGetDS( pItem, pKey->key );
         break;
      case 'L':
         pKey->key[0] = ( hb_itemGetL( pItem ) ? 'T':'F' );
         pKey->key[1] = 0;
         break;
      default:
         memset( pKey->key, '\0', pTag->KeyLength );
   }
   pKey->Xtra = ulRecNo;
   pKey->Tag = 0;

   return pKey;
}
dbfntx1.c402
STATIC PHB_ITEMhb_ntxKeyGetItem( PHB_ITEM pItem, LPKEYINFO pKey, LPTAGINFO pTag, BOOL fTrans )
static PHB_ITEM hb_ntxKeyGetItem( PHB_ITEM pItem, LPKEYINFO pKey,
                                  LPTAGINFO pTag, BOOL fTrans )
{
   if( pKey )
   {
      switch( pTag->KeyType )
      {
         case 'C':
#ifndef HB_CDP_SUPPORT_OFF
            if( fTrans && pTag->Owner->Owner->cdPage != hb_vmCDP() )
            {
               char * pVal = ( char * ) hb_xgrab( pTag->KeyLength + 1 );
               memcpy( pVal, pKey->key, pTag->KeyLength );
               pVal[ pTag->KeyLength ] = '\0';
               hb_cdpnTranslate( pVal, pTag->Owner->Owner->cdPage, hb_vmCDP(),
                                 pTag->KeyLength );
               pItem = hb_itemPutCLPtr( pItem, pVal, pTag->KeyLength );
            }
            else
#else
            HB_SYMBOL_UNUSED( fTrans );
#endif
            {
               pItem = hb_itemPutCL( pItem, pKey->key, pTag->KeyLength );
            }
            break;
         case 'N':
            pItem = hb_ntxStrToNum( pItem, pKey->key, pTag->KeyLength, pTag->KeyDec );
            break;
         case 'D':
            pItem = hb_itemPutDS( pItem, pKey->key );
            break;
         case 'L':
            pItem = hb_itemPutL( pItem, pKey->key[0] == 'T' );
            break;
         default:
            if( pItem )
               hb_itemClear( pItem );
            else
               pItem = hb_itemNew( NULL );
      }
   }
   else if( pItem )
      hb_itemClear( pItem );
   else
      pItem = hb_itemNew( NULL );

   return pItem;
}
dbfntx1.c461
STATIC BOOLhb_ntxEvalCond( NTXAREAP pArea, PHB_ITEM pCondItem, BOOL fSetWA )
static BOOL hb_ntxEvalCond( NTXAREAP pArea, PHB_ITEM pCondItem, BOOL fSetWA )
{
   int iCurrArea = 0;
   BOOL fRet;

   if( fSetWA )
   {
      iCurrArea = hb_rddGetCurrentWorkAreaNumber();
      if( iCurrArea != pArea->uiArea )
         hb_rddSelectWorkAreaNumber( pArea->uiArea );
      else
         iCurrArea = 0;
   }

   fRet = hb_itemGetL( hb_vmEvalBlockOrMacro( pCondItem ) );

   if( iCurrArea )
      hb_rddSelectWorkAreaNumber( iCurrArea );

   return fRet;
}
dbfntx1.c514
STATIC BOOLhb_ntxEvalSeekCond( LPTAGINFO pTag, PHB_ITEM pCondItem )
static BOOL hb_ntxEvalSeekCond( LPTAGINFO pTag, PHB_ITEM pCondItem )
{
   BOOL fRet;
   PHB_ITEM pKeyVal, pKeyRec;

   pKeyVal = hb_ntxKeyGetItem( NULL, pTag->CurKeyInfo, pTag, TRUE );
   pKeyRec = hb_itemPutNInt( NULL, pTag->CurKeyInfo->Xtra );

   fRet = hb_itemGetL( hb_vmEvalBlockV( pCondItem, 2, pKeyVal, pKeyRec ) );

   hb_itemRelease( pKeyVal );
   hb_itemRelease( pKeyRec );

   return fRet;
}
dbfntx1.c539
STATIC BYTEhb_ntxGetKeyType( LPTAGINFO pTag )
static BYTE hb_ntxGetKeyType( LPTAGINFO pTag )
{
   BYTE bType;

   if( pTag->nField )
   {
      PHB_ITEM pItem = hb_itemNew( NULL );
      SELF_GETVALUE( ( AREAP ) pTag->Owner->Owner, pTag->nField, pItem );
      bType = hb_ntxItemType( pItem );
      hb_itemRelease( pItem );
   }
   else
   {
      int iCurrArea = hb_rddGetCurrentWorkAreaNumber();

      if( iCurrArea != pTag->Owner->Owner->uiArea )
         hb_rddSelectWorkAreaNumber( pTag->Owner->Owner->uiArea );
      else
         iCurrArea = 0;

      bType = hb_ntxItemType( hb_vmEvalBlockOrMacro( pTag->pKeyItem ) );

      if( iCurrArea )
         hb_rddSelectWorkAreaNumber( iCurrArea );
   }
   return bType;
}
dbfntx1.c558
STATIC LPKEYINFOhb_ntxEvalKey( LPKEYINFO pKey, LPTAGINFO pTag )
static LPKEYINFO hb_ntxEvalKey( LPKEYINFO pKey, LPTAGINFO pTag )
{
   NTXAREAP pArea = pTag->Owner->Owner;
   PHB_ITEM pItem;
#ifndef HB_CDP_SUPPORT_OFF
   PHB_CODEPAGE cdpTmp = hb_cdpSelect( pArea->cdPage );
#endif

   if( pTag->nField )
   {
      pItem = hb_itemNew( NULL );
      SELF_GETVALUE( ( AREAP ) pArea, pTag->nField, pItem );
      pKey = hb_ntxKeyPutItem( pKey, pItem, pArea->ulRecNo, pTag, FALSE, NULL );
      hb_itemRelease( pItem );
   }
   else
   {
      int iCurrArea = hb_rddGetCurrentWorkAreaNumber();

      if( iCurrArea != pArea->uiArea )
         hb_rddSelectWorkAreaNumber( pArea->uiArea );
      else
         iCurrArea = 0;

      pItem = hb_vmEvalBlockOrMacro( pTag->pKeyItem );
      pKey = hb_ntxKeyPutItem( pKey, pItem, pArea->ulRecNo, pTag, FALSE, NULL );

      if( iCurrArea )
         hb_rddSelectWorkAreaNumber( iCurrArea );
   }

#ifndef HB_CDP_SUPPORT_OFF
   hb_cdpSelect( cdpTmp );
#endif

   return pKey;
}
dbfntx1.c589
STATIC INThb_ntxValCompare( LPTAGINFO pTag, char* val1, int len1, char* val2, int len2, BOOL fExact )
static int hb_ntxValCompare( LPTAGINFO pTag, char* val1, int len1,
                             char* val2, int len2, BOOL fExact )
{
   int iLimit, iResult = 0;

   iLimit = (len1 > len2) ? len2 : len1;

   if( pTag->KeyType == 'C' )
   {
      if( iLimit > 0 )
      {
#ifndef HB_CDP_SUPPORT_OFF
         if( pTag->Owner->Owner->cdPage->lSort )
            iResult = hb_cdpcmp( val1, ( ULONG ) iLimit, val2, ( ULONG ) iLimit, pTag->Owner->Owner->cdPage, 0 );
         else
#endif
            iResult = memcmp( val1, val2, iLimit );
      }

      if( iResult == 0 )
      {
         if( len1 > len2 )
            iResult = 1;
         else if( len1 < len2 && fExact )
            iResult = -1;
      }
   }
   else
   {
      if( iLimit <= 0 || (iResult = memcmp( val1, val2, iLimit )) == 0 )
      {
         if( len1 > len2 )
            iResult = 1;
         else if( len1 < len2 )
            iResult = -1;
      }
   }
   return iResult;
}
dbfntx1.c630
STATIC BOOLhb_ntxInTopScope( LPTAGINFO pTag, char* key )
static BOOL hb_ntxInTopScope( LPTAGINFO pTag, char* key )
{
   PHB_NTXSCOPE pScope = pTag->fUsrDescend ? &pTag->bottom : &pTag->top;

   if( pScope->scopeKeyLen )
   {
      int i = hb_ntxValCompare( pTag, pScope->scopeKey->key, pScope->scopeKeyLen,
                                 key, pTag->KeyLength, FALSE );
      return pTag->fUsrDescend ? i >= 0 : i <= 0;
   }
   else
      return TRUE;
}
dbfntx1.c673
STATIC BOOLhb_ntxInBottomScope( LPTAGINFO pTag, char* key )
static BOOL hb_ntxInBottomScope( LPTAGINFO pTag, char* key )
{
   PHB_NTXSCOPE pScope = pTag->fUsrDescend ? &pTag->top : &pTag->bottom;

   if( pScope->scopeKeyLen )
   {
      int i = hb_ntxValCompare( pTag, pScope->scopeKey->key, pScope->scopeKeyLen,
                                key, pTag->KeyLength, FALSE );
      return pTag->fUsrDescend ? i <= 0 : i >= 0;
   }
   else
      return TRUE;
}
dbfntx1.c690
STATIC BOOLhb_ntxKeyInScope( LPTAGINFO pTag, LPKEYINFO pKey )
static BOOL hb_ntxKeyInScope( LPTAGINFO pTag, LPKEYINFO pKey )
{
   return hb_ntxInTopScope( pTag, pKey->key ) &&
          hb_ntxInBottomScope( pTag, pKey->key );
}
dbfntx1.c707
STATIC VOIDhb_ntxTagClearScope( LPTAGINFO pTag, USHORT nScope )
static void hb_ntxTagClearScope( LPTAGINFO pTag, USHORT nScope )
{
   NTXAREAP pArea = pTag->Owner->Owner;
   PHB_NTXSCOPE pScope;

   /* resolve any pending scope relations first */
   if( pArea->lpdbPendingRel && pArea->lpdbPendingRel->isScoped )
      SELF_FORCEREL( ( AREAP ) pArea );

   if( pTag->fUsrDescend )
      nScope = ( nScope == 0 ) ? 1 : 0;

   pScope = ( nScope == 0 ) ? &pTag->top : &pTag->bottom;

   if( pScope->scopeKey )
   {
      hb_ntxKeyFree( pScope->scopeKey );
      pScope->scopeKey = NULL;
   }
   if( pScope->scopeItem )
   {
      hb_itemRelease( pScope->scopeItem );
      pScope->scopeItem = NULL;
   }
   pScope->scopeKeyLen = 0;

   pTag->keyCount = 0;
}
dbfntx1.c716
STATIC VOIDhb_ntxTagSetScope( LPTAGINFO pTag, USHORT nScope, PHB_ITEM pItem )
static void hb_ntxTagSetScope( LPTAGINFO pTag, USHORT nScope, PHB_ITEM pItem )
{
   NTXAREAP pArea = pTag->Owner->Owner;
   PHB_ITEM pScopeVal;

   /* resolve any pending scope relations first */
   if( pArea->lpdbPendingRel && pArea->lpdbPendingRel->isScoped )
      SELF_FORCEREL( ( AREAP ) pArea );

   pScopeVal = ( hb_itemType( pItem ) == HB_IT_BLOCK ) ?
                           hb_vmEvalBlock( pItem ) : pItem;

   if( pTag->KeyType == hb_ntxItemType( pScopeVal ) )
   {
      PHB_NTXSCOPE pScope;
      BOOL fTop = ( nScope == 0 );

      if( pTag->fUsrDescend )
         fTop = !fTop;

      pScope = fTop ? &pTag->top : &pTag->bottom;

      pScope->scopeKey = hb_ntxKeyPutItem( pScope->scopeKey, pScopeVal,
               ( fTop == pTag->AscendKey ) ? NTX_IGNORE_REC_NUM : NTX_MAX_REC_NUM,
               pTag, TRUE, &pScope->scopeKeyLen );

      if( pScope->scopeItem == NULL )
         pScope->scopeItem = hb_itemNew( NULL );
      hb_itemCopy( pScope->scopeItem, pItem );

      pTag->keyCount = 0;
   }
   else
   {
      hb_ntxTagClearScope( pTag, nScope );
   }
}
dbfntx1.c748
STATIC VOIDhb_ntxTagGetScope( LPTAGINFO pTag, USHORT nScope, PHB_ITEM pItem )
static void hb_ntxTagGetScope( LPTAGINFO pTag, USHORT nScope, PHB_ITEM pItem )
{
   NTXAREAP pArea = pTag->Owner->Owner;
   PHB_NTXSCOPE pScope;

   /* resolve any pending scope relations first */
   if( pArea->lpdbPendingRel && pArea->lpdbPendingRel->isScoped )
      SELF_FORCEREL( ( AREAP ) pArea );

   if( pTag->fUsrDescend )
      nScope = ( nScope == 0 ) ? 1 : 0;

   pScope = ( nScope == 0 ) ? &pTag->top : &pTag->bottom;

   if( pScope->scopeItem )
      hb_itemCopy( pItem, pScope->scopeItem );
   else
      hb_itemClear( pItem );
}
dbfntx1.c789
STATIC VOIDhb_ntxTagRefreshScope( LPTAGINFO pTag )
static void hb_ntxTagRefreshScope( LPTAGINFO pTag )
{
   PHB_ITEM pItem;

   /* resolve any pending scope relations first */
   if( pTag->Owner->Owner->lpdbPendingRel &&
       pTag->Owner->Owner->lpdbPendingRel->isScoped )
      SELF_FORCEREL( ( AREAP ) pTag->Owner->Owner );

   if( hb_itemType( pTag->top.scopeItem ) == HB_IT_BLOCK )
   {
      pItem = hb_vmEvalBlock( pTag->top.scopeItem );
      pTag->top.scopeKey = hb_ntxKeyPutItem( pTag->top.scopeKey, pItem,
               pTag->top.scopeKey->Xtra, pTag, TRUE, &pTag->top.scopeKeyLen );
   }
   if( hb_itemType( pTag->bottom.scopeItem ) == HB_IT_BLOCK )
   {
      pItem = hb_vmEvalBlock( pTag->bottom.scopeItem );
      pTag->bottom.scopeKey = hb_ntxKeyPutItem( pTag->bottom.scopeKey, pItem,
         pTag->bottom.scopeKey->Xtra, pTag, TRUE, &pTag->bottom.scopeKeyLen );
   }
}
dbfntx1.c812
STATIC BOOLhb_ntxCheckRecordScope( NTXAREAP pArea, ULONG ulRec )
static BOOL hb_ntxCheckRecordScope( NTXAREAP pArea, ULONG ulRec )
{
   LONG lRecNo = ( LONG ) ulRec;

   if ( SELF_COUNTSCOPE( ( AREAP ) pArea, NULL, &lRecNo ) == SUCCESS && lRecNo == 0 )
   {
      return FALSE;
   }
   return TRUE;
}
dbfntx1.c838
STATIC VOIDhb_ntxTagCheckBuffers( LPTAGINFO pTag )
static void hb_ntxTagCheckBuffers( LPTAGINFO pTag )
{
   LPPAGEINFO pPage;
   ULONG i;

   if( ( pTag->HdrChanged || pTag->Owner->Changed ) && !pTag->Owner->lockWrite )
      hb_errInternal( 9301, "hb_ntxTagCheckBuffers: tag modified in unlocked index", NULL, NULL );

   for( i = 0; i < pTag->Owner->ulPages; i++ )
   {
      pPage = pTag->Owner->pages[ i ];
      if( pPage->Changed && !pTag->Owner->lockWrite )
         hb_errInternal( 9302, "hb_ntxTagCheckBuffers: page modified in unlocked index", NULL, NULL );
      if( pPage->iUsed )
         hb_errInternal( 9303, "hb_ntxTagCheckBuffers: page still allocated", NULL, NULL );
   }
}
dbfntx1.c853
STATIC VOIDhb_ntxPageCheckKeys( LPPAGEINFO pPage, LPTAGINFO pTag, int iPos, int iType )
static void hb_ntxPageCheckKeys( LPPAGEINFO pPage, LPTAGINFO pTag, int iPos, int iType )
{
   USHORT u;
   int i;

   for( u = 1; u < pPage->uiKeys; u++ )
   {
      i = hb_ntxValCompare( pTag,
                            hb_ntxGetKeyVal( pPage, u - 1 ), pTag->KeyLength,
                            hb_ntxGetKeyVal( pPage, u ), pTag->KeyLength, TRUE );
      if( !pTag->AscendKey )
         i = -i;
      if( i > 0 )
      {
         printf("\r\nuiKeys=%d(%d/%d), (%d)[%.*s]>(%d)[%.*s]", pPage->uiKeys, iPos, iType,
                u - 1, pTag->KeyLength, hb_ntxGetKeyVal( pPage, u - 1 ),
                u, pTag->KeyLength, hb_ntxGetKeyVal( pPage, u ) );
         fflush(stdout);
         hb_errInternal( 9304, "hb_ntxPageCheckKeys: keys sorted wrong.", NULL, NULL );
      }
   }
}
dbfntx1.c871
STATIC BOOLhb_ntxBlockRead( LPNTXINDEX pIndex, ULONG ulBlock, BYTE *buffer, int iSize )
static BOOL hb_ntxBlockRead( LPNTXINDEX pIndex, ULONG ulBlock, BYTE *buffer, int iSize )
{
   if( !pIndex->lockRead && !pIndex->lockWrite )
      hb_errInternal( 9103, "hb_ntxBlockRead on not locked index file.", NULL, NULL );

#ifdef HB_NTX_DEBUG_DISP
   s_rdNO++;
#endif
   if( hb_fileReadAt( pIndex->DiskFile, buffer, iSize,
                      hb_ntxFileOffset( pIndex, ulBlock ) ) != ( ULONG ) iSize )
   {
      hb_ntxErrorRT( pIndex->Owner, EG_READ, EDBF_READ,
                     pIndex->IndexName, hb_fsError(), 0 );
      return FALSE;
   }
   return TRUE;
}
dbfntx1.c895
STATIC BOOLhb_ntxBlockWrite( LPNTXINDEX pIndex, ULONG ulBlock, BYTE *buffer, int iSize )
static BOOL hb_ntxBlockWrite( LPNTXINDEX pIndex, ULONG ulBlock, BYTE *buffer, int iSize )
{
   if( !pIndex->lockWrite )
      hb_errInternal( 9102, "hb_ntxBlockWrite on not locked index file.", NULL, NULL );

#ifdef HB_NTX_DEBUG_DISP
   s_wrNO++;
#endif
   if( hb_fileWriteAt( pIndex->DiskFile, buffer, iSize,
                       hb_ntxFileOffset( pIndex, ulBlock ) ) != ( ULONG ) iSize )
   {
      hb_ntxErrorRT( pIndex->Owner, EG_WRITE, EDBF_WRITE,
                     pIndex->IndexName, hb_fsError(), 0 );
      return FALSE;
   }
   return TRUE;
}
dbfntx1.c916
STATIC BOOLhb_ntxPageSave( LPNTXINDEX pIndex, LPPAGEINFO pPage )
static BOOL hb_ntxPageSave( LPNTXINDEX pIndex, LPPAGEINFO pPage )
{
   hb_ntxSetKeyCount( pPage, pPage->uiKeys );
   if( !hb_ntxBlockWrite( pIndex, pPage->Page,
                          (BYTE *) hb_ntxPageBuffer( pPage ), NTXBLOCKSIZE ) )
      return FALSE;
   pPage->Changed = FALSE;
   pIndex->fFlush = TRUE;
   /* In shared mode we have to update counter in version field of
      NTXHEADER to signal for other stations that their index buffers
      has to be discarded */
   if( pIndex->fShared )
      pIndex->Changed = TRUE;
   return TRUE;
}
dbfntx1.c937
STATIC VOIDhb_ntxDiscardBuffers( LPNTXINDEX pIndex )
static void hb_ntxDiscardBuffers( LPNTXINDEX pIndex )
{
   pIndex->ulPages = pIndex->ulPageLast = 0;
   pIndex->pChanged = pIndex->pFirst = pIndex->pLast = NULL;
   if( pIndex->Compound )
   {
      int i;

      for( i = 0; i < pIndex->iTags; i++ )
      {
         pIndex->lpTags[ i ]->RootBlock = 0;
         pIndex->lpTags[ i ]->stackLevel = 0;
      }
   }
   else
   {
      pIndex->TagBlock = 0;
      if( pIndex->iTags )
         pIndex->lpTags[ 0 ]->stackLevel = 0;
   }
}
dbfntx1.c956
STATIC VOIDhb_ntxTagUpdateFlags( LPTAGINFO pTag )
static void hb_ntxTagUpdateFlags( LPTAGINFO pTag )
{
   USHORT uiSignature = pTag->Signature;

   pTag->Custom    = ( uiSignature & NTX_FLAG_CUSTOM ) != 0;
   pTag->ChgOnly   = ( uiSignature & NTX_FLAG_CHGONLY ) != 0;
   pTag->Partial   = ( uiSignature & NTX_FLAG_PARTIAL ) != 0;
   pTag->Template  = ( uiSignature & NTX_FLAG_TEMPLATE ) != 0;
   pTag->MultiKey  = ( uiSignature & NTX_FLAG_MULTIKEY ) != 0;
   pTag->fSortRec  = ( uiSignature & NTX_FLAG_SORTRECNO ) != 0;
}
dbfntx1.c981
STATIC BOOLhb_ntxTagHeaderCheck( LPTAGINFO pTag )
static BOOL hb_ntxTagHeaderCheck( LPTAGINFO pTag )
{
   if( !pTag->RootBlock )
   {
      if( pTag->HeadBlock )
      {
         BYTE buffer[ 12 ];
         if( hb_ntxBlockRead( pTag->Owner, pTag->HeadBlock, buffer, 12 ) )
         {
            pTag->Signature = HB_GET_LE_UINT16( ( ( LPNTXHEADER ) buffer )->type );
            pTag->RootBlock = HB_GET_LE_UINT32( ( ( LPNTXHEADER ) buffer )->root );
            hb_ntxTagUpdateFlags( pTag );
         }
      }
   }
   return pTag->RootBlock != 0;
}
dbfntx1.c996
STATIC VOIDhb_ntxFreePageBuffer( LPNTXINDEX pIndex )
static void hb_ntxFreePageBuffer( LPNTXINDEX pIndex )
{
   ULONG ul, ulMax = pIndex->ulPagesDepth;
   LPPAGEINFO * pPagePtr = pIndex->pages;

   if( ulMax )
   {
      for( ul = 0; ul < ulMax; ul++, pPagePtr++ )
      {
         if( *pPagePtr )
         {
#ifdef HB_NTX_EXTERNAL_PAGEBUFFER
            if( hb_ntxPageBuffer( *pPagePtr ) )
               hb_xfree( hb_ntxPageBuffer( *pPagePtr ) );
#endif
            hb_xfree( *pPagePtr );
         }
      }
      hb_xfree( pIndex->pages );
      pIndex->pages = NULL;
      pIndex->ulPages = pIndex->ulPageLast = pIndex->ulPagesDepth = 0;
      pIndex->pFirst = pIndex->pLast = pIndex->pChanged = NULL;
   }
}
dbfntx1.c1017
STATIC VOIDhb_ntxIndexTrunc( LPNTXINDEX pIndex )
static void hb_ntxIndexTrunc( LPNTXINDEX pIndex )
{
   if( !pIndex->lockWrite )
      hb_errInternal( 9102, "hb_ntxIndexTrunc on not locked index file.", NULL, NULL );

   hb_ntxFreePageBuffer( pIndex );
   pIndex->Update = pIndex->Changed = pIndex->fFlush = TRUE;
   pIndex->TagBlock = pIndex->NextAvail = 0;
   pIndex->Version = 0;
   hb_fileTruncAt( pIndex->DiskFile, NTXBLOCKSIZE );
}
dbfntx1.c1045
STATIC LPPAGEINFOhb_ntxPageFind( LPTAGINFO pTag, ULONG ulPage )
static LPPAGEINFO hb_ntxPageFind( LPTAGINFO pTag, ULONG ulPage )
{
   LPPAGEINFO * pPagePtr = pTag->Owner->pages;
   ULONG u;

   for( u = pTag->Owner->ulPages; u; u--, pPagePtr++ )
   {
      if( *pPagePtr && (*pPagePtr)->Page == ulPage )
         return *pPagePtr;
   }
   return NULL;
}
dbfntx1.c1060
STATIC LPPAGEINFOhb_ntxPageGetBuffer( LPTAGINFO pTag, ULONG ulPage )
static LPPAGEINFO hb_ntxPageGetBuffer( LPTAGINFO pTag, ULONG ulPage )
{
   LPNTXINDEX pIndex = pTag->Owner;
   LPPAGEINFO * pPagePtr;

   if( pIndex->ulPages < pIndex->ulPagesDepth )
   {
      pPagePtr = &pIndex->pages[ pIndex->ulPages++ ];
   }
   else if( pIndex->pFirst )
   {
      LPPAGEINFO pPage = pIndex->pFirst;

      if( pPage->iUsed )
         hb_errInternal( 9305, "hb_ntxPageGetBuffer: page used.", NULL, NULL );
      if( pPage->Changed )
         hb_errInternal( 9306, "hb_ntxPageGetBuffer: page changed.", NULL, NULL );

      pIndex->pFirst = pPage->pNext;
      if( pIndex->pFirst )
         pIndex->pFirst->pPrev = NULL;
      else
         pIndex->pLast = NULL;
      pPage->pPrev = NULL;
      pPage->Page = ulPage;
      pPage->iUsed = 1;

      return pPage;
   }
   else if( pIndex->ulPagesDepth == 0 )
   {
      pIndex->ulPages = 1;
      pIndex->ulPageLast = 0;
      pIndex->ulPagesDepth = NTX_PAGES_PER_TAG;
      pIndex->pages = (LPPAGEINFO*) hb_xgrab( sizeof(LPPAGEINFO) * NTX_PAGES_PER_TAG );
      memset( pIndex->pages, 0, sizeof(LPPAGEINFO) * NTX_PAGES_PER_TAG );
      pPagePtr = &pIndex->pages[0];
   }
   else
   {
      ULONG ul = pIndex->ulPageLast;
      for( ;; )
      {
         if( ++ul >= pIndex->ulPagesDepth )
            ul = 0;
         pPagePtr = &pIndex->pages[ ul ];
         if( !(*pPagePtr)->iUsed && !(*pPagePtr)->Changed )
         {
            pIndex->ulPageLast = ul;
            break;
         }
         if( ul == pIndex->ulPageLast )
         {
            ul = pIndex->ulPagesDepth;
            pIndex->ulPagesDepth += NTX_PAGES_PER_TAG >> 1;
            pIndex->pages = (LPPAGEINFO*) hb_xrealloc( pIndex->pages,
                                 sizeof(LPPAGEINFO) * pIndex->ulPagesDepth );
            memset( pIndex->pages + ul, 0,
                         ( NTX_PAGES_PER_TAG >> 1 ) * sizeof( LPPAGEINFO ) );
            pIndex->ulPages++;
            pPagePtr = &pIndex->pages[ ul ];
            pIndex->ulPageLast = 0;
            break;
         }
      }
   }

   if( !*pPagePtr )
   {
      *pPagePtr = ( LPPAGEINFO ) hb_xgrab( sizeof( HB_PAGEINFO ) );
      memset( *pPagePtr, 0, sizeof( HB_PAGEINFO ) );
   }
#ifdef HB_NTX_EXTERNAL_PAGEBUFFER
   if( !hb_ntxPageBuffer( *pPagePtr ) )
   {
      hb_ntxPageBuffer( *pPagePtr ) = ( char* ) hb_xgrab( NTXBLOCKSIZE );
      memset( hb_ntxPageBuffer( *pPagePtr ), 0, NTXBLOCKSIZE );
   }
#endif
   (*pPagePtr)->pPrev = NULL;
   (*pPagePtr)->Page = ulPage;
   (*pPagePtr)->iUsed = 1;
   return *pPagePtr;
}
dbfntx1.c1076
STATIC VOIDhb_ntxPageFree( LPTAGINFO pTag, LPPAGEINFO pPage )
static void hb_ntxPageFree( LPTAGINFO pTag, LPPAGEINFO pPage )
{
   hb_ntxSetKeyPage( pPage, 0, pTag->Owner->NextAvail );
   pTag->Owner->NextAvail = pPage->Page;
   pTag->Owner->Changed = pPage->Changed = TRUE;
}
dbfntx1.c1164
STATIC VOIDhb_ntxPageRelease( LPTAGINFO pTag, LPPAGEINFO pPage )
static void hb_ntxPageRelease( LPTAGINFO pTag, LPPAGEINFO pPage )
{
   LPNTXINDEX pIndex = pTag->Owner;

   if( --pPage->iUsed == 0 )
   {
      if( pPage->Changed )
      {
         if( !pPage->pPrev )
         {
            pPage->pPrev = pPage;
            pPage->pNext = pIndex->pChanged;
            pIndex->pChanged = pPage;
         }
      }
      else if( pIndex->pLast )
      {
         pIndex->pLast->pNext = pPage;
         pPage->pPrev = pIndex->pLast;
         pPage->pNext = NULL;
         pIndex->pLast = pPage;
      }
      else
      {
         pPage->pNext = pPage->pPrev = NULL;
         pIndex->pFirst = pIndex->pLast = pPage;
      }
   }
   else if( pPage->iUsed < 0 )
      hb_errInternal( 9307, "hb_ntxPageRelease: unused page freed.", NULL, NULL );
}
dbfntx1.c1174
STATIC LPPAGEINFOhb_ntxPageLoad( LPTAGINFO pTag, ULONG ulPage )
static LPPAGEINFO hb_ntxPageLoad( LPTAGINFO pTag, ULONG ulPage )
{
   LPPAGEINFO pPage;

   if( !ulPage )
   {
      if( hb_ntxTagHeaderCheck( pTag ) )
         ulPage = pTag->RootBlock;
      if( !ulPage )
      {
         hb_ntxErrorRT( pTag->Owner->Owner, EG_CORRUPTION, EDBF_CORRUPT,
                        pTag->Owner->IndexName, 0, 0 );
         return NULL;
      }
   }
   pPage = hb_ntxPageFind( pTag, ulPage );
   if( pPage )
   {
      if( !pPage->Changed && !pPage->iUsed )
      {
         if( pPage->pNext )
            pPage->pNext->pPrev = pPage->pPrev;
         else
            pTag->Owner->pLast = pPage->pPrev;
         if( pPage->pPrev )
         {
            pPage->pPrev->pNext = pPage->pNext;
            pPage->pPrev = NULL;
         }
         else
            pTag->Owner->pFirst = pPage->pNext;
      }
      pPage->iUsed++;
   }
   else
   {
      pPage = hb_ntxPageGetBuffer( pTag, ulPage );
      pPage->Changed = FALSE;
      if( !hb_ntxBlockRead( pTag->Owner, ulPage,
                            (BYTE *) hb_ntxPageBuffer( pPage ), NTXBLOCKSIZE ) )
      {
         hb_ntxPageRelease( pTag, pPage );
         return NULL;
      }
      pPage->uiKeys = hb_ntxGetKeyCount( pPage );
   }
   return pPage;
}
dbfntx1.c1209
STATIC VOIDhb_ntxPageInit( LPTAGINFO pTag, LPPAGEINFO pPage )
static void hb_ntxPageInit( LPTAGINFO pTag, LPPAGEINFO pPage )
{
   USHORT u, o = ( pTag->MaxKeys + 2 ) << 1;

   for( u = 0; u <= pTag->MaxKeys; u++, o += pTag->KeyLength + 8 )
      hb_ntxSetKeyOffset( pPage, u, o );
   hb_ntxSetKeyPage( pPage, 0, 0 );
   pPage->uiKeys = 0;
}
dbfntx1.c1261
STATIC ULONGhb_ntxPageAlloc( LPNTXINDEX pIndex )
static ULONG hb_ntxPageAlloc( LPNTXINDEX pIndex )
{
   ULONG ulPage;
   if( !pIndex->TagBlock )
   {
      HB_FOFFSET fOffset;
      fOffset = hb_fileSize( pIndex->DiskFile );
      pIndex->TagBlock = ( ULONG )
                     ( fOffset >> ( pIndex->LargeFile ? NTXBLOCKBITS : 0 ) );
   }
   ulPage = pIndex->TagBlock;
   pIndex->TagBlock += pIndex->LargeFile ? 1 : NTXBLOCKSIZE;
   return ulPage;
}
dbfntx1.c1274
STATIC LPPAGEINFOhb_ntxPageNew( LPTAGINFO pTag, BOOL fNull )
static LPPAGEINFO hb_ntxPageNew( LPTAGINFO pTag, BOOL fNull )
{
   LPPAGEINFO pPage;

   if( pTag->Owner->NextAvail != 0 )
   {
      /*
         Handling of a pool of empty pages.
         Some sources says that this address is in the first 4 bytes of
         a page ( http://www.e-bachmann.dk/docs/xbase.htm ).
         But as I understood, studying dumps of Clipper ntx'es, address of the
         next available page is in the address field of a first key item
         in the page - it is done here now in such a way.
         = Alexander Kresin =
      */
      pPage = hb_ntxPageLoad( pTag, pTag->Owner->NextAvail );
      if( ! pPage )
         return NULL;
      /*
         Unfortunately Clipper does not left unused index pages clean and
         the key counter can be set to non zero value so to make possible
         concurrent index access from Clipper and xHarbour it's necessary
         to disable the check code below. [druzus]
       */
#if 0
      if( pPage->uiKeys != 0 )
      {
         hb_ntxErrorRT( pTag->Owner->Owner, EG_CORRUPTION, EDBF_CORRUPT,
                        pTag->Owner->IndexName, 0, 0 );
         return NULL;
      }
#endif
      pTag->Owner->NextAvail = hb_ntxGetKeyPage( pPage, 0 );
#if defined( HB_NTX_NOMULTITAG )
      hb_ntxSetKeyPage( pPage, 0, 0 );
      pPage->uiKeys = 0;
#else
      hb_ntxPageInit( pTag, pPage );
#endif
   }
   else
   {
      pPage = hb_ntxPageGetBuffer( pTag, fNull ? 0 : hb_ntxPageAlloc( pTag->Owner ) );
      hb_ntxPageInit( pTag, pPage );
   }
   pTag->Owner->Changed = pPage->Changed = TRUE;

   return pPage;
}
dbfntx1.c1292
STATIC VOIDhb_ntxPageAddFree( LPTAGINFO pTag, ULONG ulPage )
static void hb_ntxPageAddFree( LPTAGINFO pTag, ULONG ulPage )
{
   LPPAGEINFO pPage = hb_ntxPageGetBuffer( pTag, ulPage );
   pPage->Changed = TRUE;
   hb_ntxPageInit( pTag, pPage );
   hb_ntxPageFree( pTag, pPage );
   hb_ntxPageSave( pTag->Owner, pPage );
   hb_ntxPageRelease( pTag, pPage );
}
dbfntx1.c1345
STATIC ULONGhb_ntxPageGetFree( LPTAGINFO pTag )
static ULONG hb_ntxPageGetFree( LPTAGINFO pTag )
{
   LPPAGEINFO pPage = hb_ntxPageNew( pTag, FALSE );
   ULONG ulPage = 0;

   if( pPage )
   {
      ulPage = pPage->Page;
      pPage->Changed = FALSE;
      hb_ntxPageRelease( pTag, pPage );
   }
   return ulPage;
}
dbfntx1.c1358
STATIC LPTAGINFOhb_ntxTagNew( LPNTXINDEX pIndex, char * szTagName, BOOL fTagName, char *szKeyExpr, PHB_ITEM pKeyExpr, BYTE bKeyType, USHORT uiKeyLen, USHORT uiKeyDec, char *szForExpr, PHB_ITEM pForExpr, BOOL fAscendKey, BOOL fUnique, BOOL fCustom, BOOL fSortRec )
static LPTAGINFO hb_ntxTagNew( LPNTXINDEX pIndex,
                               char * szTagName, BOOL fTagName,
                               char *szKeyExpr, PHB_ITEM pKeyExpr,
                               BYTE bKeyType, USHORT uiKeyLen, USHORT uiKeyDec,
                               char *szForExpr, PHB_ITEM pForExpr,
                               BOOL fAscendKey, BOOL fUnique, BOOL fCustom,
                               BOOL fSortRec )
{
   LPTAGINFO pTag;

   pTag = ( LPTAGINFO ) hb_xgrab( sizeof( TAGINFO ) );
   memset( pTag, 0, sizeof( TAGINFO ) );
   pTag->TagName = hb_strndup( szTagName, NTX_MAX_TAGNAME );
   pTag->fTagName = fTagName;
   pTag->Owner = pIndex;
   if( szKeyExpr )
   {
      pTag->KeyExpr = hb_strndup( szKeyExpr, NTX_MAX_EXP );
   }
   if( pForExpr && szForExpr )
   {
      pTag->ForExpr = hb_strndup( szForExpr, NTX_MAX_EXP );
   }
   pTag->nField = hb_rddFieldExpIndex( ( AREAP ) pIndex->Owner, pTag->KeyExpr );
   pTag->pKeyItem = pKeyExpr;
   pTag->pForItem = pForExpr;
   pTag->AscendKey = fAscendKey;
   pTag->fUsrDescend = !pTag->AscendKey;
   pTag->UniqueKey = fUnique;
   pTag->Custom = fCustom;
   pTag->MultiKey = fCustom && NTXAREA_DATA( pIndex->Owner )->fMultiKey;
   pTag->KeyType = bKeyType;
   pTag->KeyLength = uiKeyLen;
   pTag->KeyDec = uiKeyDec;
   pTag->fSortRec = fSortRec;
   /*
    * TODO?: keep during page update the offset to 'MaxKeys' key fixed
    * so we will be able to store 1 key more in the page
    */
   pTag->MaxKeys = ( NTXBLOCKSIZE - 2 ) / ( uiKeyLen + 10 ) - 1;

   /* TODO?: is it necessary? It should not interact with well implemented
      algorithm */
   if( pTag->MaxKeys & 0x01 && pTag->MaxKeys > 2 )
      pTag->MaxKeys--;

   pTag->CurKeyInfo = hb_ntxKeyNew( NULL, pTag->KeyLength );

   return pTag;
}
dbfntx1.c1375
STATIC VOIDhb_ntxTagFree( LPTAGINFO pTag )
static void hb_ntxTagFree( LPTAGINFO pTag )
{
   if( pTag == pTag->Owner->Owner->lpCurTag )
      pTag->Owner->Owner->lpCurTag = NULL;
   hb_xfree( pTag->TagName );
   if( pTag->KeyExpr )
      hb_xfree( pTag->KeyExpr );
   if( pTag->ForExpr )
      hb_xfree( pTag->ForExpr );
   if( pTag->pKeyItem )
      hb_vmDestroyBlockOrMacro( pTag->pKeyItem );
   if( pTag->pForItem )
      hb_vmDestroyBlockOrMacro( pTag->pForItem );
   if( pTag->HotKeyInfo )
      hb_ntxKeyFree( pTag->HotKeyInfo );
   hb_ntxKeyFree( pTag->CurKeyInfo );
   hb_ntxTagClearScope( pTag, 0 );
   hb_ntxTagClearScope( pTag, 1 );
   if( pTag->stack )
      hb_xfree( pTag->stack );
   hb_xfree( pTag );
}
dbfntx1.c1429
STATIC VOIDhb_ntxTagDelete( LPTAGINFO pTag )
static void hb_ntxTagDelete( LPTAGINFO pTag )
{
   LPNTXINDEX pIndex = pTag->Owner;
   int i;

   for( i = 0; i < pIndex->iTags; i++ )
   {
      if( pTag == pIndex->lpTags[ i ] )
      {
         while( ++i < pIndex->iTags )
            pIndex->lpTags[ i - 1 ] = pIndex->lpTags[ i ];
         if( --pIndex->iTags )
            pIndex->lpTags = ( LPTAGINFO * ) hb_xrealloc( pIndex->lpTags,
                                       sizeof( LPTAGINFO ) * pIndex->iTags );
         else
            hb_xfree( pIndex->lpTags );
         break;
      }
   }
   hb_ntxTagFree( pTag );
   pIndex->Owner->fSetTagNumbers = TRUE;
   return;
}
dbfntx1.c1455
STATIC ERRCODEhb_ntxTagAdd( LPNTXINDEX pIndex, LPTAGINFO pTag )
static ERRCODE hb_ntxTagAdd( LPNTXINDEX pIndex, LPTAGINFO pTag )
{
   if( pIndex->iTags >= CTX_MAX_TAGS )
      return FAILURE;

   if( pIndex->iTags )
      pIndex->lpTags = ( LPTAGINFO * ) hb_xrealloc( pIndex->lpTags,
                                 sizeof( LPTAGINFO ) * ( pIndex->iTags + 1 ) );
   else
      pIndex->lpTags = ( LPTAGINFO * ) hb_xgrab( sizeof( LPTAGINFO ) );

   pIndex->lpTags[ pIndex->iTags++ ] = pTag;
   pIndex->Owner->fSetTagNumbers = TRUE;
   return SUCCESS;
}
dbfntx1.c1482
STATIC LPTAGINFOhb_ntxTagLoad( LPNTXINDEX pIndex, ULONG ulBlock, char * szTagName, BYTE * buffer )
static LPTAGINFO hb_ntxTagLoad( LPNTXINDEX pIndex, ULONG ulBlock,
                                char * szTagName, BYTE * buffer )
{
   LPNTXHEADER lpNTX = ( LPNTXHEADER ) buffer;
   LPTAGINFO pTag;
   PHB_ITEM pKeyExp, pForExp = NULL;
   USHORT usType;
   BOOL fName;

   usType = HB_GET_LE_UINT16( lpNTX->type );

   if( ( usType & ~NTX_FLAG_MASK ) ||
       ( ( usType & NTX_FLAG_DEFALUT ) != NTX_FLAG_DEFALUT &&
         usType != NTX_FLAG_OLDDEFALUT ) ||
       lpNTX->key_expr[0] < 0x20 )
      return NULL;

   if( SELF_COMPILE( ( AREAP ) pIndex->Owner, lpNTX->key_expr ) == FAILURE )
      return NULL;
   pKeyExp = pIndex->Owner->valResult;
   pIndex->Owner->valResult = NULL;

   if( usType & NTX_FLAG_FORITEM && lpNTX->for_expr[0] >= 0x20 )
   {
      if( SELF_COMPILE( ( AREAP ) pIndex->Owner, lpNTX->for_expr ) == FAILURE )
      {
         hb_vmDestroyBlockOrMacro( pKeyExp );
         return NULL;
      }
      pForExp = pIndex->Owner->valResult;
      pIndex->Owner->valResult = NULL;
   }
   fName = !pIndex->Compound && lpNTX->tag_name[0] >= 0x20;
   pTag = hb_ntxTagNew( pIndex,
                        fName ? (char *) lpNTX->tag_name : szTagName, fName,
                        (char *) lpNTX->key_expr, pKeyExp,
                        '\0',
                        HB_GET_LE_UINT16( lpNTX->key_size ),
                        HB_GET_LE_UINT16( lpNTX->key_dec ),
                        (char *) lpNTX->for_expr, pForExp,
                        lpNTX->descend[0] == 0, lpNTX->unique[0] != 0,
                        ( usType & NTX_FLAG_CUSTOM ) != 0 || lpNTX->custom[0] != 0,
                        ( usType & NTX_FLAG_SORTRECNO ) != 0 );

   pTag->Signature = usType;
   hb_ntxTagUpdateFlags( pTag );
   pTag->HeadBlock = ulBlock;
   pTag->RootBlock = HB_GET_LE_UINT32( lpNTX->root );
   pTag->MaxKeys = HB_GET_LE_UINT16( lpNTX->max_item );
   pTag->KeyType = hb_ntxGetKeyType( pTag );

   pIndex->LargeFile = ( usType & NTX_FLAG_LARGEFILE ) != 0;

   if( !pIndex->Compound )
   {
      pIndex->Version = HB_GET_LE_UINT16( lpNTX->version );
      pIndex->NextAvail = HB_GET_LE_UINT32( lpNTX->next_page );
      pIndex->TagBlock = 0;

      /* TODO: this breaks unlocking !!! */
      if( usType & NTX_FLAG_LARGEFILE )
      {
         pIndex->Owner->bLockType = DB_DBFLOCK_XHB64;
      }
      else if( usType & NTX_FLAG_EXTLOCK )
      {
         pIndex->Owner->bLockType = DB_DBFLOCK_CL53EXT;
      }
      else if( ! pIndex->Owner->bLockType )
      {
         pIndex->Owner->bLockType = usType & NTX_FLAG_EXTLOCK ?
                           DB_DBFLOCK_CL53EXT : DB_DBFLOCK_CLIP;
      }
   }
   return pTag;
}
dbfntx1.c1501
STATIC VOIDhb_ntxIndexTagAdd( LPNTXINDEX pIndex, LPTAGINFO pTag )
static void hb_ntxIndexTagAdd( LPNTXINDEX pIndex, LPTAGINFO pTag )
{
   LPCTXHEADER lpCTX = ( LPCTXHEADER ) pIndex->HeaderBuff;
   int iTags = HB_GET_LE_UINT16( lpCTX->ntags ), iLen, i;
   LPCTXTAGITEM pTagItem = ( LPCTXTAGITEM ) lpCTX->tags;

   for( i = 0; i < iTags; pTagItem++, i++ )
   {
      if( !hb_strnicmp( ( char * ) pTagItem->tag_name, pTag->TagName, NTX_MAX_TAGNAME ) )
         break;
   }
   if( i == iTags )
   {
      ++iTags;
      HB_PUT_LE_UINT16( lpCTX->ntags, iTags );
      iLen = ( int ) strlen( pTag->TagName );
      if( iLen > NTX_MAX_TAGNAME )
         iLen = NTX_MAX_TAGNAME;
      memcpy( pTagItem->tag_name, pTag->TagName, iLen );
      memset( pTagItem->tag_name + iLen, 0, sizeof( pTagItem->tag_name ) - iLen );
   }
   HB_PUT_LE_UINT32( pTagItem->tag_header, pTag->HeadBlock );
   pIndex->Update = TRUE;
}
dbfntx1.c1581
STATIC VOIDhb_ntxIndexTagDel( LPNTXINDEX pIndex, char * szTagName )
static void hb_ntxIndexTagDel( LPNTXINDEX pIndex, char * szTagName )
{
   LPCTXHEADER lpCTX = ( LPCTXHEADER ) pIndex->HeaderBuff;
   int iTags = HB_GET_LE_UINT16( lpCTX->ntags ), i;
   LPCTXTAGITEM pTagItem = ( LPCTXTAGITEM ) lpCTX->tags;

   for( i = 0; i < iTags; pTagItem++, i++ )
   {
      if( !hb_strnicmp( ( char * ) pTagItem->tag_name, szTagName, NTX_MAX_TAGNAME ) )
      {
         memmove( pTagItem, pTagItem + 1, ( iTags - i ) * NTX_TAGITEMSIZE );
         memset( pTagItem + iTags - 1, 0, NTX_TAGITEMSIZE );
         --iTags;
         HB_PUT_LE_UINT16( lpCTX->ntags, iTags );
         pIndex->Update = TRUE;
         break;
      }
   }
}
dbfntx1.c1609
STATIC ULONGhb_ntxIndexTagFind( LPCTXHEADER lpCTX, char * szTagName )
static ULONG hb_ntxIndexTagFind( LPCTXHEADER lpCTX, char * szTagName )
{
   int iTags = HB_GET_LE_UINT16( lpCTX->ntags ), i;
   LPCTXTAGITEM pTagItem = ( LPCTXTAGITEM ) lpCTX->tags;

   for( i = 0; i < iTags; pTagItem++, i++ )
   {
      if( !hb_strnicmp( ( char * ) pTagItem->tag_name, szTagName, NTX_MAX_TAGNAME ) )
         return HB_GET_LE_UINT32( pTagItem->tag_header );
   }
   return NTX_DUMMYNODE;
}
dbfntx1.c1632
STATIC ERRCODEhb_ntxTagHeaderSave( LPTAGINFO pTag )
static ERRCODE hb_ntxTagHeaderSave( LPTAGINFO pTag )
{
   LPNTXINDEX pIndex = pTag->Owner;
   NTXHEADER Header;
   int iSize = 12, type, version = 0, iLen;
   ULONG next = 0;

   if( pIndex->Compound )
   {
      if( !pTag->HeadBlock )
      {
         pTag->HeadBlock = hb_ntxPageGetFree( pTag );
         if( !pTag->HeadBlock )
            return FAILURE;
         hb_ntxIndexTagAdd( pIndex, pTag );
      }
   }
   else
   {
      if( pTag->HeadBlock )
      {
         hb_ntxPageAddFree( pTag, pTag->HeadBlock );
         pTag->HeadBlock = 0;
         pIndex->Update = TRUE;
      }
      pIndex->Version++;
      version = pIndex->Version &= 0xffff;
      next = pIndex->NextAvail;
   }

   type = NTX_FLAG_DEFALUT |
      ( pTag->ForExpr ? NTX_FLAG_FORITEM : 0 ) |
      ( pTag->Partial ? NTX_FLAG_PARTIAL | NTX_FLAG_FORITEM : 0 ) |
      ( pIndex->Owner->bLockType == DB_DBFLOCK_CL53EXT ? NTX_FLAG_EXTLOCK : 0 ) |
      ( pTag->Partial  ? NTX_FLAG_PARTIAL | NTX_FLAG_FORITEM : 0 ) |
      /* non CLipper flags */
      ( pTag->Custom   ? NTX_FLAG_CUSTOM : 0 ) |
      ( pTag->ChgOnly  ? NTX_FLAG_CHGONLY : 0 ) |
      ( pTag->Template ? NTX_FLAG_TEMPLATE : 0 ) |
      ( pTag->MultiKey ? NTX_FLAG_MULTIKEY : 0 ) |
      ( pTag->fSortRec ? NTX_FLAG_SORTRECNO : 0 ) |
      ( pIndex->LargeFile ? NTX_FLAG_LARGEFILE : 0 );

   HB_PUT_LE_UINT16( Header.type, type );
   HB_PUT_LE_UINT16( Header.version, version );
   HB_PUT_LE_UINT32( Header.root, pTag->RootBlock );
   HB_PUT_LE_UINT32( Header.next_page, next );

   if( pIndex->Update )
   {
      memset( ( BYTE * ) &Header + 12, 0, sizeof( NTXHEADER ) - 12 );

      HB_PUT_LE_UINT16( Header.item_size, pTag->KeyLength + 8 );
      HB_PUT_LE_UINT16( Header.key_size,  pTag->KeyLength );
      HB_PUT_LE_UINT16( Header.key_dec,   pTag->KeyDec );
      HB_PUT_LE_UINT16( Header.max_item,  pTag->MaxKeys );
      HB_PUT_LE_UINT16( Header.half_page, pTag->MaxKeys >> 1 );
      Header.unique[0]  = pTag->UniqueKey ? 1 : 0;
      Header.descend[0] = pTag->AscendKey ? 0 : 1;
      Header.custom[0]  = pTag->Custom    ? 1 : 0;
      iLen = ( int ) strlen( pTag->KeyExpr );
      if( iLen > NTX_MAX_EXP )
         iLen = NTX_MAX_EXP;
      memcpy( Header.key_expr, pTag->KeyExpr, iLen );
      if( pTag->ForExpr )
      {
         iLen = ( int ) strlen( pTag->ForExpr );
         if( iLen > NTX_MAX_EXP )
            iLen = NTX_MAX_EXP;
         memcpy( Header.for_expr, pTag->ForExpr, iLen );
      }
      if( pTag->fTagName )
      {
         iLen = ( int ) strlen( pTag->TagName );
         if( iLen > NTX_MAX_TAGNAME )
            iLen = NTX_MAX_TAGNAME;
         memcpy( Header.tag_name, pTag->TagName, iLen );
      }
      iSize = sizeof( NTXHEADER );
   }

   if( !hb_ntxBlockWrite( pIndex, pTag->HeadBlock, ( BYTE * ) &Header, iSize ) )
      return FAILURE;
   pTag->HdrChanged = FALSE;
   pIndex->Changed = pIndex->Compound;
   pIndex->fFlush = TRUE;
   return SUCCESS;
}
dbfntx1.c1648
STATIC LPNTXINDEXhb_ntxIndexNew( NTXAREAP pArea )
static LPNTXINDEX hb_ntxIndexNew( NTXAREAP pArea )
{
   LPNTXINDEX pIndex;

   pIndex = ( LPNTXINDEX ) hb_xgrab( sizeof( NTXINDEX ) );
   memset( pIndex, 0, sizeof( NTXINDEX ) );

   pIndex->DiskFile = NULL;
   pIndex->Owner = pArea;
   return pIndex;
}
dbfntx1.c1740
STATIC VOIDhb_ntxIndexFree( LPNTXINDEX pIndex )
static void hb_ntxIndexFree( LPNTXINDEX pIndex )
{
   hb_ntxFreePageBuffer( pIndex );
   if( pIndex->iTags )
   {
      int i;
      for( i = 0; i < pIndex->iTags; i++ )
         hb_ntxTagFree( pIndex->lpTags[i] );
      hb_xfree( pIndex->lpTags );
   }
   if( pIndex->HeaderBuff )
      hb_xfree( pIndex->HeaderBuff );
   if( pIndex->DiskFile )
   {
      hb_fileClose( pIndex->DiskFile );
      if( pIndex->fDelete )
      {
         hb_fsDelete( ( BYTE * ) ( pIndex->RealName ?
                                   pIndex->RealName : pIndex->IndexName ) );
      }
   }
   if( pIndex->IndexName )
      hb_xfree( pIndex->IndexName );
   if( pIndex->RealName )
      hb_xfree( pIndex->RealName );
   hb_xfree( pIndex );
}
dbfntx1.c1755
STATIC ERRCODEhb_ntxIndexHeaderSave( LPNTXINDEX pIndex )
static ERRCODE hb_ntxIndexHeaderSave( LPNTXINDEX pIndex )
{
   if( pIndex->Compound )
   {
      LPCTXHEADER lpCTX = ( LPCTXHEADER ) pIndex->HeaderBuff;
      int iSize = pIndex->Update ? NTXBLOCKSIZE : 16;
      USHORT type;

      type = NTX_FLAG_COMPOUND | ( pIndex->LargeFile ? NTX_FLAG_LARGEFILE : 0 );

      pIndex->Version++;
      HB_PUT_LE_UINT16( lpCTX->type, type );
      HB_PUT_LE_UINT16( lpCTX->ntags, pIndex->iTags );
      HB_PUT_LE_UINT32( lpCTX->version, pIndex->Version );
      HB_PUT_LE_UINT32( lpCTX->freepage, pIndex->NextAvail );
      HB_PUT_LE_UINT32( lpCTX->filesize, pIndex->TagBlock );

      if( !hb_ntxBlockWrite( pIndex, 0, ( BYTE * ) lpCTX, iSize ) )
         return FAILURE;
   }
   pIndex->Changed = pIndex->Update = FALSE;
   return SUCCESS;
}
dbfntx1.c1786
STATIC ERRCODEhb_ntxIndexLoad( LPNTXINDEX pIndex, char * szTagName )
static ERRCODE hb_ntxIndexLoad( LPNTXINDEX pIndex, char * szTagName )
{
   LPTAGINFO pTag;
   USHORT type;

   if( !pIndex->fValidHeader )
   {
      if( !pIndex->HeaderBuff )
         pIndex->HeaderBuff = ( BYTE * ) hb_xgrab( NTXBLOCKSIZE );
      if( !hb_ntxBlockRead( pIndex, 0, pIndex->HeaderBuff, NTXBLOCKSIZE ) )
         return FAILURE;
      pIndex->fValidHeader = TRUE;
   }

   type = HB_GET_LE_UINT16( pIndex->HeaderBuff );
#if !defined( HB_NTX_NOMULTITAG )
   pIndex->Compound = ( type & NTX_FLAG_COMPOUND ) != 0;
   if( pIndex->Compound )
   {
      BYTE tagbuffer[ NTXBLOCKSIZE ];
      LPCTXHEADER lpCTX = ( LPCTXHEADER ) pIndex->HeaderBuff;
      LPCTXTAGITEM pTagItem = ( LPCTXTAGITEM ) lpCTX->tags;
      ULONG ulBlock;
      int iTags;

      iTags = HB_GET_LE_UINT16( lpCTX->ntags );
      if( iTags > CTX_MAX_TAGS )
         return FAILURE;
      pIndex->Version = HB_GET_LE_UINT32( lpCTX->version );
      pIndex->NextAvail = HB_GET_LE_UINT32( lpCTX->freepage );
      pIndex->TagBlock = HB_GET_LE_UINT32( lpCTX->filesize );
      pIndex->LargeFile = ( type & NTX_FLAG_LARGEFILE ) != 0;

      for( pIndex->iTags = 0; pIndex->iTags < iTags; pTagItem++ )
      {
         ulBlock = HB_GET_LE_UINT32( pTagItem->tag_header );
         if( ulBlock == 0 || pTagItem->tag_name[ 0 ] <= 0x20 )
            return FAILURE;
         if( !hb_ntxBlockRead( pIndex, ulBlock, tagbuffer, NTXBLOCKSIZE ) )
            return FAILURE;
         pTag = hb_ntxTagLoad( pIndex, ulBlock, ( char * ) pTagItem->tag_name, tagbuffer );
         if( !pTag )
            return FAILURE;
         hb_ntxTagAdd( pIndex, pTag );
      }
   }
   else
#endif
   {
      pTag = hb_ntxTagLoad( pIndex, 0, szTagName, pIndex->HeaderBuff );
      if( !pTag )
         return FAILURE;
      hb_ntxTagAdd( pIndex, pTag );
   }

   return SUCCESS;
}
dbfntx1.c1813
STATIC ERRCODEhb_ntxIndexHeaderRead( LPNTXINDEX pIndex )
static ERRCODE hb_ntxIndexHeaderRead( LPNTXINDEX pIndex )
{
   USHORT type;

   if( !pIndex->HeaderBuff )
      pIndex->HeaderBuff = ( BYTE * ) hb_xgrab( NTXBLOCKSIZE );

   if( !hb_ntxBlockRead( pIndex, 0, pIndex->HeaderBuff, NTXBLOCKSIZE ) )
      return FAILURE;

   type = HB_GET_LE_UINT16( pIndex->HeaderBuff );
   if( ( type & NTX_FLAG_COMPOUND ) != 0 )
   {
#if defined( HB_NTX_NOMULTITAG )
      hb_ntxErrorRT( pIndex->Owner, EG_CORRUPTION, EDBF_CORRUPT,
                     pIndex->IndexName, hb_fsError(), 0 );
      return FAILURE;
#else
      LPCTXHEADER lpCTX = ( LPCTXHEADER ) pIndex->HeaderBuff;
      ULONG ulVersion, ulNext;
      /* USHORT usTags = HB_GET_LE_UINT16( lpCTX->ntags ); */

      ulVersion = HB_GET_LE_UINT32( lpCTX->version );
      ulNext = HB_GET_LE_UINT32( lpCTX->freepage );
      pIndex->TagBlock = HB_GET_LE_UINT32( lpCTX->filesize );

      if( pIndex->Version != ulVersion || pIndex->NextAvail != ulNext ||
          !pIndex->Compound )
      {
         int i;
         hb_ntxDiscardBuffers( pIndex );
         pIndex->Version = ulVersion;
         pIndex->NextAvail = ulNext;
         pIndex->Compound = TRUE;
         for( i = 1; i < pIndex->iTags; i++ )
         {
            pIndex->lpTags[ i ]->HeadBlock =
                     hb_ntxIndexTagFind( lpCTX, pIndex->lpTags[ i ]->TagName );
            if( !pIndex->lpTags[ i ]->HeadBlock )
               pIndex->lpTags[ i ]->RootBlock = 0;
         }
      }
#endif
   }
   else
   {
      LPNTXHEADER lpNTX = ( LPNTXHEADER ) pIndex->HeaderBuff;
      ULONG ulRootPage, ulVersion;
      LPTAGINFO pTag;

      if( pIndex->Compound )
      {
         hb_ntxErrorRT( pIndex->Owner, EG_CORRUPTION, EDBF_CORRUPT,
                        pIndex->IndexName, hb_fsError(), 0 );
         return FAILURE;
      }
      pTag = pIndex->iTags ? pIndex->lpTags[0] : NULL;

      ulVersion = HB_GET_LE_UINT16( lpNTX->version );
      ulRootPage = HB_GET_LE_UINT32( lpNTX->root );
      pIndex->NextAvail = HB_GET_LE_UINT32( lpNTX->next_page );
      if( pIndex->Version != ulVersion || ( pTag &&
          ( pTag->Signature != type || ulRootPage != pTag->RootBlock ) ) )
      {
         hb_ntxDiscardBuffers( pIndex );
         pIndex->Version = ulVersion;
         if( pTag )
         {
            pTag->RootBlock = ulRootPage;
            pTag->Signature = type;
            hb_ntxTagUpdateFlags( pTag );
         }
      }
   }
   return SUCCESS;
}
dbfntx1.c1874
STATIC VOIDhb_ntxIndexFlush( LPNTXINDEX pIndex )
static void hb_ntxIndexFlush( LPNTXINDEX pIndex )
{
   while( pIndex->pChanged )
   {
      LPPAGEINFO pPage = pIndex->pChanged;
      pIndex->pChanged = pPage->pNext;
      if( pPage->Changed )
      {
         hb_ntxPageSave( pIndex, pPage );
         ++pPage->iUsed;
         hb_ntxPageRelease( pIndex->lpTags[0], pPage );
      }
      else
         hb_errInternal( 9308, "hb_ntxIndexFlush: unchaged page in the list.", NULL, NULL );
   }

   if( pIndex->Compound )
   {
      int i;

      for( i = 0; i < pIndex->iTags; i++ )
         if( pIndex->lpTags[ i ]->HdrChanged )
            hb_ntxTagHeaderSave( pIndex->lpTags[ i ] );
      if( pIndex->Changed )
         hb_ntxIndexHeaderSave( pIndex );
   }
   else
   {
      if( pIndex->Changed || pIndex->lpTags[ 0 ]->HdrChanged )
         hb_ntxTagHeaderSave( pIndex->lpTags[ 0 ] );
   }
}
dbfntx1.c1954
STATIC BOOLhb_ntxIndexLockRead( LPNTXINDEX pIndex )
static BOOL hb_ntxIndexLockRead( LPNTXINDEX pIndex )
{
   BOOL fOK;

   if( pIndex->lockRead > 0 || pIndex->lockWrite > 0 || !pIndex->fShared ||
       HB_DIRTYREAD( pIndex->Owner ) )
   {
      fOK = TRUE;
      pIndex->lockRead++;
   }
   else
   {
      fOK = hb_dbfLockIdxFile( pIndex->DiskFile, pIndex->Owner->bLockType,
                        FL_LOCK | FLX_SHARED | FLX_WAIT, &pIndex->ulLockPos );
      /* if fOK then check VERSION field in NTXHEADER and
       * if it has been changed then discard all page buffers
       */
      if( fOK )
      {
         pIndex->lockRead++;
         if( hb_ntxIndexHeaderRead( pIndex ) != SUCCESS )
         {
            pIndex->lockRead--;
            hb_dbfLockIdxFile( pIndex->DiskFile, pIndex->Owner->bLockType,
                               FL_UNLOCK, &pIndex->ulLockPos );
            return FALSE;
         }
      }
   }
   if( !fOK )
      hb_ntxErrorRT( pIndex->Owner, EG_LOCK, EDBF_LOCK, pIndex->IndexName, hb_fsError(), 0 );

   return fOK;
}
dbfntx1.c1990
STATIC BOOLhb_ntxIndexLockWrite( LPNTXINDEX pIndex, BOOL fCheck )
static BOOL hb_ntxIndexLockWrite( LPNTXINDEX pIndex, BOOL fCheck )
{
   BOOL fOK;

   if( pIndex->fReadonly )
      hb_errInternal( 9101, "hb_ntxIndexLockWrite: readonly index.", NULL, NULL );

   if( pIndex->lockRead )
      hb_errInternal( 9105, "hb_ntxIndexLockWrite: writeLock after readLock.", NULL, NULL );

   if( pIndex->lockWrite > 0 || !pIndex->fShared )
   {
      fOK = TRUE;
      pIndex->lockWrite++;
   }
   else
   {
      fOK = hb_dbfLockIdxFile( pIndex->DiskFile, pIndex->Owner->bLockType,
                               FL_LOCK | FLX_WAIT, &pIndex->ulLockPos );
      /* if fOK then check VERSION field in NTXHEADER and
       * if it has been changed then discard all page buffers
       */
      if( fOK )
      {
         pIndex->lockWrite++;
         if( fCheck && hb_ntxIndexHeaderRead( pIndex ) != SUCCESS )
         {
            pIndex->lockWrite--;
            hb_dbfLockIdxFile( pIndex->DiskFile, pIndex->Owner->bLockType,
                               FL_UNLOCK, &pIndex->ulLockPos );
            return FALSE;
         }
      }
   }
   if( !fOK )
      hb_ntxErrorRT( pIndex->Owner, EG_LOCK, EDBF_LOCK, pIndex->IndexName, hb_fsError(), 0 );

   return fOK;
}
dbfntx1.c2028
STATIC BOOLhb_ntxIndexUnLockRead( LPNTXINDEX pIndex )
static BOOL hb_ntxIndexUnLockRead( LPNTXINDEX pIndex )
{
   BOOL fOK;

#ifdef HB_NTX_DEBUG
   int i;
   for( i = 0; i < pIndex->iTags; i++ )
      hb_ntxTagCheckBuffers( pIndex->lpTags[ i ] );
#endif

   pIndex->lockRead--;
   if( pIndex->lockRead < 0 )
      hb_errInternal( 9106, "hb_ntxIndexUnLockRead: bad count of locks.", NULL, NULL );

   if( pIndex->lockRead || pIndex->lockWrite || !pIndex->fShared ||
       HB_DIRTYREAD( pIndex->Owner ) )
   {
      fOK = TRUE;
   }
   else
   {
      pIndex->fValidHeader = FALSE;
      fOK = hb_dbfLockIdxFile( pIndex->DiskFile, pIndex->Owner->bLockType,
                               FL_UNLOCK, &pIndex->ulLockPos );
   }
   if( !fOK )
      hb_errInternal( 9108, "hb_ntxIndexUnLockRead: unlock error.", NULL, NULL );

   return fOK;
}
dbfntx1.c2071
STATIC BOOLhb_ntxIndexUnLockWrite( LPNTXINDEX pIndex )
static BOOL hb_ntxIndexUnLockWrite( LPNTXINDEX pIndex )
{
   BOOL fOK;

#ifdef HB_NTX_DEBUG
   int i;
   for( i = 0; i < pIndex->iTags; i++ )
      hb_ntxTagCheckBuffers( pIndex->lpTags[ i ] );
#endif

   if( pIndex->lockWrite <= 0 )
      hb_errInternal( 9106, "hb_ntxIndexUnLockWrite: bad count of locks.", NULL, NULL );
   if( pIndex->lockRead )
      hb_errInternal( 9105, "hb_ntxIndexUnLockWrite: writeUnLock before readUnLock.", NULL, NULL );

   hb_ntxIndexFlush( pIndex );
   pIndex->lockWrite--;

   if( pIndex->lockWrite || !pIndex->fShared )
   {
      fOK = TRUE;
   }
   else
   {
      pIndex->fValidHeader = FALSE;
      fOK = hb_dbfLockIdxFile( pIndex->DiskFile, pIndex->Owner->bLockType,
                               FL_UNLOCK, &pIndex->ulLockPos );
   }
   if( !fOK )
      hb_errInternal( 9108, "hb_ntxIndexUnLockWrite: unlock error.", NULL, NULL );

   return fOK;
}
dbfntx1.c2105
STATIC BOOLhb_ntxTagLockRead( LPTAGINFO pTag )
static BOOL hb_ntxTagLockRead( LPTAGINFO pTag )
{
   BOOL fOK = FALSE;

   if( hb_ntxIndexLockRead( pTag->Owner ) )
   {
      fOK = hb_ntxTagHeaderCheck( pTag );
      if( !fOK )
      {
         hb_ntxIndexUnLockRead( pTag->Owner );
         hb_ntxErrorRT( pTag->Owner->Owner, EG_CORRUPTION, EDBF_CORRUPT,
                        pTag->Owner->IndexName, 0, 0 );
      }
   }
   return fOK;
}
dbfntx1.c2142
STATIC BOOLhb_ntxTagLockWrite( LPTAGINFO pTag )
static BOOL hb_ntxTagLockWrite( LPTAGINFO pTag )
{
   BOOL fOK = FALSE;

   if( hb_ntxIndexLockWrite( pTag->Owner, TRUE ) )
   {
      fOK = hb_ntxTagHeaderCheck( pTag );
      if( !fOK )
      {
         hb_ntxIndexUnLockWrite( pTag->Owner );
         hb_ntxErrorRT( pTag->Owner->Owner, EG_CORRUPTION, EDBF_CORRUPT,
                        pTag->Owner->IndexName, 0, 0 );
      }
   }
   return fOK;
}
dbfntx1.c2162
STATIC BOOLhb_ntxTagUnLockRead( LPTAGINFO pTag )
static BOOL hb_ntxTagUnLockRead( LPTAGINFO pTag )
{
   return hb_ntxIndexUnLockRead( pTag->Owner );
}
dbfntx1.c2182
STATIC BOOLhb_ntxTagUnLockWrite( LPTAGINFO pTag )
static BOOL hb_ntxTagUnLockWrite( LPTAGINFO pTag )
{
   return hb_ntxIndexUnLockWrite( pTag->Owner );
}
dbfntx1.c2190
STATIC VOIDhb_ntxPageGetKey( LPPAGEINFO pPage, USHORT uiKey, LPKEYINFO pKey, USHORT uiLen )
static void hb_ntxPageGetKey( LPPAGEINFO pPage, USHORT uiKey, LPKEYINFO pKey, USHORT uiLen )
{
   if( uiKey < pPage->uiKeys )
   {
      memcpy( pKey->key, hb_ntxGetKeyVal( pPage, uiKey ), uiLen );
      pKey->Xtra = hb_ntxGetKeyRec( pPage, uiKey );
      pKey->Tag = pPage->Page;
   }
   else
   {
      pKey->Xtra = pKey->Tag = 0;
   }
}
dbfntx1.c2198
STATIC VOIDhb_ntxTagSetPageStack( LPTAGINFO pTag, ULONG ulPage, USHORT uiKey )
static void hb_ntxTagSetPageStack( LPTAGINFO pTag, ULONG ulPage, USHORT uiKey )
{
   if( pTag->stackLevel == pTag->stackSize )
   {
      if( pTag->stackSize == 0 )
      {
         pTag->stackSize = NTX_STACKSIZE;
         pTag->stack = (LPTREESTACK) hb_xgrab( sizeof(TREE_STACK) * NTX_STACKSIZE );
      }
      else
      {
         pTag->stackSize += NTX_STACKSIZE;
         pTag->stack = ( LPTREESTACK ) hb_xrealloc( pTag->stack,
                                    sizeof( TREE_STACK ) * pTag->stackSize );
      }
   }
   pTag->stack[ pTag->stackLevel ].page = ulPage;
   pTag->stack[ pTag->stackLevel++ ].ikey = uiKey;
}
dbfntx1.c2215
STATIC LPPAGEINFOhb_ntxPageTopMove( LPTAGINFO pTag, ULONG ulPage )
static LPPAGEINFO hb_ntxPageTopMove( LPTAGINFO pTag, ULONG ulPage )
{
   LPPAGEINFO pPage = NULL;

   do
   {
      if( pPage )
         hb_ntxPageRelease( pTag, pPage );
      pPage = hb_ntxPageLoad( pTag, ulPage );
      if( ! pPage )
         return NULL;
#ifdef HB_NTX_DEBUG_EXT
      if( pPage->uiKeys == 0 && pTag->stackLevel > 0 )
      {
         hb_errInternal( 9201, "hb_ntxPageTopMove: index corrupted.", NULL, NULL );
         return NULL;
      }
#endif
      ulPage = hb_ntxGetKeyPage( pPage, 0 );
      hb_ntxTagSetPageStack( pTag, pPage->Page, 0 );
   }
   while( ulPage );

   return pPage;
}
dbfntx1.c2238
STATIC LPPAGEINFOhb_ntxPageBottomMove( LPTAGINFO pTag, ULONG ulPage )
static LPPAGEINFO hb_ntxPageBottomMove( LPTAGINFO pTag, ULONG ulPage )
{
   LPPAGEINFO pPage = NULL;

   do
   {
      if( pPage )
         hb_ntxPageRelease( pTag, pPage );
      pPage = hb_ntxPageLoad( pTag, ulPage );
      if( ! pPage )
         return NULL;
#ifdef HB_NTX_DEBUG_EXT
      if( pPage->uiKeys == 0 && pTag->stackLevel > 0 )
      {
         hb_errInternal( 9201, "hb_ntxPageBottomMove: index corrupted.", NULL, NULL );
         return NULL;
      }
#endif
      ulPage = hb_ntxGetKeyPage( pPage, pPage->uiKeys );
      hb_ntxTagSetPageStack( pTag, pPage->Page, pPage->uiKeys -
                                    ( ulPage || pPage->uiKeys == 0 ? 0 : 1 ) );
   }
   while( ulPage );

   return pPage;
}
dbfntx1.c2267
STATIC BOOLhb_ntxTagTopKey( LPTAGINFO pTag )
static BOOL hb_ntxTagTopKey( LPTAGINFO pTag )
{
   LPPAGEINFO pPage;
   int iKeys;

   pTag->stackLevel = 0;
   pPage = hb_ntxPageTopMove( pTag, 0 );
   if( ! pPage )
      return FALSE;
   hb_ntxPageGetKey( pPage, 0, pTag->CurKeyInfo, pTag->KeyLength );
   iKeys = pPage->uiKeys;
   hb_ntxPageRelease( pTag, pPage );
   return iKeys != 0;
}
dbfntx1.c2297
STATIC BOOLhb_ntxTagBottomKey( LPTAGINFO pTag )
static BOOL hb_ntxTagBottomKey( LPTAGINFO pTag )
{
   LPPAGEINFO pPage;
   int iKeys;

   pTag->stackLevel = 0;
   pPage = hb_ntxPageBottomMove( pTag, 0 );
   if( ! pPage )
      return FALSE;
   hb_ntxPageGetKey( pPage, pTag->stack[ pTag->stackLevel - 1 ].ikey,
                     pTag->CurKeyInfo, pTag->KeyLength );
   iKeys = pPage->uiKeys;
   hb_ntxPageRelease( pTag, pPage );
   return iKeys != 0;
}
dbfntx1.c2315
STATIC BOOLhb_ntxTagNextKey( LPTAGINFO pTag )
static BOOL hb_ntxTagNextKey( LPTAGINFO pTag )
{
   int iLevel = pTag->stackLevel - 1;
   LPPAGEINFO pPage;
   ULONG ulPage = 0;

   if( iLevel >= 0 )
   {
      pPage = hb_ntxPageLoad( pTag, pTag->stack[ iLevel ].page );
      if( ! pPage )
         return FALSE;
      if( pTag->stack[ iLevel ].ikey < pPage->uiKeys )
         ulPage = hb_ntxGetKeyPage( pPage, pTag->stack[ iLevel ].ikey + 1 );
      if( ulPage || pTag->stack[ iLevel ].ikey + 1 < pPage->uiKeys )
      {
         pTag->stack[ iLevel ].ikey++;
         if( ulPage )
         {
            hb_ntxPageRelease( pTag, pPage );
            pPage = hb_ntxPageTopMove( pTag, ulPage );
            if( ! pPage )
               return FALSE;
         }
      }
      else
      {
         while( --iLevel >= 0 )
         {
            hb_ntxPageRelease( pTag, pPage );
            pPage = hb_ntxPageLoad( pTag, pTag->stack[ iLevel ].page );
            if( ! pPage )
               return FALSE;
            if( pTag->stack[ iLevel ].ikey < pPage->uiKeys )
               break;
         }
         if( iLevel < 0 )
         {
            hb_ntxPageRelease( pTag, pPage );
            return FALSE;
         }
         pTag->stackLevel = iLevel + 1;
      }
      hb_ntxPageGetKey( pPage, pTag->stack[ pTag->stackLevel - 1 ].ikey,
                        pTag->CurKeyInfo, pTag->KeyLength );
      hb_ntxPageRelease( pTag, pPage );
      return TRUE;
   }
   return FALSE;
}
dbfntx1.c2334
STATIC BOOLhb_ntxTagPrevKey( LPTAGINFO pTag )
static BOOL hb_ntxTagPrevKey( LPTAGINFO pTag )
{
   int iLevel = pTag->stackLevel - 1;
   LPPAGEINFO pPage;
   ULONG ulPage;

   if( iLevel >= 0 )
   {
      pPage = hb_ntxPageLoad( pTag, pTag->stack[ iLevel ].page );
      if( ! pPage )
         return FALSE;
      ulPage = hb_ntxGetKeyPage( pPage, pTag->stack[ iLevel ].ikey );
      if( ulPage )
      {
         hb_ntxPageRelease( pTag, pPage );
         pPage = hb_ntxPageBottomMove( pTag, ulPage );
         if( ! pPage )
            return FALSE;
      }
      else if( pTag->stack[ iLevel ].ikey )
      {
         pTag->stack[ iLevel ].ikey--;
      }
      else
      {
         while( --iLevel >= 0 )
         {
            hb_ntxPageRelease( pTag, pPage );
            pPage = hb_ntxPageLoad( pTag, pTag->stack[ iLevel ].page );
            if( ! pPage )
               return FALSE;
            if( pTag->stack[ iLevel ].ikey )
            {
               pTag->stack[ iLevel ].ikey--;
               break;
            }
         }
         if( iLevel < 0 )
         {
            hb_ntxPageRelease( pTag, pPage );
            return FALSE;
         }
         pTag->stackLevel = iLevel + 1;
      }
      hb_ntxPageGetKey( pPage, pTag->stack[ pTag->stackLevel - 1 ].ikey,
                        pTag->CurKeyInfo, pTag->KeyLength );
      hb_ntxPageRelease( pTag, pPage );
      return TRUE;
   }
   return FALSE;
}
dbfntx1.c2387
STATIC INThb_ntxPageKeyFind( LPTAGINFO pTag, LPPAGEINFO pPage, char* key, SHORT keylen, BOOL fNext, ULONG ulRecNo, BOOL *fStop )
static int hb_ntxPageKeyFind( LPTAGINFO pTag, LPPAGEINFO pPage,
                              char* key, SHORT keylen, BOOL fNext,
                              ULONG ulRecNo, BOOL *fStop )
{
   SHORT iLast = -1, iBegin = 0, iEnd = pPage->uiKeys - 1, k, i;

   *fStop = FALSE;
   while( iBegin <= iEnd )
   {
      i = ( iBegin + iEnd ) >> 1;
      k = hb_ntxValCompare( pTag, key, keylen, hb_ntxGetKeyVal( pPage, i ),
                            pTag->KeyLength, FALSE );
      if( k == 0 )
      {
         if( ulRecNo != 0 && pTag->fSortRec )
         {
            ULONG ulRec = hb_ntxGetKeyRec( pPage, i );
            if( ulRecNo < ulRec )
               k = -1;
            else if( ulRecNo > ulRec )
               k = 1;
            else
            {
               *fStop = TRUE;
               return i;
            }
         }
      }
      else if( !pTag->AscendKey )
         k = -k;
      if( fNext ? k >= 0 : k > 0 )
         iBegin = i + 1;
      else
      {
         if( k == 0 && !ulRecNo )
            *fStop = TRUE;
         iLast = i;
         iEnd = i - 1;
      }
   }
   return iLast >= 0 ? iLast : pPage->uiKeys;
}
dbfntx1.c2442
STATIC BOOLhb_ntxPageFindRecNo( LPPAGEINFO pPage, int * iStart, ULONG ulRecno )
static BOOL hb_ntxPageFindRecNo( LPPAGEINFO pPage, int * iStart, ULONG ulRecno )
{
   int iKey = *iStart;
   while( iKey < pPage->uiKeys )
   {
      if( hb_ntxGetKeyRec( pPage, iKey ) == ulRecno )
      {
         *iStart = iKey;
         return TRUE;
      }
      iKey++;
   }
   return FALSE;
}
dbfntx1.c2488
STATIC BOOLhb_ntxTagKeyFind( LPTAGINFO pTag, LPKEYINFO pKey, USHORT uiLen )
static BOOL hb_ntxTagKeyFind( LPTAGINFO pTag, LPKEYINFO pKey, USHORT uiLen )
{
   LPPAGEINFO pPage = NULL;
   ULONG ulPage = 0, ulRecNo = 0;
   int iKey;
   BOOL fStop = FALSE, fNext = FALSE, fPrev = FALSE, fOut = FALSE;

   if( pKey->Tag == NTX_MAX_REC_NUM )          /* for key add */
   {
      if( pTag->fSortRec )
         ulRecNo = pKey->Xtra;
      else
         fNext = TRUE;
   }
   else if( pKey->Xtra == NTX_MAX_REC_NUM )    /* for seek last */
      fNext = fPrev = TRUE;
   else if( pKey->Xtra != NTX_IGNORE_REC_NUM ) /* for key del and current key */
      ulRecNo = pKey->Xtra;
   /* else -> normal seek */

   pTag->stackLevel = 0;
   do
   {
      if( pPage )
         hb_ntxPageRelease( pTag, pPage );
      pPage = hb_ntxPageLoad( pTag, ulPage );
      if( ! pPage )
         return FALSE;
      iKey = hb_ntxPageKeyFind( pTag, pPage, pKey->key, uiLen, fNext, ulRecNo, &fStop );
      hb_ntxTagSetPageStack( pTag, pPage->Page, iKey );
      if( fStop && ulRecNo && pTag->fSortRec )
         break;
      ulPage = hb_ntxGetKeyPage( pPage, iKey );
   } while( ulPage != 0 );

   if( ulRecNo && !pTag->fSortRec ) /* small hack - should speedup in some cases */
   {
      if( hb_ntxPageFindRecNo( pPage, &iKey, ulRecNo ) )
         pTag->stack[ pTag->stackLevel - 1 ].ikey = iKey;
   }

   hb_ntxPageGetKey( pPage, iKey, pTag->CurKeyInfo, pTag->KeyLength );
   hb_ntxPageRelease( pTag, pPage );

   if( ulRecNo )
   {
      if( !pTag->fSortRec )
      {
         fStop = TRUE;
         while( fStop && ulRecNo != pTag->CurKeyInfo->Xtra )
         {
            if( ! hb_ntxTagNextKey( pTag ) ) /* Tag EOF */
            {
               fOut = TRUE;
               fStop = FALSE;
            }
            else
            {
               fStop = hb_ntxValCompare( pTag, pKey->key, uiLen,
                                         pTag->CurKeyInfo->key, pTag->KeyLength,
                                         FALSE ) == 0;
            }
         }
      }
   }
   else if( fPrev )
   {
      if( !hb_ntxTagPrevKey( pTag ) )
      {
         fOut = TRUE;
         fStop = FALSE;
      }
      else
      {
         fStop = hb_ntxValCompare( pTag, pKey->key, uiLen, pTag->CurKeyInfo->key,
                                   pTag->KeyLength, FALSE ) == 0;
      }
   }
   else if( !fNext && !fStop && pTag->CurKeyInfo->Xtra == 0 )
   {
      if( ! hb_ntxTagNextKey( pTag ) ) /* Tag EOF */
      {
         fOut = TRUE;
         fStop = FALSE;
      }
      else
      {
         fStop = hb_ntxValCompare( pTag, pKey->key, uiLen,
                                   pTag->CurKeyInfo->key, pTag->KeyLength,
                                   FALSE ) == 0;
      }
   }

   pTag->TagBOF = pTag->TagEOF = fOut || pTag->CurKeyInfo->Xtra == 0;

   return fStop;
}
dbfntx1.c2506
STATIC VOIDhb_ntxPageKeySet( LPTAGINFO pTag, LPPAGEINFO pPage, USHORT uiPos, ULONG ulPage, ULONG ulRec, char * keyVal )
static void hb_ntxPageKeySet( LPTAGINFO pTag, LPPAGEINFO pPage, USHORT uiPos,
                              ULONG ulPage, ULONG ulRec, char * keyVal )
{
   hb_ntxSetKeyPage( pPage, uiPos, ulPage );
   hb_ntxSetKeyRec( pPage, uiPos, ulRec );
   memcpy( hb_ntxGetKeyVal( pPage, uiPos ), keyVal, pTag->KeyLength );
   pPage->Changed = TRUE;
}
dbfntx1.c2607
STATIC VOIDhb_ntxPageKeyAdd( LPTAGINFO pTag, LPPAGEINFO pPage, USHORT uiPos, ULONG ulPage, ULONG ulRec, char * keyVal )
static void hb_ntxPageKeyAdd( LPTAGINFO pTag, LPPAGEINFO pPage, USHORT uiPos,
                              ULONG ulPage, ULONG ulRec, char * keyVal )
{
   USHORT u, ntmp = hb_ntxGetKeyOffset( pPage, pPage->uiKeys + 1 );

   /* TODO?: update to keep last key pointer fixed */
   for( u = pPage->uiKeys + 1; u > uiPos; u-- )
   {
      hb_ntxSetKeyOffset( pPage, u, hb_ntxGetKeyOffset( pPage, u - 1 ) );
   }
   hb_ntxSetKeyOffset( pPage, uiPos, ntmp );
   pPage->uiKeys++;

   hb_ntxPageKeySet( pTag, pPage, uiPos, ulPage, ulRec, keyVal );
#ifdef HB_NTX_DEBUG
   hb_ntxPageCheckKeys( pPage, pTag, uiPos, 41 );
#endif
}
dbfntx1.c2619
STATIC VOIDhb_ntxPageKeyDel( LPPAGEINFO pPage, USHORT uiPos )
static void hb_ntxPageKeyDel( LPPAGEINFO pPage, USHORT uiPos )
{
   USHORT u, ntmp = hb_ntxGetKeyOffset( pPage, uiPos );

   /* TODO?: update to keep last key pointer fixed */
   for( u = uiPos; u < pPage->uiKeys; u++ )
      hb_ntxSetKeyOffset( pPage, u, hb_ntxGetKeyOffset( pPage, u + 1 ) );
   hb_ntxSetKeyOffset( pPage, pPage->uiKeys, ntmp );

   pPage->uiKeys--;
   pPage->Changed = TRUE;
}
dbfntx1.c2641
STATIC LPKEYINFOhb_ntxPageSplit( LPTAGINFO pTag, LPPAGEINFO pPage, LPKEYINFO pKey, USHORT uiPos )
static LPKEYINFO hb_ntxPageSplit( LPTAGINFO pTag, LPPAGEINFO pPage,
                                  LPKEYINFO pKey, USHORT uiPos )
{
   LPPAGEINFO pNewPage = hb_ntxPageNew( pTag, FALSE );
   LPKEYINFO pKeyNew;
   USHORT uiKeys = pPage->uiKeys + 1, uiLen = pTag->KeyLength + 8,
          i, j, u, uiHalf;
   ULONG ulPage;

   if( ! pNewPage )
      return NULL;
   pKeyNew = hb_ntxKeyNew( NULL, pTag->KeyLength );

   uiHalf = uiKeys >> 1;

   j = 0;
   while( pNewPage->uiKeys < uiHalf )
   {
      if( pNewPage->uiKeys == uiPos )
      {
         hb_ntxSetKeyPage( pNewPage, pNewPage->uiKeys, pKey->Tag );
         hb_ntxSetKeyRec( pNewPage, pNewPage->uiKeys, pKey->Xtra );
         memcpy( hb_ntxGetKeyVal( pNewPage, pNewPage->uiKeys ), pKey->key, pTag->KeyLength );
      }
      else
      {
         memcpy( hb_ntxGetKeyPtr( pNewPage, pNewPage->uiKeys ),
                 hb_ntxGetKeyPtr( pPage, j ), uiLen );
         j++;
      }
      pNewPage->uiKeys++;
   }

   if( uiHalf == uiPos )
   {
      pKeyNew->Xtra = pKey->Xtra;
      memcpy( pKeyNew->key, pKey->key, pTag->KeyLength );
      hb_ntxSetKeyPage( pNewPage, pNewPage->uiKeys, pKey->Tag );
   }
   else
   {
      pKeyNew->Xtra = hb_ntxGetKeyRec( pPage, j );
      memcpy( pKeyNew->key, hb_ntxGetKeyVal( pPage, j ), pTag->KeyLength );
      hb_ntxSetKeyPage( pNewPage, pNewPage->uiKeys, hb_ntxGetKeyPage( pPage, j ) );
      j++;
   }
   pKeyNew->Tag = pNewPage->Page;

   i = 0;
   while( ++uiHalf < uiKeys )
   {
      if( uiHalf == uiPos )
      {
         hb_ntxSetKeyPage( pPage, i, pKey->Tag );
         hb_ntxSetKeyRec( pPage, i, pKey->Xtra );
         memcpy( hb_ntxGetKeyVal( pPage, i ), pKey->key, pTag->KeyLength );
      }
      else
      {
         u = hb_ntxGetKeyOffset( pPage, j );
         hb_ntxSetKeyOffset( pPage, j, hb_ntxGetKeyOffset( pPage, i ) );
         hb_ntxSetKeyOffset( pPage, i, u );
         j++;
      }
      i++;
   }
   ulPage = hb_ntxGetKeyPage( pPage, pPage->uiKeys );
   hb_ntxSetKeyPage( pPage, pPage->uiKeys, 0 );
   hb_ntxSetKeyPage( pPage, i, ulPage );
   pPage->uiKeys = i;

   pPage->Changed = pNewPage->Changed = TRUE;
#ifdef HB_NTX_DEBUG
   hb_ntxPageCheckKeys( pNewPage, pTag, uiPos, 1 );
   hb_ntxPageCheckKeys( pPage, pTag, uiPos - pNewPage->uiKeys, 2 );
#endif
   hb_ntxPageRelease( pTag, pNewPage );

   return pKeyNew;
}
dbfntx1.c2657
STATIC VOIDhb_ntxPageJoin( LPTAGINFO pTag, LPPAGEINFO pBasePage, USHORT uiPos, LPPAGEINFO pFirst, LPPAGEINFO pLast )
static void hb_ntxPageJoin( LPTAGINFO pTag, LPPAGEINFO pBasePage, USHORT uiPos,
                            LPPAGEINFO pFirst, LPPAGEINFO pLast )
{
   USHORT uiLen = pTag->KeyLength + 8, i;

   hb_ntxSetKeyRec( pFirst, pFirst->uiKeys, hb_ntxGetKeyRec( pBasePage, uiPos ) );
   memcpy( hb_ntxGetKeyVal( pFirst, pFirst->uiKeys ),
           hb_ntxGetKeyVal( pBasePage, uiPos ), pTag->KeyLength );
   pFirst->uiKeys++;
   hb_ntxPageKeyDel( pBasePage, uiPos );
   hb_ntxSetKeyPage( pBasePage, uiPos, pFirst->Page );
   for( i = 0; i < pLast->uiKeys; i++ )
   {
      memcpy( hb_ntxGetKeyPtr( pFirst, pFirst->uiKeys ),
              hb_ntxGetKeyPtr( pLast, i ), uiLen );
      pFirst->uiKeys++;
   }
   hb_ntxSetKeyPage( pFirst, pFirst->uiKeys, hb_ntxGetKeyPage( pLast, pLast->uiKeys ) );
   pLast->uiKeys = 0;
   hb_ntxPageFree( pTag, pLast );
   pFirst->Changed = pLast->Changed = TRUE;
#ifdef HB_NTX_DEBUG
   hb_ntxPageCheckKeys( pBasePage, pTag, uiPos, 11 );
   hb_ntxPageCheckKeys( pFirst, pTag, 0, 12 );
#endif
}
dbfntx1.c2741
STATIC VOIDhb_ntxBalancePages( LPTAGINFO pTag, LPPAGEINFO pBasePage, USHORT uiPos, LPPAGEINFO pFirst, LPPAGEINFO pLast )
static void hb_ntxBalancePages( LPTAGINFO pTag, LPPAGEINFO pBasePage, USHORT uiPos,
                                LPPAGEINFO pFirst, LPPAGEINFO pLast )
{
   USHORT uiLen = pTag->KeyLength + 8, n;
   int i, j, iMove = ( ( pFirst->uiKeys + pLast->uiKeys + 1 ) >> 1 ) - pFirst->uiKeys;

   /*
    * such situation should not exist even max keys, though it does not cost
    * much and I want to be able to call hb_ntxBalancePages in any case for
    * some advanced balancing
    */
   if( iMove == 0 )
      return;

#ifdef HB_NTX_DEBUG
   hb_ntxPageCheckKeys( pBasePage, pTag, uiPos, 31 );
   hb_ntxPageCheckKeys( pFirst, pTag, iMove, 32 );
   hb_ntxPageCheckKeys( pLast, pTag, iMove, 33 );
#endif

   if( iMove > 0 )
   {
      hb_ntxSetKeyRec( pFirst, pFirst->uiKeys, hb_ntxGetKeyRec( pBasePage, uiPos ) );
      memcpy( hb_ntxGetKeyVal( pFirst, pFirst->uiKeys ),
              hb_ntxGetKeyVal( pBasePage, uiPos ), pTag->KeyLength );
      pFirst->uiKeys++;
      i = 0;
      while( --iMove )
      {
         memcpy( hb_ntxGetKeyPtr( pFirst, pFirst->uiKeys ),
                 hb_ntxGetKeyPtr( pLast, i ), uiLen );
         pFirst->uiKeys++;
         i++;
      }
      hb_ntxSetKeyRec( pBasePage, uiPos, hb_ntxGetKeyRec( pLast, i ) );
      memcpy( hb_ntxGetKeyVal( pBasePage, uiPos ),
              hb_ntxGetKeyVal( pLast, i ), pTag->KeyLength );
      hb_ntxSetKeyPage( pFirst, pFirst->uiKeys, hb_ntxGetKeyPage( pLast, i ) );
      i++;
      pLast->uiKeys -= i;
      /* TODO?: update to keep last key pointer fixed */
      for( j = 0; j <= pLast->uiKeys; j++ )
      {
         n = hb_ntxGetKeyOffset( pLast, j );
         hb_ntxSetKeyOffset( pLast, j, hb_ntxGetKeyOffset( pLast, j + i ) );
         hb_ntxSetKeyOffset( pLast, j + i, n );
      }
   }
   else
   {
      /* TODO?: update to keep last key pointer fixed */
      for( j = pLast->uiKeys; j >= 0; j-- )
      {
         n = hb_ntxGetKeyOffset( pLast, j - iMove );
         hb_ntxSetKeyOffset( pLast, j - iMove, hb_ntxGetKeyOffset( pLast, j ) );
         hb_ntxSetKeyOffset( pLast, j, n );
      }
      i = -iMove - 1;
      hb_ntxSetKeyRec( pLast, i, hb_ntxGetKeyRec( pBasePage, uiPos ) );
      memcpy( hb_ntxGetKeyVal( pLast, i ),
              hb_ntxGetKeyVal( pBasePage, uiPos ), pTag->KeyLength );
      hb_ntxSetKeyPage( pLast, i, hb_ntxGetKeyPage( pFirst, pFirst->uiKeys ) );
      while( --i >= 0 )
      {
         pFirst->uiKeys--;
         memcpy( hb_ntxGetKeyPtr( pLast, i ),
                 hb_ntxGetKeyPtr( pFirst, pFirst->uiKeys ), uiLen );
      }
      pLast->uiKeys -= iMove;
      pFirst->uiKeys--;
      hb_ntxSetKeyRec( pBasePage, uiPos, hb_ntxGetKeyRec( pFirst, pFirst->uiKeys ) );
      memcpy( hb_ntxGetKeyVal( pBasePage, uiPos ),
              hb_ntxGetKeyVal( pFirst, pFirst->uiKeys ), pTag->KeyLength );
   }
   pFirst->Changed = pLast->Changed = pBasePage->Changed = TRUE;
#ifdef HB_NTX_DEBUG
   hb_ntxPageCheckKeys( pBasePage, pTag, uiPos, 21 );
   hb_ntxPageCheckKeys( pFirst, pTag, iMove, 22 );
   hb_ntxPageCheckKeys( pLast, pTag, iMove, 23 );
#endif
}
dbfntx1.c2771
STATIC BOOLhb_ntxTagKeyAdd( LPTAGINFO pTag, LPKEYINFO pKey )
static BOOL hb_ntxTagKeyAdd( LPTAGINFO pTag, LPKEYINFO pKey )
{
   int iLevel, iKey;
   LPPAGEINFO pPage = NULL;
   LPKEYINFO pNewKey = NULL;
   ULONG ulPage;
   BOOL fFound, fBottom = FALSE;

   if( pTag->UniqueKey )
   {
      ULONG ulRecNo = pKey->Xtra;

      pKey->Xtra = NTX_IGNORE_REC_NUM;
      fFound = hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength );
      pKey->Xtra = ulRecNo;
      if( fFound )
         return FALSE;
      fBottom = TRUE;
   }
   else
   {
      pKey->Tag = NTX_MAX_REC_NUM;
      fFound = hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength );
      pKey->Tag = 0;
      if( fFound )
      {
         if( pTag->MultiKey )
            fBottom = TRUE;
         else
            return FALSE;
      }
   }

   iLevel = pTag->stackLevel - 1;
   if( fBottom )
   {
      pPage = hb_ntxPageLoad( pTag, pTag->stack[ iLevel ].page );
      if( ! pPage )
         return FALSE;
      ulPage = hb_ntxGetKeyPage( pPage, pTag->stack[ iLevel ].ikey );
      if( ulPage )
      {
         hb_ntxPageRelease( pTag, pPage );
         pPage = hb_ntxPageBottomMove( pTag, ulPage );
         if( ! pPage )
            return FALSE;
         iLevel = pTag->stackLevel - 1;
         if( pTag->stack[ iLevel ].ikey < pPage->uiKeys )
            pTag->stack[ iLevel ].ikey++;
      }
   }

   pTag->CurKeyInfo = hb_ntxKeyCopy( pTag->CurKeyInfo, pKey, pTag->KeyLength );

   while( iLevel >= 0 && pKey )
   {
      if( pPage )
         hb_ntxPageRelease( pTag, pPage );
      pPage = hb_ntxPageLoad( pTag, pTag->stack[ iLevel ].page );
      if( ! pPage )
      {
         if( pNewKey )
            hb_ntxKeyFree( pNewKey );
         pTag->stackLevel = 0;
         return FALSE;
      }
      iKey = pTag->stack[ iLevel ].ikey;
      if( pPage->uiKeys < pTag->MaxKeys )
      {
         hb_ntxPageKeyAdd( pTag, pPage, iKey, pKey->Tag, pKey->Xtra, pKey->key );
         pKey = NULL;
      }
      else
      {
         pTag->stackLevel = 0;
#if defined( HB_NTX_STRONG_BALANCE )
         if( iLevel > 0 )
         {
            LPPAGEINFO pBasePage;
            USHORT uiFirst, uiLast, uiBaseKey;
            pBasePage = hb_ntxPageLoad( pTag, pTag->stack[ iLevel - 1 ].page );
            if( !pBasePage )
            {
               hb_ntxPageRelease( pTag, pPage );
               if( pNewKey )
                  hb_ntxKeyFree( pNewKey );
               return FALSE;
            }
            uiFirst = uiLast = uiBaseKey = pTag->stack[ iLevel -1 ].ikey;
            if( uiLast < pBasePage->uiKeys && hb_ntxGetKeyPage( pBasePage, uiLast + 1 ) != 0 )
               uiLast++;
            else if( uiFirst > 0 && hb_ntxGetKeyPage( pBasePage, uiFirst - 1 ) != 0 )
               uiFirst--;
            if( uiFirst != uiLast )
            {
               LPPAGEINFO pFirst, pLast;

               if( uiFirst == uiBaseKey )
               {
                  pFirst = pPage;
                  pLast = hb_ntxPageLoad( pTag, hb_ntxGetKeyPage( pBasePage, uiLast ) );
                  if( ! pLast )
                  {
                     hb_ntxPageRelease( pTag, pPage );
                     hb_ntxPageRelease( pTag, pBasePage );
                     if( pNewKey )
                        hb_ntxKeyFree( pNewKey );
                     return FALSE;
                  }
                  uiBaseKey = iKey;
               }
               else
               {
                  pLast = pPage;
                  pFirst = hb_ntxPageLoad( pTag, hb_ntxGetKeyPage( pBasePage, uiFirst ) );
                  if( ! pFirst )
                  {
                     hb_ntxPageRelease( pTag, pPage );
                     hb_ntxPageRelease( pTag, pBasePage );
                     if( pNewKey )
                        hb_ntxKeyFree( pNewKey );
                     return FALSE;
                  }
                  uiBaseKey = pFirst->uiKeys + iKey + 1;
               }
               if( ( pFirst->uiKeys + pLast->uiKeys ) <= ( ( pTag->MaxKeys - 1 ) << 1 ) )
               {
                  hb_ntxBalancePages( pTag, pBasePage, uiFirst, pFirst, pLast );
                  if( pFirst->uiKeys >= uiBaseKey )
                     hb_ntxPageKeyAdd( pTag, pFirst, uiBaseKey, pKey->Tag, pKey->Xtra, pKey->key );
                  else
                     hb_ntxPageKeyAdd( pTag, pLast, uiBaseKey - pFirst->uiKeys - 1, pKey->Tag, pKey->Xtra, pKey->key );
                  pKey = NULL;
               }
               if( pFirst != pPage )
                  hb_ntxPageRelease( pTag, pFirst );
               else
                  hb_ntxPageRelease( pTag, pLast );
               hb_ntxPageRelease( pTag, pBasePage );
               if( !pKey )
                  break;
            }
         }
#endif
         pKey = hb_ntxPageSplit( pTag, pPage, pKey, iKey );
         if( pNewKey )
            hb_ntxKeyFree( pNewKey );
         pNewKey = pKey;
      }
      iLevel--;
   }
   hb_ntxPageRelease( pTag, pPage );
   if( pKey )
   {
      pPage = hb_ntxPageNew( pTag, FALSE );
      if( ! pPage )
         return FALSE;
      hb_ntxPageKeyAdd( pTag, pPage, 0, pKey->Tag, pKey->Xtra, pKey->key );
      hb_ntxSetKeyPage( pPage, 1, pTag->RootBlock );
      pTag->RootBlock = pPage->Page;
      pTag->HdrChanged = TRUE;
      hb_ntxPageRelease( pTag, pPage );
      pTag->stackLevel = 0;
   }
   if( pNewKey )
      hb_ntxKeyFree( pNewKey );
   return TRUE;
}
dbfntx1.c2856
STATIC BOOLhb_ntxTagKeyDel( LPTAGINFO pTag, LPKEYINFO pKey )
static BOOL hb_ntxTagKeyDel( LPTAGINFO pTag, LPKEYINFO pKey )
{
   int iLevel, iBaseKey, iKey;
   LPPAGEINFO pBasePage, pPage;
   ULONG ulPage;

   pKey->Tag = 0;
   if( pTag->stackLevel == 0 || pTag->CurKeyInfo->Xtra != pKey->Xtra ||
       memcmp( pTag->CurKeyInfo->key, pKey->key, pTag->KeyLength ) != 0 )
   {
      if( ! hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength ) )
         return FALSE;
   }

   iLevel = pTag->stackLevel - 1;

   pPage = hb_ntxPageLoad( pTag, pTag->stack[ iLevel ].page );
   if( ! pPage )
      return FALSE;
   iKey = pTag->stack[ iLevel ].ikey;
   ulPage = hb_ntxGetKeyPage( pPage, iKey );

   if( ulPage )
   {
      pBasePage = pPage;
      iBaseKey = iKey;
      pPage = hb_ntxPageBottomMove( pTag, ulPage );
      if( ! pPage )
      {
         hb_ntxPageRelease( pTag, pBasePage );
         return FALSE;
      }
      iLevel = pTag->stackLevel - 1;
      iKey = pTag->stack[ iLevel ].ikey;

      hb_ntxSetKeyRec( pBasePage, iBaseKey, hb_ntxGetKeyRec( pPage, iKey ) );
      memcpy( hb_ntxGetKeyVal( pBasePage, iBaseKey ),
              hb_ntxGetKeyVal( pPage, iKey ), pTag->KeyLength );
      pBasePage->Changed = TRUE;
#ifdef HB_NTX_DEBUG
      hb_ntxPageCheckKeys( pBasePage, pTag, iBaseKey, 61 );
#endif
      hb_ntxPageRelease( pTag, pBasePage );
   }
   hb_ntxPageKeyDel( pPage, iKey );

   while( iLevel > 0 )
   {
      if( pPage->uiKeys < ( pTag->MaxKeys >> 1 ) )
      {
         USHORT uiFirst, uiLast, uiBaseKey;

         pBasePage = hb_ntxPageLoad( pTag, pTag->stack[ iLevel -1 ].page );
         if( ! pBasePage )
         {
            hb_ntxPageRelease( pTag, pPage );
            return FALSE;
         }
         uiFirst = uiLast = uiBaseKey = pTag->stack[ iLevel -1 ].ikey;
         if( uiLast < pBasePage->uiKeys && hb_ntxGetKeyPage( pBasePage, uiLast + 1 ) != 0 )
            uiLast++;
         else if( uiFirst > 0 && hb_ntxGetKeyPage( pBasePage, uiFirst - 1 ) != 0 )
            uiFirst--;

         if( uiFirst == uiLast )
         {
            if( pPage->uiKeys == 0 )
            {
               hb_ntxSetKeyPage( pBasePage, uiBaseKey, 0 );
               hb_ntxPageFree( pTag, pPage );
            }
            hb_ntxPageRelease( pTag, pPage );
         }
         else
         {
            LPPAGEINFO pFirst, pLast;

            if( uiFirst == uiBaseKey )
            {
               pFirst = pPage;
               pLast = hb_ntxPageLoad( pTag, hb_ntxGetKeyPage( pBasePage, uiLast ) );
               if( ! pLast )
               {
                  hb_ntxPageRelease( pTag, pPage );
                  hb_ntxPageRelease( pTag, pBasePage );
                  pTag->stackLevel = 0;
                  return FALSE;
               }
            }
            else
            {
               pLast = pPage;
               pFirst = hb_ntxPageLoad( pTag, hb_ntxGetKeyPage( pBasePage, uiFirst ) );
               if( ! pFirst )
               {
                  hb_ntxPageRelease( pTag, pPage );
                  hb_ntxPageRelease( pTag, pBasePage );
                  pTag->stackLevel = 0;
                  return FALSE;
               }
            }
            if( pFirst->uiKeys + pLast->uiKeys < pTag->MaxKeys )
               hb_ntxPageJoin( pTag, pBasePage, uiFirst, pFirst, pLast );
            else
               hb_ntxBalancePages( pTag, pBasePage, uiFirst, pFirst, pLast );
            hb_ntxPageRelease( pTag, pFirst );
            hb_ntxPageRelease( pTag, pLast );
         }
         pPage = pBasePage;
      }
      else
         break;
      iLevel--;
   }

   if( pPage->uiKeys == 0 && pPage->Page == pTag->RootBlock )
   {
      ulPage = hb_ntxGetKeyPage( pPage, 0 );
      if( ulPage != 0 )
      {
         pTag->RootBlock = ulPage;
         pTag->HdrChanged = TRUE;
         hb_ntxPageFree( pTag, pPage );
      }
   }
   hb_ntxPageRelease( pTag, pPage );
   pTag->stackLevel = 0;
   return TRUE;
}
dbfntx1.c3028
STATIC BOOLhb_ntxCurKeyRefresh( LPTAGINFO pTag )
static BOOL hb_ntxCurKeyRefresh( LPTAGINFO pTag )
{
   NTXAREAP pArea = pTag->Owner->Owner;

   if( pArea->lpdbPendingRel )
      SELF_FORCEREL( ( AREAP ) pArea );

   if( !pArea->fPositioned )
   {
      pTag->stackLevel = 0;
      pTag->TagBOF = pTag->TagEOF = TRUE;
      pTag->CurKeyInfo->Xtra = 0;
      return FALSE;
   }
   else if( pTag->stackLevel == 0 || pTag->CurKeyInfo->Xtra != pArea->ulRecNo )
   {
      BYTE buf[ NTX_MAX_KEY ];
      BOOL fBuf = FALSE;
      LPKEYINFO pKey = NULL;
      /* Try to find previous if it's key for the same record */
      if( pTag->CurKeyInfo->Xtra == pArea->ulRecNo )
      {
         fBuf = TRUE;
         memcpy( buf, pTag->CurKeyInfo->key, pTag->KeyLength );
         pKey = hb_ntxKeyCopy( pKey, pTag->CurKeyInfo, pTag->KeyLength );
         hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength );
      }
      if( pTag->CurKeyInfo->Xtra != pArea->ulRecNo )
      {
         BOOL fValidBuf = pArea->fValidBuffer;
         /* not found, create new key from DBF and if differs seek again */
         pKey = hb_ntxEvalKey( pKey, pTag );
         if( !fBuf || memcmp( buf, pKey->key, pTag->KeyLength ) != 0 )
         {
            hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength );
         }
         /* not found, if key was generated from DBF buffer then force to
          * update it, create the new key and if differs seek again */
         if( pTag->CurKeyInfo->Xtra != pArea->ulRecNo && fValidBuf )
         {
            SELF_GOTO( ( AREAP ) pArea, pArea->ulRecNo );
            memcpy( buf, pKey->key, pTag->KeyLength );
            pKey = hb_ntxEvalKey( pKey, pTag );
            if( memcmp( buf, pKey->key, pTag->KeyLength ) != 0 )
               hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength );
         }
      }
      hb_ntxKeyFree( pKey );
      return( pTag->CurKeyInfo->Xtra != 0 && pTag->CurKeyInfo->Xtra == pArea->ulRecNo );
   }
   pTag->TagBOF = pTag->TagEOF = FALSE;
   return TRUE;
}
dbfntx1.c3161
STATIC VOIDhb_ntxTagSkipFilter( LPTAGINFO pTag, BOOL fForward )
static void hb_ntxTagSkipFilter( LPTAGINFO pTag, BOOL fForward )
{
   BOOL fBack, fEof = fForward ? pTag->TagEOF : pTag->TagBOF;

   fBack = pTag->fUsrDescend == pTag->AscendKey ? fForward : !fForward;

   while( !fEof && !hb_ntxCheckRecordScope( pTag->Owner->Owner,
                                            pTag->CurKeyInfo->Xtra ) )
   {
      if( fBack )
         fEof = !hb_ntxTagPrevKey( pTag );
      else
         fEof = !hb_ntxTagNextKey( pTag );

      if( !fEof && !hb_ntxKeyInScope( pTag, pTag->CurKeyInfo ) )
      {
         fEof = TRUE;
      }
   }
   if( fEof )
   {
      if( fForward )
         pTag->TagEOF = TRUE;
      else
         pTag->TagBOF = TRUE;
   }
}
dbfntx1.c3218
STATIC VOIDhb_ntxTagGoTop( LPTAGINFO pTag )
static void hb_ntxTagGoTop( LPTAGINFO pTag )
{
   PHB_NTXSCOPE pScope = pTag->fUsrDescend ? &pTag->bottom : &pTag->top;

   if( pScope->scopeKeyLen )
      hb_ntxTagKeyFind( pTag, pScope->scopeKey, pScope->scopeKeyLen );
   else if( pTag->fUsrDescend == pTag->AscendKey )
      hb_ntxTagBottomKey( pTag );
   else
      hb_ntxTagTopKey( pTag );

   pTag->TagEOF = pTag->CurKeyInfo->Xtra == 0 ||
                  !hb_ntxKeyInScope( pTag, pTag->CurKeyInfo );

   if( ! pTag->TagEOF && pTag->Owner->Owner->dbfi.fFilter )
      hb_ntxTagSkipFilter( pTag, TRUE );

   pTag->TagBOF = pTag->TagEOF;
}
dbfntx1.c3249
STATIC VOIDhb_ntxTagGoBottom( LPTAGINFO pTag )
static void hb_ntxTagGoBottom( LPTAGINFO pTag )
{
   PHB_NTXSCOPE pScope = pTag->fUsrDescend ? &pTag->top : &pTag->bottom;

   if( pScope->scopeKeyLen )
      hb_ntxTagKeyFind( pTag, pScope->scopeKey, pScope->scopeKeyLen );
   else if( pTag->fUsrDescend == pTag->AscendKey )
      hb_ntxTagTopKey( pTag );
   else
      hb_ntxTagBottomKey( pTag );

   pTag->TagBOF = pTag->CurKeyInfo->Xtra == 0 ||
                  !hb_ntxKeyInScope( pTag, pTag->CurKeyInfo );

   if( ! pTag->TagBOF && pTag->Owner->Owner->dbfi.fFilter )
      hb_ntxTagSkipFilter( pTag, FALSE );

   pTag->TagEOF = pTag->TagBOF;
}
dbfntx1.c3272
STATIC VOIDhb_ntxTagSkipNext( LPTAGINFO pTag )
static void hb_ntxTagSkipNext( LPTAGINFO pTag )
{
   pTag->TagBOF = FALSE;

   if( pTag->stackLevel == 0 )
      pTag->TagEOF = TRUE;
   else if( ! hb_ntxInTopScope( pTag, pTag->CurKeyInfo->key ) )
      hb_ntxTagGoTop( pTag );
   else if( pTag->fUsrDescend == pTag->AscendKey )
      pTag->TagEOF = !hb_ntxTagPrevKey( pTag );
   else
      pTag->TagEOF = !hb_ntxTagNextKey( pTag );

   if( ! pTag->TagEOF && ! hb_ntxKeyInScope( pTag, pTag->CurKeyInfo ) )
      pTag->TagEOF = TRUE;

   if( ! pTag->TagEOF && pTag->Owner->Owner->dbfi.fFilter )
      hb_ntxTagSkipFilter( pTag, TRUE );
}
dbfntx1.c3295
STATIC VOIDhb_ntxTagSkipPrev( LPTAGINFO pTag )
static void hb_ntxTagSkipPrev( LPTAGINFO pTag )
{
   pTag->TagEOF = FALSE;

   if( pTag->stackLevel == 0 )
      /* TODO?: check if this is NTX behavior,
         for sure CDX works in such way */
      hb_ntxTagGoBottom( pTag );
   else if( pTag->fUsrDescend == pTag->AscendKey )
      pTag->TagBOF = !hb_ntxTagNextKey( pTag );
   else
      pTag->TagBOF = !hb_ntxTagPrevKey( pTag );

   if( ! pTag->TagBOF && ! hb_ntxKeyInScope( pTag, pTag->CurKeyInfo ) )
      pTag->TagBOF = TRUE;

   if( ! pTag->TagBOF && pTag->Owner->Owner->dbfi.fFilter )
      hb_ntxTagSkipFilter( pTag, FALSE );
}
dbfntx1.c3318
STATIC ULONGhb_ntxPageCountKeys( LPTAGINFO pTag, ULONG ulPage )
static ULONG hb_ntxPageCountKeys( LPTAGINFO pTag, ULONG ulPage )
{
   LPPAGEINFO pPage = hb_ntxPageLoad( pTag, ulPage );
   ULONG ulKeys;
   USHORT u;

   if( ! pPage )
      return 0;

   ulKeys = pPage->uiKeys;
   for( u = 0; u <= pPage->uiKeys; u++ )
   {
      ulPage = hb_ntxGetKeyPage( pPage, u );
      if( ulPage )
         ulKeys += hb_ntxPageCountKeys( pTag, ulPage );
   }
   hb_ntxPageRelease( pTag, pPage );

   return ulKeys;
}
dbfntx1.c3341
STATIC DOUBLEhb_ntxTagCountRelKeyPos( LPTAGINFO pTag )
static double hb_ntxTagCountRelKeyPos( LPTAGINFO pTag )
{
   int iLevel = pTag->stackLevel, iKeys;
   double dPos = 1.0;

   while( --iLevel >= 0 )
   {
      LPPAGEINFO pPage = hb_ntxPageLoad( pTag, pTag->stack[ iLevel ].page );
      if( ! pPage )
         break;
      iKeys = pPage->uiKeys;
      if( hb_ntxGetKeyPage( pPage, pPage->uiKeys ) )
         ++iKeys;
      else if( iLevel == pTag->stackLevel - 1 )
         dPos = 0.5;
      if( iKeys )
         dPos = ( dPos + pTag->stack[ iLevel ].ikey ) / iKeys;
      hb_ntxPageRelease( pTag, pPage );
   }
   if( pTag->fUsrDescend == pTag->AscendKey )
      dPos = 1.0 - dPos;
   return dPos;
}
dbfntx1.c3365
STATIC VOIDhb_ntxTagGoToRelKeyPos( LPTAGINFO pTag, double dPos )
static void hb_ntxTagGoToRelKeyPos( LPTAGINFO pTag, double dPos )
{
   LPPAGEINFO pPage = NULL;
   ULONG ulPage = 0;
   int iKey, iKeys;

   if( pTag->fUsrDescend == pTag->AscendKey )
      dPos = 1.0 - dPos;

   pTag->stackLevel = 0;
   do
   {
      if( pPage )
         hb_ntxPageRelease( pTag, pPage );
      pPage = hb_ntxPageLoad( pTag, ulPage );
      if( ! pPage )
      {
         pTag->stackLevel = 0;
         return;
      }
      if( pPage->uiKeys == 0 )
         iKey = 0;
      else
      {
         iKeys = pPage->uiKeys;
         if( hb_ntxGetKeyPage( pPage, pPage->uiKeys ) )
            ++iKeys;
         iKey = ( int ) ( dPos * iKeys );
         if( iKey >= iKeys )
            iKey = iKeys - 1;
         dPos = dPos * iKeys - iKey;
         if( dPos <= 0.0 )
            dPos = 0.0;
         else if( dPos >= 1.0 )
            dPos = 1.0;
      }
      hb_ntxTagSetPageStack( pTag, pPage->Page, iKey );
      ulPage = hb_ntxGetKeyPage( pPage, iKey );
   } while( ulPage != 0 );

   hb_ntxPageGetKey( pPage, iKey, pTag->CurKeyInfo, pTag->KeyLength );
   hb_ntxPageRelease( pTag, pPage );

   if( dPos > 0.75 )
      hb_ntxTagNextKey( pTag );
   else if( dPos < 0.25 )
      hb_ntxTagPrevKey( pTag );
}
dbfntx1.c3392
STATIC BOOLhb_ntxTagPagesFree( LPTAGINFO pTag, ULONG ulPage )
static BOOL hb_ntxTagPagesFree( LPTAGINFO pTag, ULONG ulPage )
{
   LPPAGEINFO pPage = hb_ntxPageLoad( pTag, ulPage );
   BOOL fOK = pPage != NULL;
   USHORT u;

   for( u = 0; fOK && u <= pPage->uiKeys; u++ )
   {
      ulPage = hb_ntxGetKeyPage( pPage, u );
      if( ulPage )
         fOK = hb_ntxTagPagesFree( pTag, ulPage );
   }

   if( fOK )
   {
      pPage->uiKeys = 0;
      hb_ntxPageFree( pTag, pPage );
      if( !pPage->pPrev )
         fOK = hb_ntxPageSave( pTag->Owner, pPage );
   }
   hb_ntxPageRelease( pTag, pPage );

   return fOK;
}
dbfntx1.c3441
STATIC ERRCODEhb_ntxTagSpaceFree( LPTAGINFO pTag )
static ERRCODE hb_ntxTagSpaceFree( LPTAGINFO pTag )
{
   if( hb_ntxTagHeaderCheck( pTag ) )
   {
      if( pTag->RootBlock )
      {
         if( ! hb_ntxTagPagesFree( pTag, pTag->RootBlock ) )
            return FAILURE;
      }
      hb_ntxPageAddFree( pTag, pTag->HeadBlock );
      hb_ntxIndexTagDel( pTag->Owner, pTag->TagName );
      pTag->Owner->Changed = TRUE;
   }
   hb_ntxTagDelete( pTag );
   return SUCCESS;
}
dbfntx1.c3469
STATIC VOIDhb_ntxCreateFName( NTXAREAP pArea, char * szBagName, BOOL * fProd, char * szFileName, char * szTagName )
static void hb_ntxCreateFName( NTXAREAP pArea, char * szBagName, BOOL * fProd,
                               char * szFileName, char * szTagName )
{
   PHB_FNAME pFileName;
   PHB_ITEM pExt = NULL;
   BOOL fName = szBagName && *szBagName;

   pFileName = hb_fsFNameSplit( fName ? szBagName : pArea->szDataFileName );

   if( szTagName )
   {
      if( pFileName->szName )
         hb_strncpyUpperTrim( szTagName, pFileName->szName, NTX_MAX_TAGNAME );
      else
         szTagName[ 0 ] = '\0';
   }

   if( ( hb_setGetDefExtension() && !pFileName->szExtension ) || !fName )
   {
      DBORDERINFO pExtInfo;
      memset( &pExtInfo, 0, sizeof( pExtInfo ) );
      pExt = pExtInfo.itmResult = hb_itemPutC( NULL, NULL );
      if( SELF_ORDINFO( ( AREAP ) pArea, DBOI_BAGEXT, &pExtInfo ) == SUCCESS &&
          hb_itemGetCLen( pExt ) > 0 )
      {
         pFileName->szExtension = hb_itemGetCPtr( pExt );
      }
   }
   hb_fsFNameMerge( szFileName, pFileName );

   if( fProd )
   {
      if( ! pFileName->szName )
         *fProd = FALSE;
      else if( !fName )
         *fProd = TRUE;
      else
      {
         PHB_FNAME pTableFileName = hb_fsFNameSplit( pArea->szDataFileName );

         *fProd = pTableFileName->szName &&
                  hb_stricmp( pTableFileName->szName, pFileName->szName ) == 0;
         if( *fProd && pFileName->szExtension && ! pExt )
         {
            DBORDERINFO pExtInfo;
            memset( &pExtInfo, 0, sizeof( pExtInfo ) );
            pExt = pExtInfo.itmResult = hb_itemPutC( NULL, NULL );
            if( SELF_ORDINFO( ( AREAP ) pArea, DBOI_BAGEXT, &pExtInfo ) == SUCCESS )
            {
               *fProd = hb_stricmp( pFileName->szExtension,
                                    hb_itemGetCPtr( pExt ) ) == 0;
            }
         }
         hb_xfree( pTableFileName );
      }
   }
   hb_xfree( pFileName );
   if( pExt )
      hb_itemRelease( pExt );
}
dbfntx1.c3489
STATIC LPNTXINDEXhb_ntxFindBag( NTXAREAP pArea, char * szBagName )
static LPNTXINDEX hb_ntxFindBag( NTXAREAP pArea, char * szBagName )
{
   LPNTXINDEX pIndex;
   PHB_FNAME pSeek, pName;
   BOOL fFound;

   pSeek = hb_fsFNameSplit( szBagName );
   if( ! pSeek->szName )
      pSeek->szName = ( char * ) "";

   pIndex = pArea->lpIndexes;
   while( pIndex )
   {
      pName = hb_fsFNameSplit( pIndex->IndexName );
      if( ! pName->szName )
         pName->szName = ( char * ) "";
      fFound = !hb_stricmp( pName->szName, pSeek->szName ) &&
               ( !pSeek->szPath || ( pName->szPath &&
                  !hb_stricmp( pName->szPath, pSeek->szPath ) ) ) &&
               ( !pSeek->szExtension || ( pName->szExtension &&
                  !hb_stricmp( pName->szExtension, pSeek->szExtension ) ) );
      hb_xfree( pName );
      if( fFound )
         break;
      pIndex = pIndex->pNext;
   }
   hb_xfree( pSeek );
   return pIndex;
}
dbfntx1.c3553
STATIC INThb_ntxFindTagByName( LPNTXINDEX pIndex, char * szTag )
static int hb_ntxFindTagByName( LPNTXINDEX pIndex, char * szTag )
{
   int i;

   for( i = 0; i < pIndex->iTags; i++ )
   {
      if( !hb_strnicmp( pIndex->lpTags[ i ]->TagName, szTag,
                        NTX_MAX_TAGNAME ) )
         return i + 1;
   }
   return 0;
}
dbfntx1.c3586
STATIC LPTAGINFOhb_ntxFindTag( NTXAREAP pArea, PHB_ITEM pTagItem, PHB_ITEM pBagItem )
static LPTAGINFO hb_ntxFindTag( NTXAREAP pArea, PHB_ITEM pTagItem,
                                PHB_ITEM pBagItem )
{
   LPNTXINDEX pIndex;
   BOOL fBag;

   if( ! pTagItem ||
       ( hb_itemType( pTagItem ) & ( HB_IT_STRING | HB_IT_NUMERIC ) ) == 0 )
      return pArea->lpCurTag;

   fBag = hb_itemGetCLen( pBagItem ) > 0;
   if( fBag )
   {
      if( hb_itemType( pTagItem ) & HB_IT_STRING )
         pIndex = hb_ntxFindBag( pArea, hb_itemGetCPtr( pBagItem ) );
      else
         pIndex = pArea->lpIndexes;
   }
   else
   {
      int iBag = hb_itemGetNI( pBagItem );

      pIndex = pArea->lpIndexes;
      if( iBag > 0 )
      {
         fBag = TRUE;
         while( pIndex )
         {
            if( --iBag == 0 )
               break;
            pIndex = pIndex->pNext;
         }
      }
      else if( iBag < 0 )
      {
         pIndex = NULL;
      }
   }
   if( pIndex )
   {
      if( hb_itemType( pTagItem ) & HB_IT_STRING )
      {
         char * szTag = hb_itemGetCPtr( pTagItem );
         int iTag;

         if( fBag )
            iTag = hb_ntxFindTagByName( pIndex, szTag );
         else
         {
            do
            {
               iTag = hb_ntxFindTagByName( pIndex, szTag );
               if( iTag )
                  break;
               pIndex = pIndex->pNext;
            } while( pIndex );
         }
         if( iTag )
            return pIndex->lpTags[ iTag - 1 ];
      }
      else
      {
         int i = hb_itemGetNI( pTagItem ) - 1;

         if( i >= 0 )
         {
            if( fBag )
            {
               if( i < pIndex->iTags )
                  return pIndex->lpTags[ i ];
            }
            else
            {
               do
               {
                  if( i < pIndex->iTags )
                     return pIndex->lpTags[ i ];
                  i -= pIndex->iTags;
                  pIndex = pIndex->pNext;
               } while( pIndex );
            }
         }
      }
   }

   return NULL;
}
dbfntx1.c3602
STATIC INThb_ntxFindTagNum( NTXAREAP pArea, LPTAGINFO pTag )
static int hb_ntxFindTagNum( NTXAREAP pArea, LPTAGINFO pTag )
{
   if( pArea->fSetTagNumbers )
   {
      LPNTXINDEX pIndex = pArea->lpIndexes;
      USHORT uiNum = 0, i;

      pTag->uiNumber = 0;
      while( pIndex )
      {
         for( i = 0; i < pIndex->iTags; i++ )
         {
            pIndex->lpTags[ i ]->uiNumber = ++uiNum;
         }
         pIndex = pIndex->pNext;
      }
      pArea->fSetTagNumbers = FALSE;
   }
   return pTag->uiNumber;
}
dbfntx1.c3693
STATIC ULONGhb_ntxOrdKeyCount( LPTAGINFO pTag )
static ULONG hb_ntxOrdKeyCount( LPTAGINFO pTag )
{
   ULONG ulKeyCount = 0;

   if( !pTag->Owner->fShared && pTag->keyCount &&
       !pTag->Owner->Owner->dbfi.fFilter )
      return pTag->keyCount;

   if( hb_ntxTagLockRead( pTag ) )
   {
      hb_ntxTagRefreshScope( pTag );

      if( pTag->top.scopeKeyLen || pTag->bottom.scopeKeyLen ||
          pTag->Owner->Owner->dbfi.fFilter )
      {
         hb_ntxTagGoTop( pTag );
         while( !pTag->TagEOF )
         {
            ulKeyCount++;
            hb_ntxTagSkipNext( pTag );
         }
      }
      else
      {
         ulKeyCount = hb_ntxPageCountKeys( pTag, 0 );
      }
      if( !pTag->Owner->Owner->dbfi.fFilter )
         pTag->keyCount = ulKeyCount;
      hb_ntxTagUnLockRead( pTag );
   }
   return ulKeyCount;
}
dbfntx1.c3717
STATIC ULONGhb_ntxOrdKeyNo( LPTAGINFO pTag )
static ULONG hb_ntxOrdKeyNo( LPTAGINFO pTag )
{
   ULONG ulKeyNo = 0;

   if( hb_ntxTagLockRead( pTag ) )
   {
      hb_ntxTagRefreshScope( pTag );
      if( hb_ntxCurKeyRefresh( pTag ) )
      {
         if( pTag->top.scopeKeyLen || pTag->bottom.scopeKeyLen ||
             pTag->Owner->Owner->dbfi.fFilter )
         {
            if( hb_ntxKeyInScope( pTag, pTag->CurKeyInfo ) )
            {
               do
               {
                  ulKeyNo++;
                  hb_ntxTagSkipPrev( pTag );
               }
               while( !pTag->TagBOF );
            }
         }
         else
         {
            int iLevel = pTag->stackLevel, iKey, iFirst = 1;
            BOOL fBack = pTag->fUsrDescend == pTag->AscendKey;
            LPPAGEINFO pPage;
            ULONG ulPage;

            while( --iLevel >= 0 )
            {
               pPage = hb_ntxPageLoad( pTag, pTag->stack[ iLevel ].page );
               if( ! pPage )
                  break;
               if( fBack )
               {
                  iKey = pTag->stack[ iLevel ].ikey;
                  ulKeyNo += pPage->uiKeys - iKey;
                  while( ++iKey <= pPage->uiKeys )
                  {
                     ulPage = hb_ntxGetKeyPage( pPage, iKey );
                     if( ulPage )
                        ulKeyNo += hb_ntxPageCountKeys( pTag, ulPage );
                  }
               }
               else
               {
                  ulKeyNo += iKey = pTag->stack[ iLevel ].ikey + iFirst;
                  iFirst = 0;
                  while( --iKey >= 0 )
                  {
                     ulPage = hb_ntxGetKeyPage( pPage, iKey );
                     if( ulPage )
                        ulKeyNo += hb_ntxPageCountKeys( pTag, ulPage );
                  }
               }
               hb_ntxPageRelease( pTag, pPage );
            }
         }
      }
      hb_ntxTagUnLockRead( pTag );
   }
   return ulKeyNo;
}
dbfntx1.c3753
STATIC BOOLhb_ntxOrdKeyGoto( LPTAGINFO pTag, ULONG ulKeyNo )
static BOOL hb_ntxOrdKeyGoto( LPTAGINFO pTag, ULONG ulKeyNo )
{
   NTXAREAP pArea = pTag->Owner->Owner;

   if( ! ulKeyNo || ! hb_ntxTagLockRead( pTag ) )
      return FALSE;

   hb_ntxTagRefreshScope( pTag );
   hb_ntxTagGoTop( pTag );
   while( !pTag->TagEOF && --ulKeyNo )
   {
      hb_ntxTagSkipNext( pTag );
   }

   if( pTag->TagEOF )
   {
      SELF_GOTO( ( AREAP ) pArea, 0 );
   }
   else
   {
      LPTAGINFO pSavedTag = pArea->lpCurTag;
      pArea->lpCurTag = pTag;
      if( SELF_GOTO( ( AREAP ) pArea, pTag->CurKeyInfo->Xtra ) == SUCCESS )
         SELF_SKIPFILTER( ( AREAP ) pArea, 1 );
      pArea->lpCurTag = pSavedTag;
   }
   hb_ntxTagUnLockRead( pTag );
   return TRUE;
}
dbfntx1.c3821
STATIC DOUBLEhb_ntxOrdGetRelKeyPos( LPTAGINFO pTag )
static double hb_ntxOrdGetRelKeyPos( LPTAGINFO pTag )
{
   double dPos = 0.0, dStart = 0.0, dStop = 1.0, dFact = 0.0000000000001;
   BOOL fOK = TRUE, fFilter = pTag->Owner->Owner->dbfi.fFilter;

   if( ! hb_ntxTagLockRead( pTag ) )
      return FALSE;

   hb_ntxTagRefreshScope( pTag );

   pTag->Owner->Owner->dbfi.fFilter = FALSE;
   if( pTag->fUsrDescend ? pTag->bottom.scopeKeyLen : pTag->top.scopeKeyLen )
   {
      hb_ntxTagGoTop( pTag );
      if( pTag->TagEOF )
         fOK = FALSE;
      else
         dStart = hb_ntxTagCountRelKeyPos( pTag );
   }
   if( fOK && ( pTag->fUsrDescend ? pTag->top.scopeKeyLen : pTag->bottom.scopeKeyLen ) )
   {
      hb_ntxTagGoBottom( pTag );
      if( pTag->TagBOF )
         fOK = FALSE;
      else
         dStop = hb_ntxTagCountRelKeyPos( pTag );
   }
   pTag->Owner->Owner->dbfi.fFilter = fFilter;

   if( fOK )
   {
      if( hb_ntxCurKeyRefresh( pTag ) &&
          hb_ntxKeyInScope( pTag, pTag->CurKeyInfo ) )
      {
         if( dStart >= dStop - dFact )
            dPos = 0.5;
         else
         {
            dPos = hb_ntxTagCountRelKeyPos( pTag );
            dPos = ( dPos - dStart ) / ( dStop - dStart );
            /* fix possible differences in FL representation */
            if( dPos <= 0.0 )
               dPos = 0.0;
            else if( dPos >= 1.0 )
               dPos = 1.0;
         }
      }
   }
   hb_ntxTagUnLockRead( pTag );

   return dPos;
}
dbfntx1.c3854
STATIC VOIDhb_ntxOrdSetRelKeyPos( LPTAGINFO pTag, double dPos )
static void hb_ntxOrdSetRelKeyPos( LPTAGINFO pTag, double dPos )
{
   if( hb_ntxTagLockRead( pTag ) )
   {
      NTXAREAP pArea = pTag->Owner->Owner;
      double dStart = 0.0, dStop = 1.0, dFact = 0.0000000000001;
      BOOL fOK = TRUE, fFilter = pArea->dbfi.fFilter;
      BOOL fForward = TRUE, fTop = FALSE;

      hb_ntxTagRefreshScope( pTag );

      if( dPos >= 1.0 )
         fForward = FALSE;
      else if( dPos <= 0.0 )
         fTop = TRUE;
      else
      {
         pArea->dbfi.fFilter = FALSE;
         if( pTag->fUsrDescend ? pTag->bottom.scopeKeyLen : pTag->top.scopeKeyLen )
         {
            hb_ntxTagGoTop( pTag );
            if( pTag->TagEOF )
               fOK = FALSE;
            else
               dStart = hb_ntxTagCountRelKeyPos( pTag );
         }
         if( fOK && ( pTag->fUsrDescend ? pTag->top.scopeKeyLen : pTag->bottom.scopeKeyLen ) )
         {
            hb_ntxTagGoBottom( pTag );
            if( pTag->TagBOF )
               fOK = FALSE;
            else
               dStop = hb_ntxTagCountRelKeyPos( pTag );
         }
         pArea->dbfi.fFilter = fFilter;

         if( fOK )
         {
            if( dStart >= dStop - dFact )
            {
               fTop = TRUE;
            }
            else
            {
               dPos = dPos * ( dStop - dStart ) + dStart;
               hb_ntxTagGoToRelKeyPos( pTag, dPos );
               if( pTag->CurKeyInfo->Xtra == 0 )
                  fForward = FALSE;
               else if( !hb_ntxInTopScope( pTag, pTag->CurKeyInfo->key ) )
                  fTop = TRUE;
               else if( !hb_ntxInBottomScope( pTag, pTag->CurKeyInfo->key ) )
                  fForward = FALSE;
            }
         }
      }
      if( !fOK )
      {
         SELF_GOTO( ( AREAP ) pArea, 0 );
      }
      else
      {
         LPTAGINFO pSavedTag = pArea->lpCurTag;
         pArea->lpCurTag = pTag;

         pArea->fTop = pArea->fBottom = FALSE;

         if( fForward )
         {
            if( fTop )
               hb_ntxTagGoTop( pTag );
            if( pTag->CurKeyInfo->Xtra != 0 )
            {
               if( SELF_GOTO( ( AREAP ) pArea, pTag->CurKeyInfo->Xtra ) == SUCCESS )
               {
                  SELF_SKIPFILTER( ( AREAP ) pArea, 1 );
                  if( pArea->fEof && !fTop )
                     fForward = FALSE;
               }
            }
            else if( fTop )
               SELF_GOTO( ( AREAP ) pArea, 0 );
            else
               fForward = FALSE;
         }
         if( !fForward )
         {
            hb_ntxTagGoBottom( pTag );
            if( SELF_GOTO( ( AREAP ) pArea, pTag->CurKeyInfo->Xtra ) == SUCCESS &&
                pTag->CurKeyInfo->Xtra != 0 )
            {
               pArea->fBottom = TRUE;
               SELF_SKIPFILTER( ( AREAP ) pArea, -1 );
            }
         }
         pArea->lpCurTag = pSavedTag;
      }
      hb_ntxTagUnLockRead( pTag );
   }
}
dbfntx1.c3910
STATIC BOOLhb_ntxOrdSkipUnique( LPTAGINFO pTag, LONG lDir )
static BOOL hb_ntxOrdSkipUnique( LPTAGINFO pTag, LONG lDir )
{
   NTXAREAP pArea = pTag->Owner->Owner;
   BOOL fOut = FALSE, fEof = FALSE, fForward = ( lDir >= 0 );

   if( pArea->lpdbPendingRel )
      SELF_FORCEREL( ( AREAP ) pArea );

   pArea->fTop = pArea->fBottom = FALSE;

   if( hb_ntxTagLockRead( pTag ) )
   {
      LPTAGINFO pSavedTag = pArea->lpCurTag;
      pArea->lpCurTag = pTag;

      hb_ntxTagRefreshScope( pTag );
      if( hb_ntxCurKeyRefresh( pTag ) )
      {
         char keyVal[ NTX_MAX_KEY ];
         memcpy( keyVal, pTag->CurKeyInfo->key, pTag->KeyLength );

         do
         {
            if( fForward )
               hb_ntxTagSkipNext( pTag );
            else
               hb_ntxTagSkipPrev( pTag );
            fOut = pTag->TagEOF || pTag->TagBOF;
         }
         while( !fOut && hb_ntxValCompare( pTag,
                                       pTag->CurKeyInfo->key, pTag->KeyLength,
                                       keyVal, pTag->KeyLength, TRUE ) == 0 );
      }
      else if( !fForward && !pArea->fPositioned )
      {
         hb_ntxTagGoBottom( pTag );
         fEof = pTag->TagEOF;
      }
      else
      {
         fOut = TRUE;
      }
      if( fOut )
      {
         if( fForward )
            fEof = TRUE;
         else
         {
            hb_ntxTagGoTop( pTag );
            fEof = pTag->TagEOF;
         }
      }
      hb_ntxTagUnLockRead( pTag );

      if( SELF_GOTO( ( AREAP ) pArea, fEof ? 0 : pTag->CurKeyInfo->Xtra ) == SUCCESS &&
          !fEof )
      {
         SELF_SKIPFILTER( ( AREAP ) pArea, ( fForward || fOut ) ? 1 : -1 );
         if( ! fForward && fOut )
            pArea->fBof = TRUE;
      }

      /* Update Bof and Eof flags */
      if( fForward )
         pArea->fBof = FALSE;
      else
         pArea->fEof = FALSE;

      pArea->lpCurTag = pSavedTag;
      return TRUE;
   }
   return FALSE;
}
dbfntx1.c4013
STATIC BOOLhb_ntxOrdSkipEval( LPTAGINFO pTag, BOOL fForward, PHB_ITEM pEval )
static BOOL hb_ntxOrdSkipEval( LPTAGINFO pTag, BOOL fForward, PHB_ITEM pEval )
{
   NTXAREAP pArea = pTag->Owner->Owner;
   BOOL fFound = FALSE;

   HB_TRACE(HB_TR_DEBUG, ("hb_ntxOrdSkipEval(%p, %d, %p)", pTag, fForward, pEval));

   if( hb_itemType( pEval ) != HB_IT_BLOCK )
   {
      if( SELF_SKIP( ( AREAP ) pArea, fForward ? 1 : -1 ) != SUCCESS )
         return FALSE;
      return fForward ? !pArea->fEof : !pArea->fBof;
   }

   if( pArea->lpdbPendingRel )
      SELF_FORCEREL( ( AREAP ) pArea );

   pArea->fTop = pArea->fBottom = FALSE;

   if( hb_ntxTagLockRead( pTag ) )
   {
      LPTAGINFO pSavedTag = pArea->lpCurTag;
      pArea->lpCurTag = pTag;

      hb_ntxTagRefreshScope( pTag );
      if( hb_ntxCurKeyRefresh( pTag ) )
      {
         if( fForward )
            hb_ntxTagSkipNext( pTag );
         else
            hb_ntxTagSkipPrev( pTag );

         while( fForward ? !pTag->TagEOF : !pTag->TagBOF )
         {
            if( SELF_GOTO( ( AREAP ) pArea, pTag->CurKeyInfo->Xtra ) != SUCCESS )
               break;
            if( hb_ntxEvalSeekCond( pTag, pEval ) )
            {
               ULONG ulRecNo = pArea->ulRecNo;
               if( SELF_SKIPFILTER( ( AREAP ) pArea, fForward ? 1 : -1 ) != SUCCESS ||
                   pArea->ulRecNo == ulRecNo || hb_ntxEvalSeekCond( pTag, pEval ) )
               {
                  fFound = TRUE;
                  break;
               }
            }
            if( fForward )
               hb_ntxTagSkipNext( pTag );
            else
               hb_ntxTagSkipPrev( pTag );
         }
         if( !fFound )
         {
            if( fForward )
               SELF_GOTO( ( AREAP ) pArea, 0 );
            else
            {
               SELF_GOTOP( ( AREAP ) pArea );
               pArea->fBof = TRUE;
            }
         }
      }
      pArea->lpCurTag = pSavedTag;
      hb_ntxTagUnLockRead( pTag );
   }

   /* Update Bof and Eof flags */
   if( fForward )
      pArea->fBof = FALSE;
   else
      pArea->fEof = FALSE;

   return fFound;
}
dbfntx1.c4090
STATIC BOOLhb_ntxOrdSkipWild( LPTAGINFO pTag, BOOL fForward, PHB_ITEM pWildItm )
static BOOL hb_ntxOrdSkipWild( LPTAGINFO pTag, BOOL fForward, PHB_ITEM pWildItm )
{
   NTXAREAP pArea = pTag->Owner->Owner;
   char *szPattern, *szFree = NULL;
   BOOL fFound = FALSE;
   int iFixed = 0;

   HB_TRACE(HB_TR_DEBUG, ("hb_ntxOrdSkipWild(%p, %d, %p)", pTag, fForward, pWildItm));

   szPattern = hb_itemGetCPtr( pWildItm );

   if( pTag->KeyType != 'C' || !szPattern || !*szPattern )
   {
      if( SELF_SKIP( ( AREAP ) pArea, fForward ? 1 : -1 ) != SUCCESS )
         return FALSE;
      return fForward ? !pArea->fEof : !pArea->fBof;
   }

#ifndef HB_CDP_SUPPORT_OFF
   if( pArea->cdPage != hb_vmCDP() )
   {
      szPattern = szFree = hb_strdup( szPattern );
      hb_cdpTranslate( szPattern, hb_vmCDP(), pArea->cdPage );
   }
#endif
   while( iFixed < pTag->KeyLength && szPattern[ iFixed ] &&
          szPattern[ iFixed ] != '*' && szPattern[ iFixed ] != '?' )
   {
      ++iFixed;
   }

   if( pArea->lpdbPendingRel )
      SELF_FORCEREL( ( AREAP ) pArea );

   pArea->fTop = pArea->fBottom = FALSE;

   if( hb_ntxTagLockRead( pTag ) )
   {
      LPTAGINFO pSavedTag = pArea->lpCurTag;
      pArea->lpCurTag = pTag;

      hb_ntxTagRefreshScope( pTag );
      if( hb_ntxCurKeyRefresh( pTag ) )
      {
         int iStop = fForward ? -1 : 1;
         if( pTag->fUsrDescend )
            iStop = -iStop;
         if( iFixed && hb_ntxValCompare( pTag, szPattern, iFixed,
                             pTag->CurKeyInfo->key, iFixed, FALSE ) == -iStop )
         {
            LPKEYINFO pKey;
            pKey = hb_ntxKeyNew( NULL, pTag->KeyLength );
            memcpy( pKey->key, szPattern, iFixed );
            pKey->key[ iFixed ] = '\0';
            pKey->Xtra = pArea->lpCurTag->fUsrDescend ==
                         pArea->lpCurTag->AscendKey ? NTX_MAX_REC_NUM :
                                                      NTX_IGNORE_REC_NUM;
            if( !hb_ntxTagKeyFind( pTag, pKey, iFixed ) )
            {
               if( fForward )
                  pTag->TagEOF = TRUE;
               else
                  pTag->TagBOF = TRUE;
            }
            hb_ntxKeyFree( pKey );
         }
         else if( fForward )
            hb_ntxTagSkipNext( pTag );
         else
            hb_ntxTagSkipPrev( pTag );

         while( fForward ? !pTag->TagEOF : !pTag->TagBOF )
         {
            if( hb_strMatchWild( pTag->CurKeyInfo->key, szPattern ) )
            {
               ULONG ulRecNo = pTag->CurKeyInfo->Xtra;
               if( SELF_GOTO( ( AREAP ) pArea, ulRecNo ) != SUCCESS )
                  break;
               if( SELF_SKIPFILTER( ( AREAP ) pArea, fForward ? 1 : -1 ) != SUCCESS ||
                   pArea->ulRecNo == ulRecNo ||
                   hb_strMatchWild( pTag->CurKeyInfo->key, szPattern ) )
               {
                  fFound = TRUE;
                  break;
               }
            }
            if( iFixed && hb_ntxValCompare( pTag, szPattern, iFixed,
                             pTag->CurKeyInfo->key, iFixed, FALSE ) == iStop )
            {
               break;
            }
            if( fForward )
               hb_ntxTagSkipNext( pTag );
            else
               hb_ntxTagSkipPrev( pTag );
         }
         if( !fFound )
         {
            if( fForward )
               SELF_GOTO( ( AREAP ) pArea, 0 );
            else
            {
               SELF_GOTOP( ( AREAP ) pArea );
               pArea->fBof = TRUE;
            }
         }
      }
      pArea->lpCurTag = pSavedTag;
      hb_ntxTagUnLockRead( pTag );
   }

   /* Update Bof and Eof flags */
   if( fForward )
      pArea->fBof = FALSE;
   else
      pArea->fEof = FALSE;

   if( szFree )
      hb_xfree( szPattern );

   return fFound;
}
dbfntx1.c4168
STATIC BOOLhb_ntxRegexMatch( LPTAGINFO pTag, PHB_REGEX pRegEx, char * szKey )
static BOOL hb_ntxRegexMatch( LPTAGINFO pTag, PHB_REGEX pRegEx, char * szKey )
{
#ifndef HB_CDP_SUPPORT_OFF
   char szBuff[ NTX_MAX_KEY + 1 ];

   if( pTag->Owner->Owner->cdPage != hb_vmCDP() )
   {
      memcpy( szBuff, pTag->CurKeyInfo->key, pTag->KeyLength + 1 );
      hb_cdpnTranslate( szBuff, pTag->Owner->Owner->cdPage, hb_vmCDP(), pTag->KeyLength );
      szKey = szBuff;
   }
#else
   HB_SYMBOL_UNUSED( pTag );
#endif
   return hb_regexMatch( pRegEx, szKey, pTag->KeyLength, FALSE );
}
dbfntx1.c4294
STATIC BOOLhb_ntxOrdSkipRegEx( LPTAGINFO pTag, BOOL fForward, PHB_ITEM pRegExItm )
static BOOL hb_ntxOrdSkipRegEx( LPTAGINFO pTag, BOOL fForward, PHB_ITEM pRegExItm )
{
   NTXAREAP pArea = pTag->Owner->Owner;
   BOOL fFound = FALSE;
   PHB_REGEX pRegEx;

   HB_TRACE(HB_TR_DEBUG, ("hb_ntxOrdSkipRegEx(%p, %d, %p)", pTag, fForward, pRegExItm));

   if( pTag->KeyType != 'C' || ( pRegEx = hb_regexGet( pRegExItm, 0 ) ) == NULL )
   {
      if( SELF_SKIP( ( AREAP ) pArea, fForward ? 1 : -1 ) != SUCCESS )
         return FALSE;
      return fForward ? !pArea->fEof : !pArea->fBof;
   }

   if( pArea->lpdbPendingRel )
      SELF_FORCEREL( ( AREAP ) pArea );

   pArea->fTop = pArea->fBottom = FALSE;

   if( hb_ntxTagLockRead( pTag ) )
   {
      LPTAGINFO pSavedTag = pArea->lpCurTag;
      pArea->lpCurTag = pTag;

      hb_ntxTagRefreshScope( pTag );
      if( hb_ntxCurKeyRefresh( pTag ) )
      {
         if( fForward )
            hb_ntxTagSkipNext( pTag );
         else
            hb_ntxTagSkipPrev( pTag );

         while( fForward ? !pTag->TagEOF : !pTag->TagBOF )
         {
            if( SELF_GOTO( ( AREAP ) pArea, pTag->CurKeyInfo->Xtra ) != SUCCESS )
               break;

            if( hb_ntxRegexMatch( pTag, pRegEx, ( char * ) pTag->CurKeyInfo->key ) )
            {
               ULONG ulRecNo = pArea->ulRecNo;
               if( SELF_SKIPFILTER( ( AREAP ) pArea, fForward ? 1 : -1 ) != SUCCESS ||
                   pArea->ulRecNo == ulRecNo ||
                   hb_ntxRegexMatch( pTag, pRegEx, ( char * ) pTag->CurKeyInfo->key ) )
               {
                  fFound = TRUE;
                  break;
               }
            }
            if( fForward )
               hb_ntxTagSkipNext( pTag );
            else
               hb_ntxTagSkipPrev( pTag );
         }
         if( !fFound )
         {
            if( fForward )
               SELF_GOTO( ( AREAP ) pArea, 0 );
            else
            {
               SELF_GOTOP( ( AREAP ) pArea );
               pArea->fBof = TRUE;
            }
         }
      }
      pArea->lpCurTag = pSavedTag;
      hb_ntxTagUnLockRead( pTag );
   }

   /* Update Bof and Eof flags */
   if( fForward )
      pArea->fBof = FALSE;
   else
      pArea->fEof = FALSE;

   hb_regexFree( pRegEx );

   return fFound;
}
dbfntx1.c4311
STATIC BOOLhb_ntxOrdKeyAdd( LPTAGINFO pTag, PHB_ITEM pItem )
static BOOL hb_ntxOrdKeyAdd( LPTAGINFO pTag, PHB_ITEM pItem )
{
   NTXAREAP pArea = pTag->Owner->Owner;
   BOOL fResult = FALSE;
   LPKEYINFO pKey;

   if( pArea->lpdbPendingRel )
      SELF_FORCEREL( ( AREAP ) pArea );

   if( !pArea->fPositioned )
      return FALSE;

   if( pTag->pForItem && !hb_ntxEvalCond( pArea, pTag->pForItem, TRUE ) )
      return FALSE;

   if( pTag->Template && pItem && hb_itemType( pItem ) != HB_IT_NIL )
   {
      pKey = hb_ntxKeyPutItem( NULL, pItem, pArea->ulRecNo, pTag, TRUE, NULL );
   }
   else
   {
      pKey = hb_ntxEvalKey( NULL, pTag );
   }

   if( hb_ntxTagLockWrite( pTag ) )
   {
      if( hb_ntxTagKeyAdd( pTag, pKey ) )
      {
         fResult = TRUE;
         if( !pTag->Owner->fShared && pTag->keyCount &&
             hb_ntxKeyInScope( pTag, pKey ) )
            pTag->keyCount++;
      }
      hb_ntxTagUnLockWrite( pTag );
   }
   hb_ntxKeyFree( pKey );
   return fResult;
}
dbfntx1.c4394
STATIC BOOLhb_ntxOrdKeyDel( LPTAGINFO pTag, PHB_ITEM pItem )
static BOOL hb_ntxOrdKeyDel( LPTAGINFO pTag, PHB_ITEM pItem )
{
   NTXAREAP pArea = pTag->Owner->Owner;
   BOOL fResult = FALSE;
   LPKEYINFO pKey = NULL;

   if( pArea->lpdbPendingRel )
      SELF_FORCEREL( ( AREAP ) pArea );

   if( !pArea->fPositioned )
      return FALSE;

   if( pTag->pForItem && !hb_ntxEvalCond( pArea, pTag->pForItem, TRUE ) )
      return FALSE;

   if( pTag->Template && pItem && hb_itemType( pItem ) != HB_IT_NIL )
   {
      pKey = hb_ntxKeyPutItem( NULL, pItem, pArea->ulRecNo, pTag, TRUE, NULL );
   }

   if( hb_ntxTagLockWrite( pTag ) )
   {
      if( pKey == NULL )
      {
         if( hb_ntxCurKeyRefresh( pTag ) )
            pKey = hb_ntxKeyCopy( NULL, pTag->CurKeyInfo, pTag->KeyLength );
         else
            pKey = hb_ntxEvalKey( NULL, pTag );
      }
      if( hb_ntxTagKeyDel( pTag, pKey ) )
      {
         fResult = TRUE;
         if( !pTag->Owner->fShared && pTag->keyCount &&
             hb_ntxKeyInScope( pTag, pKey ) )
            pTag->keyCount--;
      }
      hb_ntxTagUnLockWrite( pTag );
   }
   hb_ntxKeyFree( pKey );
   return fResult;
}
dbfntx1.c4437
STATIC BOOLhb_ntxOrdFindRec( LPTAGINFO pTag, ULONG ulRecNo, BOOL fCont )
static BOOL hb_ntxOrdFindRec( LPTAGINFO pTag, ULONG ulRecNo, BOOL fCont )
{
   NTXAREAP pArea = pTag->Owner->Owner;
   BOOL fFound = FALSE;

   if( pTag && ulRecNo )
   {
      if( pArea->lpdbPendingRel && pArea->lpdbPendingRel->isScoped )
         SELF_FORCEREL( ( AREAP ) pArea );

      if( hb_ntxTagLockRead( pTag ) )
      {
         hb_ntxTagRefreshScope( pTag );
         if( fCont )
         {
            if( ! hb_ntxCurKeyRefresh( pTag ) )
               ulRecNo = 0;
            else
               hb_ntxTagSkipNext( pTag );
         }
         else
         {
            hb_ntxTagGoTop( pTag );
         }
         if( ulRecNo )
         {
            while( !pTag->TagEOF )
            {
               if( pTag->CurKeyInfo->Xtra == ulRecNo )
               {
                  fFound = TRUE;
                  break;
               }
               hb_ntxTagSkipNext( pTag );
            }
         }
         hb_ntxTagUnLockRead( pTag );
      }
   }
   SELF_GOTO( ( AREAP ) pArea, fFound ? ulRecNo : 0 );
   return fFound;
}
dbfntx1.c4483
STATIC ULONGhb_ntxOrdScopeEval( LPTAGINFO pTag, HB_EVALSCOPE_FUNC pFunc, void *pParam, PHB_ITEM pItemLo, PHB_ITEM pItemHi )
static ULONG hb_ntxOrdScopeEval( LPTAGINFO pTag,
                                 HB_EVALSCOPE_FUNC pFunc, void *pParam,
                                 PHB_ITEM pItemLo, PHB_ITEM pItemHi )
{
   ULONG ulCount = 0, ulLen = ( ULONG ) pTag->KeyLength;
   PHB_ITEM pItemTop = hb_itemNew( NULL ), pItemBottom = hb_itemNew( NULL );

   hb_ntxTagGetScope( pTag, 0, pItemTop );
   hb_ntxTagGetScope( pTag, 1, pItemBottom );
   hb_ntxTagSetScope( pTag, 0, pItemLo );
   hb_ntxTagSetScope( pTag, 1, pItemHi );

   if( hb_ntxTagLockRead( pTag ) )
   {
      hb_ntxTagGoTop( pTag );
      while( !pTag->TagEOF )
      {
         pFunc( pTag->CurKeyInfo->Xtra, (BYTE *) pTag->CurKeyInfo->key, ulLen, pParam );
         ulCount++;
         hb_ntxTagSkipNext( pTag );
      }
      hb_ntxTagUnLockRead( pTag );
   }

   hb_ntxTagSetScope( pTag, 0, pItemTop );
   hb_ntxTagSetScope( pTag, 1, pItemBottom );
   hb_itemRelease( pItemTop );
   hb_itemRelease( pItemBottom );

   return ulCount;
}

/* ************************************************************************* */
dbfntx1.c4531
STATIC INThb_ntxQuickSortCompare( LPNTXSORTINFO pSort, BYTE * pKey1, BYTE * pKey2 )
static int hb_ntxQuickSortCompare( LPNTXSORTINFO pSort, BYTE * pKey1, BYTE * pKey2 )
{
   int iLen = pSort->keyLen, i;

   i = hb_ntxValCompare( pSort->pTag, (char *) pKey1, iLen, (char *) pKey2, iLen, TRUE );
   if( i == 0 )
   {
      if( pSort->pTag->fSortRec )
         i = ( HB_GET_LE_UINT32( pKey1 + iLen ) < HB_GET_LE_UINT32( pKey2 + iLen ) ) ? -1 : 1;
   }
   else if( ! pSort->pTag->AscendKey )
   {
      i = -i;
   }

   return i;
}
dbfntx1.c4570
STATIC BOOLhb_ntxQSort( LPNTXSORTINFO pSort, BYTE * pSrc, BYTE * pBuf, LONG lKeys )
static BOOL hb_ntxQSort( LPNTXSORTINFO pSort, BYTE * pSrc, BYTE * pBuf, LONG lKeys )
{
   if( lKeys > 1 )
   {
      int iLen = pSort->keyLen + 4;
      LONG l1, l2;
      BYTE * pPtr1, * pPtr2, *pDst;
      BOOL f1, f2;

      l1 = lKeys >> 1;
      l2 = lKeys - l1;
      pPtr1 = &pSrc[ 0 ];
      pPtr2 = &pSrc[ l1 * iLen ];

      f1 = hb_ntxQSort( pSort, pPtr1, &pBuf[ 0 ], l1 );
      f2 = hb_ntxQSort( pSort, pPtr2, &pBuf[ l1 * iLen ], l2 );
      if( f1 )
      {
         pDst = pBuf;
      }
      else
      {
         pDst = pSrc;
         pPtr1 = &pBuf[ 0 ];
      }
      if( !f2 )
      {
         pPtr2 = &pBuf[ l1 * iLen ];
      }
      while( l1 > 0 && l2 > 0 )
      {
         if( hb_ntxQuickSortCompare( pSort, pPtr1, pPtr2 ) <= 0 )
         {
            memcpy( pDst, pPtr1, iLen );
            pPtr1 += iLen;
            l1--;
         }
         else
         {
            memcpy( pDst, pPtr2, iLen );
            pPtr2 += iLen;
            l2--;
         }
         pDst += iLen;
      }
      if( l1 > 0 )
      {
         memcpy( pDst, pPtr1, iLen * l1 );
      }
      else if( l2 > 0 && f1 == f2 )
      {
         memcpy( pDst, pPtr2, iLen * l2 );
      }
      return !f1;
   }
   return TRUE;
}
dbfntx1.c4588
STATIC VOIDhb_ntxSortSortPage( LPNTXSORTINFO pSort )
static void hb_ntxSortSortPage( LPNTXSORTINFO pSort )
{
   ULONG ulSize = pSort->ulKeys * ( pSort->keyLen + 4 );
   if( !hb_ntxQSort( pSort, pSort->pKeyPool, &pSort->pKeyPool[ ulSize ], pSort->ulKeys ) )
   {
      pSort->pStartKey = &pSort->pKeyPool[ ulSize ];
   }
   else
   {
      pSort->pStartKey = pSort->pKeyPool;
   }
}
dbfntx1.c4646
STATIC VOIDhb_ntxSortBufferFlush( LPNTXSORTINFO pSort )
static void hb_ntxSortBufferFlush( LPNTXSORTINFO pSort )
{
   ULONG ulSize;
   if( pSort->ulPagesIO )
   {
      LPNTXINDEX pIndex = pSort->pTag->Owner;
      ulSize = pSort->ulPagesIO * NTXBLOCKSIZE;
      if( hb_fileWriteAt( pIndex->DiskFile, pSort->pBuffIO, ulSize,
                     hb_ntxFileOffset( pIndex, pSort->ulFirstIO ) ) != ulSize )
      {
         hb_ntxErrorRT( pIndex->Owner, EG_WRITE, EDBF_WRITE,
                        pIndex->IndexName, hb_fsError(), 0 );
      }
      pSort->ulPagesIO = 0;
      pIndex->fFlush = TRUE;
      if( pIndex->fShared )
         pIndex->Changed = TRUE;
   }
}
dbfntx1.c4659
STATIC VOIDhb_ntxSortStorePage( LPNTXSORTINFO pSort, LPPAGEINFO pPage )
static void hb_ntxSortStorePage( LPNTXSORTINFO pSort, LPPAGEINFO pPage )
{
   LPNTXINDEX pIndex = pSort->pTag->Owner;
   if( !pPage->Page )
   {
      pPage->Page = hb_ntxPageAlloc( pIndex );
      if( pSort->ulSizeIO )
      {
         if( pSort->ulPagesIO == pSort->ulSizeIO )
            hb_ntxSortBufferFlush( pSort );
         if( !pSort->ulPagesIO ||
             hb_ntxFileOffset( pIndex, pSort->ulLastIO ) + NTXBLOCKSIZE ==
             hb_ntxFileOffset( pIndex, pPage->Page ) )
         {
            hb_ntxSetKeyCount( pPage, pPage->uiKeys );
            memcpy( pSort->pBuffIO + pSort->ulPagesIO * NTXBLOCKSIZE,
                    hb_ntxPageBuffer( pPage ), NTXBLOCKSIZE );
            pSort->ulLastIO = pPage->Page;
            if( !pSort->ulPagesIO++ )
               pSort->ulFirstIO = pPage->Page;
            pPage->Changed = FALSE;
            return;
         }
      }
   }
   if( !pPage->pPrev )
      hb_ntxPageSave( pIndex, pPage );
}
dbfntx1.c4679
STATIC VOIDhb_ntxSortAddNodeKey( LPNTXSORTINFO pSort, BYTE *pKeyVal, ULONG ulRec )
static void hb_ntxSortAddNodeKey( LPNTXSORTINFO pSort, BYTE *pKeyVal, ULONG ulRec )
{
   LPPAGEINFO pPage;
   ULONG ulPage = 0;
   int iLevel = 0;

   for( ;; )
   {
      pPage = pSort->NodeList[ iLevel ];
      if( pPage == NULL )
      {
         pPage = pSort->NodeList[ iLevel ] = hb_ntxPageNew( pSort->pTag, TRUE );
         break;
      }
      else if( pPage->uiKeys >= pSort->pTag->MaxKeys )
      {
         hb_ntxSetKeyPage( pPage, pPage->uiKeys, ulPage );
         hb_ntxSortStorePage( pSort, pPage );
         ulPage = pPage->Page;
         hb_ntxPageRelease( pSort->pTag, pPage );
         pSort->NodeList[ iLevel++ ] = hb_ntxPageNew( pSort->pTag, TRUE );
      }
      else
         break;
   }

   memcpy( hb_ntxGetKeyVal( pPage, pPage->uiKeys ), pKeyVal, pSort->pTag->KeyLength );
   hb_ntxSetKeyRec( pPage, pPage->uiKeys, ulRec );
   hb_ntxSetKeyPage( pPage, pPage->uiKeys, ulPage );
   pPage->uiKeys++;
}
dbfntx1.c4708
STATIC VOIDhb_ntxSortWritePage( LPNTXSORTINFO pSort )
static void hb_ntxSortWritePage( LPNTXSORTINFO pSort )
{
   ULONG ulSize = pSort->ulKeys * ( pSort->keyLen + 4 );

   hb_ntxSortSortPage( pSort );

   if( pSort->hTempFile == FS_ERROR )
   {
      BYTE szName[ _POSIX_PATH_MAX + 1 ];
      pSort->hTempFile = hb_fsCreateTemp( NULL, NULL, FC_NORMAL, szName );
      if( pSort->hTempFile == FS_ERROR )
         hb_ntxErrorRT( pSort->pTag->Owner->Owner, EG_CREATE, EDBF_CREATE_TEMP,
                        ( char * ) szName, 0, 0 );
      else
         pSort->szTempFileName = hb_strdup( ( char * ) szName );
   }

   pSort->pSwapPage[ pSort->ulCurPage ].ulKeys = pSort->ulKeys;
   if( pSort->hTempFile != FS_ERROR )
   {
      pSort->pSwapPage[ pSort->ulCurPage ].nOffset = hb_fsSeekLarge( pSort->hTempFile, 0, FS_END );
      if( hb_fsWriteLarge( pSort->hTempFile, pSort->pStartKey, ulSize ) != ulSize )
         hb_ntxErrorRT( pSort->pTag->Owner->Owner, EG_WRITE, EDBF_WRITE_TEMP,
                        pSort->szTempFileName, 0, 0 );
   }
   else
      pSort->pSwapPage[ pSort->ulCurPage ].nOffset = 0;
   pSort->ulKeys = 0;
   pSort->ulCurPage++;
}
dbfntx1.c4740
STATIC VOIDhb_ntxSortGetPageKey( LPNTXSORTINFO pSort, ULONG ulPage, BYTE ** pKeyVal, ULONG *pulRec )
static void hb_ntxSortGetPageKey( LPNTXSORTINFO pSort, ULONG ulPage,
                                  BYTE ** pKeyVal, ULONG *pulRec )
{
   int iLen = pSort->keyLen;

   if( pSort->pSwapPage[ ulPage ].ulKeyBuf == 0 )
   {
      ULONG ulKeys = HB_MIN( pSort->ulPgKeys, pSort->pSwapPage[ ulPage ].ulKeys );
      ULONG ulSize = ulKeys * ( iLen + 4 );

      if( pSort->hTempFile != FS_ERROR &&
         ( hb_fsSeekLarge( pSort->hTempFile, pSort->pSwapPage[ ulPage ].nOffset, FS_SET ) != pSort->pSwapPage[ ulPage ].nOffset ||
           hb_fsReadLarge( pSort->hTempFile, pSort->pSwapPage[ ulPage ].pKeyPool, ulSize ) != ulSize ) )
      {
         hb_ntxErrorRT( pSort->pTag->Owner->Owner, EG_READ, EDBF_READ_TEMP,
                        pSort->szTempFileName, 0, 0 );
      }
      pSort->pSwapPage[ ulPage ].nOffset += ulSize;
      pSort->pSwapPage[ ulPage ].ulKeyBuf = ulKeys;
      pSort->pSwapPage[ ulPage ].ulCurKey = 0;
   }
   *pKeyVal = &pSort->pSwapPage[ ulPage ].pKeyPool[ pSort->pSwapPage[ ulPage ].ulCurKey * ( iLen + 4 ) ];
   *pulRec = HB_GET_LE_UINT32( *pKeyVal + iLen );
}
dbfntx1.c4771
STATIC VOIDhb_ntxSortOrderPages( LPNTXSORTINFO pSort )
static void hb_ntxSortOrderPages( LPNTXSORTINFO pSort )
{
   int iLen = pSort->keyLen, i;
   LONG l, r, m;
   ULONG n, ulPage, ulRec;
   BYTE *pKey = NULL, *pTmp;

   pSort->ulFirst = 0;
   pSort->pSortedPages = ( ULONG * ) hb_xgrab( pSort->ulPages * sizeof( ULONG ) );
   pSort->pSortedPages[ 0 ] = 0;

   if( pSort->ulTotKeys > 0 )
   {
      for( n = 0; n < pSort->ulPages; n++ )
      {
         hb_ntxSortGetPageKey( pSort, n, &pKey, &ulRec );
         l = 0;
         r = n - 1;
         while( l <= r )
         {
            m = ( l + r ) >> 1;
            ulPage = pSort->pSortedPages[ m ];
            pTmp = &pSort->pSwapPage[ ulPage ].pKeyPool[ pSort->pSwapPage[ ulPage ].ulCurKey * ( iLen + 4 ) ];
            i = hb_ntxValCompare( pSort->pTag, (char *) pKey, iLen, (char *) pTmp, iLen, TRUE );
            if( i == 0 )
            {
               if( pSort->pTag->fSortRec )
                  i = ( ulRec < HB_GET_LE_UINT32( &pTmp[ iLen ] ) ) ? -1 : 1;
            }
            else if( ! pSort->pTag->AscendKey )
               i = -i;
            if( i >= 0 )
               l = m + 1;
            else
               r = m - 1;
         }
         for( r = n; r > l; r-- )
            pSort->pSortedPages[ r ] = pSort->pSortedPages[ r - 1 ];
         pSort->pSortedPages[ l ] = n;
      }
   }
}
dbfntx1.c4796
STATIC BOOLhb_ntxSortKeyGet( LPNTXSORTINFO pSort, BYTE ** pKeyVal, ULONG *pulRec )
static BOOL hb_ntxSortKeyGet( LPNTXSORTINFO pSort, BYTE ** pKeyVal, ULONG *pulRec )
{
   int iLen = pSort->keyLen, i;
   LONG l, r, m;
   ULONG ulPage;

   ulPage = pSort->pSortedPages[ pSort->ulFirst ];

   /* check if first page has some keys yet */
   if( pSort->pSwapPage[ ulPage ].ulKeys > 0 )
   {
      BYTE *pKey, *pTmp;
      ULONG ulRec, ulPg;

      /*
       * last key was taken from this page - we have to resort it.
       * This is done intentionally here to be sure that the key
       * value return by this function will not be overwritten by
       * next keys in page read from temporary file in function
       * hb_ntxSortGetPageKey() - please do not move this part down
       * even it seems to be correct
       */
      hb_ntxSortGetPageKey( pSort, ulPage, &pKey, &ulRec );

      l = pSort->ulFirst + 1;
      r = pSort->ulPages - 1;
      while( l <= r )
      {
         m = ( l + r ) >> 1;
         ulPg = pSort->pSortedPages[ m ];
         pTmp = &pSort->pSwapPage[ ulPg ].pKeyPool[ pSort->pSwapPage[ ulPg ].ulCurKey * ( iLen + 4 ) ];
         i = hb_ntxValCompare( pSort->pTag, (char *) pKey, iLen, (char *) pTmp, iLen, TRUE );
         if( i == 0 )
         {
            if( pSort->pTag->fSortRec )
               i = ( ulRec < HB_GET_LE_UINT32( &pTmp[ iLen ] ) ) ? -1 : 1;
            else
               i = ( ulPage < ulPg ) ? -1 : 1;
         }
         else if( ! pSort->pTag->AscendKey )
            i = -i;
         if( i > 0 )
            l = m + 1;
         else
            r = m - 1;
      }
      if( l > ( LONG ) pSort->ulFirst + 1 )
      {
         ulPage = pSort->pSortedPages[ pSort->ulFirst ];
         for( r = pSort->ulFirst + 1; r < l; r++ )
            pSort->pSortedPages[ r - 1 ] = pSort->pSortedPages[ r ];
         pSort->pSortedPages[ l - 1 ] = ulPage;
      }
   }
   else
   {
      pSort->ulFirst++;
   }
   if( pSort->ulFirst < pSort->ulPages )
   {
      ulPage = pSort->pSortedPages[ pSort->ulFirst ];
      hb_ntxSortGetPageKey( pSort, ulPage, pKeyVal, pulRec );
      pSort->pSwapPage[ ulPage ].ulCurKey++;
      pSort->pSwapPage[ ulPage ].ulKeys--;
      pSort->pSwapPage[ ulPage ].ulKeyBuf--;
      return TRUE;
   }

   *pKeyVal = NULL;
   *pulRec = 0;

   return FALSE;
}
dbfntx1.c4839
STATIC VOIDhb_ntxSortKeyAdd( LPNTXSORTINFO pSort, ULONG ulRec, char * pKeyVal, int iKeyLen )
static void hb_ntxSortKeyAdd( LPNTXSORTINFO pSort, ULONG ulRec, char * pKeyVal, int iKeyLen )
{
   int iLen = pSort->keyLen;
   BYTE *pDst;

   if( pSort->ulKeys >= pSort->ulPgKeys )
   {
      hb_ntxSortWritePage( pSort );
   }
   pDst = &pSort->pKeyPool[ pSort->ulKeys * ( iLen + 4 ) ];

   if( iLen > iKeyLen )
   {
      memcpy( pDst, pKeyVal, iKeyLen );
      memset( &pDst[ iKeyLen ], ' ', iLen - iKeyLen );
   }
   else
   {
      memcpy( pDst, pKeyVal, iLen );
   }
   HB_PUT_LE_UINT32( &pDst[ iLen ], ulRec );
   pSort->ulKeys++;
   pSort->ulTotKeys++;
}
dbfntx1.c4913
STATIC LPNTXSORTINFOhb_ntxSortNew( LPTAGINFO pTag, ULONG ulRecCount )
static LPNTXSORTINFO hb_ntxSortNew( LPTAGINFO pTag, ULONG ulRecCount )
{
   LPNTXSORTINFO pSort;
   BYTE * pBuf;
   int iLen = pTag->KeyLength;
   ULONG ulSize, ulMax, ulMin;

   if( ulRecCount == 0 )
      ulRecCount = 1;

   pSort = ( LPNTXSORTINFO ) hb_xgrab( sizeof( NTXSORTINFO ) );
   memset( pSort, 0, sizeof( NTXSORTINFO ) );

   ulMin = ( ULONG ) ceil( sqrt( ( double ) ulRecCount ) );
   ulMax = ( ( ULONG ) ceil( sqrt( ( double ) ulRecCount / ( iLen + 4 ) ) ) ) << 7;
   /*
    * this effectively increase allocated memory buffer for very large files
    * moving the maximum to: 270'566'400 for 4'294'967'295 records and 256
    * index key length.
    * if you want to force smaller buffer I wrote below then add here:
    * ulMax = ulMin;
    */
   ulSize = ( 1L << 20 ) / ( iLen + 4 );
   while( ulMax < ulSize )
      ulMax <<= 1;
   if( ulMax > ulRecCount )
      ulMax = ulRecCount;

   do
   {
      ulSize = ulMax * ( iLen + 4 );
      pBuf = ( BYTE * ) hb_xalloc( ulSize << 2 );
      if( pBuf )
      {
         hb_xfree( pBuf );
         pBuf = ( BYTE * ) hb_xalloc( ulSize << 1 );
      }
      else
      {
         ulMax >>= 1;
      }
   }
   while( ! pBuf && ulMax >= ulMin );

   if( ! pBuf )
   {
      /* call hb_xgrab() to force out of memory error,
       * though in multi process environment this call may return
       * with success when other process free some memory
       * (also the size of buf is reduced to absolute minimum).
       * Sorry but I'm to lazy to implement indexing with smaller
       * memory though it's possible - just simply I can even create
       * index on-line by key adding like in normal update process.
       * The memory necessary to index file is now ~
       *    ~ (keySize+4+sizeof(NTXSWAPPAGE)) * sqrt(ulRecCount) * 2
       * so the maximum is for DBF with 2^32 records and keySize 256 ~
       * ~ 2^17 * 284 ~=~ 37 Mb
       * this is not a problem for current computers and I do not see
       * any way to use DBFs with four billions records and indexes with
       * such long (256 bytes) keys on the old ones - they will be simply
       * to slow. IMHO it's also better to signal out of memory here and
       * force some system upgrades then run process which will have to
       * take many hours, Druzus.
       */
      ulMax = ulMin;
      pBuf = ( BYTE * ) hb_xgrab( ( ulMax << 1 ) * ( iLen + 4 ) );
   }

   pSort->pTag = pTag;
   pSort->hTempFile = FS_ERROR;
   pSort->keyLen = iLen;
   pSort->fUnique = pTag->UniqueKey;
   pSort->ulMaxKey = ulMax << 1;
   pSort->ulPgKeys = ulMax;
   pSort->ulMaxRec = ulRecCount;
   pSort->pKeyPool = pBuf;
   pSort->ulPages = ( ulRecCount + pSort->ulPgKeys - 1 ) / pSort->ulPgKeys;
   /* check for overflow on 32 bit machines when number of records is nearly 2^32 */
   if( !pSort->ulPages )
      pSort->ulPages = ulRecCount / pSort->ulPgKeys + 1;
   pSort->pSwapPage = ( LPNTXSWAPPAGE ) hb_xgrab( sizeof( NTXSWAPPAGE ) * pSort->ulPages );
   memset( pSort->pSwapPage, 0, sizeof( NTXSWAPPAGE ) * pSort->ulPages );
   return pSort;
}
dbfntx1.c4938
STATIC VOIDhb_ntxSortFree( LPNTXSORTINFO pSort, BOOL fFull )
static void hb_ntxSortFree( LPNTXSORTINFO pSort, BOOL fFull )
{
   if( pSort->hTempFile != FS_ERROR )
   {
      hb_fsClose( pSort->hTempFile );
      pSort->hTempFile = FS_ERROR;
   }
   if( pSort->szTempFileName )
   {
      hb_fsDelete( ( BYTE * )  pSort->szTempFileName );
      hb_xfree( pSort->szTempFileName );
      pSort->szTempFileName = NULL;
   }
   if( pSort->pKeyPool )
   {
      hb_xfree( pSort->pKeyPool );
      pSort->pKeyPool = NULL;
   }
   if( pSort->pSwapPage )
   {
      hb_xfree( pSort->pSwapPage );
      pSort->pSwapPage = NULL;
   }
   if( pSort->pBuffIO )
   {
      hb_xfree( pSort->pBuffIO );
      pSort->pBuffIO = NULL;
   }
   if( pSort->pSortedPages )
   {
      hb_xfree( pSort->pSortedPages );
      pSort->pSortedPages = NULL;
   }
   if( fFull )
   {
      hb_xfree( pSort );
   }
}
dbfntx1.c5023
STATIC VOIDhb_ntxSortOut( LPNTXSORTINFO pSort )
static void hb_ntxSortOut( LPNTXSORTINFO pSort )
{
   BOOL fUnique = pSort->fUnique, fBalance, fNext;
   LPTAGINFO pTag = pSort->pTag;
   ULONG ulPage, ulRec, ulKey;
   USHORT uiHalf;
   BYTE * pKeyVal;
   int iLen = pSort->keyLen, iLevel;

   pSort->ulPages = pSort->ulCurPage + 1;
   pSort->ulPgKeys = pSort->ulMaxKey / pSort->ulPages;
   if( pSort->ulPages > 1 )
   {
      BYTE * pBuf = pSort->pKeyPool;
      hb_ntxSortWritePage( pSort );
      for( ulPage = 0; ulPage < pSort->ulPages; ulPage++ )
      {
         pSort->pSwapPage[ ulPage ].ulKeyBuf = 0;
         pSort->pSwapPage[ ulPage ].ulCurKey = 0;
         pSort->pSwapPage[ ulPage ].pKeyPool = pBuf;
         pBuf += pSort->ulPgKeys * ( pSort->keyLen + 4 );
      }
   }
   else
   {
      hb_ntxSortSortPage( pSort );
      pSort->pSwapPage[ 0 ].ulKeys = pSort->ulKeys;
      pSort->pSwapPage[ 0 ].ulKeyBuf = pSort->ulKeys;
      pSort->pSwapPage[ 0 ].ulCurKey = 0;
      pSort->pSwapPage[ 0 ].pKeyPool = pSort->pStartKey;
   }
   /* printf("pSort->ulPages=%ld, pSort->ulPgKeys=%ld", pSort->ulPages, pSort->ulPgKeys);fflush(stdout); */

   hb_ntxSortOrderPages( pSort );

   if( hb_vmRequestQuery() != 0 )
      return;

   for( ulKey = 0; ulKey < pSort->ulTotKeys; ulKey++ )
   {
      if( ! hb_ntxSortKeyGet( pSort, &pKeyVal, &ulRec ) )
      {
         if( hb_vmRequestQuery() != 0 )
            return;
         hb_errInternal( 9309, "hb_ntxSortOut: memory structure corrupted.", NULL, NULL );
      }
      if( fUnique )
      {
         if( ulKey != 0 && hb_ntxValCompare( pTag, (char *) pSort->pLastKey, iLen, (char *) pKeyVal, iLen, TRUE ) == 0 )
         {
            continue;
         }
#ifndef HB_NTX_DEBUG_EXT
         else
         {
            memcpy( pSort->pLastKey, pKeyVal, iLen );
         }
#endif
      }
#ifdef HB_NTX_DEBUG_EXT
      if( ulKey != 0 )
      {
         int i = hb_ntxValCompare( pTag, (char *) pSort->pLastKey, iLen, (char *) pKeyVal, iLen, TRUE );
         if( ! pTag->AscendKey )
            i = -i;
         if( i == 0 )
            i = ( pSort->ulLastRec < ulRec ) ? -1 : 1;
         if( i > 0 )
         {
            printf("\r\nulKey=%ld, pKeyVal=[%s][%ld], pKeyLast=[%s][%ld]\r\n",
                   ulKey, pKeyVal, ulRec, pSort->pLastKey, pSort->ulLastRec); fflush(stdout);
            if( hb_vmRequestQuery() != 0 )
               return;
            hb_errInternal( 9310, "hb_ntxSortOut: sorting fails.", NULL, NULL );
         }
      }
      memcpy( pSort->pLastKey, pKeyVal, iLen );
      pSort->ulLastRec = ulRec;
#endif
      hb_ntxSortAddNodeKey( pSort, pKeyVal, ulRec );
   }

#ifdef HB_NTX_DEBUG
   if( hb_ntxSortKeyGet( pSort, &pKeyVal, &ulRec ) )
   {
      if( hb_vmRequestQuery() != 0 )
         return;
      hb_errInternal( 9311, "hb_ntxSortOut: memory structure corrupted(2).", NULL, NULL );
   }
#endif

   if( pSort->NodeList[ 0 ] == NULL )
   {
      pSort->NodeList[ 0 ] = hb_ntxPageNew( pTag, TRUE );
   }
   hb_ntxSetKeyPage( pSort->NodeList[ 0 ], pSort->NodeList[ 0 ]->uiKeys, 0 );

   iLevel = 0;
   fNext = TRUE;
   fBalance = FALSE;
   uiHalf = pTag->MaxKeys >> 1;
   do
   {
      hb_ntxSortStorePage( pSort, pSort->NodeList[ iLevel ] );
      if( iLevel + 1 == NTX_STACKSIZE || pSort->NodeList[ iLevel + 1 ] == NULL )
      {
         pTag->RootBlock = pSort->NodeList[ iLevel ]->Page;
         fNext = FALSE;
      }
      else
      {
         hb_ntxSetKeyPage( pSort->NodeList[ iLevel + 1 ],
                           pSort->NodeList[ iLevel + 1 ]->uiKeys,
                           pSort->NodeList[ iLevel ]->Page );
         if( pSort->NodeList[ iLevel ]->uiKeys < uiHalf )
         {
            fBalance = TRUE;
         }
      }
      hb_ntxPageRelease( pTag, pSort->NodeList[ iLevel ] );
      iLevel++;
   }
   while( fNext );

   hb_ntxSortBufferFlush( pSort );
   hb_ntxSortFree( pSort, FALSE );

   if( fBalance )
   {
      LPPAGEINFO pPage, pFirst, pLast;

      ulPage = pTag->RootBlock;
      while( ulPage )
      {
         pPage = hb_ntxPageLoad( pTag, ulPage );
         if( ! pPage )
            return;
         ulPage = hb_ntxGetKeyPage( pPage, pPage->uiKeys );
         if( ulPage && pPage->uiKeys )
         {
            pLast = hb_ntxPageLoad( pTag, ulPage );
            if( ! pLast )
            {
               hb_ntxPageRelease( pTag, pPage );
               return;
            }
            if( pLast->uiKeys < uiHalf )
            {
               pFirst = hb_ntxPageLoad( pTag, hb_ntxGetKeyPage( pPage,
                                                         pPage->uiKeys - 1 ) );
               if( ! pFirst )
               {
                  hb_ntxPageRelease( pTag, pPage );
                  hb_ntxPageRelease( pTag, pLast );
                  return;
               }
               hb_ntxBalancePages( pTag, pPage, pPage->uiKeys - 1, pFirst, pLast );
               hb_ntxPageRelease( pTag, pFirst );
            }
            hb_ntxPageRelease( pTag, pLast );
         }
         hb_ntxPageRelease( pTag, pPage );
      }
   }
}
dbfntx1.c5062
STATIC ERRCODEhb_ntxTagCreate( LPTAGINFO pTag, BOOL fReindex )
static ERRCODE hb_ntxTagCreate( LPTAGINFO pTag, BOOL fReindex )
{
   LPNTXAREA pArea = pTag->Owner->Owner;
   PHB_ITEM pForItem, pWhileItem = NULL, pEvalItem = NULL, pItem = NULL;
   ULONG ulRecCount, ulRecNo = pArea->ulRecNo;
   LPNTXSORTINFO pSort;
   LONG lStep = 0;
   ERRCODE errCode = SUCCESS;

   if( pArea->lpdbOrdCondInfo )
   {
      pWhileItem = pArea->lpdbOrdCondInfo->itmCobWhile;
      lStep = pArea->lpdbOrdCondInfo->lStep;
      pEvalItem = pArea->lpdbOrdCondInfo->itmCobEval;
   }

   if( pTag->Custom )
   {
      ulRecCount = 0;
   }
   else
   {
      errCode = SELF_RECCOUNT( ( AREAP ) pArea, &ulRecCount );
      if( errCode != SUCCESS )
         return errCode;
   }
   pArea->pSort = pSort = hb_ntxSortNew( pTag, ulRecCount );
   pSort->fReindex = fReindex;

   if( ulRecCount == 0 )
   {
      LPPAGEINFO pPage = hb_ntxPageNew( pTag, FALSE );

      if( pPage )
      {
         pTag->RootBlock = pPage->Page;
         hb_ntxPageRelease( pTag, pPage );
      }
      else
      {
         errCode = FAILURE;
      }
   }
   else
   {
      LPTAGINFO pSaveTag = pArea->lpCurTag;
      ULONG ulStartRec = 0, ulNextCount = 0;
      BOOL fDirectRead, fUseFilter = FALSE;
      BYTE * pSaveRecBuff = pArea->pRecord;
      char szBuffer[ NTX_MAX_KEY ];
      int iRecBuff = 0, iRecBufSize, iRec;
#ifndef HB_CDP_SUPPORT_OFF
      PHB_CODEPAGE cdpTmp = hb_cdpSelect( pArea->cdPage );
#endif

      pForItem = pTag->pForItem;
      if( pTag->nField )
         pItem = hb_itemNew( NULL );

      if( !pArea->lpdbOrdCondInfo || pArea->lpdbOrdCondInfo->fAll )
      {
         pArea->lpCurTag = NULL;
      }
      else
      {
         if( pArea->lpdbOrdCondInfo->itmRecID )
            ulStartRec = hb_itemGetNL( pArea->lpdbOrdCondInfo->itmRecID );
         if ( ulStartRec )
         {
            ulNextCount = 1;
         }
         else if( pArea->lpdbOrdCondInfo->fRest || pArea->lpdbOrdCondInfo->lNextCount > 0 )
         {
            if( pArea->lpdbOrdCondInfo->itmStartRecID )
               ulStartRec = hb_itemGetNL( pArea->lpdbOrdCondInfo->itmStartRecID );
            if( !ulStartRec )
               ulStartRec = ulRecNo;
            if( pArea->lpdbOrdCondInfo->lNextCount > 0 )
               ulNextCount = pArea->lpdbOrdCondInfo->lNextCount;
         }
         else if( pArea->lpdbOrdCondInfo->fUseFilter )
         {
            fUseFilter = TRUE;
         }
         else if( !pArea->lpdbOrdCondInfo->fUseCurrent )
         {
            pArea->lpCurTag = NULL;
         }
      }

      fDirectRead = !hb_setGetStrictRead() && /* !pArea->lpdbRelations && */
                    ( !pArea->lpdbOrdCondInfo || pArea->lpdbOrdCondInfo->fAll ||
                      ( pArea->lpCurTag == NULL && !fUseFilter ) );

      pSort->ulSizeIO = ( 1 << 16 ) / NTXBLOCKSIZE;
      pSort->pBuffIO = (BYTE *) hb_xgrab( pSort->ulSizeIO * NTXBLOCKSIZE );
      iRecBufSize = ( pSort->ulSizeIO * NTXBLOCKSIZE ) / pArea->uiRecordLen;

      if( ulStartRec == 0 && pArea->lpCurTag == NULL )
         ulStartRec = 1;

      if( ulStartRec == 0 )
      {
         errCode = SELF_GOTOP( ( AREAP ) pArea );
      }
      else
      {
         errCode = SELF_GOTO( ( AREAP ) pArea, ulStartRec );
         if( fUseFilter && errCode == SUCCESS )
            errCode = SELF_SKIPFILTER( ( AREAP ) pArea, 1 );
      }

      ulRecNo = pArea->ulRecNo;

      while( errCode == SUCCESS && !pArea->fEof )
      {
         if( hb_vmRequestQuery() != 0 )
         {
            errCode = FAILURE;
            break;
         }

         if( fDirectRead )
         {
            if( ulRecNo > ulRecCount )
               break;
            if( iRecBuff == 0 || iRecBuff >= iRecBufSize )
            {
               if( ulRecCount - ulRecNo >= ( ULONG ) iRecBufSize )
                  iRec = iRecBufSize;
               else
                  iRec = ulRecCount - ulRecNo + 1;
               if( ulNextCount > 0 && ulNextCount < ( ULONG ) iRec )
                  iRec = ( int ) ulNextCount;
               hb_fileReadAt( pArea->pDataFile, pSort->pBuffIO, pArea->uiRecordLen * iRec,
                              ( HB_FOFFSET ) pArea->uiHeaderLen +
                              ( HB_FOFFSET ) ( ulRecNo - 1 ) *
                              ( HB_FOFFSET ) pArea->uiRecordLen );
               iRecBuff = 0;
            }
            pArea->pRecord = pSort->pBuffIO + iRecBuff * pArea->uiRecordLen;
            pArea->ulRecNo = ulRecNo;
            if( SELF_GETREC( ( AREAP ) pArea, NULL ) == FAILURE )
               break;
            pArea->fValidBuffer = pArea->fPositioned = TRUE;
            pArea->fDeleted = pArea->pRecord[ 0 ] == '*';
            /* Force relational movement in child WorkAreas */
            if( pArea->lpdbRelations )
            {
               errCode = SELF_SYNCCHILDREN( ( AREAP ) pArea );
               if( errCode != SUCCESS )
                  break;
            }
            iRecBuff++;
         }

         if( pWhileItem && !hb_ntxEvalCond( NULL, pWhileItem, FALSE ) )
            break;

         if( ulRecNo <= ulRecCount &&
             ( pForItem == NULL || hb_ntxEvalCond( pArea, pForItem, FALSE ) ) )
         {
            if( pTag->nField )
               errCode = SELF_GETVALUE( ( AREAP ) pArea, pTag->nField, pItem );
            else
               pItem = hb_vmEvalBlockOrMacro( pTag->pKeyItem );

            switch( hb_itemType( pItem ) )
            {
               case HB_IT_STRING:
               case HB_IT_STRING | HB_IT_MEMO:
                  hb_ntxSortKeyAdd( pSort, pArea->ulRecNo,
                                    hb_itemGetCPtr( pItem ),
                                    hb_itemGetCLen( pItem ) );
                  break;

               case HB_IT_INTEGER:
               case HB_IT_LONG:
               case HB_IT_DOUBLE:
                  hb_ntxNumToStr( pItem, szBuffer, pTag->KeyLength, pTag->KeyDec );
                  hb_ntxSortKeyAdd( pSort, pArea->ulRecNo, szBuffer, pTag->KeyLength );
                  break;

               case HB_IT_DATE:
                  hb_itemGetDS( pItem, szBuffer );
                  hb_ntxSortKeyAdd( pSort, pArea->ulRecNo, szBuffer, 8 );
                  break;

               case HB_IT_LOGICAL:
                  szBuffer[0] = hb_itemGetL( pItem ) ? 'T' : 'F';
                  hb_ntxSortKeyAdd( pSort, pArea->ulRecNo, szBuffer, 1 );
                  break;

               default:
                  hb_ntxErrorRT( pArea, EG_DATATYPE, EDBF_INVALIDKEY,
                                 pTag->Owner->IndexName, 0, 0 );
                  errCode = FAILURE;
                  pTag->Partial = TRUE;
                  pEvalItem = NULL;
                  ulNextCount = 1;
                  break;
            }
         }

         if( ulNextCount > 0 )
         {
            if( --ulNextCount == 0 )
               break;
         }

         if( pEvalItem )
         {
            if( lStep >= pArea->lpdbOrdCondInfo->lStep )
            {
               lStep = 0;
               if( !hb_ntxEvalCond( pArea, pEvalItem, FALSE ) )
               {
                  pTag->Partial = TRUE;
                  break;
               }
            }
            ++lStep;
         }

         if( fDirectRead )
            ulRecNo++;
         else if( errCode == SUCCESS )
         {
            errCode = SELF_SKIPRAW( ( AREAP ) pArea, 1 );
            if( fUseFilter && errCode == SUCCESS )
               errCode = SELF_SKIPFILTER( ( AREAP ) pArea, 1 );
            ulRecNo = pArea->ulRecNo;
         }
      }

      if( fDirectRead )
      {
         pArea->pRecord = pSaveRecBuff;
         pArea->fValidBuffer = FALSE;
         if( errCode == SUCCESS )
            errCode = SELF_GOTO( ( AREAP ) pArea, ulRecNo );
      }

      if( errCode == SUCCESS )
         hb_ntxSortOut( pSort );

      if( pTag->nField )
         hb_itemRelease( pItem );

      pArea->lpCurTag = pSaveTag;
#ifndef HB_CDP_SUPPORT_OFF
      hb_cdpSelect( cdpTmp );
#endif
   }

   hb_ntxSortFree( pSort, TRUE );
   pArea->pSort = NULL;

   return errCode;
}
dbfntx1.c5228
STATIC ERRCODEhb_ntxReIndex( LPNTXINDEX pIndex )
static ERRCODE hb_ntxReIndex( LPNTXINDEX pIndex )
{
   ERRCODE errCode = FAILURE;
   int i;

   if( hb_ntxIndexLockWrite( pIndex, FALSE ) )
   {
      errCode = SUCCESS;
      hb_ntxIndexTrunc( pIndex );

      for( i = 0; i < pIndex->iTags; i++ )
      {
         LPTAGINFO pTag = pIndex->lpTags[ i ];
         pTag->HeadBlock = pTag->RootBlock = pTag->keyCount = 0;
         pTag->HdrChanged = TRUE;
         errCode = hb_ntxTagCreate( pTag, TRUE );
         if( errCode != SUCCESS )
            break;
      }
      hb_ntxIndexUnLockWrite( pIndex );
   }
   return errCode;
}


dbfntx1.c5492
STATIC ERRCODEntxGoBottom( NTXAREAP pArea )
static ERRCODE ntxGoBottom( NTXAREAP pArea )
{
   ERRCODE retval;

   HB_TRACE(HB_TR_DEBUG, ("ntxGoBottom(%p)", pArea));

   if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE )
      return FAILURE;

   if( !pArea->lpCurTag )
      return SUPER_GOBOTTOM( ( AREAP ) pArea );

   if( pArea->lpdbPendingRel && pArea->lpdbPendingRel->isScoped )
      SELF_FORCEREL( ( AREAP ) pArea );

   if( ! hb_ntxTagLockRead( pArea->lpCurTag ) )
      return FAILURE;
   hb_ntxTagRefreshScope( pArea->lpCurTag );

   hb_ntxTagGoBottom( pArea->lpCurTag );

   pArea->fTop = FALSE;
   pArea->fBottom = TRUE;

   if( pArea->lpCurTag->TagEOF )
      retval = SELF_GOTO( ( AREAP ) pArea, 0 );
   else
   {
      retval = SELF_GOTO( ( AREAP ) pArea, pArea->lpCurTag->CurKeyInfo->Xtra );
      if( retval != FAILURE && pArea->fPositioned )
         retval = SELF_SKIPFILTER( ( AREAP ) pArea, -1 );
   }
   hb_ntxTagUnLockRead( pArea->lpCurTag );

   return retval;
}
dbfntx1.c5524
STATIC ERRCODEntxGoTop( NTXAREAP pArea )
static ERRCODE ntxGoTop( NTXAREAP pArea )
{
   ERRCODE retval;

   HB_TRACE(HB_TR_DEBUG, ("ntxGoTop(%p)", pArea));

   if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE )
      return FAILURE;

   if( !pArea->lpCurTag )
      return SUPER_GOTOP( ( AREAP ) pArea );

   if( pArea->lpdbPendingRel && pArea->lpdbPendingRel->isScoped )
      SELF_FORCEREL( ( AREAP ) pArea );

   if( ! hb_ntxTagLockRead( pArea->lpCurTag ) )
      return FAILURE;
   hb_ntxTagRefreshScope( pArea->lpCurTag );

   hb_ntxTagGoTop( pArea->lpCurTag );

   pArea->fTop = TRUE;
   pArea->fBottom = FALSE;

   if( pArea->lpCurTag->TagEOF )
      retval = SELF_GOTO( ( AREAP ) pArea, 0 );
   else
   {
      retval = SELF_GOTO( ( AREAP ) pArea, pArea->lpCurTag->CurKeyInfo->Xtra );
      if( retval != FAILURE && pArea->fPositioned )
         retval = SELF_SKIPFILTER( ( AREAP ) pArea, 1 );
   }
   hb_ntxTagUnLockRead( pArea->lpCurTag );

   return retval;
}
dbfntx1.c5561
STATIC ERRCODEntxSeek( NTXAREAP pArea, BOOL fSoftSeek, PHB_ITEM pItem, BOOL fFindLast )
static ERRCODE ntxSeek( NTXAREAP pArea, BOOL fSoftSeek, PHB_ITEM pItem, BOOL fFindLast )
{
   HB_TRACE(HB_TR_DEBUG, ("ntxSeek(%p, %d, %p, %d)", pArea, fSoftSeek, pItem, fFindLast));

   if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE )
      return FAILURE;

   if( ! pArea->lpCurTag )
   {
      hb_ntxErrorRT( pArea, EG_NOORDER, EDBF_NOTINDEXED, NULL, 0, EF_CANDEFAULT );
      return FAILURE;
   }
   else
   {
      LPKEYINFO pKey;
      ERRCODE retval = SUCCESS;
      BOOL  fEOF = FALSE, fLast;
      USHORT uiLen;
      ULONG ulRec;

      if( pArea->lpdbPendingRel && pArea->lpdbPendingRel->isScoped )
         SELF_FORCEREL( ( AREAP ) pArea );

      pArea->fTop = pArea->fBottom = FALSE;
      pArea->fEof = FALSE;

      fLast = pArea->lpCurTag->fUsrDescend == pArea->lpCurTag->AscendKey ?
              !fFindLast : fFindLast;

      pKey = hb_ntxKeyPutItem( NULL, pItem, fLast ? NTX_MAX_REC_NUM :
                         NTX_IGNORE_REC_NUM, pArea->lpCurTag, TRUE, &uiLen );

      if( ! hb_ntxTagLockRead( pArea->lpCurTag ) )
      {
         hb_ntxKeyFree( pKey );
         return FAILURE;
      }
      hb_ntxTagRefreshScope( pArea->lpCurTag );

      if( hb_ntxTagKeyFind( pArea->lpCurTag, pKey, uiLen ) )
         ulRec = pArea->lpCurTag->CurKeyInfo->Xtra;
      else
         ulRec = 0;

      if( ( ulRec == 0 && ! fSoftSeek ) || pArea->lpCurTag->TagEOF )
         fEOF = TRUE;
      else
      {
         if( ! hb_ntxInBottomScope( pArea->lpCurTag, pArea->lpCurTag->CurKeyInfo->key ) )
            fEOF = TRUE;
         else if( ! hb_ntxInTopScope( pArea->lpCurTag, pArea->lpCurTag->CurKeyInfo->key ) )
         {
            hb_ntxTagGoTop( pArea->lpCurTag );
            if( pArea->lpCurTag->CurKeyInfo->Xtra == 0 ||
                pArea->lpCurTag->TagEOF )
               fEOF = TRUE;
         }
      }
      hb_ntxTagUnLockRead( pArea->lpCurTag );
      if( !fEOF )
      {
         retval = SELF_GOTO( ( AREAP ) pArea, pArea->lpCurTag->CurKeyInfo->Xtra );
         if( retval != FAILURE && pArea->fPositioned )
         {
            retval = SELF_SKIPFILTER( ( AREAP ) pArea, fFindLast ? -1 : 1 );
            if( retval != FAILURE && ulRec && pArea->fPositioned )
            {
               pArea->fFound = ( ulRec == pArea->ulRecNo ||
                     hb_ntxValCompare( pArea->lpCurTag, pKey->key, uiLen,
                                       pArea->lpCurTag->CurKeyInfo->key,
                                       pArea->lpCurTag->KeyLength, FALSE ) == 0 );
               if( ! pArea->fFound && ! fSoftSeek )
                  fEOF = TRUE;
            }
         }
      }
      if( retval != FAILURE && ( fEOF ||
          !hb_ntxKeyInScope( pArea->lpCurTag, pArea->lpCurTag->CurKeyInfo ) ) )
      {
         retval = SELF_GOTO( ( AREAP ) pArea, 0 );
      }
      if( pArea->fPositioned || pArea->ulRecNo != 1 )
         pArea->fBof = FALSE;
      hb_ntxKeyFree( pKey );
      return retval;
   }
}
dbfntx1.c5598
STATIC ERRCODEntxSkipRaw( NTXAREAP pArea, LONG lToSkip )
static ERRCODE ntxSkipRaw( NTXAREAP pArea, LONG lToSkip )
{
   ERRCODE retval;
   BOOL fOut = FALSE, fForward;

   HB_TRACE(HB_TR_DEBUG, ("ntxSkipRaw(%p, %ld)", pArea, lToSkip));

   if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE )
      return FAILURE;

   if( ! pArea->lpCurTag || lToSkip == 0 )
      return SUPER_SKIPRAW( ( AREAP ) pArea, lToSkip );

   if( ! hb_ntxTagLockRead( pArea->lpCurTag ) )
      return FAILURE;
   hb_ntxTagRefreshScope( pArea->lpCurTag );

   fForward = ( lToSkip > 0 );

   if( ! hb_ntxCurKeyRefresh( pArea->lpCurTag ) )
   {
      if( fForward || pArea->fPositioned )
         fOut = TRUE;
      else
      {
         hb_ntxTagGoBottom( pArea->lpCurTag );
         fOut = pArea->lpCurTag->TagEOF;
         lToSkip++;
      }
   }

   if( fForward )
   {
      while( !fOut && !pArea->lpCurTag->TagEOF && lToSkip-- > 0 )
      {
         hb_ntxTagSkipNext( pArea->lpCurTag );
      }
      retval = SELF_GOTO( ( AREAP ) pArea,
                                    ( pArea->lpCurTag->TagEOF || fOut ) ? 0 :
                                    pArea->lpCurTag->CurKeyInfo->Xtra );
   }
   else /* if( lToSkip < 0 ) */
   {
      while( !fOut && !pArea->lpCurTag->TagBOF && lToSkip++ < 0 )
      {
         hb_ntxTagSkipPrev( pArea->lpCurTag );
      }
      if( fOut || pArea->lpCurTag->TagBOF )
      {
         hb_ntxTagGoTop( pArea->lpCurTag );
         fOut = TRUE;
      }
      retval = SELF_GOTO( ( AREAP ) pArea, pArea->lpCurTag->TagEOF ? 0 :
                                          pArea->lpCurTag->CurKeyInfo->Xtra );
      pArea->fBof = fOut;
   }

   hb_ntxTagUnLockRead( pArea->lpCurTag );
   /* Update Bof and Eof flags */
   /*
   if( fForward )
      pArea->fBof = FALSE;
   else
      pArea->fEof = FALSE;
   */
   return retval;
}
dbfntx1.c5686
STATIC ERRCODEntxFlush( NTXAREAP pArea )
static ERRCODE ntxFlush( NTXAREAP pArea )
{
   ERRCODE uiError;

   HB_TRACE(HB_TR_DEBUG, ("ntxFlush(%p)", pArea));

   uiError = SELF_GOCOLD( ( AREAP ) pArea );
   if( uiError == SUCCESS )
   {
      uiError = SUPER_FLUSH( ( AREAP ) pArea );

      if( hb_setGetHardCommit() )
      {
         LPNTXINDEX pIndex = pArea->lpIndexes;
         while( pIndex )
         {
            if( pIndex->fFlush /* && !pIndex->Temporary */ )
            {
               hb_fileCommit( pIndex->DiskFile );
               pIndex->fFlush = FALSE;
            }
            pIndex = pIndex->pNext;
         }
      }
   }

   return uiError;
}
dbfntx1.c5754
STATIC ERRCODEntxGoCold( NTXAREAP pArea )
static ERRCODE ntxGoCold( NTXAREAP pArea )
{
   BOOL fRecordChanged = pArea->fRecordChanged;
   BOOL fAppend = pArea->fAppend;

   HB_TRACE(HB_TR_DEBUG, ("ntxGoCold(%p)", pArea));

   if( SUPER_GOCOLD( ( AREAP ) pArea ) == SUCCESS )
   {
      if( fRecordChanged || pArea->fNtxAppend )
      {
         if( fAppend && pArea->fShared )
         {
            if( pArea->fNtxAppend )
               hb_errInternal( 9312, "ntxGoCold: multiple appending without GOCOLD.", NULL, NULL );
            pArea->fNtxAppend = TRUE;
         }
         else
         {
            LPNTXINDEX pIndex = pArea->lpIndexes;
            LPTAGINFO pTag;
            LPKEYINFO pKey;
            BOOL fAdd, fDel, fLck = FALSE;
            int i;

            /* The pending relation may move the record pointer so we should
               disable them for KEY/FOR evaluation */
            LPDBRELINFO lpdbPendingRel = pArea->lpdbPendingRel;
            pArea->lpdbPendingRel = NULL;

            if( pArea->fShared )
            {
               fAppend = pArea->fNtxAppend;
               pArea->fNtxAppend = FALSE;
            }

            while( pIndex )
            {
               for( i = 0; i < pIndex->iTags; i++ )
               {
                  pTag = pIndex->lpTags[ i ];
                  if( pIndex->fReadonly || pTag->Custom ||
                      ( pTag->Owner->Compound && !pTag->HeadBlock ) ||
                      ( fAppend && pTag->ChgOnly ) )
                     continue;

                  pKey = hb_ntxEvalKey( NULL, pTag );

                  fAdd = ( pTag->pForItem == NULL ||
                           hb_ntxEvalCond( pArea, pTag->pForItem, TRUE ) );
                  if( fAppend )
                  {
                     fDel = FALSE;
                  }
                  else
                  {
                     if( hb_ntxValCompare( pTag, pKey->key, pTag->KeyLength,
                          pTag->HotKeyInfo->key, pTag->KeyLength, TRUE ) == 0 )
                     {
                        if( pTag->HotFor ? fAdd : !fAdd )
                           fAdd = fDel = FALSE;
                        else
                           fDel = !fAdd;
                     }
                     else
                     {
                        fDel = pTag->HotFor || pTag->Partial;
                     }
                  }
                  if( fDel || fAdd )
                  {
                     if( !fLck )
                     {
                        if( !hb_ntxIndexLockWrite( pIndex, TRUE ) )
                        {
                           hb_ntxKeyFree( pKey );
                           break;
                        }
                        fLck = TRUE;
                        if( ( pTag->Owner->Compound && !pTag->HeadBlock ) ||
                            !pTag->RootBlock )
                           fAdd = fDel = FALSE;
                     }
                     if( fDel )
                     {
                        if( hb_ntxTagKeyDel( pTag, pTag->HotKeyInfo ) )
                        {
                           if( !pIndex->fShared && pTag->keyCount &&
                               hb_ntxKeyInScope( pTag, pTag->HotKeyInfo ) )
                              pTag->keyCount--;
                        }
                        else
                        {
                           if( pTag->ChgOnly )
                              fAdd = FALSE;
                           else if( !pTag->Partial && !pTag->UniqueKey )
                              hb_ntxErrorRT( pTag->Owner->Owner,
                                             EG_CORRUPTION, EDBF_CORRUPT,
                                             pTag->Owner->IndexName, 0, 0 );
                        }
                     }
                     if( fAdd )
                     {
                        if( hb_ntxTagKeyAdd( pTag, pKey ) )
                        {
                           if( !pIndex->fShared && pTag->keyCount &&
                               hb_ntxKeyInScope( pTag, pKey ) )
                              pTag->keyCount++;
                        }
                     }
                  }
                  hb_ntxKeyFree( pKey );
               }
               if( fLck )
               {
                  hb_ntxIndexUnLockWrite( pIndex );
                  fLck = FALSE;
               }
               pIndex = pIndex->pNext;
            }

            /* Restore disabled pending relation */
            pArea->lpdbPendingRel = lpdbPendingRel;
         }
      }
      return SUCCESS;
   }
   return FAILURE;
}
dbfntx1.c5786
STATIC ERRCODEntxGoHot( NTXAREAP pArea )
static ERRCODE ntxGoHot( NTXAREAP pArea )
{
   ERRCODE errCode;

   HB_TRACE(HB_TR_DEBUG, ("ntxGoHot(%p)", pArea));

   errCode = SUPER_GOHOT( ( AREAP ) pArea );
   if( errCode == SUCCESS )
   {
      if( !pArea->fNtxAppend )
      {
         LPNTXINDEX pIndex = pArea->lpIndexes;
         LPTAGINFO pTag;
         int i;

         while( pIndex )
         {
            if( !pIndex->fReadonly )
            {
               for( i = 0; i < pIndex->iTags; i++ )
               {
                  pTag = pIndex->lpTags[ i ];
                  if( !pTag->Custom )
                  {
                     pTag->HotKeyInfo = hb_ntxEvalKey( pTag->HotKeyInfo, pTag );
                     pTag->HotFor = ( pTag->pForItem == NULL ||
                                 hb_ntxEvalCond( pArea, pTag->pForItem, TRUE ) );
                  }
               }
            }
            pIndex = pIndex->pNext;
         }
      }
      return SUCCESS;
   }
   return errCode;
}
dbfntx1.c5919
STATIC ERRCODEntxClose( NTXAREAP pArea )
static ERRCODE ntxClose( NTXAREAP pArea )
{
   ERRCODE errCode;

   HB_TRACE(HB_TR_DEBUG, ("ntxClose(%p)", pArea));

   if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE )
      return FAILURE;

   errCode = SUPER_CLOSE( ( AREAP ) pArea );

   if( errCode == SUCCESS )
   {
      if( pArea->pSort )
      {
         hb_ntxSortFree( pArea->pSort, TRUE );
         pArea->pSort = NULL;
      }

      SELF_ORDLSTCLEAR( ( AREAP ) pArea );

      /* close also production indexes if any */
      while( pArea->lpIndexes )
      {
         LPNTXINDEX pIndex = pArea->lpIndexes;
         pArea->lpIndexes = pIndex->pNext;
         hb_ntxIndexFree( pIndex );
      }

#ifdef HB_NTX_DEBUG_DISP
      printf("\r\n#reads=%ld, #writes=%ld\r\n", s_rdNO, s_wrNO ); fflush(stdout);
#endif
   }

   return errCode;
}

/*
 * Retrieve the size of the WorkArea structure.
 */
static ERRCODE ntxStructSize( NTXAREAP pArea, USHORT * uiSize )
dbfntx1.c5960
STATIC ERRCODEntxStructSize( NTXAREAP pArea, USHORT * uiSize )
{
   HB_TRACE(HB_TR_DEBUG, ("ntxStructSize(%p, %p)", pArea, uiSize));
   HB_SYMBOL_UNUSED( pArea );

   * uiSize = sizeof( NTXAREA );
   return SUCCESS;
}
dbfntx1.c6005
STATIC ERRCODEntxOpen( NTXAREAP pArea, LPDBOPENINFO pOpenInfo )
static ERRCODE ntxOpen( NTXAREAP pArea, LPDBOPENINFO pOpenInfo )
{
   ERRCODE errCode;

   HB_TRACE(HB_TR_DEBUG, ("ntxOpen(%p, %p)", pArea, pOpenInfo));

   errCode = SUPER_OPEN( ( AREAP ) pArea, pOpenInfo );

   if( errCode == SUCCESS && NTXAREA_DATA( pArea )->fStruct &&
       ( NTXAREA_DATA( pArea )->fStrictStruct ? pArea->fHasTags : hb_setGetAutOpen() ) )
   {
      char szFileName[ _POSIX_PATH_MAX + 1 ];

      hb_ntxCreateFName( pArea, NULL, NULL, szFileName, NULL );
      if( hb_spFile( ( BYTE * ) szFileName, NULL ) ||
          NTXAREA_DATA( pArea )->fStrictStruct )
      {
         DBORDERINFO pOrderInfo;

         pOrderInfo.itmResult = hb_itemPutNI( NULL, 0 );
         pOrderInfo.atomBagName = hb_itemPutC( NULL, szFileName );
         pOrderInfo.itmNewVal = NULL;
         pOrderInfo.itmOrder  = NULL;
         errCode = SELF_ORDLSTADD( ( AREAP ) pArea, &pOrderInfo );
         if( errCode == SUCCESS )
         {
            pOrderInfo.itmOrder  = hb_itemPutNI( NULL, hb_setGetAutOrder() );
            errCode = SELF_ORDLSTFOCUS( ( AREAP ) pArea, &pOrderInfo );
            hb_itemRelease( pOrderInfo.itmOrder );
            if( errCode == SUCCESS )
               errCode = SELF_GOTOP( ( AREAP ) pArea );
         }
         hb_itemRelease( pOrderInfo.atomBagName );
         hb_itemRelease( pOrderInfo.itmResult );
      }
   }

   return errCode;
}
dbfntx1.c6013
STATIC ERRCODEntxPack( NTXAREAP pArea )
static ERRCODE ntxPack( NTXAREAP pArea )
{
   ERRCODE errCode;
   HB_TRACE(HB_TR_DEBUG, ("ntxPack(%p)", pArea ));

   errCode = SUPER_PACK( ( AREAP ) pArea );
   if( errCode == SUCCESS )
      return SELF_ORDLSTREBUILD( ( AREAP ) pArea );

   return errCode;
}
dbfntx1.c6056
STATIC ERRCODEntxZap( NTXAREAP pArea )
static ERRCODE ntxZap( NTXAREAP pArea )
{
   ERRCODE errCode;

   HB_TRACE(HB_TR_DEBUG, ("ntxZap(%p)", pArea ));

   errCode = SUPER_ZAP( ( AREAP ) pArea );
   if( errCode == SUCCESS )
      return SELF_ORDLSTREBUILD( ( AREAP ) pArea );

   return errCode;
}
dbfntx1.c6068
STATIC ERRCODEntxOrderCreate( NTXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo )
static ERRCODE ntxOrderCreate( NTXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo )
{
   PHB_ITEM pResult, pKeyExp, pForExp = NULL;
   int iLen, iDec, iTag, i;
   char szFileName[ _POSIX_PATH_MAX + 1 ], szSpFile[ _POSIX_PATH_MAX + 1 ],
        szTagName[ NTX_MAX_TAGNAME + 1 ], * szKey, * szFor = NULL;
   LPNTXINDEX pIndex, * pIndexPtr;
   LPTAGINFO pTag = NULL;
   ERRCODE errCode;
   ULONG ulRecNo;
   BOOL fCompound, fTagName, fBagName, fProd, fLocked = FALSE,
        fAscend = TRUE, fCustom = FALSE, fTemporary = FALSE, fExclusive = FALSE;
   BYTE bType;

   HB_TRACE(HB_TR_DEBUG, ("ntxOrderCreate(%p, %p)", pArea, pOrderInfo));

   errCode = SELF_GOCOLD( ( AREAP ) pArea );
   if( errCode != SUCCESS )
      return errCode;

   if( pArea->lpdbPendingRel )
   {
      errCode = SELF_FORCEREL( ( AREAP ) pArea );
      if( errCode != SUCCESS )
         return errCode;
   }

   szKey = hb_itemGetCPtr( pOrderInfo->abExpr );
   /* If we have a codeblock for the expression, use it */
   if( pOrderInfo->itmCobExpr )
      pKeyExp = hb_itemNew( pOrderInfo->itmCobExpr );
   else /* Otherwise, try compiling the key expression string */
   {
      errCode = SELF_COMPILE( ( AREAP ) pArea, ( BYTE * ) szKey );
      if( errCode != SUCCESS )
         return errCode;
      pKeyExp = pArea->valResult;
      pArea->valResult = NULL;
   }

   /* Get a blank record before testing expression */
   ulRecNo = pArea->ulRecNo;
   errCode = SELF_GOTO( ( AREAP ) pArea, 0 );
   if( errCode != SUCCESS )
      return errCode;

   errCode = SELF_EVALBLOCK( ( AREAP ) pArea, pKeyExp );
   if( errCode != SUCCESS )
   {
      hb_vmDestroyBlockOrMacro( pKeyExp );
      SELF_GOTO( ( AREAP ) pArea, ulRecNo );
      return errCode;
   }
   pResult = pArea->valResult;
   pArea->valResult = NULL;

   bType = hb_ntxItemType( pResult );
   iLen = iDec = 0;
   switch( bType )
   {
      case 'N':
         hb_itemGetNLen( pResult, &iLen, &iDec );
         if( iDec )
            iLen += iDec + 1;
         break;
      case 'D':
         iLen = 8;
         break;
      case 'L':
         iLen = 1;
         break;
      case 'C':
         iLen = hb_itemGetCLen( pResult );
         if( iLen > NTX_MAX_KEY )
            iLen = NTX_MAX_KEY;
         break;
      default:
         bType = 'U';
   }
   hb_itemRelease( pResult );

   /* Make sure KEY has proper type and iLen is not 0 */
   if( bType == 'U' || iLen == 0 )
   {
      hb_vmDestroyBlockOrMacro( pKeyExp );
      SELF_GOTO( ( AREAP ) pArea, ulRecNo );
      hb_ntxErrorRT( pArea, bType == 'U' ? EG_DATATYPE : EG_DATAWIDTH,
                     1026, NULL, 0, 0 );
      return FAILURE;
   }

   if( pArea->lpdbOrdCondInfo )
   {
      fAscend = !pArea->lpdbOrdCondInfo->fDescending;
      fCustom = pArea->lpdbOrdCondInfo->fCustom;
      fTemporary = pArea->lpdbOrdCondInfo->fTemporary;
      fExclusive = pArea->lpdbOrdCondInfo->fExclusive;
      /* Check conditional expression */
      szFor = ( char * ) pArea->lpdbOrdCondInfo->abFor;
      if( pArea->lpdbOrdCondInfo->itmCobFor )
         /* If we have a codeblock for the conditional expression, use it */
         pForExp = hb_itemNew( pArea->lpdbOrdCondInfo->itmCobFor );
      else if( szFor )
      {
         /* Otherwise, try compiling the conditional expression string */
         errCode = SELF_COMPILE( ( AREAP ) pArea, ( BYTE * ) szFor );
         if( errCode != SUCCESS )
         {
            hb_vmDestroyBlockOrMacro( pKeyExp );
            SELF_GOTO( ( AREAP ) pArea, ulRecNo );
            return errCode;
         }
         pForExp = pArea->valResult;
         pArea->valResult = NULL;
      }
   }

   /* Test conditional expression */
   if( pForExp )
   {
      BOOL fOK;

      errCode = SELF_EVALBLOCK( ( AREAP ) pArea, pForExp );
      if( errCode != SUCCESS )
      {
         hb_vmDestroyBlockOrMacro( pKeyExp );
         hb_vmDestroyBlockOrMacro( pForExp );
         SELF_GOTO( ( AREAP ) pArea, ulRecNo );
         return errCode;
      }
      fOK = hb_itemType( pArea->valResult ) == HB_IT_LOGICAL;
      hb_itemRelease( pArea->valResult );
      pArea->valResult = NULL;
      if( ! fOK )
      {
         hb_vmDestroyBlockOrMacro( pKeyExp );
         hb_vmDestroyBlockOrMacro( pForExp );
         SELF_GOTO( ( AREAP ) pArea, ulRecNo );
         hb_ntxErrorRT( pArea, EG_DATATYPE, EDBF_INVALIDFOR, NULL, 0, 0 );
         return FAILURE;
      }
   }

   SELF_GOTO( ( AREAP ) pArea, ulRecNo );

   /*
    * abBagName -> cBag, atomBagName -> cTag
    * The following scheme implemented:
    * 1. abBagName == NULL   -> add the Tag to the structural index
    *    if no compound index support then create new separate index
    *    with atomBagName
    * 2. atomBagName == NULL -> overwrite any index file of abBagName
    * 3. ads the Tag to index file
    */
   fTagName = pOrderInfo->atomBagName && pOrderInfo->atomBagName[0];
   fBagName = pOrderInfo->abBagName && pOrderInfo->abBagName[0];
#if defined( HB_NTX_NOMULTITAG )
   fCompound = FALSE;
#else
   fCompound = fTagName && NTXAREA_DATA( pArea )->fMultiTag;
#endif
   hb_ntxCreateFName( pArea, ( char * ) ( ( fBagName || fCompound ) ?
                      pOrderInfo->abBagName : pOrderInfo->atomBagName ),
                      &fProd, szFileName, szTagName );
   if( fTagName )
      hb_strncpyUpperTrim( szTagName, ( char * ) pOrderInfo->atomBagName, NTX_MAX_TAGNAME );

   pIndex = hb_ntxFindBag( pArea, szFileName );
   if( pIndex && !fCompound )
   {
      pIndexPtr = &pArea->lpIndexes;
      while( *pIndexPtr )
      {
         if( pIndex == *pIndexPtr )
         {
            *pIndexPtr = pIndex->pNext;
            hb_ntxIndexFree( pIndex );
            break;
         }
         pIndexPtr = &(*pIndexPtr)->pNext;
      }
      pIndex = NULL;
   }

   if( pIndex )
   {
      if( pIndex->fReadonly )
      {
         hb_vmDestroyBlockOrMacro( pKeyExp );
         if( pForExp != NULL )
            hb_vmDestroyBlockOrMacro( pForExp );
         hb_ntxErrorRT( pArea, EG_READONLY, EDBF_READONLY, pIndex->IndexName, 0, 0 );
         return FAILURE;
      }
#if 0 /* enable this code if you want to forbid tag deleting in shared mode */
      else if( pIndex->fShared )
      {
         hb_vmDestroyBlockOrMacro( pKeyExp );
         if( pForExp != NULL )
            hb_vmDestroyBlockOrMacro( pForExp );
         hb_ntxErrorRT( pArea, EG_SHARED, EDBF_SHARED, pIndex->IndexName, 0, 0 );
         return FAILURE;
      }
#endif
   }
   else
   {
      PHB_FILE pFile;
      BOOL bRetry, fOld, fShared = pArea->fShared && !fTemporary && !fExclusive;
      USHORT uiFlags = FO_READWRITE | ( fShared ? FO_DENYNONE : FO_EXCLUSIVE );

      fOld = fCompound;
      do
      {
         if( fTemporary )
         {
            pFile = hb_fileCreateTemp( NULL, NULL, FC_NORMAL, ( BYTE * ) szSpFile );
            fOld = FALSE;
         }
         else
         {
            pFile = hb_fileExtOpen( ( BYTE * ) szFileName, NULL, uiFlags |
                                    ( fOld ? FXO_APPEND : FXO_TRUNCATE ) |
                                    FXO_DEFAULTS | FXO_SHARELOCK | FXO_COPYNAME,
                                    NULL, NULL );
         }
         if( !pFile )
            bRetry = ( hb_ntxErrorRT( pArea, EG_CREATE, EDBF_CREATE, szFileName,
                                      hb_fsError(), EF_CANRETRY | EF_CANDEFAULT ) == E_RETRY );
         else
         {
            bRetry = FALSE;
            if( fOld )
               fOld = ( hb_fileSize( pFile ) != 0 );
         }
      }
      while( bRetry );

      if( !pFile )
      {
         hb_vmDestroyBlockOrMacro( pKeyExp );
         if( pForExp != NULL )
            hb_vmDestroyBlockOrMacro( pForExp );
         /* hb_ntxSetTagNumbers() */
         return FAILURE;
      }

      pIndex = hb_ntxIndexNew( pArea );
      pIndex->IndexName = hb_strdup( szFileName );
      pIndex->fReadonly = FALSE;
      pIndex->fShared = fShared;
      pIndex->DiskFile = pFile;
      pIndex->fDelete = fTemporary;
      if( fTemporary )
         pIndex->RealName = hb_strdup( szSpFile );
      else
         pIndex->Production = fProd;

      pIndexPtr = &pArea->lpIndexes;
      while( *pIndexPtr )
         pIndexPtr = &(*pIndexPtr)->pNext;
      *pIndexPtr = pIndex;
      if( fOld )
      {
         if( !hb_ntxIndexLockWrite( pIndex, TRUE ) )
            errCode = FAILURE;
         else
         {
            errCode = hb_ntxIndexLoad( pIndex, szTagName );
            if( errCode != SUCCESS )
               hb_ntxIndexUnLockWrite( pIndex );
            else
               fLocked = TRUE;
         }
         if( errCode != SUCCESS )
         {
            *pIndexPtr = pIndex->pNext;
            hb_ntxIndexFree( pIndex );
            hb_vmDestroyBlockOrMacro( pKeyExp );
            if( pForExp != NULL )
               hb_vmDestroyBlockOrMacro( pForExp );
            /* hb_ntxSetTagNumbers() */
            hb_ntxErrorRT( pArea, EG_CORRUPTION, EDBF_CORRUPT, szFileName, 0, 0 );
            return errCode;
         }
      }
      else
      {
         pIndex->LargeFile = ( pIndex->Owner->bLockType == DB_DBFLOCK_XHB64 );
      }
   }

   iTag = hb_ntxFindTagByName( pIndex, szTagName );
   fCompound = ( pIndex->iTags > ( iTag ? 1 : 0 ) );

   if( ! iTag && pIndex->iTags == CTX_MAX_TAGS )
   {
      if( fLocked )
         hb_ntxIndexUnLockWrite( pIndex );
      hb_vmDestroyBlockOrMacro( pKeyExp );
      if( pForExp != NULL )
         hb_vmDestroyBlockOrMacro( pForExp );
      /* hb_ntxSetTagNumbers() */
      hb_ntxErrorRT( pArea, EG_LIMIT, EDBF_LIMITEXCEEDED, pIndex->IndexName, 0, 0 );
      return FAILURE;
   }

   if( !fLocked && !hb_ntxIndexLockWrite( pIndex, fCompound ) )
   {
      errCode = FAILURE;
   }
   else
   {
      if( pIndex->Compound != fCompound )
      {
         pIndex->Compound = fCompound;
         if( fCompound )
         {
            if( !pIndex->HeaderBuff )
               pIndex->HeaderBuff = ( BYTE * ) hb_xgrab( NTXBLOCKSIZE );
            memset( pIndex->HeaderBuff, 0, NTXBLOCKSIZE );
            pIndex->fValidHeader = TRUE;
         }
         for( i = 0; i < pIndex->iTags; i++ )
         {
            pIndex->lpTags[ i ]->HdrChanged = TRUE;
            pIndex->lpTags[ i ]->HeadBlock = 0;
            if( fCompound )
               hb_ntxIndexTagAdd( pIndex, pIndex->lpTags[ i ] );
         }
      }
      pTag = hb_ntxTagNew( pIndex, szTagName, fTagName,
                           szKey, pKeyExp, bType, (USHORT) iLen, (USHORT) iDec,
                           szFor, pForExp,
                           fAscend, pOrderInfo->fUnique, fCustom, NTXAREA_DATA( pArea )->fSortRecNo );
      pTag->Partial = ( pArea->lpdbOrdCondInfo && !pArea->lpdbOrdCondInfo->fAll );

      if( ! pIndex->Compound )
      {
         while( pIndex->iTags )
            hb_ntxTagDelete( pIndex->lpTags[ 0 ] );
         hb_ntxIndexTrunc( pIndex );
         iTag = 0;
      }

      if( iTag )
      {
         pTag->HeadBlock = pIndex->lpTags[ iTag - 1 ]->HeadBlock;
         if( pIndex->lpTags[ iTag - 1 ]->RootBlock &&
             ! hb_ntxTagPagesFree( pIndex->lpTags[ iTag - 1 ],
                                   pIndex->lpTags[ iTag - 1 ]->RootBlock ) )
         {
            errCode = FAILURE;
         }
         else
         {
            hb_ntxTagFree( pIndex->lpTags[ iTag - 1 ] );
            pIndex->lpTags[ iTag - 1 ] = pTag;
         }
      }
      else
      {
         hb_ntxTagAdd( pIndex, pTag );
         if( pIndex->Compound )
            hb_ntxIndexTagAdd( pIndex, pTag );
      }

      if( errCode == SUCCESS )
      {
         pIndex->Update = pIndex->Changed = pTag->HdrChanged = TRUE;
         errCode = hb_ntxTagCreate( pTag, FALSE );
      }
      hb_ntxIndexUnLockWrite( pIndex );
   }

   pIndexPtr = &pArea->lpIndexes;
   while( *pIndexPtr && *pIndexPtr != pIndex )
      pIndexPtr = &(*pIndexPtr)->pNext;

   /* It should not happen, reintrance? */
   if( !*pIndexPtr )
      return FAILURE;

   if( errCode != SUCCESS )
   {
      *pIndexPtr = pIndex->pNext;
      hb_ntxIndexFree( pIndex );
      /* hb_ntxSetTagNumbers() */
      return errCode;
   }

   if( !pArea->lpdbOrdCondInfo || !pArea->lpdbOrdCondInfo->fAdditive )
   {
      *pIndexPtr = pIndex->pNext;
      pIndex->pNext = NULL;
      SELF_ORDLSTCLEAR( ( AREAP ) pArea );
      pIndexPtr = &pArea->lpIndexes;
      while( *pIndexPtr )
         pIndexPtr = &(*pIndexPtr)->pNext;
      *pIndexPtr = pIndex;
   }
   if( pIndex->Production && !pArea->fHasTags &&
       NTXAREA_DATA( pArea )->fStruct &&
       ( NTXAREA_DATA( pArea )->fStrictStruct || hb_setGetAutOpen() ) )
   {
      pArea->fHasTags = TRUE;
      if( !pArea->fReadonly && ( pArea->dbfHeader.bHasTags & 0x01 ) == 0 )
         SELF_WRITEDBHEADER( ( AREAP ) pArea );
   }
   /* hb_ntxSetTagNumbers() */
   pArea->lpCurTag = pTag;
   SELF_ORDSETCOND( ( AREAP ) pArea, NULL );
   return SELF_GOTOP( ( AREAP ) pArea );
}
dbfntx1.c6081
STATIC ERRCODEntxOrderDestroy( NTXAREAP pArea, LPDBORDERINFO pOrderInfo )
static ERRCODE ntxOrderDestroy( NTXAREAP pArea, LPDBORDERINFO pOrderInfo )
{
   ERRCODE errCode;

   HB_TRACE(HB_TR_DEBUG, ("ntxOrderDestroy(%p, %p)", pArea, pOrderInfo));

   errCode = SELF_GOCOLD( ( AREAP ) pArea );
   if( errCode != SUCCESS )
      return errCode;

   if( pArea->lpdbPendingRel )
   {
      errCode = SELF_FORCEREL( ( AREAP ) pArea );
      if( errCode != SUCCESS )
         return errCode;
   }

   if( pOrderInfo->itmOrder )
   {
      LPTAGINFO pTag = hb_ntxFindTag( pArea, pOrderInfo->itmOrder, pOrderInfo->atomBagName );

      if( pTag )
      {
         LPNTXINDEX pIndex = pTag->Owner, *pIndexPtr;

         if( pIndex->iTags == 1 )
         {
            BOOL fProd = pIndex->Production;
            pIndexPtr = &pArea->lpIndexes;
            while( *pIndexPtr != pIndex )
               pIndexPtr = &(*pIndexPtr)->pNext;
            *pIndexPtr = pIndex->pNext;
            pIndex->fDelete = TRUE;
            hb_ntxIndexFree( pIndex );
            if( fProd && pArea->fHasTags &&
                NTXAREA_DATA( pArea )->fStruct &&
                ( NTXAREA_DATA( pArea )->fStrictStruct || hb_setGetAutOpen() ) )
            {
               pArea->fHasTags = FALSE;
               if( !pArea->fReadonly && ( pArea->dbfHeader.bHasTags & 0x01 ) != 0 )
                  SELF_WRITEDBHEADER( ( AREAP ) pArea );
            }
         }
         else if( pIndex->fReadonly )
         {
            hb_ntxErrorRT( pArea, EG_READONLY, EDBF_READONLY, pIndex->IndexName, 0, 0 );
            return FAILURE;
         }
#if 0 /* enable this code if you want to forbid tag deleting in shared mode */
         else if( pIndex->fShared )
         {
            hb_ntxErrorRT( pArea, EG_SHARED, EDBF_SHARED, pIndex->IndexName, 0, 0 );
            return FAILURE;
         }
#endif
         else if( !hb_ntxIndexLockWrite( pIndex, TRUE ) )
         {
            return FAILURE;
         }
         else
         {
            errCode = hb_ntxTagSpaceFree( pTag );
            hb_ntxIndexUnLockWrite( pIndex );
         }
         /* hb_ntxSetTagNumbers() */
      }
   }

   return errCode;
}
dbfntx1.c6496
STATIC ERRCODEntxOrderInfo( NTXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pInfo )
static ERRCODE ntxOrderInfo( NTXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pInfo )
{
   LPTAGINFO pTag;
   HB_TRACE(HB_TR_DEBUG, ("ntxOrderInfo(%p, %hu, %p)", pArea, uiIndex, pInfo));

   switch( uiIndex )
   {
      case DBOI_STRICTREAD:
         hb_itemClear( pInfo->itmResult );
         return SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_STRICTREAD, 0, pInfo->itmResult );
      case DBOI_OPTIMIZE:
         hb_itemClear( pInfo->itmResult );
         return SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_OPTIMIZE, 0, pInfo->itmResult );
      case DBOI_AUTOOPEN:
         hb_itemClear( pInfo->itmResult );
         return SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_AUTOOPEN, 0, pInfo->itmResult );
      case DBOI_AUTOORDER:
         hb_itemClear( pInfo->itmResult );
         return SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_AUTOORDER, 0, pInfo->itmResult );
      case DBOI_AUTOSHARE:
         hb_itemClear( pInfo->itmResult );
         return SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_AUTOSHARE, 0, pInfo->itmResult );
      case DBOI_BAGEXT:
         hb_itemClear( pInfo->itmResult );
         return SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_ORDBAGEXT, 0, pInfo->itmResult );
      case DBOI_EVALSTEP:
         hb_itemPutNL( pInfo->itmResult,
                  pArea->lpdbOrdCondInfo ? pArea->lpdbOrdCondInfo->lStep : 0 );
         return SUCCESS;
      case DBOI_KEYSINCLUDED:
         hb_itemPutNL( pInfo->itmResult,
                       pArea->pSort ? pArea->pSort->ulTotKeys : 0 );
         return SUCCESS;
      case DBOI_I_TAGNAME:
         hb_itemPutC( pInfo->itmResult,
                      pArea->pSort ? pArea->pSort->pTag->TagName : NULL );
         return SUCCESS;
      case DBOI_I_BAGNAME:
         hb_itemPutC( pInfo->itmResult, pArea->pSort ?
                      pArea->pSort->pTag->Owner->IndexName : NULL );
         return SUCCESS;
      case DBOI_ISREINDEX:
         hb_itemPutL( pInfo->itmResult,
                      pArea->pSort ? pArea->pSort->fReindex : FALSE );
         return SUCCESS;
      case DBOI_LOCKOFFSET:
      case DBOI_HPLOCKING:
      {
         HB_FOFFSET ulPos, ulPool;
         hb_dbfLockIdxGetData( pArea->bLockType, &ulPos, &ulPool );
         if( uiIndex == DBOI_LOCKOFFSET )
            hb_itemPutNInt( pInfo->itmResult, ulPos );
         else
            hb_itemPutL( pInfo->itmResult, ulPool > 0 );
         return SUCCESS;
      }
      case DBOI_ORDERCOUNT:
      {
         int i = 0;
         BOOL fBag = hb_itemGetCLen( pInfo->atomBagName ) > 0;
         LPNTXINDEX pIndex = fBag ?
               hb_ntxFindBag( pArea, hb_itemGetCPtr( pInfo->atomBagName ) ) :
               pArea->lpIndexes;
         while( pIndex )
         {
            i += pIndex->iTags;
            if( fBag )
               break;
            pIndex = pIndex->pNext;
         }
         hb_itemPutNI( pInfo->itmResult, i );
         return SUCCESS;
      }
      case DBOI_BAGCOUNT:
      {
         int i = 0;
         LPNTXINDEX pIndex = pArea->lpIndexes;
         while( pIndex )
         {
            ++i;
            pIndex = pIndex->pNext;
         }
         hb_itemPutNI( pInfo->itmResult, i );
         return SUCCESS;
      }
      case DBOI_BAGNUMBER:
      {
         LPNTXINDEX pIndex = pArea->lpIndexes, pIndexSeek = NULL;
         int i = 0;

         if( hb_itemGetCLen( pInfo->atomBagName ) > 0 )
            pIndexSeek = hb_ntxFindBag( pArea,
                                        hb_itemGetCPtr( pInfo->atomBagName ) );
         else if( pArea->lpCurTag )
            pIndexSeek = pArea->lpCurTag->Owner;

         if( pIndexSeek )
         {
            do
            {
               ++i;
               if( pIndex == pIndexSeek )
                  break;
               pIndex = pIndex->pNext;
            }
            while( pIndex );
         }
         hb_itemPutNI( pInfo->itmResult, pIndex ? i : 0 );
         return SUCCESS;
      }
      case DBOI_BAGORDER:
      {
         LPNTXINDEX pIndex = pArea->lpIndexes, pIndexSeek = NULL;
         int i = 0;

         if( hb_itemGetCLen( pInfo->atomBagName ) > 0 )
            pIndexSeek = hb_ntxFindBag( pArea,
                                        hb_itemGetCPtr( pInfo->atomBagName ) );
         else if( pArea->lpCurTag )
            pIndexSeek = pArea->lpCurTag->Owner;

         if( pIndexSeek )
         {
            ++i;
            do
            {
               if( pIndex == pIndexSeek )
                  break;
               i += pIndex->iTags;
               pIndex = pIndex->pNext;
            }
            while( pIndex );
         }
         hb_itemPutNI( pInfo->itmResult, pIndex ? i : 0 );
         return SUCCESS;
      }
   }

   if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE )
      return FAILURE;

   pTag = hb_ntxFindTag( pArea, pInfo->itmOrder, pInfo->atomBagName );

   if( pTag )
   {
      switch( uiIndex )
      {
         case DBOI_CONDITION:
            hb_itemPutC( pInfo->itmResult, pTag->ForExpr ? pTag->ForExpr : NULL );
            if( hb_itemType( pInfo->itmNewVal ) & HB_IT_STRING )
            {
               char * szForExpr = hb_itemGetCPtr( pInfo->itmNewVal );
               if( pTag->ForExpr ?
                   strncmp( pTag->ForExpr, szForExpr, NTX_MAX_EXP ) != 0 :
                   *szForExpr )
               {
                  PHB_ITEM pForItem = NULL;
                  BOOL fOK = *szForExpr == 0;
                  if( !fOK )
                  {
                     if( SELF_COMPILE( ( AREAP ) pArea, ( BYTE *) szForExpr ) == SUCCESS )
                     {
                        pForItem = pArea->valResult;
                        pArea->valResult = NULL;
                        if( SELF_EVALBLOCK( ( AREAP ) pArea, pForItem ) == SUCCESS )
                        {
                           fOK = hb_itemType( pArea->valResult ) == HB_IT_LOGICAL;
                           hb_itemRelease( pArea->valResult );
                           pArea->valResult = NULL;
                        }
                     }
                  }
                  if( fOK && hb_ntxTagLockWrite( pTag ) )
                  {
                     if( pTag->ForExpr )
                        hb_xfree( pTag->ForExpr );
                     if( pTag->pForItem )
                        hb_vmDestroyBlockOrMacro( pTag->pForItem );
                     if( pForItem )
                     {
                        pTag->ForExpr = hb_strndup( szForExpr, NTX_MAX_EXP );
                        pTag->pForItem = pForItem;
                        pForItem = NULL;
                     }
                     else
                     {
                        pTag->ForExpr = NULL;
                        pTag->pForItem = NULL;
                     }
                     pTag->Partial = TRUE;
                     pTag->HdrChanged = TRUE;
                     pTag->Owner->Update = TRUE;
                     hb_ntxTagUnLockWrite( pTag );
                  }
                  if( pForItem )
                     hb_vmDestroyBlockOrMacro( pForItem );
               }
            }
            break;
         case DBOI_EXPRESSION:
            hb_itemPutC( pInfo->itmResult, pTag->KeyExpr );
            break;
         case DBOI_BAGNAME:
            hb_itemPutC( pInfo->itmResult, pTag->Owner->IndexName );
            break;
         case DBOI_NAME:
            hb_itemPutC( pInfo->itmResult, pTag->TagName );
            break;
         case DBOI_NUMBER:
            hb_itemPutNI( pInfo->itmResult, hb_ntxFindTagNum( pArea, pTag ) );
            break;
         case DBOI_FILEHANDLE:
            hb_itemPutNInt( pInfo->itmResult,
                     ( HB_NHANDLE ) hb_fileHandle( pTag->Owner->DiskFile ) );
            break;
         case DBOI_FULLPATH:
            hb_itemPutC( pInfo->itmResult, pTag->Owner->IndexName );
            break;
         case DBOI_KEYCOUNT:
         case DBOI_KEYCOUNTRAW:
            hb_itemPutNL( pInfo->itmResult, hb_ntxOrdKeyCount( pTag ) );
            break;
         case DBOI_POSITION:
         case DBOI_KEYNORAW:
         /* case DBOI_RECNO: */
            if( hb_itemType( pInfo->itmNewVal ) & HB_IT_NUMERIC )
               hb_itemPutL( pInfo->itmResult,
                  hb_ntxOrdKeyGoto( pTag, hb_itemGetNL( pInfo->itmNewVal ) ) );
            else
               hb_itemPutNL( pInfo->itmResult, hb_ntxOrdKeyNo( pTag ) );
            break;
         case DBOI_RELKEYPOS:
            if( hb_itemType( pInfo->itmNewVal ) & HB_IT_NUMERIC )
               hb_ntxOrdSetRelKeyPos( pTag, hb_itemGetND( pInfo->itmNewVal ) );
            else
               hb_itemPutND( pInfo->itmResult, hb_ntxOrdGetRelKeyPos( pTag ) );
            break;
         case DBOI_ISCOND:
            hb_itemPutL( pInfo->itmResult, pTag->ForExpr != NULL );
            break;
         case DBOI_ISDESC:
            hb_itemPutL( pInfo->itmResult, pTag->fUsrDescend );
            if( hb_itemType( pInfo->itmNewVal ) == HB_IT_LOGICAL )
               pTag->fUsrDescend = hb_itemGetL( pInfo->itmNewVal );
            break;
         case DBOI_UNIQUE:
            hb_itemPutL( pInfo->itmResult, pTag->UniqueKey );
            break;
         case DBOI_CUSTOM:
            if( hb_itemType( pInfo->itmNewVal ) == HB_IT_LOGICAL )
            {
               if( hb_ntxTagLockWrite( pTag ) )
               {
                  if( !pTag->Template )
                  {
                     BOOL fNewVal = hb_itemGetL( pInfo->itmNewVal );
                     if( pTag->Custom ? ! fNewVal : fNewVal )
                     {
                        pTag->Custom = fNewVal;
                        pTag->Partial = TRUE;
                        pTag->ChgOnly = FALSE;
                        pTag->HdrChanged = TRUE;
                     }
                  }
                  hb_ntxTagUnLockWrite( pTag );
               }
            }
            hb_itemPutL( pInfo->itmResult, pTag->Custom );
            break;
         case DBOI_CHGONLY:
            if( hb_itemType( pInfo->itmNewVal ) == HB_IT_LOGICAL )
            {
               if( hb_ntxTagLockWrite( pTag ) )
               {
                  if( !pTag->Custom )
                  {
                     BOOL fNewVal = hb_itemGetL( pInfo->itmNewVal );
                     if( pTag->ChgOnly ? ! fNewVal : fNewVal )
                     {
                        pTag->ChgOnly = fNewVal;
                        pTag->Partial = TRUE;
                        pTag->HdrChanged = TRUE;
                     }
                  }
                  hb_ntxTagUnLockWrite( pTag );
               }
            }
            hb_itemPutL( pInfo->itmResult, pTag->ChgOnly );
            break;
         case DBOI_TEMPLATE:
            if( hb_itemType( pInfo->itmNewVal ) == HB_IT_LOGICAL &&
                hb_itemGetL( pInfo->itmNewVal ) )
            {
               if( hb_ntxTagLockWrite( pTag ) )
               {
                  if( pTag->Custom && !pTag->Template )
                  {
                     pTag->Template = TRUE;
                     pTag->HdrChanged = TRUE;
                  }
                  hb_ntxTagUnLockWrite( pTag );
               }
            }
            hb_itemPutL( pInfo->itmResult, pTag->Template );
            break;
         case DBOI_MULTIKEY:
            if( hb_itemGetL( pInfo->itmNewVal ) )
            {
               if( hb_ntxTagLockWrite( pTag ) )
               {
                  if( pTag->Custom && !pTag->MultiKey )
                  {
                     pTag->MultiKey = TRUE;
                     pTag->HdrChanged = TRUE;
                  }
                  hb_ntxTagUnLockWrite( pTag );
               }
            }
            hb_itemPutL( pInfo->itmResult, pTag->MultiKey );
            break;
         case DBOI_PARTIAL:
            hb_itemPutL( pInfo->itmResult, pTag->Partial );
            break;
         case DBOI_SCOPETOP:
            if( pInfo->itmResult )
               hb_ntxTagGetScope( pTag, 0, pInfo->itmResult );
            if( pInfo->itmNewVal )
               hb_ntxTagSetScope( pTag, 0, pInfo->itmNewVal );
            break;
         case DBOI_SCOPEBOTTOM:
            if( pInfo->itmResult )
               hb_ntxTagGetScope( pTag, 1, pInfo->itmResult );
            if( pInfo->itmNewVal )
               hb_ntxTagSetScope( pTag, 1, pInfo->itmNewVal );
            break;
         case DBOI_SCOPESET:
            if( pInfo->itmNewVal )
            {
               hb_ntxTagSetScope( pTag, 0, pInfo->itmNewVal );
               hb_ntxTagSetScope( pTag, 1, pInfo->itmNewVal );
            }
            if( pInfo->itmResult )
               hb_itemClear( pInfo->itmResult );
            break;
         case DBOI_SCOPETOPCLEAR:
            if( pInfo->itmResult )
               hb_ntxTagGetScope( pTag, 0, pInfo->itmResult );
            hb_ntxTagClearScope( pTag, 0 );
            break;
         case DBOI_SCOPEBOTTOMCLEAR:
            if( pInfo->itmResult )
               hb_ntxTagGetScope( pTag, 1, pInfo->itmResult );
            hb_ntxTagClearScope( pTag, 1 );
            break;
         case DBOI_SCOPECLEAR:
            hb_ntxTagClearScope( pTag, 0 );
            hb_ntxTagClearScope( pTag, 1 );
            if( pInfo->itmResult )
               hb_itemClear( pInfo->itmResult );
            break;
         case DBOI_KEYADD:
            if( pTag->Owner->fReadonly )
            {
               hb_ntxErrorRT( pArea, EG_READONLY, EDBF_READONLY, pTag->Owner->IndexName, 0, 0 );
               return FAILURE;
            }
            if( pTag->Custom )
            {
               hb_itemPutL( pInfo->itmResult,
                            hb_ntxOrdKeyAdd( pTag, pInfo->itmNewVal ) );
            }
            else
            {
               hb_ntxErrorRT( pArea, 0, 1052, NULL, 0, 0 );
               return FAILURE;
            }
            break;
         case DBOI_KEYDELETE:
            if( pTag->Owner->fReadonly )
            {
               hb_ntxErrorRT( pArea, EG_READONLY, EDBF_READONLY, pTag->Owner->IndexName, 0, 0 );
               return FAILURE;
            }
            if( pTag->Custom )
            {
               hb_itemPutL( pInfo->itmResult,
                            hb_ntxOrdKeyDel( pTag, pInfo->itmNewVal ) );
            }
            else
            {
               hb_ntxErrorRT( pArea, 0, 1052, NULL, 0, 0 );
               return FAILURE;
            }
            break;
         case DBOI_KEYTYPE:
            {
               char szType[2];
               szType[0] = (char) pTag->KeyType;
               szType[1] = 0;
               hb_itemPutC( pInfo->itmResult, szType );
            }
            break;
         case DBOI_KEYSIZE:
            hb_itemPutNI( pInfo->itmResult, pTag->KeyLength );
            break;
         case DBOI_KEYDEC:
            hb_itemPutNI( pInfo->itmResult, pTag->KeyDec );
            break;
         case DBOI_KEYVAL:
            if( hb_ntxTagLockRead( pTag ) )
            {
               if( hb_ntxCurKeyRefresh( pTag ) )
                  hb_ntxKeyGetItem( pInfo->itmResult, pTag->CurKeyInfo, pTag, TRUE );
               else
                  hb_itemClear( pInfo->itmResult );
               hb_ntxTagUnLockRead( pTag );
            }
            break;
         case DBOI_SKIPUNIQUE:
            hb_itemPutL( pInfo->itmResult, hb_ntxOrdSkipUnique( pTag,
                                          hb_itemGetNL( pInfo->itmNewVal ) ) );
            break;
         case DBOI_SKIPEVAL:
         case DBOI_SKIPEVALBACK:
            hb_itemPutL( pInfo->itmResult, hb_ntxOrdSkipEval( pTag,
                              uiIndex == DBOI_SKIPEVAL, pInfo->itmNewVal ) );
            break;
         case DBOI_SKIPWILD:
         case DBOI_SKIPWILDBACK:
            hb_itemPutL( pInfo->itmResult, hb_ntxOrdSkipWild( pTag,
                              uiIndex == DBOI_SKIPWILD, pInfo->itmNewVal ) );
            break;
         case DBOI_SKIPREGEX:
         case DBOI_SKIPREGEXBACK:
            hb_itemPutL( pInfo->itmResult, hb_ntxOrdSkipRegEx( pTag,
                              uiIndex == DBOI_SKIPREGEX, pInfo->itmNewVal ) );
            break;
         case DBOI_FINDREC:
         case DBOI_FINDRECCONT:
            hb_itemPutL( pInfo->itmResult, hb_ntxOrdFindRec( pTag,
                                             hb_itemGetNL( pInfo->itmNewVal ),
                                             uiIndex == DBOI_FINDRECCONT ) );
            break;
         case DBOI_SCOPEEVAL:
            if( hb_itemType( pInfo->itmNewVal ) == HB_IT_ARRAY &&
                hb_arrayLen( pInfo->itmNewVal ) == DBRMI_SIZE &&
                hb_arrayGetPtr( pInfo->itmNewVal, DBRMI_FUNCTION ) != NULL )
            {
               hb_itemPutNL( pInfo->itmResult, hb_ntxOrdScopeEval( pTag,
                     ( HB_EVALSCOPE_FUNC )
                     hb_arrayGetPtr( pInfo->itmNewVal, DBRMI_FUNCTION ),
                     hb_arrayGetPtr( pInfo->itmNewVal, DBRMI_PARAM ),
                     hb_arrayGetItemPtr( pInfo->itmNewVal, DBRMI_LOVAL ),
                     hb_arrayGetItemPtr( pInfo->itmNewVal, DBRMI_HIVAL ) ) );
            }
            else
            {
               hb_itemPutNI( pInfo->itmResult, 0 );
            }
            break;
         case DBOI_UPDATECOUNTER:
            /* refresh update counter */
            if( hb_ntxIndexLockRead( pTag->Owner ) )
               hb_ntxIndexUnLockRead( pTag->Owner );
            hb_itemPutNInt( pInfo->itmResult, pTag->Owner->Version );
            break;
         case DBOI_READLOCK:
            if( hb_itemType( pInfo->itmNewVal ) == HB_IT_LOGICAL )
            {
               hb_itemPutL( pInfo->itmResult,
                            hb_itemGetL( pInfo->itmNewVal ) ?
                                 hb_ntxIndexLockRead( pTag->Owner ) :
                                 hb_ntxIndexUnLockRead( pTag->Owner ) );
            }
            else
            {
               hb_itemPutL( pInfo->itmResult, pTag->Owner->lockRead > 0 );
            }
            break;
         case DBOI_WRITELOCK:
            if( hb_itemType( pInfo->itmNewVal ) == HB_IT_LOGICAL )
            {
               hb_itemPutL( pInfo->itmResult,
                            hb_itemGetL( pInfo->itmNewVal ) ?
                                 hb_ntxIndexLockWrite( pTag->Owner, TRUE ) :
                                 hb_ntxIndexUnLockWrite( pTag->Owner ) );
            }
            else
            {
               hb_itemPutL( pInfo->itmResult, pTag->Owner->lockWrite > 0 );
            }
            break;
         case DBOI_ISSORTRECNO:
            hb_itemPutL( pInfo->itmResult, pTag->fSortRec );
            break;
         case DBOI_ISMULTITAG:
#if defined( HB_NTX_NOMULTITAG )
            hb_itemPutL( pInfo->itmResult, FALSE );
#else
            hb_itemPutL( pInfo->itmResult, pTag->Owner->Compound );
#endif
            break;
         case DBOI_LARGEFILE:
            hb_itemPutL( pInfo->itmResult, pTag->Owner->LargeFile );
            break;
         case DBOI_SHARED:
            hb_itemPutL( pInfo->itmResult, pTag->Owner->fShared );
            if( hb_itemType( pInfo->itmNewVal ) == HB_IT_LOGICAL )
               pTag->Owner->fShared = hb_itemGetL( pInfo->itmNewVal );
            break;
         case DBOI_ISREADONLY:
            hb_itemPutL( pInfo->itmResult, pTag->Owner->fReadonly );
            break;
         case DBOI_INDEXTYPE:
#if defined( HB_NTX_NOMULTITAG )
            hb_itemPutNI( pInfo->itmResult, DBOI_TYPE_NONCOMPACT );
#else
            hb_itemPutNI( pInfo->itmResult, pTag->Owner->Compound ?
                          DBOI_TYPE_COMPOUND : DBOI_TYPE_NONCOMPACT );
#endif
            break;
      }
   }
   else if( pInfo->itmResult )
   {
      switch( uiIndex )
      {
         case DBOI_KEYCOUNT:
         case DBOI_KEYCOUNTRAW:
         {
            ULONG ulRecCount = 0;
            SELF_RECCOUNT( ( AREAP ) pArea, &ulRecCount );
            hb_itemPutNInt( pInfo->itmResult, ulRecCount );
            break;
         }
         case DBOI_POSITION:
         case DBOI_KEYNORAW:
         /* case DBOI_RECNO: */
            if( pInfo->itmNewVal && hb_itemType( pInfo->itmNewVal ) & HB_IT_NUMERIC )
               hb_itemPutL( pInfo->itmResult, SELF_GOTO( ( AREAP ) pArea,
                              hb_itemGetNL( pInfo->itmNewVal ) ) == SUCCESS );
            else
               SELF_RECID( ( AREAP ) pArea, pInfo->itmResult );
            break;
         case DBOI_RELKEYPOS:
            if( hb_itemType( pInfo->itmNewVal ) & HB_IT_NUMERIC )
            {
               double dPos = hb_itemGetND( pInfo->itmNewVal );
               LPTAGINFO pSavedTag = pArea->lpCurTag;
               pArea->lpCurTag = NULL;
               if( dPos >= 1.0 )
               {
                  SELF_GOBOTTOM( ( AREAP ) pArea );
               }
               else if( dPos <= 0.0 )
               {
                  SELF_GOTOP( ( AREAP ) pArea );
               }
               else
               {
                  ULONG ulRecCount, ulRecNo;
                  SELF_RECCOUNT( ( AREAP ) pArea, &ulRecCount );
                  ulRecNo = ( ULONG ) dPos * ulRecCount + 1;
                  if( ulRecNo >= ulRecCount )
                     ulRecNo = ulRecCount;
                  if( SELF_GOTO( ( AREAP ) pArea, ulRecNo ) == SUCCESS &&
                      SELF_SKIPFILTER( ( AREAP ) pArea, 1 ) == SUCCESS &&
                      pArea->fEof )
                     SELF_GOTOP( ( AREAP ) pArea );
               }
               pArea->lpCurTag = pSavedTag;
            }
            else
            {
               ULONG ulRecNo = 0, ulRecCount = 0;
               double dPos = 0.0;
               /* resolve any pending relations */
               if( SELF_RECNO( ( AREAP ) pArea, &ulRecNo ) == SUCCESS )
               {
                  if( !pArea->fPositioned )
                  {
                     if( ulRecNo > 1 )
                        dPos = 1.0;
                  }
                  else
                  {
                     SELF_RECCOUNT( ( AREAP ) pArea, &ulRecCount );
                     if( ulRecCount != 0 )
                        dPos = ( 0.5 + ulRecNo ) / ulRecCount;
                  }
               }
               hb_itemPutND( pInfo->itmResult, dPos );
            }
            break;
         case DBOI_SKIPUNIQUE:
            hb_itemPutL( pInfo->itmResult, SELF_SKIP( ( AREAP ) pArea,
               hb_itemGetNL( pInfo->itmNewVal ) >= 0 ? 1 : -1 ) == SUCCESS );
            break;
         case DBOI_SKIPEVAL:
         case DBOI_SKIPEVALBACK:
         case DBOI_SKIPWILD:
         case DBOI_SKIPWILDBACK:
         case DBOI_SKIPREGEX:
         case DBOI_SKIPREGEXBACK:
         case DBOI_FINDREC:
         case DBOI_FINDRECCONT:
            SELF_GOTO( ( AREAP ) pArea, 0 );
            hb_itemPutL( pInfo->itmResult, FALSE );
            break;
         case DBOI_ISCOND:
         case DBOI_ISDESC:
         case DBOI_UNIQUE:
         case DBOI_CUSTOM:
         case DBOI_KEYADD:
         case DBOI_KEYDELETE:

         case DBOI_ISSORTRECNO:
         case DBOI_ISMULTITAG:
         case DBOI_LARGEFILE:
         case DBOI_TEMPLATE:
         case DBOI_MULTIKEY:
         case DBOI_PARTIAL:
         case DBOI_CHGONLY:
         case DBOI_SHARED:
         case DBOI_ISREADONLY:
         case DBOI_WRITELOCK:
         case DBOI_READLOCK:
            hb_itemPutL( pInfo->itmResult, FALSE );
            break;
         case DBOI_KEYVAL:
         case DBOI_SCOPETOP:
         case DBOI_SCOPEBOTTOM:
         case DBOI_SCOPESET:
         case DBOI_SCOPETOPCLEAR:
         case DBOI_SCOPEBOTTOMCLEAR:
         case DBOI_SCOPECLEAR:
            hb_itemClear( pInfo->itmResult );
            break;
         case DBOI_KEYSIZE:
         case DBOI_KEYDEC:
         case DBOI_NUMBER:
         case DBOI_ORDERCOUNT:
         case DBOI_SCOPEEVAL:
         case DBOI_UPDATECOUNTER:
            hb_itemPutNI( pInfo->itmResult, 0 );
            break;
         case DBOI_FILEHANDLE:
            hb_itemPutNInt( pInfo->itmResult, ( HB_NHANDLE ) FS_ERROR );
            break;
         case DBOI_INDEXTYPE:
            hb_itemPutNI( pInfo->itmResult, DBOI_TYPE_UNDEF );
            break;
         case DBOI_BAGNAME:
         case DBOI_CONDITION:
         case DBOI_EXPRESSION:
         case DBOI_FULLPATH:
         case DBOI_NAME:
         case DBOI_KEYTYPE:
            hb_itemPutC( pInfo->itmResult, NULL );
            break;
         default:
            hb_itemClear( pInfo->itmResult );
      }
   }
   return SUCCESS;
}
dbfntx1.c6567
STATIC ERRCODEntxCountScope( NTXAREAP pArea, void * pPtr, LONG * plRecNo )
static ERRCODE ntxCountScope( NTXAREAP pArea, void * pPtr, LONG * plRecNo )
{
   HB_TRACE(HB_TR_DEBUG, ("ntxCountScope(%p, %p, %p)", pArea, pPtr, plRecNo));

   if ( pPtr == NULL )
   {
      return SUCCESS;
   }
   return SUPER_COUNTSCOPE( ( AREAP ) pArea, pPtr, plRecNo );
}
dbfntx1.c7234
STATIC ERRCODEntxOrderListAdd( NTXAREAP pArea, LPDBORDERINFO pOrderInfo )
static ERRCODE ntxOrderListAdd( NTXAREAP pArea, LPDBORDERINFO pOrderInfo )
{
   USHORT uiFlags;
   PHB_FILE pFile;
   char szFileName[ _POSIX_PATH_MAX + 1 ], szTagName[ NTX_MAX_TAGNAME + 1 ];
   LPNTXINDEX pIndex, *pIndexPtr;
   ERRCODE errCode;
   BOOL fRetry, fReadonly, fShared, fProd;

   HB_TRACE(HB_TR_DEBUG, ("ntxOrderListAdd(%p, %p)", pArea, pOrderInfo));

   errCode = SELF_GOCOLD( ( AREAP ) pArea );
   if( errCode != SUCCESS )
      return errCode;

   if( hb_itemGetCLen( pOrderInfo->atomBagName ) == 0 )
      return FAILURE;

   hb_ntxCreateFName( pArea, hb_itemGetCPtr( pOrderInfo->atomBagName ),
                      &fProd, szFileName, szTagName );

/*
   if( ! szTagName[0] )
      return FAILURE;
*/

   pIndex = hb_ntxFindBag( pArea, szFileName );

   if( ! pIndex )
   {
      fReadonly = pArea->fReadonly;
      fShared = pArea->fShared;
      uiFlags = ( fReadonly ? FO_READ : FO_READWRITE ) |
                ( fShared ? FO_DENYNONE : FO_EXCLUSIVE );
      do
      {
         fRetry = FALSE;
         pFile = hb_fileExtOpen( ( BYTE * ) szFileName, NULL, uiFlags |
                                 FXO_DEFAULTS | FXO_SHARELOCK | FXO_COPYNAME,
                                 NULL, NULL );
         if( !pFile )
         {
            fRetry = ( hb_ntxErrorRT( pArea, EG_OPEN, EDBF_OPEN_INDEX, szFileName,
                     hb_fsError(), EF_CANRETRY | EF_CANDEFAULT ) == E_RETRY );
         }
      }
      while( fRetry );

      if( !pFile )
         return FAILURE;

      pIndex = hb_ntxIndexNew( pArea );
      pIndex->IndexName = hb_strdup( szFileName );
      pIndex->fReadonly = fReadonly;
      pIndex->fShared = fShared;
      pIndex->DiskFile = pFile;
      pIndex->Production = fProd;

      pIndexPtr = &pArea->lpIndexes;
      while( *pIndexPtr )
         pIndexPtr = &(*pIndexPtr)->pNext;
      *pIndexPtr = pIndex;

      if( hb_ntxIndexLockRead( pIndex ) )
      {
         errCode = hb_ntxIndexLoad( pIndex, szTagName );
         hb_ntxIndexUnLockRead( pIndex );
      }
      else
         errCode = FAILURE;

      if( errCode != SUCCESS )
      {
         *pIndexPtr = pIndex->pNext;
         hb_ntxIndexFree( pIndex );
         hb_ntxErrorRT( pArea, EG_CORRUPTION, EDBF_CORRUPT, szFileName, 0, 0 );
         return errCode;
      }
      /* hb_ntxSetTagNumbers() */
   }

   if( !pArea->lpCurTag && pIndex->iTags )
   {
      pArea->lpCurTag = pIndex->lpTags[0];
      errCode = SELF_GOTOP( ( AREAP ) pArea );
   }
   return errCode;
}
dbfntx1.c7245
STATIC ERRCODEntxOrderListClear( NTXAREAP pArea )
static ERRCODE ntxOrderListClear( NTXAREAP pArea )
{
   LPNTXINDEX *pIndexPtr, pIndex;

   HB_TRACE(HB_TR_DEBUG, ("ntxOrderListClear(%p)", pArea));

   if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE )
      return FAILURE;

   pArea->lpCurTag = NULL;
   pIndexPtr = &pArea->lpIndexes;
   while( *pIndexPtr )
   {
      pIndex = *pIndexPtr;
      if( NTXAREA_DATA( pArea )->fStruct && pIndex->Production &&
          ( NTXAREA_DATA( pArea )->fStrictStruct ? pArea->fHasTags :
                                                   hb_setGetAutOpen() ) )
      {
         pIndexPtr = &pIndex->pNext;
      }
      else
      {
         *pIndexPtr = pIndex->pNext;
         hb_ntxIndexFree( pIndex );
      }
   }
   /* hb_ntxSetTagNumbers() */
   return SUCCESS;
}
dbfntx1.c7334
STATIC ERRCODEntxOrderListDelete( NTXAREAP pArea, LPDBORDERINFO pOrderInfo )
static ERRCODE ntxOrderListDelete( NTXAREAP pArea, LPDBORDERINFO pOrderInfo )
{
   char szTagName[ NTX_MAX_TAGNAME + 1 ];
   char szFileName[ _POSIX_PATH_MAX + 1 ];
   LPNTXINDEX pIndex, * pIndexPtr;
   BOOL fProd;

   HB_TRACE(HB_TR_DEBUG, ("ntxOrderListDelete(%p, %p)", pArea, pOrderInfo));

   if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE )
      return FAILURE;

   hb_ntxCreateFName( pArea, hb_itemGetCPtr( pOrderInfo->atomBagName ), &fProd,
                      szFileName, szTagName );
   pIndex = hb_ntxFindBag( pArea, szFileName );

   if( pIndex && !( pIndex->Production && NTXAREA_DATA( pArea )->fStruct &&
                    ( NTXAREA_DATA( pArea )->fStrictStruct ?
                      pArea->fHasTags : hb_setGetAutOpen() ) ) )
   {
      pIndexPtr = &pArea->lpIndexes;
      while( *pIndexPtr )
      {
         if( pIndex == *pIndexPtr )
         {
            *pIndexPtr = pIndex->pNext;
            hb_ntxIndexFree( pIndex );
            /* hb_ntxSetTagNumbers() */
            break;
         }
         pIndexPtr = &(*pIndexPtr)->pNext;
      }
   }
   return SUCCESS;
}
dbfntx1.c7364
STATIC ERRCODEntxOrderListFocus( NTXAREAP pArea, LPDBORDERINFO pOrderInfo )
static ERRCODE ntxOrderListFocus( NTXAREAP pArea, LPDBORDERINFO pOrderInfo )
{
   HB_TRACE(HB_TR_DEBUG, ("ntxOrderListFocus(%p, %p)", pArea, pOrderInfo));

   pOrderInfo->itmResult = hb_itemPutC( pOrderInfo->itmResult,
                             pArea->lpCurTag ? pArea->lpCurTag->TagName : NULL );

   if( pOrderInfo->itmOrder )
   {
      /*
       * In Clipper tag is not changed when bad name is given in DBFNTX
       * but not in DBFCDX. I'd like to keep the same behavior in
       * [x]Harbour RDDs and I chosen DBFCDX one as default. [druzus]
       */
#ifdef HB_C52_STRICT
      LPTAGINFO pTag = hb_ntxFindTag( pArea, pOrderInfo->itmOrder,
                                      pOrderInfo->atomBagName );
      if( pTag )
         pArea->lpCurTag = pTag;
#else
      pArea->lpCurTag = hb_ntxFindTag( pArea, pOrderInfo->itmOrder,
                                       pOrderInfo->atomBagName );
#endif
   }

   return SUCCESS;
}
dbfntx1.c7400
STATIC ERRCODEntxOrderListRebuild( NTXAREAP pArea )
static ERRCODE ntxOrderListRebuild( NTXAREAP pArea )
{
   LPTAGINFO pCurrTag;
   LPNTXINDEX pIndex;
   ERRCODE errCode;

   HB_TRACE(HB_TR_DEBUG, ("ntxOrderListRebuild(%p)", pArea));

   errCode = SELF_GOCOLD( ( AREAP ) pArea );
   if( errCode != SUCCESS )
      return errCode;

   if( pArea->fShared )
   {
      hb_ntxErrorRT( pArea, EG_SHARED, EDBF_SHARED, pArea->szDataFileName, 0, 0 );
      return FAILURE;
   }
   if( pArea->fReadonly )
   {
      hb_ntxErrorRT( pArea, EG_READONLY, EDBF_READONLY, pArea->szDataFileName, 0, 0 );
      return FAILURE;
   }

   if( pArea->lpdbPendingRel )
   {
      errCode = SELF_FORCEREL( ( AREAP ) pArea );
      if( errCode != SUCCESS )
         return errCode;
   }
   pCurrTag = pArea->lpCurTag;
   pArea->lpCurTag = NULL;
   pIndex = pArea->lpIndexes;
   while( pIndex && errCode == SUCCESS )
   {
      errCode = hb_ntxReIndex( pIndex );
      pIndex = pIndex->pNext;
   }
   if( errCode == SUCCESS )
   {
      pArea->lpCurTag = pCurrTag;
      errCode = SELF_GOTOP( ( AREAP ) pArea );
   }
   return errCode;
}
dbfntx1.c7428
STATIC ERRCODEntxInit( LPRDDNODE pRDD )
static ERRCODE ntxInit( LPRDDNODE pRDD )
{
   ERRCODE errCode;

   HB_TRACE(HB_TR_DEBUG, ("ntxInit(%p)", pRDD));

   errCode = SUPER_INIT( pRDD );
#if !defined( HB_NTX_NOMULTITAG )
   if( errCode == SUCCESS )
      NTXNODE_DATA( pRDD )->fMultiTag = TRUE;
#endif
      
   return errCode;
}
dbfntx1.c7473
STATIC ERRCODEntxRddInfo( LPRDDNODE pRDD, USHORT uiIndex, ULONG ulConnect, PHB_ITEM pItem )
static ERRCODE ntxRddInfo( LPRDDNODE pRDD, USHORT uiIndex, ULONG ulConnect, PHB_ITEM pItem )
{
   LPDBFDATA pData;

   HB_TRACE(HB_TR_DEBUG, ("ntxRddInfo(%p, %hu, %lu, %p)", pRDD, uiIndex, ulConnect, pItem));

   pData = NTXNODE_DATA( pRDD );

   switch( uiIndex )
   {
      case RDDI_ORDBAGEXT:
      case RDDI_ORDEREXT:
      case RDDI_ORDSTRUCTEXT:
      {
         char * szNew = hb_itemGetCPtr( pItem );

         if( szNew[0] == '.' && szNew[1] )
            szNew = hb_strdup( szNew );
         else
            szNew = NULL;

         hb_itemPutC( pItem, pData->szIndexExt[ 0 ] ? pData->szIndexExt : NTX_INDEXEXT );
         if( szNew )
         {
            hb_strncpy( pData->szIndexExt, szNew, sizeof( pData->szIndexExt ) - 1 );
            hb_xfree( szNew );
         }
         break;
      }

      case RDDI_MULTITAG:
      {
#if defined( HB_NTX_NOMULTITAG )
         hb_itemPutL( pItem, FALSE );
#else
         BOOL fMultiTag = pData->fMultiTag;
         if( hb_itemType( pItem ) == HB_IT_LOGICAL )
            pData->fMultiTag = hb_itemGetL( pItem );
         hb_itemPutL( pItem, fMultiTag );
#endif
         break;
      }

      case RDDI_SORTRECNO:
      {
         BOOL fSortRecNo = pData->fSortRecNo;
         if( hb_itemType( pItem ) == HB_IT_LOGICAL )
            pData->fSortRecNo = hb_itemGetL( pItem );
         hb_itemPutL( pItem, fSortRecNo );
         break;
      }

      case RDDI_STRUCTORD:
      {
         BOOL fStruct = pData->fStruct;
         if( hb_itemType( pItem ) == HB_IT_LOGICAL )
            pData->fStruct = hb_itemGetL( pItem );
         hb_itemPutL( pItem, fStruct );
         break;
      }

      case RDDI_STRICTSTRUCT:
      {
         BOOL fStrictStruct = pData->fStrictStruct;
         if( hb_itemType( pItem ) == HB_IT_LOGICAL )
            pData->fStrictStruct = hb_itemGetL( pItem );
         hb_itemPutL( pItem, fStrictStruct );
         break;
      }

      case RDDI_MULTIKEY:
      {
         BOOL fMultiKey = pData->fMultiKey;
         if( hb_itemType( pItem ) == HB_IT_LOGICAL )
            pData->fMultiKey = hb_itemGetL( pItem );
         hb_itemPutL( pItem, fMultiKey );
         break;
      }


      default:
         return SUPER_RDDINFO( pRDD, uiIndex, ulConnect, pItem );

   }

   return SUCCESS;
}

static const RDDFUNCS ntxTable = {
                             ntxBof,
                             ntxEof,
                             ntxFound,
                             ( DBENTRYP_V ) ntxGoBottom,
                             ntxGoTo,
                             ntxGoToId,
                             ( DBENTRYP_V ) ntxGoTop,
                             ( DBENTRYP_BIB ) ntxSeek,
                             ntxSkip,
                             ntxSkipFilter,
                             ( DBENTRYP_L ) ntxSkipRaw,
                             ntxAddField,
                             ( DBENTRYP_B ) ntxAppend,
                             ntxCreateFields,
                             ntxDeleteRec,
                             ntxDeleted,
                             ntxFieldCount,
                             ntxFieldDisplay,
                             ntxFieldInfo,
                             ntxFieldName,
                             ( DBENTRYP_V ) ntxFlush,
                             ntxGetRec,
                             ntxGetValue,
                             ntxGetVarLen,
                             ( DBENTRYP_V ) ntxGoCold,
                             ( DBENTRYP_V ) ntxGoHot,
                             ntxPutRec,
                             ntxPutValue,
                             ntxRecall,
                             ntxRecCount,
                             ntxRecInfo,
                             ntxRecNo,
                             ntxRecId,
                             ntxSetFieldsExtent,
                             ntxAlias,
                             ( DBENTRYP_V ) ntxClose,
                             ntxCreate,
                             ntxInfo,
                             ntxNewArea,
                             ( DBENTRYP_VP ) ntxOpen,
                             ntxRelease,
                             ( DBENTRYP_SP ) ntxStructSize,
                             ntxSysName,
                             ntxEval,
                             ( DBENTRYP_V ) ntxPack,
                             ntPackRec,
                             ntxSort,
                             ntxTrans,
                             ntxTransRec,
                             ( DBENTRYP_V ) ntxZap,
                             ntxchildEnd,
                             ntxchildStart,
                             ntxchildSync,
                             ntxsyncChildren,
                             ntxclearRel,
                             ntxforceRel,
                             ntxrelArea,
                             ntxrelEval,
                             ntxrelText,
                             ntxsetRel,
                             ( DBENTRYP_OI ) ntxOrderListAdd,
                             ( DBENTRYP_V ) ntxOrderListClear,
                             ( DBENTRYP_OI ) ntxOrderListDelete,
                             ( DBENTRYP_OI ) ntxOrderListFocus,
                             ( DBENTRYP_V ) ntxOrderListRebuild,
                             ntxOrderCondition,
                             ( DBENTRYP_VOC ) ntxOrderCreate,
                             ( DBENTRYP_OI ) ntxOrderDestroy,
                             ( DBENTRYP_OII ) ntxOrderInfo,
                             ntxClearFilter,
                             ntxClearLocate,
                             ntxClearScope,
                             ( DBENTRYP_VPLP ) ntxCountScope,
                             ntxFilterText,
                             ntxScopeInfo,
                             ntxSetFilter,
                             ntxSetLocate,
                             ntxSetScope,
                             ntxSkipScope,
                             ntxLocate,
                             ntxCompile,
                             ntxError,
                             ntxEvalBlock,
                             ntxRawLock,
                             ntxLock,
                             ntxUnLock,
                             ntxCloseMemFile,
                             ntxCreateMemFile,
                             ntxGetValueFile,
                             ntxOpenMemFile,
                             ntxPutValueFile,
                             ntxReadDBHeader,
                             ntxWriteDBHeader,
                             ntxInit,
                             ntxExit,
                             ntxDrop,
                             ntxExists,
                             ( DBENTRYP_RSLV ) ntxRddInfo,
                             ntxWhoCares
                           };

HB_FUNC( DBFNTX ) {;}
dbfntx1.c7488
}HB_FUNC( DBFNTX_GETFUNCTABLE )
HB_FUNC( DBFNTX_GETFUNCTABLE )
{
   RDDFUNCS * pTable;
   USHORT * uiCount, uiRddId;

   uiCount = ( USHORT * ) hb_parptr( 1 );
   pTable = ( RDDFUNCS * ) hb_parptr( 2 );
   uiRddId = hb_parni( 4 );

   if( pTable )
   {
      ERRCODE errCode;

      if( uiCount )
         * uiCount = RDDFUNCSCOUNT;
      errCode = hb_rddInherit( pTable, &ntxTable, &ntxSuper, "DBFFPT" );
      if( errCode != SUCCESS )
         errCode = hb_rddInherit( pTable, &ntxTable, &ntxSuper, "DBFDBT" );
      if( errCode != SUCCESS )
         errCode = hb_rddInherit( pTable, &ntxTable, &ntxSuper, "DBF" );
      if( errCode == SUCCESS )
      {
         /*
          * we successfully register our RDD so now we can initialize it
          * You may think that this place is RDD init statement, Druzus
          */
         s_uiRddId = uiRddId;
      }
      hb_retni( errCode );
   }
   else
   {
      hb_retni( FAILURE );
   }
}


#define __PRG_SOURCE__ __FILE__

#ifdef HB_PCODE_VER
#  undef HB_PRG_PCODE_VER
#  define HB_PRG_PCODE_VER HB_PCODE_VER
#endif

HB_FUNC_EXTERN( _DBF );
dbfntx1.c7680
STATIC VOIDhb_dbfntxRddInit( void * cargo )
static void hb_dbfntxRddInit( void * cargo )
{
   HB_SYMBOL_UNUSED( cargo );

   if( hb_rddRegister( "DBF",    RDT_FULL ) <= 1 )
   {
      USHORT usResult;

      hb_rddRegister( "DBFFPT", RDT_FULL );
      usResult = hb_rddRegister( "DBFNTX", RDT_FULL );
      if( usResult <= 1 )
      {
         if( usResult == 0 )
         {
            PHB_ITEM pItem = hb_itemPutNI( NULL, DB_MEMO_DBT );
            SELF_RDDINFO( hb_rddGetNode( s_uiRddId ), RDDI_MEMOTYPE, 0, pItem );
            hb_itemRelease( pItem );
         }
         return;
      }
   }

   hb_errInternal( HB_EI_RDDINVALID, NULL, NULL, NULL );

   /* not executed, only to force DBF RDD linking */
   HB_FUNC_EXEC( _DBF );
}
dbfntx1.c7726
HB_INIT_SYMBOLS_BEGIN(dbfntx1__InitSymbols )
HB_INIT_SYMBOLS_BEGIN( dbfntx1__InitSymbols )
{ "DBFNTX",              {HB_FS_PUBLIC|HB_FS_LOCAL}, {HB_FUNCNAME( DBFNTX )}, NULL },
{ "DBFNTX_GETFUNCTABLE", {HB_FS_PUBLIC|HB_FS_LOCAL}, {HB_FUNCNAME( DBFNTX_GETFUNCTABLE )}, NULL }
HB_INIT_SYMBOLS_END( dbfntx1__InitSymbols )

HB_CALL_ON_STARTUP_BEGIN( _hb_dbfntx_rdd_init_ )
   hb_vmAtInit( hb_dbfntxRddInit, NULL );
HB_CALL_ON_STARTUP_END( _hb_dbfntx_rdd_init_ )

#if defined( HB_PRAGMA_STARTUP )
   #pragma startup dbfntx1__InitSymbols
   #pragma startup _hb_dbfntx_rdd_init_
#elif defined( HB_MSC_STARTUP )
   #if defined( HB_OS_WIN_64 )
      #pragma section( HB_MSC_START_SEGMENT, long, read )
   #endif
   #pragma data_seg( HB_MSC_START_SEGMENT )
   static HB_$INITSYM hb_vm_auto_dbfntx1__InitSymbols = dbfntx1__InitSymbols;
   static HB_$INITSYM hb_vm_auto_dbfntx_rdd_init = _hb_dbfntx_rdd_init_;
dbfntx1.c7754

Page url: http://www.yourdomain.com/help/index.html?dbfntx.htm