/* f4filese.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved. */ #include "d4all.h" #ifndef S4UNIX #ifdef __TURBOC__ #pragma hdrstop #endif #endif unsigned S4FUNCTION file4seq_read( FILE4SEQ_READ *seq_read, void *ptr, unsigned len ) { CODE4 *c4 ; unsigned urc, buffer_i, copy_bytes ; long lrc ; #ifdef S4DEBUG if ( seq_read == 0 || ( ptr == 0 && len ) ) e4severe( e4parm, E4_F4SEQ_READ ) ; if ( seq_read->file == 0 ) e4severe( e4info, E4_F4SEQ_READ ) ; #endif c4 = seq_read->file->code_base ; if ( c4->error_code < 0 ) return 0 ; if ( seq_read->buffer == 0 ) { urc = file4read( seq_read->file, seq_read->pos, ptr, len ) ; seq_read->pos += urc ; return urc ; } if ( seq_read->avail == 0 ) { #ifdef S4DEBUG if ( seq_read->pos < 0 ) e4severe( e4result, E4_F4SEQ_READ ) ; #endif #ifdef S4WINDOWS lrc = _llseek( seq_read->file->hand, seq_read->pos, 0 ) ; #else #ifdef S4MACINTOSH lrc = MAClseek( seq_read->file->hand, seq_read->pos, 0, 0 ) ; #else #ifdef S4WIN32 if ( SetFilePointer( (HANDLE)seq_read->file->hand, seq_read->pos, NULL, FILE_BEGIN ) != (DWORD)-1 ) lrc = seq_read->pos ; #else #ifdef S4LSEEK lrc = f4lseek( seq_read->file, seq_read->pos, 0, 0 ) ; #else lrc = lseek( seq_read->file->hand, seq_read->pos, 0 ) ; #endif #endif #endif #endif if ( lrc != seq_read->pos ) { file4read_error( seq_read->file ) ; return 0 ; } #ifdef S4WINDOWS seq_read->avail = seq_read->working = (unsigned)_lread( seq_read->file->hand, seq_read->buffer, seq_read->next_read_len ) ; #else #ifdef S4MACINTOSH lrc = (long) seq_read->next_read_len ; urc = FSRead( seq_read->file->hand, &lrc, seq_read->buffer ) ; if ( urc == 0 ) urc = seq_read->next_read_len ; seq_read->avail = seq_read->working = urc ; #else #ifdef S4WIN32 ReadFile( (HANDLE)seq_read->file->hand, seq_read->buffer, seq_read->next_read_len, (unsigned long *)&seq_read->working, NULL ) ; seq_read->avail = seq_read->working ; #else seq_read->avail = seq_read->working = (unsigned)read( seq_read->file->hand, seq_read->buffer, seq_read->next_read_len ) ; #endif #endif #endif if ( seq_read->working == UINT_MAX ) { file4read_error( seq_read->file ) ; return 0 ; } #ifdef S4DEBUG /* Make sure reading is aligned correctly for maximum speed */ if ( ( seq_read->pos + seq_read->next_read_len ) % 0x400 && seq_read->avail ) e4severe( e4result, E4_F4SEQ_READ ) ; #endif seq_read->pos += seq_read->working ; seq_read->next_read_len = seq_read->total ; } if ( seq_read->avail >= len ) { buffer_i = seq_read->working - seq_read->avail ; memcpy( ptr, seq_read->buffer + buffer_i, len ) ; seq_read->avail -= len ; return len ; } else { if ( seq_read->avail == 0 ) return 0 ; buffer_i = seq_read->working - seq_read->avail ; memcpy( ptr, seq_read->buffer + buffer_i, seq_read->avail ) ; copy_bytes = seq_read->avail ; seq_read->avail = 0 ; urc = file4seq_read( seq_read, (char *)ptr + copy_bytes, len - copy_bytes ) ; if ( c4->error_code < 0 ) return 0 ; return urc + copy_bytes ; } } int S4FUNCTION file4seq_read_all( FILE4SEQ_READ *seq_read, void *ptr, unsigned len ) { unsigned len_read ; #ifdef S4DEBUG if ( seq_read == 0 || ( ptr == 0 && len ) ) e4severe( e4parm, E4_F4SEQ_READ_ALL ) ; if ( seq_read->file == 0 ) e4severe( e4info, E4_F4SEQ_READ_ALL ) ; #endif len_read = file4seq_read( seq_read, ptr, len ) ; if ( seq_read->file->code_base->error_code < 0 ) return -1 ; if ( len_read != len ) return file4read_error( seq_read->file ) ; return 0 ; } void S4FUNCTION file4seq_read_init( FILE4SEQ_READ *seq_read, FILE4 *file, long start_pos, void *buffer, unsigned buffer_len ) { #ifdef S4DEBUG if ( start_pos < 0 || seq_read == 0 || file == 0 ) e4severe( e4parm, E4_F4SEQ_READ_IN ) ; #endif memset( (void *)seq_read, 0, sizeof( FILE4SEQ_READ ) ) ; #ifndef S4OPTIMIZE_OFF file4low_flush( file, 1 ) ; #endif if ( buffer_len > 0 ) { seq_read->total = buffer_len & 0xFC00 ; /* Make it a multiple of 1K */ if ( seq_read->total > (unsigned)( start_pos % 0x400 ) ) seq_read->next_read_len = seq_read->total - (unsigned)( start_pos % 0x400 ) ; seq_read->buffer = (char *)buffer ; } seq_read->pos = start_pos ; seq_read->file = file ; } int S4FUNCTION file4seq_write( FILE4SEQ_WRITE *seq_write, void *buffer, unsigned ptr_len ) { int rc ; unsigned first_len ; #ifdef S4DEBUG if ( seq_write == 0 || ( ptr_len && buffer == 0 ) ) e4severe( e4parm, E4_F4SEQ_WRITE ) ; #endif if ( seq_write->file->code_base->error_code < 0 ) return -1 ; if ( seq_write->buffer == 0 ) { rc = file4write( seq_write->file, seq_write->pos, buffer, ptr_len ) ; #ifndef S4OPTIMIZE_OFF #ifdef S4DEBUG_DEV if ( seq_write->file->has_dup == 1 ) if ( file4write_part( buffer, seq_write->file, seq_write->pos, ptr_len ) != 0 ) e4severe( e4opt, "file4write() - file corruption" ) ; #endif #endif seq_write->pos += ptr_len ; return rc ; } if ( seq_write->avail == 0 ) if ( file4seq_write_flush( seq_write ) < 0 ) return -1 ; if ( seq_write->avail >= ptr_len ) { #ifdef S4DEBUG if ( seq_write->working < seq_write->avail || ( seq_write->working - seq_write->avail + ptr_len ) > seq_write->total ) e4severe( e4result, E4_F4SEQ_WRITE ) ; #endif memcpy( seq_write->buffer + ( seq_write->working - seq_write->avail ), buffer, ptr_len ) ; seq_write->avail -= ptr_len ; return 0 ; } else { first_len = seq_write->avail ; #ifdef S4DEBUG if ( seq_write->working < seq_write->avail || seq_write->working > seq_write->total ) e4severe( e4result, E4_F4SEQ_WRITE ) ; #endif memcpy( seq_write->buffer + ( seq_write->working - seq_write->avail ), buffer, seq_write->avail ) ; seq_write->avail = 0 ; return file4seq_write( seq_write, (char *)buffer + first_len, ptr_len - first_len ) ; } } int S4FUNCTION file4seq_write_flush( FILE4SEQ_WRITE *seq_write ) { unsigned to_write ; #ifdef S4MACINTOSH long long_to_write ; short vRefNum ; #endif #ifdef S4DEBUG if ( seq_write == 0 ) e4severe( e4parm, E4_F4SEQ_WRT_FLSH ) ; #endif if ( seq_write->file->code_base->error_code < 0 ) return -1 ; if ( seq_write->buffer == 0 ) return 0 ; #ifdef S4DEBUG if( seq_write->pos < 0 ) e4severe( e4result, (char *) 0 ) ; #endif to_write = seq_write->working - seq_write->avail ; #ifndef S4OPTIMIZE_OFF #ifdef S4DEBUG_DEV if ( seq_write->file->has_dup == 1 ) if ( file4write_part( seq_write->buffer, seq_write->file, seq_write->pos, to_write ) != 0 ) e4severe( e4opt, "file4write() - file corruption" ) ; #endif if ( seq_write->file->do_buffer == 1 && seq_write->file->buffer_writes == 1 ) { if ( file4write( seq_write->file, seq_write->pos, seq_write->buffer, to_write ) != 0 ) return e4( seq_write->file->code_base, e4write, seq_write->file->name ) ; } else #endif #ifdef S4WINDOWS { if ( _llseek( seq_write->file->hand, seq_write->pos, 0 ) != seq_write->pos ) return e4( seq_write->file->code_base, e4write, seq_write->file->name ) ; if ( (unsigned)_lwrite( seq_write->file->hand, seq_write->buffer, to_write) != to_write) return e4( seq_write->file->code_base, e4write, seq_write->file->name ) ; } #else { #ifdef S4MACINTOSH if ( MAClseek( seq_write->file->hand, seq_write->pos, 0, 1 ) != seq_write->pos ) return e4( seq_write->file->code_base, e4write, seq_write->file->name ) ; long_to_write = (long ) to_write ; if ( FSWrite( seq_write->file->hand, &long_to_write, seq_write->buffer ) < 0 ) return e4( seq_write->file->code_base, e4write, seq_write->file->name ) ; if (GetVRefNum( seq_write->file->hand, &vRefNum ) != 0 ) return e4( seq_write->file->code_base, e4write, 0 ) ; if (FlushVol( 0, vRefNum ) != 0 ) return e4( seq_write->file->code_base, e4write, 0 ) ; #else #ifdef S4WIN32 long urc ; if ( SetFilePointer( (HANDLE)seq_write->file->hand, seq_write->pos, NULL, FILE_BEGIN ) == (DWORD)-1 ) return e4( seq_write->file->code_base, e4write, seq_write->file->name ) ; WriteFile( (HANDLE)seq_write->file->hand, seq_write->buffer, to_write, (unsigned long *)&urc, NULL ) ; if ( urc != to_write ) return e4( seq_write->file->code_base, e4write, seq_write->file->name ) ; #else #ifdef S4LSEEK if ( f4lseek( seq_write->file, seq_write->pos, 0, 1 ) != seq_write->pos ) return e4( seq_write->file->code_base, e4write, seq_write->file->name ) ; #else if ( lseek( seq_write->file->hand, seq_write->pos, 0 ) != seq_write->pos ) return e4( seq_write->file->code_base, e4write, seq_write->file->name ) ; #endif if ( (unsigned)write( seq_write->file->hand, seq_write->buffer, to_write) != to_write) return e4( seq_write->file->code_base, e4write, seq_write->file->name ) ; #endif #endif } #endif /* file4flush( seq_write->file ) VAX fix (flush req'd on write) */ seq_write->pos += to_write ; seq_write->avail = seq_write->working = seq_write->total ; return 0 ; } /* note that the sequential functions are not generally useful when hashing is in place since hashing effectively performs bufferring */ void S4FUNCTION file4seq_write_init( FILE4SEQ_WRITE *seq_write, FILE4 *file, long start_offset, void *ptr, unsigned ptr_len ) { #ifdef S4DEBUG if ( seq_write == 0 || file == 0 ) e4severe( e4parm, E4_F4SEQ_WRT_INIT ) ; #endif memset( (void *)seq_write, 0, sizeof( FILE4SEQ_WRITE ) ) ; #ifndef S4OPTIMIZE_OFF file4low_flush( file, 1 ) ; #endif seq_write->file = file ; if ( ptr_len > 0 ) { seq_write->total = ptr_len & 0xFC00 ; /* Make it a multiple of 1K */ seq_write->buffer = (char *)ptr ; if ( seq_write->total > (unsigned)( start_offset % 0x400 ) ) seq_write->avail = seq_write->working = seq_write->total - (unsigned)( start_offset % 0x400 ) ; } seq_write->pos = start_offset ; } int S4FUNCTION file4seq_write_repeat( FILE4SEQ_WRITE *seq_write, long num_repeat, char ch ) { char buf[512] ; #ifdef S4DEBUG if ( seq_write == 0 || num_repeat < 0 ) e4severe( e4parm, E4_F4SEQ_WRT_REP ) ; #endif memset( (void *)buf, ch, sizeof(buf) ) ; while ( num_repeat > sizeof(buf) ) { if ( file4seq_write( seq_write, buf, (unsigned)sizeof( buf ) ) < 0 ) return -1 ; num_repeat -= sizeof(buf) ; } return file4seq_write( seq_write, buf, (unsigned)num_repeat ) ; }