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
		
			
				
	
	
		
			452 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			452 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* 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 <sys\stat.h>
 | 
						|
#include <share.h>
 | 
						|
#endif
 | 
						|
#include <fcntl.h>
 | 
						|
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
 | 
						|
}
 |