249 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			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
 | 
						|
}
 |