campo-sirio/cb/source/i4positi.c

306 lines
6.2 KiB
C
Raw Normal View History

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