DWIOBUFF *DwioBuffWrite( // WRITE A RECORD DWIOBUFF *ctl, // - buffer control void *record, // - record to be written size_t size ) // - record size { DWIOBUFF *next; // - next buffer control size_t len; // - amount to write for(;;) { len = DWBLOCK_BSIZE - ctl->current_offset; if( len > size ) { len = size; } memcpy( pointXfer( ctl ), record, len ); ctl->written = false; ctl->current_offset += len; record = (void *)((char *)record + len); size -= len; if( size == 0 ) break; if( ctl->next_addr == 0 ) { next = findWrBuffer(); ctl->next_addr = next->disk_addr; next->prev_addr = ctl->disk_addr; next->block_num = ctl->block_num + 1; } else { next = findReWrBuffer( ctl->next_addr ); } next->current_offset = 0; finishWrBuffer( ctl ); ctl = next; } return ctl; }
DWIOBUFF *DwioBuffSeek( // POSITION TO SPECIFIED OFFSET FROM START DWIOBUFF *ctl, // - current buffer control DISK_ADDR block, // - starting disk address size_t offset ) // - where to position to { DWIOBUFF *next; // - next buffer control size_t required_block; size_t required_offset; required_block = offset / DWBLOCK_BSIZE; required_offset = offset % DWBLOCK_BSIZE; while( ctl->block_num != required_block ) { if( ctl->block_num < required_block ) { if( ctl->next_addr == 0 ) { next = findWrBuffer(); ctl->next_addr = next->disk_addr; next->prev_addr = ctl->disk_addr; next->block_num = ctl->block_num + 1; } else { next = findReWrBuffer( ctl->next_addr ); } } else { if( (ctl->block_num - required_block) > required_block ) { next = findReWrBuffer( block ); } else { if( ctl->prev_addr == 0 ) { #ifndef NDEBUG CFatal( "dwiobuff: attempt to seek off start of file" ); #endif } else { next = findReWrBuffer( ctl->prev_addr ); } } } finishWrBuffer( ctl ); ctl = next; } ctl->current_offset = required_offset; return( ctl ); }
void DwioBuffWrClose( // RELEASE BUFFER AFTER WRITING DWIOBUFF *ctl ) // - buffer control { finishWrBuffer( ctl ); }