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