int FSkipLogical( b_file *io ) //================================ { unsigned_32 tag; unsigned_32 save_tag; size_t rc; for(;;) { rc = SysRead( io, (char *)(&tag), sizeof( unsigned_32 ) ); if( rc == READ_ERROR ) { if( io->stat != IO_EOF ) return( -1 ); // if an EOF occurs we've skipped the record IOOk( io ); return( 0 ); } if( (tag & 0x80000000) == 0 ) break; save_tag = tag; tag &= 0x7fffffff; if( SysSeek( io, tag, SEEK_CUR ) < 0 ) return( -1 ); rc = SysRead( io, (char *)(&tag), sizeof( unsigned_32 ) ); if( rc == READ_ERROR ) return( -1 ); if( tag != save_tag ) { FSetErr( IO_BAD_RECORD, io ); return( -1 ); } } if( SysSeek( io, -(long)sizeof( unsigned_32 ), SEEK_CUR ) < 0 ) return( -1 ); return( 0 ); }
static size_t GetVariableRec( b_file *io, char *b, size_t len ) //============================================================= // Get a record from a file with "variable" records. { size_t tag_len; unsigned_32 tag; unsigned_32 save_tag; if( SysRead( io, (char *)(&tag), sizeof( unsigned_32 ) ) == READ_ERROR ) { return( 0 ); } save_tag = tag; tag_len = tag & 0x7fffffff; if( tag_len > len ) { FSetTrunc( io ); if( SysRead( io, b, len ) == READ_ERROR ) return( 0 ); if( SysSeek( io, (long)tag_len - (long)len, SEEK_CUR ) < 0 ) { FSetSysErr( io ); return( 0 ); } } else { if( SysRead( io, b, tag_len ) == READ_ERROR ) return( 0 ); len = tag_len; } if( SysRead( io, (char *)(&tag), sizeof( unsigned_32 ) ) == READ_ERROR ) return( 0 ); if( tag != save_tag ) { FSetErr( IO_BAD_RECORD, io ); return( 0 ); } return( len ); }
signed_32 FGetVarRecLen( b_file *io ) //========================================= { unsigned_32 tag; unsigned_32 save_tag; int rc; long pos; unsigned_32 size = 0; pos = FGetFilePos( io ); for( ;; ) { rc = SysRead( io, (char *)(&tag), sizeof( unsigned_32 ) ); if( rc == READ_ERROR ) { if( io->stat != IO_EOF ) return( -1 ); // if an EOF occurs we've skipped the record IOOk( io ); break; } save_tag = tag; if( !size ) { if( tag & 0x80000000 ) { FSetErr( IO_BAD_RECORD, io ); return( -1 ); } } else { if( tag & 0x80000000 ) { tag &= 0x7fffffff; } else { break; } } size += tag; if( SysSeek( io, tag, SEEK_CUR ) < 0 ) return( -1 ); rc = SysRead( io, (char *)(&tag), sizeof( unsigned_32 ) ); if( rc == READ_ERROR ) return( -1 ); if( tag != save_tag ) { FSetErr( IO_BAD_RECORD, io ); return( -1 ); } } if( SysSeek( io, pos, SEEK_SET ) < 0 ) return( -1 ); return( size ); }
static void ChkDisk( ftnfile *fcb ) { //======================================= // Make sure that the file is a disk file. if( IsDevice( fcb ) ) { FSetErr( IO_BAD_OPERATION, fcb->fileptr ); } }
b_file *_AllocFile( int h, f_attrs attrs, long int fpos ) { // Allocate file structure. b_file *io; struct stat info; int buff_size; if( fstat( h, &info ) == -1 ) { FSetSysErr( NULL ); return( NULL ); } attrs &= ~CREATION_MASK; if( S_ISCHR( info.st_mode ) ) { io = MEM_ALLOC( sizeof( a_file ) ); // Turn off truncate just in case we turned it on by accident due to // a buggy NT dos box. We NEVER want to truncate a device. attrs &= ~TRUNC_ON_WRITE; attrs |= CHAR_DEVICE; } else { attrs |= BUFFERED; buff_size = IOBufferSize; io = MEM_ALLOC( sizeof( b_file ) + IOBufferSize - MIN_BUFFER ); if( ( io == NULL ) && ( IOBufferSize > MIN_BUFFER ) ) { // buffer is too big (low on memory) so use small buffer buff_size = MIN_BUFFER; io = MEM_ALLOC( sizeof( b_file ) ); } } if( io == NULL ) { close( h ); FSetErr( IO_NO_MEM, NULL ); } else { if( attrs & CARRIAGE_CONTROL ) { attrs |= CC_NOLF; } io->attrs = attrs; io->handle = h; if( attrs & BUFFERED ) { io->b_curs = 0; io->read_len = 0; io->buff_size = buff_size; io->high_water = 0; } io->phys_offset = fpos; IOOk( io ); } return( io ); }
void FSeekRec( b_file *io, unsigned_32 rec, uint recsize ) // Seek to specified record in file. { IOOk( io ); if( io->attrs & SEEK ) { if( io->attrs & REC_TEXT ) { #if defined( __UNIX__ ) recsize += sizeof( char ); // compensate for LF #else recsize += 2 * sizeof( char ); // compensate for CR/LF #endif } else if( io->attrs & REC_VARIABLE ) { recsize += 2 * sizeof( unsigned_32 ); // compensate for length tags } SysSeek( io, rec * recsize, SEEK_SET ); } else { FSetErr( IO_BAD_OPERATION, io ); } }
static size_t GetTextRec( b_file *io, char *b, size_t len ) //========================================================= // Get a record from a TEXT file. { char ch; size_t read; char rs[2]; if( io->attrs & SEEK ) { // direct access if( SysRead( io, b, len ) == READ_ERROR ) return( 0 ); if( SysRead( io, rs, sizeof( char ) ) == READ_ERROR ) return( 0 ); if( rs[0] == LF ) return( len ); #if ! defined( __UNIX__ ) if( rs[0] == CR ) { if( SysRead( io, &rs[1], sizeof( char ) ) == READ_ERROR ) { return( 0 ); } if( rs[1] == LF ) return( len ); if( ( io->attrs & CARRIAGE_CONTROL ) && ( rs[1] == FF ) ) { return( len ); } } #endif FSetErr( IO_BAD_RECORD, io ); return( 0 ); } else if( io->attrs & BUFFERED ) { char *ptr; char *stop; bool seen_cr; bool trunc; size_t max_valid; // determine maximum valid position in the buffer max_valid = io->read_len; if( max_valid < io->high_water ) { max_valid = io->high_water; } stop = io->buffer + max_valid; ptr = io->buffer + io->b_curs; read = 0; seen_cr = false; trunc = false; for( ;; ) { if( ptr >= stop ) { io->b_curs = ptr - io->buffer; if( FillBuffer( io ) < 0 ) { // we have to do this so that io->b_curs is set properly // on end of file ptr = io->buffer + io->b_curs; if( read > 0 && io->stat == IO_EOF ) { IOOk( io ); } break; } stop = io->buffer + io->read_len; ptr = io->buffer + io->b_curs; } ch = *ptr; ++ptr; if( ch == LF ) break; if( !seen_cr ) { if( ch == CTRL_Z ) { --ptr; // give back char so we don't read past EOF if( read == 0 ) FSetEof( io ); break; } if( ch == CR ) { seen_cr = true; } else if( read < len ) { b[read] = ch; ++read; } else { trunc = true; } } else { if( ch == FF && (io->attrs & CARRIAGE_CONTROL) ) break; --ptr; // give back the char seen_cr = false; if( read < len ) { b[read] = CR; ++read; } else { trunc = true; } } } io->b_curs = ptr - io->buffer; if( trunc ) { FSetTrunc( io ); } return( read ); } else { // device (CON) read = 0; len = readbytes( io, b, len ); if( len == READ_ERROR ) return( 0 ); for( ;; ) { if( read == len ) break; #if defined( __UNIX__ ) || defined( __NETWARE__ ) if( *b == LF ) return( read ); #else if( *b == CR ) { ++b; if( read == len - 1 ) break; if( *b == LF ) return( read ); --b; } else if( *b == CTRL_Z ) { FSetEof( io ); return( read ); } #endif ++b; ++read; } FSetTrunc( io ); return( read ); } }