Exemplo n.º 1
0
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 );
}
Exemplo n.º 2
0
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 );
}
Exemplo n.º 3
0
long int        FGetFilePos( b_file *io )
{
    return( CurrFileOffset( io ) );
}