campo-sirio/cb/source/f4field.c

1326 lines
30 KiB
C
Raw Normal View History

/* f4field.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
#include "d4all.h"
#ifndef S4UNIX
#ifdef __TURBOC__
#pragma hdrstop
#endif
#endif
#ifndef S4OFF_WRITE
char *S4FUNCTION f4assignPtr( FIELD4 *field )
{
#ifdef E4PARM_HIGH
if ( field == 0 )
{
error4( 0, e4parm_null, E90507 ) ;
return 0 ;
}
#endif
#ifdef S4CLIENT_OR_FOX
if ( d4version( field->data ) == 0x30 )
f4assignNotNull( field ) ;
#endif
field->data->recordChanged = 1 ;
return ( field->data->record + field->offset ) ;
}
void S4FUNCTION f4blank( FIELD4 *field )
{
#ifdef S4VBASIC
if ( c4parm_check( (void *)field, 3, E90508 ) )
return ;
#endif
#ifdef E4PARM_HIGH
if ( field == 0 )
{
error4( 0, e4parm_null, E90508 ) ;
return ;
}
#endif
if ( error4code( field->data->codeBase ) < 0 )
return ;
#ifndef S4SERVER
#ifndef S4OFF_ENFORCE_LOCK
if ( field->data->codeBase->lockEnforce && field->data->recNum > 0L )
if ( d4lockTest( field->data, field->data->recNum ) != 1 )
{
error4( field->data->codeBase, e4lock, E90508 ) ;
return ;
}
#endif
#endif
#ifdef S4CLIENT_OR_FOX
if ( field->binary )
memset( f4assignPtr( field ), 0, field->len ) ;
else
#endif
memset( f4assignPtr( field ), ' ', field->len ) ;
}
#endif
DATA4 *S4FUNCTION f4data( const FIELD4 *field )
{
#ifdef E4PARM_HIGH
if ( field == 0 )
{
error4( 0, e4parm_null, E90509 ) ;
return 0 ;
}
#endif
return field->data ;
}
int S4FUNCTION f4decimals( const FIELD4 *field )
{
#ifdef S4VBASIC
if ( c4parm_check( (void *)field, 3, E90510 ) )
return -1 ;
#endif
#ifdef E4PARM_HIGH
if ( field == 0 )
return error4( 0, e4parm_null, E90510 ) ;
#endif
return field->dec ;
}
unsigned S4FUNCTION f4len( const FIELD4 *field )
{
#ifdef S4VBASIC
if ( c4parm_check( (void *)field, 3, E90511 ) )
return 0 ;
#endif
#ifdef E4PARM_HIGH
if ( field == 0 )
{
error4( 0, e4parm_null, E90511 ) ;
return 0 ;
}
#endif
return field->len ;
}
S4CONST char *S4FUNCTION f4name( S4CONST FIELD4 *field )
{
#ifdef S4VBASIC
if ( c4parm_check( (void *)field, 3, E90512 ) )
return 0 ;
#endif
#ifdef E4PARM_HIGH
if ( field == 0 )
{
error4( 0, e4parm_null, E90512 ) ;
return 0 ;
}
#endif
return field->name ;
}
int S4FUNCTION f4number( const FIELD4 *field )
{
FIELD4 *fieldOn ;
int fNum ;
#ifdef E4PARM_HIGH
if ( field == 0 )
return error4( 0, e4parm_null, E90538 ) ;
#endif
fieldOn = field->data->fields ;
for ( fNum = 1 ;; fNum++ )
{
if ( fieldOn == field )
return fNum ;
fieldOn++ ;
}
}
int S4FUNCTION f4type( const FIELD4 *field )
{
#ifdef S4VBASIC
if ( c4parm_check( (void *)field, 3, E90513 ) )
return -1 ;
#endif
#ifdef E4PARM_HIGH
if ( field == 0 )
return error4( 0, e4parm_null, E90513 ) ;
#endif
#ifdef S4CLIENT_OR_FOX
switch( field->type )
{
case 'F':
return (int)r4num ;
case 'C':
if ( field->binary )
return r4charBin ;
else
return r4str ;
case 'M':
if ( field->binary == 1 )
return r4memoBin ;
else
return r4memo ;
default:
return (int)field->type ;
}
#else
if ( field->type == 'F' )
return (int)r4num ;
else
return (int)field->type ;
#endif
}
#ifdef S4CLIENT_OR_FOX
static void negate( CURRENCY4 *, const CURRENCY4 * ) ;
static void shiftLeft( long *, long *, int ) ;
int S4FUNCTION date4timeCompare( const long *dt1, const long *dt2 )
{
long date1, date2, time1, time2 ;
date1 = dt1[0] ;
date2 = dt2[0] ;
if ( date1 == date2 ) /* must compare on times */
{
time1 = dt1[1] ;
time2 = dt2[1] ;
if ( time1 > time2 )
return 1 ;
if ( time1 < time2 )
return -1 ;
return 0 ;
}
else /* dates not equal */
{
if ( date1 > date2 )
return 1 ;
return -1 ;
}
}
/* returns -1 if c1 < c2, 0 if equal, 1 if c1 > c2 */
int S4FUNCTION currency4compare( const CURRENCY4 *c1, const CURRENCY4 *c2 )
{
char sign1, sign2 ;
short int loop ;
long result ;
sign1 = (short int)(c1->lo[3]) >= 0 ? 1 : -1 ;
sign2 = (short int)(c2->lo[3]) >= 0 ? 1 : -1 ;
if ( sign1 != sign2 ) /* one positive, one negative, so comparison easy */
{
if ( sign1 == -1 )
return -1 ;
else
return 1 ;
}
if ( sign1 == -1 ) /* negative comparison, larger value is smaller */
{
for ( loop = 3 ; loop > 0 ; loop-- )
{
result = c1->lo[loop] ;
result -= c2->lo[loop] ;
if ( result < 0 )
return 1 ;
if ( result > 0 )
return -1 ;
}
return 0 ;
}
/* otherwise both values positive, larger is larger */
for ( loop = 3 ; loop > 0 ; loop-- )
{
result = c1->lo[loop] ;
result -= c2->lo[loop] ;
if ( result < 0 )
return -1 ;
if ( result > 0 )
return 1 ;
}
return 0 ;
}
int S4FUNCTION currency4add( CURRENCY4 *result, const CURRENCY4 *c1, const CURRENCY4 *c2 )
{
char sign1, sign2, carry ;
short int loop ;
long val1, val2, resultVal ;
sign1 = (short int)(c1->lo[3]) >= 0 ? 1 : -1 ;
sign2 = (short int)(c2->lo[3]) >= 0 ? 1 : -1 ;
carry = 0 ;
for ( loop = 0 ; loop < 4 ; loop++ )
{
if ( sign1 == -1 && sign2 == -1 )
{
val1 = -(short int)(c1->lo[loop]) ;
val2 = -(short int)(c2->lo[loop]) ;
if ( val1 == 0 )
val1 = 65536 ;
if ( val2 == 0 )
val2 = 65536 ;
if ( loop != 0 )
val2-- ;
}
else
{
val1 = c1->lo[loop] ;
val2 = c2->lo[loop] ;
}
resultVal = val1 + val2 + carry ;
carry = 0 ;
if ( resultVal > USHRT_MAX )
{
#ifdef S4TESTING
if ( ( resultVal - (long)USHRT_MAX ) > USHRT_MAX )
return error4( 0, e4info, E99999 ) ;
#endif
carry = 1 ;
result->lo[loop] = (int)(resultVal - (long)USHRT_MAX - 1) ;
}
else
result->lo[loop] = (int)resultVal ;
if ( sign1 == -1 && sign2 == -1 )
result->lo[loop] = -((short int)result->lo[loop]) ;
}
return 0 ;
}
int S4FUNCTION currency4subtract( CURRENCY4 *result, const CURRENCY4 *c1, const CURRENCY4 *c2 )
{
CURRENCY4 temp ;
memcpy( &temp, c2, sizeof( CURRENCY4 ) ) ;
negate( &temp, &temp ) ;
currency4add( result, c1, &temp ) ;
return 0 ;
}
int S4FUNCTION currency4multiplyShort( CURRENCY4 *result, const CURRENCY4 *c1, const short c2 )
{
int loop, sign1, sign2, signResult, pos ;
CURRENCY4 cur1, hold ;
unsigned long val1, valResult ;
short int cur2 ;
sign1 = (short int)(c1->lo[3]) >= 0 ? 1 : -1 ;
sign2 = c2 >= 0 ? 1 : -1 ;
if ( sign1 == -1 )
{
negate( &cur1, c1 ) ;
signResult = -1 ;
}
else
{
memcpy( &cur1, c1, sizeof( CURRENCY4 ) ) ;
signResult = 1 ;
}
if ( sign2 == -1 )
{
cur2 = -c2 ;
signResult *= -1 ;
}
else /* no change to sign */
cur2 = c2 ;
memset( result, 0, sizeof( CURRENCY4 ) ) ;
for ( loop = 0 ; loop < 4 ; loop++ )
{
val1 = cur1.lo[loop] ;
pos = loop ;
if ( pos >= 4 ) /* too large to store results */
break ;
if ( val1 == 0 )
continue ;
valResult = val1 * cur2 ;
memset( &hold, 0, sizeof( CURRENCY4 ) ) ;
if ( pos == 3 ) /* only least significant bytes important */
memcpy( &(hold.lo[pos]), &valResult, 2 ) ;
else
memcpy( &(hold.lo[pos]), &valResult, 4 ) ;
currency4add( result, result, &hold ) ;
}
if ( signResult == -1 )
negate( result, result ) ;
return 0 ;
}
#ifdef NOT_IMPLEMENTED_YET
int currency4multiply( CURRENCY4 *result, const CURRENCY4 *c1, const CURRENCY4 *c2 )
{
int loop, sign1, sign2, signResult, jLoop, pos ;
CURRENCY4 cur1, cur2, hold, tenThousand ;
unsigned long val1, val2, valResult ;
sign1 = (short int)(c1->lo[3]) >= 0 ? 1 : -1 ;
sign2 = (short int)(c2->lo[3]) >= 0 ? 1 : -1 ;
if ( sign1 == -1 )
{
negate( &cur1, c1 ) ;
signResult = -1 ;
}
else
{
memcpy( &cur1, c1, sizeof( CURRENCY4 ) ) ;
signResult = 1 ;
}
if ( sign2 == -1 )
{
negate( &cur2, c2 ) ;
signResult *= -1 ;
}
else /* no change to sign */
memcpy( &cur2, c2, sizeof( CURRENCY4 ) ) ;
memset( result, 0, sizeof( CURRENCY4 ) ) ;
memset( &tenThousand, 0, sizeof( CURRENCY4 ) ) ;
tenThousand.lo[0] = 0x2710 ;
for ( jLoop = 0 ; jLoop < 4 ; jLoop++ )
{
val2 = cur2.lo[jLoop] ;
if ( val2 == 0 )
continue ;
for ( loop = 0 ; loop < 4 ; loop++ )
{
val1 = cur1.lo[loop] ;
pos = loop + jLoop ;
if ( pos >= 4 ) /* too large to store results */
break ;
if ( val1 == 0 )
continue ;
valResult = val1 * val2 ;
memset( &hold, 0, sizeof( CURRENCY4 ) ) ;
if ( pos == 3 ) /* only least significant bytes important */
memcpy( &(hold.lo[pos]), &valResult, 2 ) ;
else
memcpy( &(hold.lo[pos]), &valResult, 4 ) ;
currency4add( result, result, &hold ) ;
}
}
if ( signResult == -1 )
negate( result, result ) ;
return 0 ;
}
#endif
static void negate( CURRENCY4 *result, const CURRENCY4 *source )
{
int loop ;
CURRENCY4 one ;
if ( ( (short int)(source->lo[3]) >= 0 ? 1 : -1 ) == -1 ) /* negative */
{
memset( &one, 0, sizeof( CURRENCY4 ) ) ;
one.lo[0] = 0x0001 ;
for ( loop = 0; loop < 4 ; loop++ )
result->lo[loop] = ~source->lo[loop] ;
currency4add( result, result, &one ) ;
}
else /* positive */
{
memset( &one, (unsigned char)0xFF, sizeof( CURRENCY4 ) ) ;
memcpy( result, source, sizeof( CURRENCY4 ) ) ;
currency4add( result, result, &one ) ;
for ( loop = 0; loop < 4 ; loop++ )
result->lo[loop] = ~result->lo[loop] ;
}
}
static void shiftLeft( long *left, long *right, int numShift )
{
int loop ;
for ( loop = 0 ; loop < numShift ; loop++ )
{
*left = *left << 1 ;
*left = *left | ( 1 * ( *right & 0x80000000 ) ) ;
*right = *right << 1 ;
}
}
static void shiftRight( long *left, long *right, int numShift )
{
int loop ;
for ( loop = 0 ; loop < numShift ; loop++ )
{
*right = *right >> 1 ;
*right = *right | ( 0x80000000 * ( *left & 0x00000001 ) ) ;
*left = *left >> 1 ;
}
}
int S4FUNCTION currency4divideShort( CURRENCY4 *result, const CURRENCY4 *c1, const short c2 )
{
unsigned short int shortResult ;
short int cur2 ;
unsigned long shortMod ;
int sign1, sign2, signResult, loop ;
CURRENCY4 add, cur1 ;
sign1 = (short int)(c1->lo[3]) >= 0 ? 1 : -1 ;
sign2 = c2 >= 0 ? 1 : -1 ;
if ( sign1 == -1 )
{
negate( &cur1, c1 ) ;
signResult = -1 ;
}
else
{
memcpy( &cur1, c1, sizeof( CURRENCY4 ) ) ;
signResult = 1 ;
}
if ( sign2 == -1 )
{
cur2 = -c2 ;
signResult *= -1 ;
}
else /* no change to sign */
cur2 = c2 ;
if ( cur2 == 0 )
return -1 ;
memset( result, 0, sizeof( CURRENCY4 ) ) ;
if ( *((long *)(&cur1.lo[2])) == 0 ) /* value smaller than max long */
{
*((long *)(&result->lo[0])) = *((long *)(&cur1.lo[0])) / cur2 ;
if ( signResult == -1 )
negate( result, result ) ;
return 0 ;
}
shortMod = 0 ;
for ( loop = 3 ; loop >= 0 ; loop-- )
{
memset( &add, 0, sizeof( CURRENCY4 ) ) ;
shortResult = (unsigned short)(((unsigned long)cur1.lo[loop] + shortMod )/ cur2) ;
memcpy( ((unsigned short int *)(&add)) + loop, &shortResult, sizeof( short int ) ) ;
if ( loop != 0 )
shortMod = ((unsigned long)(USHRT_MAX)+1) * ((cur1.lo[loop] + shortMod) % cur2 ) ;
currency4add( result, result, &add) ;
}
if ( signResult == -1 )
negate( result, result ) ;
return 0 ;
}
#ifdef NOT_IMPLEMENTED_YET
int currency4divide( CURRENCY4 *result, const CURRENCY4 *c1, const CURRENCY4 *c2 )
{
long topLeft, topRight, bottomLeft, bottomRight, resultRight ;
long stopShiftVal, holdLeft, holdRight ;
int sign1, sign2, signResult, numShift, signHold ;
CURRENCY4 add, subtract, hold, hold2, cur1, cur2 ;
sign1 = (short int)(c1->lo[3]) >= 0 ? 1 : -1 ;
sign2 = (short int)(c2->lo[3]) >= 0 ? 1 : -1 ;
if ( sign1 == -1 )
{
negate( &cur1, c1 ) ;
signResult = -1 ;
}
else
{
memcpy( &cur1, c1, sizeof( CURRENCY4 ) ) ;
signResult = 1 ;
}
if ( sign2 == -1 )
{
negate( &cur2, c2 ) ;
signResult *= -1 ;
}
else /* no change to sign */
memcpy( &cur2, c2, sizeof( CURRENCY4 ) ) ;
topLeft = *((long *)(&cur1.lo[2])) ;
topRight = *((long *)(&cur1.lo[0])) ;
bottomLeft = *((long *)(&cur2.lo[2])) ;
bottomRight = *((long *)(&cur2.lo[0])) ;
if ( bottomLeft == 0 && bottomRight == 0 ) /* divide by zero */
return -1 ;
memset( result, 0, sizeof( CURRENCY4 ) ) ;
if ( topLeft == 0 ) /* value smaller than max long */
{
if ( bottomLeft != 0 ) /* bottom larger than top */
return 0 ;
if ( bottomRight == 0 )
return -1 ;
resultRight = topRight / bottomRight ;
memcpy( &(result->lo[0]), &resultRight, sizeof( long ) ) ;
if ( signResult == -1 )
negate( result, result ) ;
return 0 ;
}
if ( topLeft < bottomLeft ) /* zero return */
{
if ( signResult == -1 )
negate( result, result ) ;
return 0 ;
}
if ( topLeft == bottomLeft ) /* either one or zero return */
{
if ( topRight >= bottomRight )
{
result->lo[0] = 1 ;
if ( signResult == -1 )
negate( result, result ) ;
}
return 0 ;
}
/* case where topLeft > 0 && topLeft > bottomLeft */
memcpy( &(hold.lo[0]), &topRight, sizeof( long ) ) ;
memcpy( &(hold.lo[2]), &topLeft, sizeof( long ) ) ;
stopShiftVal = topLeft / 2 ;
for ( ;; )
{
numShift = -1 ;
while( bottomLeft < stopShiftVal )
{
holdLeft = bottomLeft ;
holdRight = bottomRight ;
shiftLeft( &bottomLeft, &bottomRight, 1 ) ;
numShift++ ;
}
bottomLeft = holdLeft ;
bottomRight = holdRight ;
memset( &add, 0, sizeof( CURRENCY4 ) ) ;
currency4add( result, result, &add ) ;
#ifdef E4DEBUG
if ( ( (short int)(hold->lo[3]) >= 0 ? 1 : -1 ) == -1 )
return error4( 0, e4info, E90542 ) ;
#endif
for ( signHold = 1 ;; )
{
memcpy( &(subtract.lo[0]), &holdRight, sizeof( long ) ) ;
memcpy( &(subtract.lo[2]), &holdLeft, sizeof( long ) ) ;
memcpy( &hold2, &hold, sizeof( CURRENCY4 ) ) ;
currency4subtract( &hold, &hold, &subtract ) ;
signHold = (short int)(hold.lo[3]) >= 0 ? 1 : -1 ;
if ( signHold == -1 )
break ;
}
memcpy( &hold, &hold2, sizeof( CURRENCY4 ) ) ;
topLeft = *((long *)(&hold.lo[2])) ;
topRight = *((long *)(&hold.lo[0])) ;
stopShiftVal = topLeft / 2 ;
while ( bottomLeft > topLeft )
{
shiftRight( &bottomLeft, &bottomRight, 1 ) ;
numShift-- ;
}
}
if ( signResult == -1 )
negate( result, result ) ;
return 0 ;
}
#endif
/*
int currency4mod( CURRENCY4 *result, const CURRENCY4 *c1, const CURRENCY4 *c1 )
{
}
*/
int S4FUNCTION c4currencyToA( char *out, int outLen, const CURRENCY4 *sourceIn, int numDec )
{
int sign, pos, loop, reqdLen ;
CURRENCY4 hold, old, mod, sv, source ;
unsigned char buf[21] ;
unsigned long l1 ;
memcpy( &source, sourceIn, sizeof( CURRENCY4 ) ) ;
sign = (short int)(source.lo[3]) >= 0 ? 1 : -1 ;
if ( sign == -1 )
negate( &source, &source ) ;
memcpy( &hold, &source, sizeof( CURRENCY4 ) ) ;
memset( buf, 0, sizeof( buf ) ) ;
for ( pos = 0 ; pos < 20 ; pos++ )
{
if ( *((long *)(&hold.lo[2])) == 0L ) /* only right portion */
break ;
memcpy( &old, &hold, sizeof( CURRENCY4 ) ) ;
currency4divideShort( &hold, &hold, 10 ) ;
currency4multiplyShort( &sv, &hold, 10 ) ;
currency4subtract( &mod, &old, &sv ) ;
buf[pos] = (char)mod.lo[0] ;
}
/* if any portion is left, it is only the right portion */
if ( *((long *)(&hold.lo[2])) == 0L ) /* only right portion */
{
l1 = *((long *)(&hold.lo[0])) ;
if ( l1 == 0 )
{
if ( pos == 0 ) /* zero */
pos = -1 ;
}
else
{
for ( ; pos < 20 ; )
{
buf[pos] = (unsigned char) (l1 % 10) ;
l1 = l1 / 10 ;
if ( l1 == 0 )
break ;
pos++ ;
}
}
}
memset( out, 0, outLen ) ;
if ( pos == -1 )
{
reqdLen = 6 ; /* x.xxxx */
memset( out, '0', 5 ) ;
}
else
{
reqdLen = pos + 2 ; /* for decimal point and because pos is 1 less than amount */
if ( reqdLen < 6 )
{
memset( out, '0', 5 ) ;
reqdLen = 6 ; /* x.xxxx */
}
}
if ( (reqdLen+1) > outLen + (sign == -1) ) /* insufficient space */
return -1 ;
loop = 5 - (pos+1) ;
if ( loop < 0 )
loop = 0 ;
for ( ; pos >= 0 ; pos--, loop++ ) /* reverse the string */
out[loop] = buf[pos] + '0' ;
/* now reposition for the decimal points */
c4memmove( &(out[reqdLen-4]), &(out[reqdLen-5]), 4 ) ;
out[reqdLen-5] = '.' ;
/* now remove any decimal points according to input */
if ( numDec == 0 )
{
reqdLen -= 5 ;
out[reqdLen] = 0 ;
}
else
{
if ( numDec > 4 || numDec < 0 )
numDec = 4 ;
out[reqdLen-4+numDec] = 0 ;
reqdLen -= (4 - numDec) ;
}
if ( sign == -1 )
{
c4memmove( out+1, out, reqdLen + 1 ) ;
out[0] = '-' ;
}
return 0 ;
}
/* returns -1 if an invalid currency input string */
int S4FUNCTION c4atoCurrency( CURRENCY4 *result, const char *str, int strLen )
{
char buf[21] ;
int loop, len, numDecimals, numWhole, sign, numDigits ;
short int multiplier, mPower ;
long val ;
const char *decPt ;
CURRENCY4 temp, mult ;
char *ptr ;
memset( result, 0, sizeof( CURRENCY4 ) ) ;
decPt = 0 ;
len = strLen ;
if ( len == 0 )
return 0 ;
for ( ;; )
{
if ( str[0] != ' ' )
break ;
len-- ;
str++ ;
if ( len == 0 )
return 0 ;
}
if ( str[0] == '-' )
{
sign = -1 ;
str++ ;
len-- ;
}
else
{
sign = 1 ;
if ( str[0] == '+' )
{
str++ ;
len-- ;
}
}
while ( str[0] == '0' && str[1] == '0' ) /* get rid of leading zeros */
{
str++ ;
len-- ;
}
numDecimals = 0 ;
numWhole = len ;
for ( loop = len - 1 ; loop >= 0 ; loop-- )
{
if ( str[loop] == '.' )
{
numDecimals = len - loop - 1 ;
numWhole = len - numDecimals - 1 ;
decPt = &str[loop]+1 ;
break ;
}
}
if ( numDecimals > 4 )
return -1 ;
numDigits = numWhole + 4 ;
if ( numDigits > 20 )
return -1 ;
memcpy( buf, str, numWhole ) ;
if ( decPt != 0 )
c4memmove( buf+numWhole, decPt, numDecimals ) ;
for ( loop = numDecimals ; loop < 4 ; loop++ )
{
buf[numWhole+loop] = '0' ;
}
buf[numDigits] = 0 ;
if ( numDigits < 10 || ( numDigits == 10 && ( str[0] <= '3' && str[0] >= '0' ) ) )
{
/* fits in a single long */
val = c4atol( buf, strlen( buf ) ) ;
if ( sign == -1 )
val = -val ;
if ( val == 0 ) /* negative 0 is still zero */
sign = 1 ;
if ( sign == 1 ) /* positive value */
{
result->lo[3] = 0 ;
result->lo[2] = 0 ;
}
else /* negative value */
{
result->lo[3] = 0xFFFF ;
result->lo[2] = 0xFFFF ;
}
memcpy( &result->lo[0], &val, sizeof( long ) ) ;
return 0 ;
}
/* more complex scenario because number is larger than a long */
/* first get the first 9 bytes and store to long */
val = c4atol( buf, 9 ) ;
memcpy( &result->lo[0], &val, sizeof( long ) ) ;
ptr = buf + 9 ;
numDigits -= 9 ;
while ( numDigits > 4 )
{
multiplier = c4atoi( ptr, 4 ) ;
memset( &mult, 0, sizeof( CURRENCY4 ) ) ;
mult.lo[0] = 10000 ;
currency4multiplyShort( &temp, result, 10000 ) ;
*result = temp ;
if ( multiplier != 0 ) /* add */
{
memset( &temp, 0, sizeof( temp ) ) ;
memcpy( &(temp.lo[0]), &multiplier, sizeof( short ) ) ;
currency4add( result, result, &temp ) ;
}
numDigits -= 4 ;
ptr += 4 ;
}
if ( numDigits != 0 )
{
multiplier = c4atoi( ptr, numDigits ) ;
mPower = 1 ;
for ( ; numDigits > 0 ; numDigits-- )
mPower *= 10 ;
currency4multiplyShort( &temp, result, mPower ) ;
*result = temp ;
if ( multiplier != 0 ) /* add */
{
memset( &temp, 0, sizeof( temp ) ) ;
memcpy( &(temp.lo[0]), &multiplier, sizeof( short ) ) ;
currency4add( result, result, &temp ) ;
}
}
if ( sign == -1 )
{
memset( &mult, 0, sizeof( CURRENCY4 ) ) ;
mult.lo[0] = 0x0001 ;
currency4subtract( result, result, &mult ) ;
for ( loop = 0; loop < 4 ; loop++ )
result->lo[loop] = ~result->lo[loop] ;
}
return 0 ;
}
#ifndef S4OFF_WRITE
void S4FUNCTION f4assignCurrency( FIELD4 *field, char *str )
{
#ifdef S4VBASIC
if ( c4parm_check( field, 3, E90541 ) )
return ;
#endif
#ifdef E4PARM_HIGH
if ( field == 0 || str == 0 )
{
error4( 0, e4parm_null, E90541 ) ;
return ;
}
#endif
if ( field->type != r4currency )
{
#ifdef E4PARM_HIGH
error4( field->data->codeBase, e4parm, E81409 ) ;
#endif
return ;
}
#ifdef E4ANALYZE
if ( field->data == 0 )
{
error4( 0, e4struct, E90541 ) ;
return ;
}
if ( field->data->codeBase == 0 )
{
error4( 0, e4struct, E90541 ) ;
return ;
}
#endif
#ifdef E4PARM_HIGH
if ( field->type != r4currency )
{
error4( field->data->codeBase, e4parm, E81404 ) ;
return ;
}
#endif
if ( error4code( field->data->codeBase ) < 0 )
return ;
#ifndef S4SERVER
#ifndef S4OFF_ENFORCE_LOCK
if ( field->data->codeBase->lockEnforce && field->data->recNum > 0L )
if ( d4lockTest( field->data, field->data->recNum ) != 1 )
{
error4( field->data->codeBase, e4lock, E90541 ) ;
return ;
}
#endif
#endif
c4atoCurrency( (CURRENCY4 *)f4assignPtr( field ), str, strlen( str ) ) ;
}
#endif /* S4OFF_WRITE */
/* this function uses the same memory as f4str() */
char *S4FUNCTION f4currency( const FIELD4 *field, int numDec )
{
CODE4 *codeBase ;
#ifdef S4VBASIC
if ( c4parm_check( field, 3, E90542 ) )
return -1 ;
#endif
#ifdef E4PARM_HIGH
if ( field == 0 || numDec < 0 || numDec > 4 )
{
error4( 0, e4parm, E90542 ) ;
return 0 ;
}
#endif
codeBase = field->data->codeBase ;
#ifdef E4PARM_HIGH
if ( field->type != r4currency )
{
error4( codeBase, e4parm, E81409 ) ;
return 0 ;
}
#endif
if ( error4code( codeBase ) < 0 )
return 0 ;
if ( codeBase->bufLen <= 20 ) /* not room for field length + null */
{
if ( u4allocAgain( codeBase, &codeBase->fieldBuffer, &codeBase->bufLen, 21 ) < 0 )
{
#ifdef E4STACK
error4stack( codeBase, e4memory, E90542 ) ;
#endif
return 0 ;
}
}
else
codeBase->fieldBuffer[20] = 0 ;
c4currencyToA( codeBase->fieldBuffer, 20, (CURRENCY4 *)f4ptr( field ), numDec ) ;
return codeBase->fieldBuffer ;
}
#ifndef S4OFF_WRITE
void S4FUNCTION f4assignNotNull( FIELD4 *field )
{
FIELD4 *nullFlags ;
unsigned short int byteNum, offset ;
char mask ;
char *fPtr ;
if ( d4version( field->data ) != 0x30 )
return ;
if ( field->null == 1 )
{
if ( f4null( field ) )
{
nullFlags = &(field->data->fields[d4numFields(field->data)]) ;
#ifdef E4MISC
if ( nullFlags->type != r4system )
{
error4( field->data->codeBase, e4data, E83805 ) ;
return ;
}
#endif
byteNum = field->nullBit / 8 ;
#ifdef E4MISC
if ( nullFlags->len < ( byteNum + 1 ) )
{
error4( field->data->codeBase, e4data, E83805 ) ;
return ;
}
#endif
offset = ( field->nullBit - (byteNum * 8) ) ;
mask = (unsigned int)0x01 << offset ;
mask = ~mask ;
fPtr = f4ptr( nullFlags ) ;
fPtr[byteNum] = fPtr[byteNum] & mask ;
}
}
}
void S4FUNCTION f4assignNull( FIELD4 *field )
{
FIELD4 *nullFlags ;
unsigned short int byteNum, offset ;
char mask ;
char *fPtr ;
#ifdef S4VBASIC
if ( c4parm_check( field, 3, E90539 ) )
return ;
#endif
#ifdef E4PARM_HIGH
if ( field == 0 )
{
error4( 0, e4parm_null, E90539 ) ;
return ;
}
#endif
if ( error4code( field->data->codeBase ) < 0 )
return ;
if ( d4version( field->data ) != 0x30 )
{
error4( field->data->codeBase, e4parm, E81409 ) ;
return ;
}
#ifndef S4SERVER
#ifndef S4OFF_ENFORCE_LOCK
if ( field->data->codeBase->lockEnforce && field->data->recNum > 0L )
if ( d4lockTest( field->data, field->data->recNum ) != 1 )
{
error4( field->data->codeBase, e4lock, E90539 ) ;
return ;
}
#endif
#endif
if ( field->null == 1 )
{
nullFlags = &(field->data->fields[d4numFields(field->data)]) ;
#ifdef E4MISC
if ( nullFlags->type != r4system )
{
error4( field->data->codeBase, e4data, E83805 ) ;
return ;
}
#endif
byteNum = field->nullBit / 8 ;
#ifdef E4MISC
if ( nullFlags->len < ( byteNum + 1 ) )
{
error4( field->data->codeBase, e4data, E83805 ) ;
return ;
}
#endif
offset = ( field->nullBit - (byteNum * 8 ) ) ;
mask = 0x01 << offset ;
fPtr = f4assignPtr( nullFlags ) ;
fPtr[byteNum] = fPtr[byteNum] | mask ;
}
#ifdef E4PARM_HIGH
else
error4( field->data->codeBase, e4parm, E81409 ) ;
#endif
}
#endif /* S4OFF_WRITE */
int S4FUNCTION f4null( const FIELD4 *field )
{
FIELD4 *nullFlags ;
unsigned short int byteNum, offset ;
char mask ;
#ifdef S4VBASIC
if ( c4parm_check( field, 3, E90540 ) )
return -1 ;
#endif
#ifdef E4PARM_HIGH
if ( field == 0 )
return error4( 0, e4parm_null, E90540 ) ;
#endif
if ( d4version( field->data ) != 0x30 )
return 0 ;
if ( field->null == 1 )
{
nullFlags = &(field->data->fields[d4numFields(field->data)]) ;
#ifdef E4MISC
if ( nullFlags->type != r4system )
return error4( field->data->codeBase, e4data, E83805 ) ;
#endif
byteNum = field->nullBit / 8 ;
#ifdef E4MISC
if ( nullFlags->len < ( byteNum + 1 ) )
return error4( field->data->codeBase, e4data, E83805 ) ;
#endif
offset = ( field->nullBit - (byteNum * 8 ) ) ;
mask = 0x01 << offset ;
if ( ( f4ptr( nullFlags )[byteNum] & mask ) != 0 )
return 1 ;
}
return 0 ;
}
static void time4assign( char *ptr, unsigned long inVal )
{
long seconds, minutes, hours, milliSeconds, val ;
val = inVal / 1000 ; /* remove the thousandths's of seconds */
milliSeconds = inVal - ( val * 1000 ) ;
seconds = val % 60 ;
val /= 60 ;
minutes = val % 60 ;
val /= 60 ;
hours = val ;
c4ltoa45( hours, ptr, -2 ) ; /* - means fill with 0s */
ptr[2] = ':' ;
c4ltoa45( minutes, ptr+3, -2 ) ; /* - means fill with 0s */
ptr[5] = ':' ;
c4ltoa45( seconds, ptr+6, -2 ) ; /* - means fill with 0s */
if ( milliSeconds != 0 )
{
ptr[8] = ':' ;
c4ltoa45( milliSeconds, ptr+9, -3 ) ; /* - means fill with 0s */
}
}
/* this function uses the same memory as f4str() */
char S4PTR *S4FUNCTION f4dateTime( const FIELD4 *field )
{
CODE4 *codeBase ;
long val ;
char *fPtr ;
#ifdef S4VBASIC
if ( c4parm_check( field, 3, E90543 ) )
return -1 ;
#endif
#ifdef E4PARM_HIGH
if ( field == 0 )
{
error4( 0, e4parm, E90543 ) ;
return 0 ;
}
#endif
codeBase = field->data->codeBase ;
#ifdef E4PARM_HIGH
if ( field->type != r4dateTime )
{
error4( codeBase, e4parm, E81409 ) ;
return 0 ;
}
#endif
if ( error4code( codeBase ) < 0 )
return 0 ;
if ( codeBase->bufLen <= 20 ) /* not room for field length + null (incl. millisecs) */
{
if ( u4allocAgain( codeBase, &codeBase->fieldBuffer, &codeBase->bufLen, 21 ) < 0 )
{
#ifdef E4STACK
error4stack( codeBase, e4memory, E90542 ) ;
#endif
return 0 ;
}
}
memset( codeBase->fieldBuffer, ' ', 20 ) ;
codeBase->fieldBuffer[20] = 0 ;
fPtr = f4ptr( field ) ;
val = *((long *)fPtr) ; /* date */
date4assign( codeBase->fieldBuffer, val ) ;
val = *(((long *)fPtr) + 1) ; /* time */
time4assign( codeBase->fieldBuffer + 8, val ) ;
c4trimN( codeBase->fieldBuffer, 21 ) ;
return codeBase->fieldBuffer ;
}
/* input date time of format: "YYYYMMDDHH:MM:SS:MMM" */
#ifndef S4OFF_WRITE
void S4FUNCTION f4assignDateTime( FIELD4 *field, char *dateTime )
{
long date, time ;
if ( field->type != r4dateTime )
{
#ifdef E4PARM_HIGH
error4( field->data->codeBase, e4parm, E81409 ) ;
#endif
return ;
}
date = date4long( dateTime ) ;
time = time4long( dateTime + 8, strlen( dateTime ) - 8 ) ;
*((long *)f4assignPtr( field )) = date ;
*(((long *)f4assignPtr( field ))+1) = time ;
}
#endif /* S4OFF_WRITE */
#endif /* S4CLIENT_OR_FOX */
#ifdef S4VBASIC
int S4FUNCTION f4len_v( FIELD4 *f4 )
{
return (int)f4len( f4 );
}
#ifdef S4VB_DOS
char * f4name_v( FIELD4 *fld )
{
return v4str( f4name(fld) ) ;
}
#endif /* S4VB_DOS */
#endif /* S4VBASIC */