306 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			306 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* i4positi.c   (c)Copyright Sequiter Software Inc., 1988-1996.  All rights reserved. */
 | 
						|
 | 
						|
#include "d4all.h"
 | 
						|
#ifndef S4UNIX
 | 
						|
   #ifdef __TURBOC__
 | 
						|
      #pragma hdrstop
 | 
						|
   #endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef S4CLIENT
 | 
						|
#ifndef S4INDEX_OFF
 | 
						|
 | 
						|
/* 'pos' is an percentage, positioning is approximate. */
 | 
						|
int tfile4position2( TAG4FILE *t4, double *result )
 | 
						|
{
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( t4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E91642 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( t4->codeBase ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   *result = tfile4position( t4 ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
#ifndef N4OTHER
 | 
						|
 | 
						|
double tfile4positionDbl( TAG4FILE *t4 )
 | 
						|
{
 | 
						|
   double pos ;
 | 
						|
   B4BLOCK *blockOn ;
 | 
						|
   int n, min, max ;
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( t4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E91642 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( t4->codeBase ) < 0 )
 | 
						|
      return (double)e4codeBase ;
 | 
						|
 | 
						|
   pos = .5 ;
 | 
						|
   min = max = 1 ;    /* is the position a minimal or maximal position? */
 | 
						|
   for ( blockOn = (B4BLOCK *)t4->blocks.lastNode ; blockOn != 0 ; )
 | 
						|
   {
 | 
						|
      #ifdef S4FOX
 | 
						|
         n = blockOn->header.nKeys ;
 | 
						|
      #else
 | 
						|
         n = blockOn->nKeys + 1 ;
 | 
						|
         if ( b4leaf( blockOn ) )
 | 
						|
            n-- ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      if( n == 0 )
 | 
						|
         max = 0 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         if ( min == 1 )
 | 
						|
            if ( blockOn->keyOn != 0 )
 | 
						|
               min = 0 ;
 | 
						|
         if ( max == 1 )
 | 
						|
            if ( blockOn->keyOn != ( n - 1 ) )
 | 
						|
               max = 0 ;
 | 
						|
         pos = ( blockOn->keyOn + pos ) / n ;
 | 
						|
      }
 | 
						|
 | 
						|
      blockOn = (B4BLOCK *)blockOn->link.p ;
 | 
						|
      if ( blockOn == (B4BLOCK *)t4->blocks.lastNode )
 | 
						|
         break ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( max == 1 )
 | 
						|
      pos = 1.0 ;
 | 
						|
   if ( min == 1 )
 | 
						|
      pos = 0.0 ;
 | 
						|
 | 
						|
   #ifdef S4FOX
 | 
						|
      if ( t4->header.descending )   /* backwards in file... */
 | 
						|
         return 1.0 - pos ;
 | 
						|
      else
 | 
						|
   #endif
 | 
						|
   return pos ;
 | 
						|
}
 | 
						|
 | 
						|
double tfile4position( TAG4FILE *t4 )
 | 
						|
{
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( t4 == 0 )
 | 
						|
         return (double)error4( 0, e4parm_null, E91642 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( t4->codeBase ) < 0 )
 | 
						|
      return (double)e4codeBase ;
 | 
						|
 | 
						|
   return tfile4positionDbl( t4 ) ;
 | 
						|
}
 | 
						|
 | 
						|
int tfile4positionSet( TAG4FILE *t4, const double ipos )
 | 
						|
{
 | 
						|
   int rc, n, finalPos ;
 | 
						|
   B4BLOCK *blockOn ;
 | 
						|
   double pos ;
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( t4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E91642 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( t4->codeBase ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   #ifndef S4SINGLE
 | 
						|
      index4versionCheck( t4->indexFile, 0 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4FOX
 | 
						|
      if ( t4->header.descending )   /* backwards in file... */
 | 
						|
         pos = 1.0 - ipos ;
 | 
						|
      else
 | 
						|
   #endif
 | 
						|
      pos = ipos ;
 | 
						|
 | 
						|
   if ( tfile4upToRoot( t4 ) < 0 )
 | 
						|
      return -1 ;
 | 
						|
 | 
						|
   for(;;)
 | 
						|
   {
 | 
						|
      #ifdef E4PARM_LOW
 | 
						|
         if ( pos < 0.0 || pos > 1.0 )  /* Could be caused by rounding error ? */
 | 
						|
            return error4( t4->codeBase, e4parm, E81604 ) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      blockOn = tfile4block( t4 ) ;
 | 
						|
 | 
						|
      #ifdef S4FOX
 | 
						|
         n = blockOn->header.nKeys ;
 | 
						|
      #else
 | 
						|
         n = blockOn->nKeys+1 ;
 | 
						|
         if ( b4leaf( blockOn ) )
 | 
						|
            n-- ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      finalPos = (int)( n * pos ) ;
 | 
						|
      if ( finalPos == n )
 | 
						|
         finalPos-- ;
 | 
						|
 | 
						|
      #ifdef S4FOX
 | 
						|
         b4go( blockOn, (long)finalPos ) ;
 | 
						|
      #else
 | 
						|
         blockOn->keyOn = finalPos ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      pos = pos*n - finalPos ;
 | 
						|
 | 
						|
      rc = tfile4down( t4 ) ;
 | 
						|
      if ( rc < 0 )
 | 
						|
         return -1 ;
 | 
						|
      if ( rc == 1 )
 | 
						|
         return 0 ;
 | 
						|
   }
 | 
						|
}
 | 
						|
 | 
						|
#endif   /*  ifndef N4OTHER  */
 | 
						|
 | 
						|
#ifdef N4OTHER
 | 
						|
 | 
						|
double tfile4positionDbl( TAG4FILE *t4 )
 | 
						|
{
 | 
						|
   return tfile4position( t4 ) ;
 | 
						|
}
 | 
						|
 | 
						|
double tfile4position( TAG4FILE *t4 )
 | 
						|
{
 | 
						|
   double pos ;
 | 
						|
   B4BLOCK *blockOn ;
 | 
						|
   int n, min, max ;
 | 
						|
   #ifdef S4CLIPPER
 | 
						|
      int first = 1 ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( t4 == 0 )
 | 
						|
         return (double)error4( 0, e4parm_null, E91642 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( t4->codeBase ) < 0 )
 | 
						|
      return (double)e4codeBase ;
 | 
						|
 | 
						|
   blockOn = (B4BLOCK *) t4->blocks.lastNode ;
 | 
						|
 | 
						|
   if ( !b4leaf(blockOn) )
 | 
						|
      pos = 1.0 ;
 | 
						|
   else
 | 
						|
      pos = .5 ;
 | 
						|
 | 
						|
   min = max = 1 ;    /* is the position a minimal or maximal position? */
 | 
						|
 | 
						|
   for ( ; blockOn != 0 ; )
 | 
						|
   {
 | 
						|
      n = blockOn->nKeys + 1 ;
 | 
						|
      #ifdef S4CLIPPER
 | 
						|
         if ( first )
 | 
						|
         {
 | 
						|
            if ( b4leaf( blockOn ) )
 | 
						|
               n-- ;
 | 
						|
            else /* if on a branch block, cannot be at min or max position */
 | 
						|
            {
 | 
						|
               min = 0 ;
 | 
						|
               max = 0 ;
 | 
						|
            }
 | 
						|
            first = 0 ;
 | 
						|
         }
 | 
						|
      #else
 | 
						|
         if ( b4leaf( blockOn ) )
 | 
						|
            n-- ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      if( n == 0 )
 | 
						|
         max = 0 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         if ( min == 1 )
 | 
						|
            if ( blockOn->keyOn != 0 )
 | 
						|
               min = 0 ;
 | 
						|
         if ( max == 1 )
 | 
						|
            if ( blockOn->keyOn != ( n - 1 ) )
 | 
						|
               max = 0 ;
 | 
						|
         pos = ( blockOn->keyOn + pos ) / n ;
 | 
						|
      }
 | 
						|
 | 
						|
      blockOn = (B4BLOCK *) blockOn->link.p ;
 | 
						|
      if ( blockOn == (B4BLOCK *)t4->blocks.lastNode )
 | 
						|
         break ;
 | 
						|
   }
 | 
						|
   if ( max == 1 )
 | 
						|
      pos = 1.0 ;
 | 
						|
   if ( min == 1 )
 | 
						|
      pos = 0.0 ;
 | 
						|
 | 
						|
   #ifdef S4CLIPPER
 | 
						|
      if ( t4->header.descending )   /* backwards in file... */
 | 
						|
         return 1.0 - pos ;
 | 
						|
      else
 | 
						|
   #endif
 | 
						|
   return pos ;
 | 
						|
}
 | 
						|
 | 
						|
int tfile4positionSet( TAG4FILE *t4, const double posIn )
 | 
						|
{
 | 
						|
   int rc, n, finalPos ;
 | 
						|
   B4BLOCK *blockOn ;
 | 
						|
   double pos ;
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( t4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E91642 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( t4->codeBase ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   #ifdef S4CLIPPER
 | 
						|
      if ( t4->header.descending )   /* backwards in file... */
 | 
						|
         pos = 1.0 - posIn ;
 | 
						|
      else
 | 
						|
   #endif
 | 
						|
   pos = posIn ;
 | 
						|
 | 
						|
   rc = tfile4upToRoot( t4 ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
      return error4stack( t4->codeBase, rc, E91642 ) ;
 | 
						|
 | 
						|
   for(;;)
 | 
						|
   {
 | 
						|
      #ifdef E4PARM_LOW
 | 
						|
         if ( pos < 0.0 || pos > 1.0 )  /* Could be caused by rounding error ? */
 | 
						|
            return error4( 0, e4parm_null, E81604 ) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      blockOn = tfile4block( t4 ) ;
 | 
						|
 | 
						|
      n = blockOn->nKeys + 1 ;
 | 
						|
      if ( b4leaf( blockOn ) )
 | 
						|
         n-- ;
 | 
						|
 | 
						|
      finalPos = (int)( n * pos ) ;
 | 
						|
      if ( finalPos == n )
 | 
						|
         finalPos-- ;
 | 
						|
 | 
						|
      blockOn->keyOn = finalPos ;
 | 
						|
      pos = pos*n - finalPos ;
 | 
						|
 | 
						|
      rc = tfile4down( t4 ) ;
 | 
						|
      if ( rc < 0 )
 | 
						|
         return -1 ;
 | 
						|
      if ( rc == 1 )
 | 
						|
         return 0 ;
 | 
						|
   }
 | 
						|
}
 | 
						|
 | 
						|
#endif  /* N4OTHER */
 | 
						|
#endif  /* S4INDEX_OFF */
 | 
						|
#endif  /* S4CLIENT */
 |