static uint GetPrevChar( b_file *io ) { //========================================= // Get previous character in file. if( CurrFileOffset( io ) == 0 ) return( NO_CHAR ); if( SysSeek( io, -1L, SEEK_CUR ) < 0 ) { return( NO_CHAR ); } if( ( io->attrs & READ_AHEAD ) && io->b_curs < io->read_len ) { return( io->buffer[ io->b_curs ] ); } else if( io->b_curs < io->high_water ) { return( io->buffer[ io->b_curs ] ); } return( NO_CHAR ); }
int SysSeek( b_file *io, long int new_offset, int seek_mode ) { long int curr_offset; long int new_page; long int page_offset; uint bytes_read; curr_offset = CurrFileOffset( io ); if( seek_mode == SEEK_CUR ) { new_offset += curr_offset; } if( io->attrs & WRITE_ONLY ) { if( curr_offset != new_offset ) { if( FlushBuffer( io ) < 0 ) { FSetSysErr( io ); return( -1 ); } if( lseek( io->handle, new_offset, SEEK_SET ) == -1 ) { FSetSysErr( io ); return( -1 ); } io->phys_offset = new_offset; } return( 0 ); } else if( io->attrs & READ_AHEAD ) { page_offset = io->phys_offset - io->read_len; if( page_offset <= new_offset ) { if( (new_offset < io->phys_offset) || ( (io->attrs & PAST_EOF) && (new_offset < page_offset + io->buff_size) ) ) { // we have the part of file in memory still, or we know we're // at the end of the file and the offset we want is on this // page as well io->b_curs = new_offset - io->phys_offset + io->read_len; return( 0 ); } } } else if( io->phys_offset <= new_offset && new_offset < io->phys_offset + io->buff_size ) { io->b_curs = new_offset - io->phys_offset; if( ( io->attrs & PAST_EOF ) || io->b_curs < io->high_water ) { // We already know that the EOF is on this page so don't bother // seeking and reading. Or we already have the part of the // file in the buffer. return( 0 ); } // we have part of this page in memory already... so read the // rest of the page if( lseek( io->handle, io->high_water, SEEK_CUR ) < 0 ) { FSetSysErr( io ); return( -1 ); } io->phys_offset += io->high_water; bytes_read = readbytes( io, io->buffer + io->high_water, io->buff_size - io->high_water ); if( bytes_read == READ_ERROR ) { if( io->stat != IO_EOF ) return( -1 ); IOOk( io ); io->phys_offset -= io->high_water; // restore offset if( lseek( io->handle, -(long)io->high_water, SEEK_CUR ) < 0 ) { FSetSysErr( io ); return( -1 ); } io->attrs |= PAST_EOF; // we now know the EOF is here } else { io->attrs |= READ_AHEAD; io->read_len = io->high_water + bytes_read; if( bytes_read < io->buff_size - io->high_water ) { io->attrs |= PAST_EOF; // we now know the EOF is here } } return( 0 ); } if( new_offset != curr_offset ) { if( FlushBuffer( io ) < 0 ) return( 0 ); // round down to the nearest multiple of buff_size new_page = new_offset - new_offset % io->buff_size; if( lseek( io->handle, new_page, SEEK_SET ) < 0 ) { FSetSysErr( io ); return( -1 ); } io->phys_offset = new_page; io->b_curs = new_offset - new_page; bytes_read = readbytes( io, io->buffer, io->buff_size ); if( bytes_read == READ_ERROR ) { if( io->stat != IO_EOF ) return( -1 ); IOOk( io ); io->attrs |= PAST_EOF; } else { if( bytes_read < io->buff_size ) { io->attrs |= PAST_EOF; } else { io->attrs &= ~PAST_EOF; } io->attrs |= READ_AHEAD; io->read_len = bytes_read; } } return( 0 ); }
long int FGetFilePos( b_file *io ) { return( CurrFileOffset( io ) ); }