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 */
|