campo-sirio/cb/source/d4positi.c
alex af15e0698b Codebase
git-svn-id: svn://10.65.10.50/trunk@4679 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-06-16 13:01:08 +00:00

249 lines
7.0 KiB
C
Executable File

/* d4positi.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
#include "d4all.h"
#ifndef S4UNIX
#ifdef __TURBOC__
#pragma hdrstop
#endif
#endif
double S4FUNCTION d4position( DATA4 *data )
{
#ifdef S4CLIENT
int rc ;
CONNECTION4 *connection ;
CONNECTION4DATA_POS_IN info ;
#else
long count ;
#ifndef S4OFF_INDEX
int len, rc ;
unsigned char *result ;
#endif
#endif
#ifndef S4OFF_INDEX
TAG4 *tag ;
#endif
#ifdef S4VBASIC
if ( c4parm_check( data, 2, E94701 ) )
return -1.0 ;
#endif
#ifdef E4PARM_HIGH
if ( data == 0 )
return (double)error4( 0, e4parm_null, E94701 ) ;
#endif
if( error4code( data->codeBase ) < 0 )
return -1.0 ;
if ( d4eof( data ) )
return 1.1 ;
#ifdef S4CLIENT
connection = data->dataFile->connection ;
if ( connection == 0 )
return e4connection ;
rc = connection4assign( connection, CON4POSITION, data4clientId( data ), data4serverId( data ) ) ;
if ( rc < 0 )
return rc ;
#ifdef S4OFF_INDEX
info.usesTag = 0 ;
#else
tag = data->tagSelected ;
if ( tag == 0 )
info.usesTag = 0 ;
else
{
info.usesTag = 1 ;
memcpy( info.tagName, tag->tagFile->alias, LEN4TAG_ALIAS ) ;
info.tagName[LEN4TAG_ALIAS] = 0 ;
}
#endif
info.startRecno = data->recNum ;
connection4addData( connection, &info, sizeof( CONNECTION4DATA_POS_IN ), 0 ) ;
connection4send( connection ) ;
rc = connection4receive( connection ) ;
if ( rc < 0 )
return error4stack( data->codeBase, rc, E94701 ) ;
rc = connection4status( connection ) ;
if ( rc < 0 )
return connection4error( connection, data->codeBase, rc, E94701 ) ;
if ( connection4len( connection ) != sizeof( CONNECTION4DATA_POS_OUT ) )
return error4( data->codeBase, e4packetLen, E94701 ) ;
return( ((CONNECTION4DATA_POS_OUT *)connection4data( connection ))->position ) ;
#else
#ifndef S4OFF_INDEX
tag = data->tagSelected ;
if ( tag == 0 || data->recNum <= 0L )
{
#endif
count = d4recCount( data ) ;
if ( count < 0 )
return -1.0 ;
if ( count == 0 || data->recNum <= 0L )
return 0.0 ;
return (double)( data->recNum - 1 ) / ( count - (count != 1 ) ) ;
#ifndef S4OFF_INDEX
}
else
{
expr4context( tag->tagFile->expr, data ) ;
len = tfile4exprKey( tag->tagFile, &result ) ;
if ( len < 0 )
return -1.0 ;
t4versionCheck( tag, 0, 0 ) ;
rc = tfile4seek( tag->tagFile, result, len ) ;
if ( rc != 0 && rc != r4eof && rc != r4after )
return -1.0 ;
return tfile4position( tag->tagFile ) ;
}
#endif
#endif
}
int S4FUNCTION d4position2( DATA4 *data, double *result )
{
*result = d4position( data ) ;
if ( *result < 0.0 )
return -1;
return 0;
}
#ifdef S4SERVER
long S4FUNCTION d4positionSet( DATA4 *data, const double per )
#else
int S4FUNCTION d4positionSet( DATA4 *data, const double per )
#endif
{
int rc ;
CODE4 *c4 ;
#ifdef S4CLIENT
CONNECTION4 *connection ;
CONNECTION4DATA_POS_SET_IN info ;
CONNECTION4GO_INFO_OUT *out ;
#else
long newRec ;
long count ;
#endif
#ifndef S4OFF_INDEX
TAG4 *tag ;
#endif
#ifdef S4VBASIC
if ( c4parm_check( data, 2, E94702 ) )
return -1 ;
#endif
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E94702 ) ;
#endif
c4 = data->codeBase ;
if( error4code( c4 ) < 0 )
return e4codeBase ;
if ( per > 1.0 )
return d4goEof( data ) ;
if ( per <= 0 )
return d4top( data ) ;
#ifdef S4CLIENT
connection = data->dataFile->connection ;
if ( connection == 0 )
return e4connection ;
rc = connection4assign( connection, CON4POSITION_SET, data4clientId( data ), data4serverId( data ) ) ;
if ( rc < 0 )
return error4stack( c4, rc, E94702 ) ;
info.position = per ;
#ifdef S4OFF_INDEX
info.usesTag = 0 ;
#else
tag = data->tagSelected ;
if ( tag == 0 )
info.usesTag = 0 ;
else
{
info.usesTag = 1 ;
memcpy( info.tagName, tag->tagFile->alias, LEN4TAG_ALIAS ) ;
info.tagName[LEN4TAG_ALIAS] = 0 ;
}
#endif
connection4addData( connection, &info, sizeof( CONNECTION4DATA_POS_SET_IN ), 0 ) ;
rc = connection4repeat( connection, -2, -1, -1, data ) ;
if ( rc == r4locked )
return r4locked ;
if ( rc < 0 )
return connection4error( connection, c4, rc, E94702 ) ;
if ( connection4len( connection ) < sizeof( CONNECTION4GO_INFO_OUT ) )
return error4( c4, e4packetLen, E94702 ) ;
out = (CONNECTION4GO_INFO_OUT *)connection4data( connection ) ;
if ( out->recNo != 0 )
{
if ( (long)connection4len( connection ) != (long)sizeof( CONNECTION4GO_INFO_OUT ) + (long)dfile4recWidth( data->dataFile ) )
return error4( c4, e4packetLen, E94802 ) ;
return d4goVirtual( data, out->recNo, rc, out, connection ) ; /* maybe r4locked, or whatever */
}
else
return d4goEof( data ) ;
#else
#ifndef S4OFF_INDEX
tag = data->tagSelected ;
if ( tag == 0 )
{
#endif
count = d4recCount( data ) ;
if ( count <= 0L )
return d4goEof( data ) ;
newRec = (long)( per * ( (double)count - 1 ) + 1.5 ) ;
if ( newRec > count )
newRec = count ;
#ifndef S4OFF_INDEX
}
else
{
rc = tfile4positionSet( tag->tagFile, per ) ;
if ( rc )
return rc ;
if ( rc == r4eof )
return d4goEof( data ) ;
newRec = tfile4recNo( tag->tagFile ) ;
}
#endif
rc = d4go( data, newRec ) ;
if ( rc != 0 )
return rc ;
#ifndef S4OFF_INDEX
if ( tag != 0 )
rc = d4tagSyncDo( data, tag, 1 ) ;
#endif
#ifndef S4OFF_MULTI
if ( rc != 0 ) /* failed, try synching the other way */
{
rc = d4go( data, newRec ) ;
#ifndef S4OFF_INDEX
#ifndef S4OFF_TRAN
if ( rc == 0 )
if ( code4transEnabled( c4 ) )
if ( t4unique( tag ) != 0 )
#ifdef S4SERVER
if ( !dfile4lockTestFile( data->dataFile, data4clientId( data ), data4serverId( data ) ) )
#else
if ( !d4lockTestFile( data ) )
#endif
rc = d4tagSyncDo( data, tag, -1 ) ;
#endif
#endif
}
#endif
return rc ;
#endif
}