/* x4filter.c (c)Copyright Sequiter Software Inc., 1990-1992. All rights reserved. */ #include "d4all.h" #include "x4filter.h" #ifndef S4UNIX #ifdef __TURBOC__ #pragma hdrstop #endif #endif void S4FUNCTION x4init_work( X4FILTER *filter, DATA4 *data, X4FUNCTION *routine, void *routine_data ) { filter->data = data ; filter->routine = routine ; filter->routine_data = routine_data ; } int S4FUNCTION x4bottom( X4FILTER *x4 ) { int rc ; DATA4 *d4 ; d4 = x4->data ; if ( (rc = d4bottom(d4)) != 0 ) return rc ; rc = x4find_good(x4,-1) ; if ( rc == r4keep ) return 0 ; if ( rc == r4bof ) { d4->bof_flag = 1 ; return x4filter_go_eof(x4) ; } return rc ; } int S4FUNCTION x4filter_test( X4FILTER *x4 ) { #ifndef S4UNIX #ifdef S4DEBUG #if ! (defined __ZTC__ && defined S4MEDIUM) if (u4ptr_equal( x4->routine, 0)) e4severe( e4info, "x4filter_test()"); #endif #endif #endif return (*x4->routine)( x4->routine_data ) ; } int x4find_good( X4FILTER *x4, int sign ) { int rc ; for(;;) { rc = x4filter_test(x4) ; if ( rc != r4ignore ) return rc ; if ( (rc = d4skip(x4->data, (long) sign)) != 0 ) return rc ; } } int x4filter_go_eof( X4FILTER *x4 ) { int rc ; rc = d4go_eof(x4->data) ; if ( rc != r4eof ) return rc ; rc = x4filter_test(x4) ; if ( rc != r4keep && rc != r4ignore ) return rc ; return r4eof ; } int S4FUNCTION x4go( X4FILTER *x4, long new_rec ) { int rc ; rc = d4go( x4->data, new_rec) ; if ( rc != 0 ) return rc ; rc = (*x4->routine)( x4->routine_data ) ; if ( rc == r4ignore ) return r4entry ; if ( rc == r4keep ) return 0 ; return rc ; } int S4FUNCTION x4seek_double( X4FILTER *x4, double d ) { int rc ; double d_on, diff ; TAG4 *tag_ptr ; rc = x4seek_do( x4, d4seek_double(x4->data,d) ) ; if ( rc != 0 ) return rc ; /* 0 may become r4after */ tag_ptr = d4tag_default(x4->data) ; d_on = expr4double( tag_ptr->expr ) ; if ( x4->data->code_base->error_code < 0 ) return -1 ; diff = d_on - d ; if ( diff < -E4ACCURACY || diff > E4ACCURACY ) return r4after ; return 0 ; } int S4FUNCTION x4seek( X4FILTER *x4, char *s ) { int rc, len, compare_len ; #ifdef S4MDX char bcd[sizeof(C4BCD)] ; #endif char *key ; double d, d_on, diff ; TAG4 *tag_ptr ; rc = x4seek_do( x4, d4seek( x4->data, s) ) ; if ( rc != 0 ) return rc ; /* 0 return may become r4after. */ tag_ptr = d4tag_default(x4->data) ; len = strlen(s) ; /* do the search according to the tag type */ switch ( t4type(tag_ptr) ) { #ifndef S4MDX case r4num_doub: d = c4atod( s, len ) ; d_on = expr4double(tag_ptr->expr) ; if ( x4->data->code_base->error_code < 0 ) return -1 ; diff = d_on - d ; if ( diff < -E4ACCURACY || diff > E4ACCURACY ) return r4after ; return 0 ; #else case r4num_doub: d = c4atod( s, len ) ; d_on = expr4double(tag_ptr->expr) ; if ( x4->data->code_base->error_code < 0 ) return -1 ; diff = d_on - d ; if ( diff < -E4ACCURACY || diff > E4ACCURACY ) return r4after ; return 0 ; case r4date_doub: d = (double) date4long(s) ; d_on = expr4double(tag_ptr->expr) ; if ( x4->data->code_base->error_code < 0 ) return -1 ; diff = d_on - d ; if ( diff < -E4ACCURACY || diff > E4ACCURACY ) return r4after ; return 0 ; case r4num: c4bcd_from_a( bcd, s, len ) ; if ( expr4key( tag_ptr->expr, &key ) < 0 ) return -1 ; if (u4memcmp( bcd, key, sizeof(C4BCD)) == 0 ) return 0 ; break ; #endif default : if ( (compare_len = expr4key( tag_ptr->expr, &key)) < 0 ) return -1 ; if ( len < compare_len ) compare_len = len ; if ( memcmp( key, s, compare_len ) == 0 ) return 0 ; break ; } return r4after ; } int x4seek_do( X4FILTER *x4, int seek_rc ) { int rc ; if ( seek_rc != r4after && seek_rc != 0 ) return seek_rc ; rc = x4find_good( x4, 1) ; if ( rc != r4keep ) return rc ; return seek_rc ; } int S4FUNCTION x4skip( X4FILTER *x4, long n ) { CODE4 *c4 ; DATA4 *d4 ; int sign, rc, save_flag ; long good_rec ; d4 = x4->data ; c4 = d4->code_base ; if ( c4->error_code < 0 ) return -1 ; if ( n < 0 ) { n = -n ; sign = -1 ; } else sign = 1 ; while ( n-- ) /* skip a record */ { good_rec = d4recno( d4 ) ; if (r4locked == d4skip( x4->data, sign) ) return r4locked ; rc = x4find_good(x4, sign) ; if ( rc != r4keep ) { if ( rc != r4eof && rc != r4bof ) return rc ; if ( sign > 0 ) { if ( (rc = x4filter_go_eof(x4)) != r4eof ) return rc ; return r4eof ; } save_flag = c4->go_error ; c4->go_error = 0 ; rc = d4go( x4->data, good_rec ) ; c4->go_error = save_flag ; d4->bof_flag = 1 ; if ( rc != 0 ) return rc ; return r4bof ; } } if ( sign < 0 ) { if ( d4->bof_flag ) return r4bof ; } else { if ( d4->eof_flag ) return r4eof ; } return 0 ; } int S4FUNCTION x4top( X4FILTER *x4 ) { int rc ; if ( (rc = d4top(x4->data)) != 0 ) return rc ; rc = x4find_good(x4, 1) ; if ( rc == r4keep ) return 0 ; if ( rc == r4eof ) { x4->data->bof_flag = 1 ; if ( (rc = x4filter_go_eof(x4)) != r4eof ) return rc ; return r4eof ; } return rc ; }