diff --git a/harbour/source/tools/hb_f.c b/harbour/source/tools/hb_f.c new file mode 100644 index 0000000000..ba674e6a25 --- /dev/null +++ b/harbour/source/tools/hb_f.c @@ -0,0 +1,287 @@ +/* +nanforum ft_f*() clones +* hb_fuse +* hb_frecno +* hb_flastrec +* hb_fgotop +* hb_fgobottom +* hb_fgoto +* hb_feof +* hb_freadln +* hb_fskip +*/ + +#include + +#define b_size 1024 +#define c_size 4096 +#define IT_NUMBER (IT_INTEGER|IT_LONG|IT_DOUBLE) + +static long _hbfskip( int recs ); +extern long _fsSeek( int, long, int ); +extern long _fsRead( int, char*, int ); +extern int _fsOpen( char*, int ); +extern void _fsClose( int ); + +static long last_rec[10]; +static long recno[10]; +static long offset[10]; +static int handles[10]; +static int area = 0; +static char *b; +static char *c; +static long last_off[10]; +static long lastbyte[10]; +static int isEof[10]; + +HARBOUR hb_fuse( void ) + +{ + + PITEM arg1_it = _param(1,IT_STRING); + PITEM arg2_it = _param(2,IT_NUMBER); + int open_flags; + + if ( arg1_it ) { + + if( arg2_it ) + open_flags = _parni(2); + else + open_flags = 0; + + handles[area] = _fsOpen( _parc(1), open_flags ); + offset[area] = 0; + recno[area] = 1; + b = _xgrab( b_size ); + c = _xgrab( c_size ); + lastbyte[area] = _fsSeek( handles[area], 0L, SEEK_END ); + _retni( handles[area] ); + } + else { + _fsClose( handles[area] ); + _xfree( b ) ; + _xfree( c ) ; + _retni( 1 ) ; + recno[area] = 0L ; + offset[area] = 0L ; + handles[area] = 0 ; + last_rec[area] = 0L ; + last_off[area] = 0L ; + lastbyte[area] = 0L ; + isEof[area] = 0 ; + } +} + + +HARBOUR hb_frecno( void ) + +{ + _retnl( recno[area] ); +} + + +HARBOUR hb_fskip( void ) + +{ + + PITEM arg1_it = _param(1,IT_NUMBER); + int nskip; + + if( arg1_it ) + nskip = _parni(1); + else + nskip = 1; + + _hbfskip(nskip); + +} + +long _hbfskip( int recs ) + +{ + + int x; + long read_pos; + size_t read_len; + long y; + + + if ( recs > 0 ) { + for (y = 0; y < recs; y++ ) { + _fsSeek( handles[area], offset[area], SEEK_SET ); + read_len = _fsRead( handles[area], b, b_size ); + for (x = 0; x < read_len; x++ ) { + if ( ((*(b + x) == 13) && (*(b + x + 1) == 10)) || + ((*(b + x) == 10) && (*(b + x + 1) == 13)) ) { + break; + } + } + if ( (offset[area] + x + 2) < lastbyte[area] ) { + isEof[area] = FALSE; + offset[area] += (x + 2); + recno[area] += 1; + } + else + isEof[area] = TRUE; + } + } + else { + recs = -recs; + isEof[area] = FALSE; + + if ( (recno[area] - recs) < 1 ) + return( 1 ); + + for (y = recs; y > 0; y-- ) { + if ( offset[area] - b_size < 0L ) { + read_pos = 0; + read_len = (size_t)offset[area]; + } + else { + read_pos = (size_t)(offset[area] - b_size); + read_len = b_size; + } + + _fsSeek( handles[area], read_pos, SEEK_SET ); + read_len = _fsRead( handles[area], b, read_len ); + + for (x = read_len - 4; x >= 0; x-- ) { + if ( ((*(b + x) == 13) && (*(b + x + 1) == 10)) || + ((*(b + x) == 10) && (*(b + x + 1) == 13)) ) { + break; + } + } + if ( x < 0 ) { + offset[area] = 0; + recno[area] = 1; + } + else { + offset[area] = read_pos + x + 2; + recno[area]--; + } + } + } + + return ( recno[area] ); +} + +HARBOUR hb_freadln( void ) + +{ + + int x; + long read; + + _fsSeek( handles[area], offset[area], SEEK_SET ); + read = _fsRead( handles[area], b, b_size ); + + for ( x = 0; x < b_size; x++ ) { + if ( ((*(b + x) == 13) && (*(b + x + 1) == 10)) || + ((*(b + x) == 10) && (*(b + x + 1) == 13)) || + (*(b + x) == 26) || ( x >= (int)read) ) { + break; + } + } + _retclen( b, x ); + +} + +HARBOUR hb_feof( void ) + +{ + + _retl( isEof[area] ); + +} + +HARBOUR hb_fgoto ( void ) + +{ + + long target; + long last; + + target = _parnl(1); + last = 0; + + if ( recno[area] > target ) { + while ( recno[area] != target ) { + last = recno[area]; + _hbfskip(-1); + if ( recno[area] == last ) + break; + } + } + else { + while ( recno[area] != target ) { + last = recno[area]; + _hbfskip(1); + if ( recno[area] == last ) + break; + } + } +} + +HARBOUR hb_fgobottom() + +{ + + int x; + int len; + long loc; + + if ( last_rec[area] != 0 ) { + recno[area] = last_rec[area]; + offset[area] = last_off[area]; + } + else { + + loc = 0L; + + do { + + _fsSeek( handles[area], offset[area], SEEK_SET ); + len = _fsRead( handles[area], c, c_size ); + for ( x = 0; x < len; x++ ) { + if ( ((*(c + x) == 13) && (*(c + x + 1) == 10)) || + ((*(c + x) == 10) && (*(c + x + 1) == 13)) || + ( x - loc > b_size ) ) { + recno[area]++; + x++; + loc = x + 1; + } + } + offset[area] += loc; + + } while ( len == c_size ); + + last_rec[area] = --recno[area]; + last_off[area] = offset[area]; + + } +} + +HARBOUR hb_fgotop( void ) +{ + + offset[area] = 0L; + recno[area] = 1L; + +} + +HARBOUR hb_flastrec( void ) +{ + + long old_rec; + long old_offset; + + old_rec = recno[area]; + old_offset = offset[area]; + + hb_fgobottom(); + _retnl( last_rec[area] ); + + recno[area] = old_rec; + offset[area] = old_offset; + +}