/* f4opt.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved. */ #include "d4all.h" #ifndef S4UNIX #ifdef __TURBOC__ #pragma hdrstop #endif #endif #ifndef S4OPTIMIZE_OFF #ifdef S4DEBUG_DEV #ifndef S4UNIX #include #include #endif #include int S4FUNCTION file4write_part( char *buf, FILE4 S4PTR *file, long pos, unsigned len ) { int h1 ; unsigned rc ; long rc1 ; if ( file->in_use == 1 ) return 0 ; file->in_use = 1 ; rc = h1 = -1 ; for ( ;; ) { h1 = sopen( file->dup_name, (int)(O_BINARY | O_RDWR), SH_DENYRW, 0 ) ; if ( h1 < 0 ) break ; rc1 = lseek( h1, pos, 0 ) ; if ( rc1 != pos ) break ; rc1 = (unsigned)write( h1, buf, len ) ; if ( rc1 != len ) break; rc = 0 ; break; } if ( h1 > 0 ) close( h1 ) ; file->in_use = 0 ; return rc ; } int S4FUNCTION file4cmp_part( CODE4 *c4, char *buf, FILE4 *file, long pos, unsigned len ) { int h1, rc ; char buf1[512] ; long len_hold, rc1 ; if ( file->in_use == 1 ) return 0 ; file->in_use = 1 ; len_hold = len ; if ( c4->error_code != 0 ) return -1 ; h1 = rc = -1 ; h1 = sopen( file->dup_name, (int)(O_BINARY | O_RDONLY), SH_DENYRW, 0 ) ; if ( h1 > 0 ) for( ;; ) { rc1 = lseek( h1, pos, 0 ) ; if ( rc1 != pos ) break ; rc1 = (unsigned)read( h1, buf1, sizeof( buf1 ) > len ? len : sizeof( buf1 ) ) ; if ( rc1 != sizeof( buf1 ) && rc1 != len ) break ; if ( memcmp( buf + ( len_hold - len ), buf1, rc1 ) != 0 ) break ; len -= rc1 ; if ( len == 0 ) { rc = 0 ; break ; } pos += rc1 ; } if ( h1 > 0 ) close( h1 ) ; file->in_use = 0 ; return rc ; } int S4FUNCTION file4cmp( FILE4 *f1 ) { int h1, rc ; unsigned rc2 ; char buf1[512], buf2[512] ; long rct, p1, rc1 ; if ( f1->in_use == 1 ) return 0 ; f1->in_use = 1 ; if ( f1->code_base->error_code != 0 || sizeof( buf1 ) != sizeof( buf2 ) ) return -1 ; p1 = 0L ; h1 = rc = -1 ; h1 = sopen( f1->dup_name, (int)(O_BINARY | O_RDONLY), SH_DENYRW, 0 ) ; if ( h1 > 0 ) for( ;; ) { rct = lseek( h1, p1, 0 ) ; if ( rct != p1 ) break ; rc1 = (unsigned)read( h1, buf1, sizeof( buf1 ) ) ; f1->has_dup = 0 ; rc2 = file4read( f1, p1, buf2, sizeof( buf2 ) ) ; f1->has_dup = 1 ; if ( rc1 != rc2 ) break ; if ( memcmp( buf1, buf2, rc1 ) != 0 ) break ; if ( rc1 < sizeof( buf1 ) ) { rc = 0 ; break ; } p1 += sizeof( buf1 ) ; } if ( h1 > 0 ) close( h1 ) ; f1->code_base->error_code = 0 ; f1->in_use = 0 ; return rc ; } static int S4FUNCTION file4copyx( CODE4 *c4, FILE4 *f1, char *f2 ) { int h1, h2, rc ; long rct ; unsigned rc1, rc2 ; char buf[1024] ; long p1 ; if ( c4->error_code != 0 ) return -1 ; h2 = -1 ; rc = -1 ; p1 = 0L ; h2 = sopen( f2, (int)(O_BINARY | O_RDWR), SH_DENYRW, 0 ) ; h1 = f1->hand ; if ( h1 > 0 && h2 > 0 ) for( ;; ) { rct = lseek( h1, p1, 0 ) ; if ( rct != p1 ) break ; rct = lseek( h2, p1, 0 ) ; if ( rct != p1 ) break ; rc1 = (unsigned)read( h1, buf, sizeof( buf ) ) ; rc2 = (unsigned)write( h2, buf, rc1 ) ; if ( rc1 != rc2 ) break ; if ( rc1 < sizeof( buf ) ) { rc = 0 ; break ; } p1 += sizeof( buf ) ; } if ( h2 > 0 ) close( h2 ) ; return rc ; } static int S4FUNCTION file4copy( CODE4 *c4, char *f1, char *f2 ) { int h1, h2, rc ; long rct ; unsigned rc1, rc2 ; char buf[1024] ; long p1 ; if ( c4->error_code != 0 ) return -1 ; h1 = h2 = -1 ; rc = -1 ; p1 = 0L ; h1 = sopen( f1, (int)(O_BINARY | O_RDWR), SH_DENYRW, 0 ) ; h2 = sopen( f2, (int)(O_BINARY | O_RDWR), SH_DENYRW, 0 ) ; if ( h1 > 0 && h2 > 0 ) for( ;; ) { rct = lseek( h1, p1, 0 ) ; if ( rct != p1 ) break ; rct = lseek( h2, p1, 0 ) ; if ( rct != p1 ) break ; rc1 = (unsigned)read( h1, buf, sizeof( buf ) ) ; rc2 = (unsigned)write( h2, buf, rc1 ) ; if ( rc1 != rc2 ) break ; if ( rc1 < sizeof( buf ) ) { rc = 0 ; break ; } p1 += sizeof( buf ) ; } if ( h1 > 0 ) close( h1 ) ; if ( h2 > 0 ) close( h2 ) ; return rc ; } #endif #endif int S4FUNCTION file4optimize( FILE4 *file, int opt_flag, int file_type ) { #ifdef S4OPTIMIZE_OFF return 0 ; #else OPT4 *opt ; int rc ; #ifdef S4DEBUG_DEV #ifndef S4OPTIMIZE_OFF char name_buf[255] ; int hand ; #endif #endif #ifdef S4DEBUG if ( file == 0 || file_type < 0 || file_type > 3 || opt_flag < -1 || opt_flag > 1 ) e4severe( e4parm, E4_F4OPTIMIZE ) ; #endif rc = 0 ; opt = &file->code_base->opt ; if ( opt_flag == -1 ) #ifdef S4SINGLE opt_flag = 1 ; #else opt_flag = ( file->is_exclusive || file->is_read_only ) ? 1 : 0 ; #endif if ( opt_flag == 1 ) { if ( file->do_buffer != 0 && file->type != OPT4NONE ) /* already optimized */ return 0 ; if ( opt->num_buffers > 0 ) { file->len = -1 ; file->hash_init = opt->hash_trail * opt->block_size ; #ifdef S4DEBUG if ( file4len( file ) < 0 || opt->block_size == 0 ) e4severe( e4info, E4_F4OPTIMIZE ) ; #endif opt->hash_trail = (opt->hash_trail + file4len( file ) / opt->block_size) % opt->num_blocks ; file->do_buffer = 1 ; } else file->hash_init = - 1 ; if ( file->type == OPT4NONE ) /* add to list... */ l4add( &opt->opt_files, file ) ; file->type = (char) file_type ; rc = file4optimize_write( file, file->code_base->optimize_write ) ; #ifdef S4DEBUG_DEV #ifndef S4OPTIMIZE_OFF strcpy( name_buf, file->name ) ; if ( name_buf[1] == ':' ) name_buf[0] = 'C' ; u4name_make( file->dup_name, sizeof( file->dup_name ), "E:", "TEMP", name_buf ) ; hand = sopen( file->dup_name, O_CREAT | O_TRUNC | O_RDWR, SH_DENYWR, S_IREAD | S_IWRITE ) ; if ( hand < 0 ) file->has_dup = 0 ; else { close( hand ) ; if ( file4len( file ) > 0 ) { if ( file4copyx( file->code_base, file, file->dup_name ) < 0 ) file->has_dup = 0 ; else file->has_dup = 1 ; } else file->has_dup = 1 ; } #endif #endif } else /* 0 */ { if ( file->type == OPT4NONE ) /* not optimized */ return 0 ; #ifdef S4DEBUG_DEV if ( file->has_dup == 1 ) { /* first do a final verification */ if ( file->do_buffer == 1 || file->link.n == 0 ) if ( file4cmp( file ) != 0 ) e4severe( e4opt, "f4close() - file corruption" ) ; u4remove( file->dup_name ) ; file->has_dup = 0 ; } #endif rc = file4optimize_write( file, 0 ) ; if ( rc == 0 ) { if ( file4low_flush( file, 1 ) < 0 ) return e4( file->code_base, e4opt_flush, 0 ) ; l4remove( &opt->opt_files, file ) ; file->type = OPT4NONE ; file->do_buffer = 0 ; } } return rc ; #endif } /* opt_flag has the same definitions as C4CODE.optimize_write */ int S4FUNCTION file4optimize_write( FILE4 *file, int opt_flag ) { #ifdef S4OPTIMIZE_OFF return 0 ; #else int rc ; rc = 0 ; #ifdef S4DEBUG if( file == 0 || opt_flag < -1 || opt_flag > 1 ) e4severe( e4parm, E4_F4OPTIMIZE_WR ) ; #endif if ( opt_flag == file->write_buffer ) return rc ; switch ( opt_flag ) { case 0: if ( file->do_buffer ) rc = file4flush( file ) ; file->write_buffer = 0 ; break ; case -1 : #ifdef S4SINGLE if ( file->do_buffer ) file->buffer_writes = 1 ; file->write_buffer = 1 ; #else if ( file->is_exclusive == 0 ) { if ( file->do_buffer ) { rc = file4flush( file ) ; file->buffer_writes = 0 ; } file->write_buffer = 0 ; } else { if ( file->do_buffer ) file->buffer_writes = 1 ; file->write_buffer = 1 ; } #endif break ; case 1: #ifndef S4SINGLE if ( file->is_exclusive == 1 ) #endif if ( file->do_buffer ) file->buffer_writes = 1 ; file->write_buffer = 1 ; break ; default: return 0 ; } return rc ; #endif } /* tries to actually turn on/off the write bufferring when locking/unlocking a file */ void S4FUNCTION file4set_write_opt( FILE4 *f4, int set_opt ) { #ifndef S4OPTIMIZE_OFF if ( set_opt == f4->buffer_writes ) return ; if ( set_opt == 1 && f4->write_buffer == 1 ) f4->buffer_writes = 1 ; if ( set_opt == 0 && f4->write_buffer == 1 ) f4->buffer_writes = 0 ; #endif }