which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@976 c028cbd2-c16b-5b4b-a496-9718f37d4682
361 lines
10 KiB
C
Executable File
361 lines
10 KiB
C
Executable File
/* 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 ) ;
|
|
}
|