campo-sirio/cb5/i4positi.c
alex a0f5e0898b This commit was generated by cvs2svn to compensate for changes in r975,
which included commits to RCS files with non-trunk default branches.

git-svn-id: svn://10.65.10.50/trunk@976 c028cbd2-c16b-5b4b-a496-9718f37d4682
1995-02-06 15:33:45 +00:00

278 lines
4.9 KiB
C
Executable File

/* i4positi.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved. */
#include "d4all.h"
#ifndef S4UNIX
#ifdef __TURBOC__
#pragma hdrstop
#endif
#endif
#ifndef S4INDEX_OFF
/* 'pos' is an percentage, positioning is approximate. */
int S4FUNCTION t4position2( TAG4 *t4, double *result )
{
#ifdef S4DEBUG
if ( t4 == 0 )
e4severe( e4parm, E4_T4POSITION2 ) ;
#endif
if ( t4->code_base->error_code < 0 )
return -1 ;
*result = t4position( t4 );
return 0;
}
#ifndef N4OTHER
double S4FUNCTION t4positionDbl( TAG4 *t4 )
{
double pos ;
B4BLOCK *block_on ;
int n ;
#ifdef S4DEBUG
if ( t4 == 0 )
e4severe( e4parm, E4_T4POSITION ) ;
#endif
if ( t4->code_base->error_code < 0 )
return -1 ;
pos = .5 ;
for ( block_on = (B4BLOCK *)t4->blocks.last_node ; block_on != 0 ; )
{
#ifdef S4FOX
n = block_on->header.n_keys ;
#else
n = block_on->n_keys + 1 ;
if ( b4leaf( block_on ) )
n-- ;
#endif
if( n == 0 )
pos = 0.0 ;
else
pos = (block_on->key_on+pos)/n ;
block_on = (B4BLOCK *) block_on->link.p ;
if ( block_on == (B4BLOCK *) t4->blocks.last_node )
break ;
}
#ifdef S4FOX
if ( t4->header.descending ) /* backwards in file... */
return 1.0 - pos ;
else
#endif
return pos ;
}
double S4FUNCTION t4position( TAG4 *t4 )
{
#ifdef S4FOX
int rc, len ;
char *result ;
#ifdef S4DEBUG
if ( t4 == 0 )
e4severe( e4parm, E4_T4POSITION ) ;
#endif
if ( t4->code_base->error_code < 0 )
return -1 ;
if ( d4tag_selected( t4->index->data ) == t4 )
{
len = t4expr_key( t4, &result ) ;
if ( len < 0 )
return -1.0 ;
t4version_check( t4, 0, 0 ) ;
rc = t4seek( t4, result, len ) ;
if ( rc != 0 && rc != r4eof && rc != r4after )
return -1.0 ;
}
#endif
return t4positionDbl( t4 ) ;
}
int S4FUNCTION t4position_set( TAG4 *t4, double pos )
{
int rc, n, final_pos ;
B4BLOCK *block_on ;
#ifdef S4DEBUG
if ( t4 == 0 )
e4severe( e4parm, E4_T4POSITION_SET ) ;
#endif
if ( t4->code_base->error_code < 0 )
return -1 ;
#ifndef S4SINGLE
i4version_check( t4->index, 0, 0 ) ;
#endif
#ifdef S4FOX
if ( t4->header.descending ) /* backwards in file... */
pos = 1.0 - pos ;
#endif
if ( t4up_to_root( t4 ) < 0 )
return -1 ;
for(;;)
{
#ifdef S4DEBUG
if ( pos < 0.0 || pos > 1.0 ) /* Could be caused by rounding error ? */
e4severe( e4parm, E4_INFO_ILP ) ;
#endif
block_on = t4block(t4) ;
#ifdef S4FOX
n = block_on->header.n_keys ;
#else
n = block_on->n_keys+1 ;
if ( b4leaf( block_on ) )
n-- ;
#endif
final_pos = (int)( n * pos ) ;
if ( final_pos == n )
final_pos-- ;
#ifdef S4FOX
b4go( block_on, final_pos ) ;
#else
block_on->key_on = final_pos ;
#endif
pos = pos*n - final_pos ;
rc = t4down( t4 ) ;
if ( rc < 0 )
return -1 ;
if ( rc == 1 )
return 0 ;
}
}
#endif /* ifndef N4OTHER */
#ifdef N4OTHER
double S4FUNCTION t4positionDbl( TAG4 *t4 )
{
return t4position( t4 ) ;
}
double S4FUNCTION t4position( TAG4 *t4 )
{
double pos ;
B4BLOCK *block_on ;
int n ;
#ifdef S4CLIPPER
int first = 1 ;
#endif
#ifdef S4DEBUG
if ( t4 == 0 )
e4severe( e4parm, E4_T4POSITION ) ;
#endif
if ( t4->code_base->error_code < 0 )
return -1 ;
block_on = (B4BLOCK *) t4->blocks.last_node ;
if ( !b4leaf(block_on) )
pos = 1.0 ;
else
pos = .5 ;
for ( ; block_on != 0 ; )
{
n = block_on->n_keys + 1 ;
#ifdef S4CLIPPER
if ( first )
{
if ( b4leaf( block_on ) )
n-- ;
first = 0 ;
}
#else
if ( b4leaf( block_on ) )
n-- ;
#endif
if( n == 0 )
pos = 0.0 ;
else
pos = ( block_on->key_on + pos ) / n ;
block_on = (B4BLOCK *) block_on->link.p ;
if ( block_on == (B4BLOCK *)t4->blocks.last_node )
break ;
}
#ifdef S4CLIPPER
if ( t4->header.descending ) /* backwards in file... */
return 1.0 - pos ;
else
#endif
return pos ;
}
int S4FUNCTION t4position_set( TAG4 *t4, double pos )
{
int rc, n, final_pos ;
B4BLOCK *block_on ;
#ifdef S4DEBUG
if ( t4 == 0 )
e4severe( e4parm, E4_T4POSITION_SET ) ;
#endif
if ( t4->code_base->error_code < 0 )
return -1 ;
#ifdef S4CLIPPER
if ( t4->header.descending ) /* backwards in file... */
pos = 1.0 - pos ;
#endif
if ( t4up_to_root( t4 ) < 0 )
return -1 ;
for(;;)
{
#ifdef S4DEBUG
if ( pos < 0.0 || pos > 1.0 ) /* Could be caused by rounding error ? */
e4severe( e4parm, E4_INFO_ILP ) ;
#endif
block_on = t4block( t4 ) ;
n = block_on->n_keys + 1 ;
if ( b4leaf( block_on ) )
n-- ;
final_pos = (int)( n * pos ) ;
if ( final_pos == n )
final_pos-- ;
block_on->key_on = final_pos ;
pos = pos*n - final_pos ;
rc = t4down( t4 ) ;
if ( rc < 0 )
return -1 ;
if ( rc == 1 )
return 0 ;
}
}
#endif /* N4OTHER */
#endif /* S4INDEX_OFF */