campo-sirio/cb5/f4file.c

866 lines
18 KiB
C
Raw Normal View History

/* f4file.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved. */
#include "d4all.h"
#ifndef S4UNIX
#ifdef __TURBOC__
#pragma hdrstop
#endif
#endif
#ifdef S4TEMP
#include "t4test.h"
#endif
#include <time.h>
#ifndef S4UNIX
#ifndef S4IBMOS2
#ifndef __TURBOC__
#include <sys\locking.h>
#define S4LOCKING
#endif
#ifdef __ZTC__
extern int errno ;
#endif
#ifdef _MSC_VER
#include <sys\types.h>
#include <sys\locking.h>
#endif
#ifdef __TURBOC__
/* extern int cdecl errno ; */
#endif
#endif
#include <sys\stat.h>
#include <share.h>
#endif
#include <fcntl.h>
#include <errno.h>
#ifdef __SC__
#include <dos.h>
#endif
#ifdef S4ERRNO
extern int errno ;
#endif
#ifdef S4NO_FILELENGTH
#ifdef S4MACINTOSH
long filelength( int hand )
{
long filelen ;
if ( GetEOF(hand, &filelen) != 0 )
e4severe( e4result, "filelength(): GetEOF()" ) ;
return filelen ;
}
#else
#ifdef S4WIN32
long filelength( int hand )
{
long rc ;
rc = (long)GetFileSize( (HANDLE)hand, NULL ) ;
if ( rc == -1L )
e4severe( e4result, "filelength()" ) ;
return rc ;
}
#else
#include <sys/types.h>
#include <sys/stat.h>
long filelength( hand )
int hand ;
{
struct stat str_stat ;
if (fstat( hand, &str_stat ) )
e4severe( e4result, "filelength()" ) ;
return( (long) str_stat.st_size ) ;
}
#endif
#endif
#endif
#ifdef S4MACINTOSH
long MAClseek(int hand, long offset, int fromwhere, int extend )
{
long filelen ;
if ( offset != 0 )
{
filelen = filelength( hand ) ;
if (extend)
{
if ( filelen < offset )
SetEOF( hand, offset ) ;
}
else
if ( filelen < offset )
{
if ( SetFPos(hand, fsFromStart, filelen ) == 0 )
return offset ;
else
return -1L ;
}
}
if ( SetFPos(hand, fsFromStart, offset ) == 0 )
return offset ;
else
return -1L ;
}
#endif
#ifdef S4LSEEK
/* if extend is set, file is extended, else lseek to EOF */
long f4lseek(FILE4 *file, long offset, int fromwhere, int extend )
{
long filelen ;
if ( offset != 0 )
{
filelen = filelength( file->hand ) ;
if (extend)
{
if ( filelen < offset )
file4change_size( file, offset ) ;
}
else
if ( filelen < offset )
{
if ( lseek( file->hand, filelen, 0 ) )
return offset ;
else
return -1L ;
}
}
return lseek( file->hand, offset, fromwhere ) ;
}
#endif
#ifdef S4NO_CHSIZE
#define E4MAXLINE 129 /* maximum file path length */
#ifdef S4MACINTOSH
int S4FUNCTION file4change_size( FILE4 *f4, long size )
{
if ( SetEOF( f4->hand, size ) != 0 )
e4severe( e4result, "file4change_size(): SetEOF" ) ;
return 0 ;
}
#else
int S4FUNCTION file4change_size( FILE4 *f4, long size )
{
char *buffer ;
char temp_name[E4MAXLINE], file_name[E4MAXLINE] ;
long buffer_size, filelen, amount_read = 0, extra_size = 0 ;
CODE4 *c4 ;
FILE4 temp ;
FILE4SEQ_WRITE seq_write ;
FILE4SEQ_READ seq_read ;
if ( f4->is_read_only )
return e4( f4->code_base, e4parm, E4_PARM_SIZ ) ;
filelen = filelength( f4->hand ) ;
if ( size == filelen )
return 0 ;
if ( size > filelen ) /* pad file to increase size */
{
file4seq_write_init( &seq_write, f4, filelen, 0, 0 ) ;
file4seq_write_repeat( &seq_write, size - filelen, '\0' ) ;
return 0 ;
}
c4 = f4->code_base ;
memcpy( file_name, f4->name, E4MAXLINE ) ;
u4name_piece( temp_name, E4MAXLINE, f4->name, 1, 0 ) ;
u4name_ext( temp_name, E4MAXLINE, "TMP", 1 ) ;
if ( file4create( &temp, c4, temp_name, 0 ) < 0 )
{
e4( c4, e4create, temp_name ) ;
return -1 ;
}
buffer_size = c4->mem_size_buffer ;
buffer = (char *)u4alloc_free( c4, buffer_size ) ;
while ( !buffer )
{
buffer_size -= 0x400 ;
if ( buffer_size <= 0 )
{
e4( c4, e4memory, 0 ) ;
return -1 ;
}
buffer = (char *)u4alloc_free( c4, buffer_size ) ;
}
file4seq_write_init( &seq_write, &temp, 0, 0, buffer_size ) ;
file4seq_read_init( &seq_read, f4, 0, 0, buffer_size ) ;
/* copy the old file contents to the temp file */
while ( size > 0 )
{
if ( size < buffer_size )
amount_read = file4seq_read( &seq_read, buffer, size ) ;
else
amount_read = file4seq_read( &seq_read, buffer, buffer_size ) ;
file4seq_write( &seq_write, buffer, amount_read ) ;
size -= amount_read ;
}
file4seq_write_flush( &seq_write ) ;
u4free( buffer ) ;
file4close( f4 ) ;
file4close( &temp ) ;
if ( u4remove( file_name ) )
{
e4( c4, e4info, file_name ) ;
return -1 ;
}
if ( u4rename( temp_name, file_name ) )
{
e4( c4, e4rename, temp_name ) ;
return -1 ;
}
if ( file4open( f4, c4, file_name, 1 ) < 0 )
{
e4( c4, e4open, file_name ) ;
return -1 ;
}
if ( file4lock( f4, L4LOCK_POS, L4LOCK_POS ) < 0 )
{
e4( c4, e4lock, file_name ) ;
return -1 ;
}
return 0 ;
}
#endif /* ifdef S4MACINTOSH */
#endif /* ifdef S4NO_CHSIZE */
long S4FUNCTION file4len( FILE4 *file )
{
long lrc ;
#ifdef S4DEBUG
if ( file == 0 )
e4severe( e4parm, E4_FILE4LEN ) ;
if ( file->hand < 0 && file->file_created != 0 )
e4severe( e4parm, E4_FILE4LEN ) ;
#endif
#ifndef S4OPTIMIZE_OFF
if ( file->is_temp == 1 && file->file_created == 0 && file->len == -1 )
return 0 ;
if ( file->do_buffer && file->len >= 0 )
lrc = file->len ;
else
#endif
lrc = filelength( file->hand ) ;
if ( lrc < 0L )
e4( file->code_base, e4len, file->name ) ;
return lrc ;
}
int S4FUNCTION file4len_set( FILE4 *file, long new_len )
{
int rc ;
#ifdef __SC__
union REGS dos_flush ;
#endif
#ifdef S4DEBUG
if ( file == 0 || new_len < 0 )
e4severe( e4parm, E4_FILE4LEN_SET ) ;
if ( file->hand < 0 && file->file_created != 0 )
e4severe( e4parm, E4_FILE4LEN_SET ) ;
#endif
if ( file->code_base->error_code > 0 && file->code_base->error_code < 200 ) /* file error */
return -1 ;
if ( file->is_read_only )
return e4( file->code_base, e4parm, E4_PARM_SIZ ) ;
#ifndef S4OPTIMIZE_OFF
if ( file->do_buffer )
{
if ( file->len > new_len ) /* must do a partial delete of memory */
opt4file_delete( file, new_len, file->len ) ;
if ( file->buffer_writes )
file->len = new_len ;
#ifdef S4DEBUG
else
if ( file->len != -1L )
e4severe( e4opt, E4_FILE4LEN_SET ) ;
#endif
}
#ifndef S4SAFE
if ( file->do_buffer == 0 || file->buffer_writes == 0 )
#endif
#endif
#ifdef S4NO_CHSIZE
rc = file4change_size( file, new_len ) ;
#else
#ifdef S4WIN32
if ( SetFilePointer( (HANDLE)file->hand, new_len, NULL, FILE_BEGIN ) == (DWORD)-1 )
return e4( file->code_base, e4len_set, file->name ) ;
if ( SetEndOfFile( (HANDLE)file->hand ) )
rc = 0 ;
else
rc = -1 ;
#else
#ifdef __SC__
dos_flush.x.ax = 0x4200;
dos_flush.x.bx = file->hand ;
memcpy((void *)&dos_flush.x.dx,(void *)&new_len,2);
memcpy((void *)&dos_flush.x.cx,((char *)&new_len)+2,2);
intdos( &dos_flush, &dos_flush ) ;
if ( dos_flush.x.cflag != 0 )
return e4( file->code_base, e4len_set, 0 ) ;
dos_flush.h.ah = 0x40;
dos_flush.x.bx = file->hand ;
dos_flush.x.cx = 0x00;
intdos( &dos_flush, &dos_flush ) ;
if ( dos_flush.x.cflag != 0 )
return e4( file->code_base, e4len_set, 0 ) ;
#else
rc = chsize( file->hand, new_len ) ;
#endif
#endif
#endif
if ( rc < 0 )
{
e4describe( file->code_base, e4len_set, E4_CREATE_FIL, file->name, (char *)0 ) ;
return -1 ;
}
return 0 ;
}
unsigned S4FUNCTION file4read( FILE4 *file, long pos, void *ptr, unsigned ptr_len )
{
long rc ;
unsigned urc ;
#ifdef S4DEBUG
if ( file == 0 || pos < 0 || ptr == 0 )
e4severe( e4parm, E4_F4READ ) ;
if ( file->hand < 0 && file->file_created != 0 )
e4severe( e4parm, E4_F4READ ) ;
#endif
if ( file->code_base->error_code < 0 )
return 0 ;
#ifndef S4OPTIMIZE_OFF
if ( file->do_buffer )
urc = (unsigned)opt4file_read( file, pos, ptr, ptr_len ) ;
else
{
#endif
#ifdef S4WINDOWS
rc = _llseek( file->hand, pos, 0 ) ;
#else
#ifdef S4MACINTOSH
rc = MAClseek( file->hand, pos, 0, 0 ) ;
#else
#ifdef S4WIN32
if ( rc = SetFilePointer( (HANDLE)file->hand, pos, NULL, FILE_BEGIN ) != (DWORD)-1 )
rc = pos ;
#else
#ifdef S4LSEEK
rc = f4lseek( file, pos, 0, 0 ) ;
#else
rc = lseek( file->hand, pos, 0 ) ;
#endif
#endif
#endif
#endif
if ( rc != pos )
{
file4read_error( file ) ;
return 0 ;
}
#ifdef S4WINDOWS
urc = (unsigned)_lread( file->hand, (char *)ptr, ptr_len ) ;
#else
#ifdef S4MACINTOSH
rc = (long) ptr_len ;
urc = FSRead( file->hand, &rc, ptr ) ;
if ( urc == 0 ) urc = ptr_len ;
if ( urc == eofErr ) urc = rc ; /* attempt to read past EOF OK */
#else
#ifdef S4WIN32
rc = ReadFile( (HANDLE)file->hand, ptr, ptr_len, (unsigned long *)&urc, NULL ) ;
if ( !rc )
rc = GetLastError() ;
#else
#ifdef S4LSEEK
/* if reading past EOF */
if ( pos+ptr_len > filelength( file->hand ) )
urc = (unsigned)read( file->hand, ptr, filelength(file->hand) - pos ) ;
else
urc = (unsigned)read( file->hand, ptr, ptr_len ) ;
#else
urc = (unsigned)read( file->hand, ptr, ptr_len ) ;
#endif
#endif
#endif
#endif
#ifndef S4OPTIMIZE_OFF
}
#endif
if ( urc != ptr_len )
if ( urc > ptr_len )
{
file4read_error( file ) ;
return 0 ;
}
#ifndef S4OPTIMIZE_OFF
#ifdef S4DEBUG_DEV
if ( file->has_dup == 1 )
if ( file->do_buffer == 1 || file->link.n == 0 )
if ( file4cmp_part( file->code_base, ptr, file, pos, urc ) != 0 )
e4severe( e4opt, "file4read() - file corruption" ) ;
#endif
#endif
return urc ;
}
int S4FUNCTION file4read_all( FILE4 *file, long pos, void *ptr, unsigned ptr_len )
{
long rc ;
unsigned urc ;
#ifdef S4DEBUG
if ( file == 0 || pos < 0 || ptr == 0 )
e4severe( e4parm, E4_F4READ_ALL ) ;
if ( file->hand < 0 && file->file_created != 0 )
e4severe( e4parm, E4_F4READ_ALL ) ;
#endif
if ( file->code_base->error_code < 0 )
return -1 ;
#ifndef S4OPTIMIZE_OFF
if ( file->do_buffer )
urc = (unsigned) opt4file_read( file, pos, ptr, ptr_len ) ;
else
{
#endif
#ifdef S4WINDOWS
rc = _llseek( file->hand, pos, 0 ) ;
#else
#ifdef S4MACINTOSH
rc = MAClseek( file->hand, pos, 0, 0 ) ;
#else
#ifdef S4WIN32
if ( SetFilePointer( (HANDLE)file->hand, pos, NULL, FILE_BEGIN ) != (DWORD)-1 )
rc = pos ;
#else
#ifdef S4LSEEK
rc = f4lseek( file, pos, 0, 0 ) ;
#else
rc = lseek( file->hand, pos, 0 ) ;
#endif
#endif
#endif
#endif
if ( rc != pos )
return file4read_error( file ) ;
#ifdef S4WINDOWS
urc = (unsigned)_lread( file->hand, (char *)ptr, ptr_len ) ;
#else
#ifdef S4MACINTOSH
rc = (long) ptr_len ;
urc = FSRead( file->hand, &rc, ptr ) ;
if ( urc == 0 )
urc = ptr_len ;
#else
#ifdef S4WIN32
rc = ReadFile( (HANDLE)file->hand, ptr, ptr_len, (unsigned long *)&urc, NULL ) ;
if ( !rc )
rc = GetLastError() ;
#else
urc = (unsigned)read( file->hand, ptr, ptr_len ) ;
#endif
#endif
#endif
#ifndef S4OPTIMIZE_OFF
}
#endif
if ( urc != ptr_len )
return file4read_error( file ) ;
#ifndef S4OPTIMIZE_OFF
#ifdef S4DEBUG_DEV
if ( file->has_dup == 1 )
if ( file->do_buffer == 1 || file->link.n == 0 )
if ( file4cmp_part( file->code_base, ptr, file, pos, urc ) != 0 )
e4severe( e4opt, "file4read_all() - file corruption" ) ;
#endif
#endif
return 0 ;
}
int S4FUNCTION file4read_error( FILE4 *file )
{
return e4describe( file->code_base, e4read, E4_CREATE_FIL, file->name, (char *) 0 ) ;
}
int S4FUNCTION file4replace( FILE4 *keep, FILE4 *from )
{
#ifdef S4NO_RENAME
return e4( from->code_base, e4not_rename, E4_F4REPLACE ) ;
#else
FILE4 tmp ;
int from_do_alloc_free, rc ;
char *from_name ;
#ifndef S4SINGLE
char *buf ;
unsigned buf_size ;
#ifndef S4OPTIMIZE_OFF
int has_opt ;
#endif
long pos, f_len ;
#endif
#ifdef S4DEBUG
if ( keep == 0 || from == 0 )
e4severe( e4parm, E4_F4REPLACE ) ;
#endif
rc = 0 ;
if ( from->is_read_only || keep->is_read_only )
return e4( from->code_base, e4parm, E4_PARM_REP ) ;
#ifndef S4SINGLE
if ( keep->is_exclusive )
{
#endif
memcpy( (void *)&tmp, (void *)keep, sizeof ( FILE4 ) ) ; /* remember settings */
keep->hand = from->hand ;
from->hand = tmp.hand ;
from_do_alloc_free = from->do_alloc_free ;
keep->do_alloc_free = 0 ;
from->do_alloc_free = 0 ;
from_name = from->name ;
from->name = keep->name ;
from->is_temp = 1 ;
if ( file4close ( from ) )
return -1 ;
if ( file4close ( keep ) )
return -1 ;
if ( rename( from_name, tmp.name ) < 0 )
return - 1 ;
if ( from_do_alloc_free )
u4free( from_name ) ;
if ( file4open ( keep, tmp.code_base, tmp.name, 0 ) )
return -1 ;
keep->is_temp = tmp.is_temp ;
keep->do_alloc_free = tmp.do_alloc_free ;
#ifndef S4OPTIMIZE_OFF
if ( tmp.link.n != 0 ) /* file was optimized... */
file4optimize( keep, tmp.code_base->optimize ,tmp.type ) ;
#endif
#ifndef S4SINGLE
}
else /* can't lose the file handle if other user's have the file open, so just do a copy */
{
file4len_set( keep, 0 ) ;
buf_size = from->code_base->mem_size_buffer ;
#ifndef S4OPTIMIZE_OFF
has_opt = from->code_base->has_opt && from->code_base->opt.num_buffers ;
d4opt_suspend( from->code_base ) ;
#endif
for ( ;; buf_size -= 0x800 )
{
if ( buf_size < 0x800 ) /* make one last try */
{
buf_size = 100 ;
buf = (char *)u4alloc_er( from->code_base, buf_size ) ;
if ( buf == 0 )
return -1 ;
}
buf = (char *)u4alloc( buf_size ) ;
if ( buf )
break ;
}
pos = 0 ;
for( f_len = file4len( from ) ; f_len > 0 ; f_len -= buf_size )
{
buf_size = ((long)buf_size > f_len) ? (unsigned)f_len : buf_size ;
if ( file4read_all( from, pos, buf, (unsigned)buf_size ) < 0 )
{
rc = -1 ;
break ;
}
if ( file4write( keep, pos, buf, (unsigned)buf_size ) < 0 )
{
rc = -1 ;
break ;
}
pos += buf_size ;
}
from->is_temp = 1 ;
file4close( from ) ;
u4free( buf ) ;
#ifndef S4OPTIMIZE_OFF
if ( has_opt )
d4opt_restart( keep->code_base ) ;
#endif
}
#endif
return rc ;
#endif
}
#ifdef S4NO_ECVT
#define S4NO_FCVT
#endif
#ifdef S4NO_FCVT
#define MAXIMUM 30
#define PRECISION 17
static char value_str[32] ;
static double minus[] =
{1e-256,1e-128,1e-64,
1e-32,1e-16,1e-8,
1e-4,1e-2,1e-1,1.0} ;
static double plus[] =
{1e+256,1e+128,1e+64,
1e+32,1e+16,1e+8,
1e+4,1e+2,1e+1} ;
#ifdef S4NO_ECVT
char *f4ecvt( double value, int numdigits, int *dec_ptr, int *sign_ptr )
{
int dptr, count, j, k ;
char *v_ptr ;
if ( numdigits < 0 )
numdigits = 0 ;
else
if ( numdigits > MAXIMUM ) numdigits = MAXIMUM ;
if ( value < 0.0 )
{
value = -value ;
*sign_ptr = 1 ;
}
else
*sign_ptr = 0 ;
if ( value == 0.0 )
{
memset( value_str, '0', numdigits ) ;
dptr = 0 ;
}
else
{
dptr = 1 ;
k = 256 ;
count = 0 ;
while ( value < 1.0 )
{
while ( value < minus[count+1] )
{
value *= plus[count] ;
dptr -= k ;
}
k /= 2 ;
count++ ;
}
k = 256 ;
count = 0 ;
while ( value >= 10.0 )
{
while ( value >= plus[count] )
{
value *= minus[count] ;
dptr += k ;
}
k /= 2 ;
count++ ;
}
for ( v_ptr = &value_str[0]; v_ptr <= &value_str[numdigits]; v_ptr++ )
{
if ( v_ptr >= &value_str[PRECISION] ) *v_ptr = '0' ;
else
{
j = value ;
*v_ptr = j + '0' ;
value = ( value - j + 1.0e-15 ) * 10.0 ;
}
}
--v_ptr ;
if ( *v_ptr >= '5' )
{
while (1)
{
if ( v_ptr == &value_str[0] )
{
dptr++ ;
value_str[0] = '1' ;
break ;
}
*v_ptr = 0 ;
--v_ptr ;
if ( *v_ptr != '9' )
{
(*v_ptr)++ ;
break ;
}
}
}
}
*dec_ptr = dptr ;
value_str[numdigits] = 0 ;
return value_str ;
}
#endif
char *f4fcvt( double value, int numdigits, int *dec_ptr, int *sign_ptr )
{
int dptr, count, j, k ;
char *v_ptr ;
if ( numdigits < 0 )
numdigits = 0 ;
else
if ( numdigits > MAXIMUM ) numdigits = MAXIMUM ;
if ( value < 0.0 )
{
value = -value ;
*sign_ptr = 1 ;
}
else
*sign_ptr = 0 ;
if ( value == 0.0 )
{
memset( value_str, '0', numdigits ) ;
dptr = 0 ;
}
else
{
dptr = 1 ;
k = 256 ;
count = 0 ;
while ( value < 1.0 )
{
while ( value < minus[count+1] )
{
value *= plus[count] ;
dptr -= k ;
}
k /= 2 ;
count++ ;
}
k = 256 ;
count = 0 ;
while ( value >= 10.0 )
{
while ( value >= plus[count] )
{
value *= minus[count] ;
dptr += k ;
}
k /= 2 ;
count++ ;
}
if ( ( numdigits += dptr ) < 0 )
numdigits = 0 ;
else
if ( numdigits > MAXIMUM ) numdigits = MAXIMUM ;
for ( v_ptr = &value_str[0]; v_ptr <= &value_str[numdigits]; v_ptr++ )
{
if ( v_ptr >= &value_str[PRECISION] ) *v_ptr = '0' ;
else
{
j = value ;
*v_ptr = j + '0' ;
value = ( value - j + 1.0e-15 ) * 10.0 ;
}
}
--v_ptr ;
if ( *v_ptr >= '5' )
{
while (1)
{
if ( v_ptr == &value_str[0] )
{
numdigits++ ;
dptr++ ;
value_str[0] = '1' ;
break ;
}
*v_ptr = 0 ;
--v_ptr ;
if ( *v_ptr != '9' )
{
(*v_ptr)++ ;
break ;
}
}
}
}
*dec_ptr = dptr ;
value_str[numdigits] = 0 ;
return value_str ;
}
#endif