/*
* Copyright 1995, 2003 Perforce Software. All rights reserved.
*
* This file is part of Perforce - the FAST SCM System.
*/
/*
* fileiozip.cc - FileIOGzip/FileIOGunzip methods
*/
# include <stdhdrs.h>
# include <error.h>
# include <strbuf.h>
# include <gzip.h>
# include "filesys.h"
# include "fileio.h"
FileIOCompress::~FileIOCompress()
{
Cleanup();
delete gzip;
delete gzbuf;
}
void
FileIOCompress::Open( FileOpenMode mode, Error *e )
{
switch ( GetType() & FST_C_MASK )
{
case FST_C_GZIP:
compMode = FIOC_GZIP;
break;
case FST_C_GUNZIP:
compMode = FIOC_GUNZIP;
break;
default:
compMode = FIOC_PASS;
}
if( compMode != FIOC_PASS )
{
gzip = new Gzip;
gzbuf = new StrFixed( BufferSize() );
// Read expects is/ie; write os/oe.
gzip->is = gzbuf->Text();
gzip->ie = gzbuf->Text();
gzip->os = gzbuf->Text();
gzip->oe = gzbuf->Text() + gzbuf->Length();
}
FileIOBinary::Open( mode, e );
if( e->Test() )
{
delete gzip;
gzip = 0;
delete gzbuf;
gzbuf = 0;
}
}
void
FileIOCompress::Write( const char *buf, int len, Error *e )
{
switch ( compMode )
{
case FIOC_PASS:
FileIOBinary::Write( buf, len, e );
break;
case FIOC_GZIP:
// Write( 0, 0 ) means flush (from Close()).
// Don't be fooled by buf, 0.
if( buf && !len )
return;
gzip->is = buf;
gzip->ie = buf + len;
// Flush output if full and Compress input
// util Compress() indicates input exhausted
do if( gzip->OutputFull() )
{
FileIOBinary::Write( gzbuf->Text(),
gzip->os - gzbuf->Text(), e );
gzip->os = gzbuf->Text();
}
while( !e->Test() && gzip->Compress( e ) && !gzip->InputEmpty() );
break;
case FIOC_GUNZIP:
gzip->is = buf;
gzip->ie = buf + len;
// Flush output if full and Compress input
// util Compress() indicates input exhausted
do if( gzip->OutputFull() )
{
FileIOBinary::Write( gzbuf->Text(),
gzip->os - gzbuf->Text(), e );
gzip->os = gzbuf->Text();
}
while( !e->Test() && gzip->Uncompress( e ) && !gzip->InputEmpty() );
break;
}
}
int
FileIOCompress::Read( char *buf, int len, Error *e )
{
int done;
switch ( compMode )
{
case FIOC_PASS:
return FileIOBinary::Read( buf, len, e );
case FIOC_GZIP:
gzip->os = buf;
gzip->oe = buf + len;
do if( gzip->InputEmpty() )
{
int l = FileIOBinary::Read( gzbuf->Text(), gzbuf->Length(), e );
if( !l )
e->Set( E_FAILED, "Unexpected end of file" );
gzip->is = gzbuf->Text();
gzip->ie = gzbuf->Text() + l;
}
while( !e->Test() && gzip->Uncompress( e ) && !gzip->OutputFull() );
return gzip->os - buf;
case FIOC_GUNZIP:
gzip->os = buf;
gzip->oe = buf + len;
done = 0;
do if( gzip->InputEmpty() && !done )
{
int l = FileIOBinary::Read( gzbuf->Text(), gzbuf->Length(), e );
gzip->is = l ? gzbuf->Text() : 0;
gzip->ie = gzbuf->Text() + l;
done |= !l;
}
while( !e->Test() && gzip->Compress( e ) && !gzip->OutputFull() );
return gzip->os - buf;
}
e->Sys( "read", Name() );
return -1;
}
void
FileIOCompress::Close( Error *e )
{
// Flush & clear gzip
switch( compMode )
{
case FIOC_GZIP:
if( gzip && mode == FOM_WRITE && GetFd() != -1 )
{
Write( 0, 0, e );
FileIOBinary::Write( gzbuf->Text(),
gzip->os - gzbuf->Text(), e );
}
break;
case FIOC_GUNZIP:
// Flush & clear gzip
if( gzip && mode == FOM_WRITE && gzip->os - gzbuf->Text() )
FileIOBinary::Write( gzbuf->Text(),
gzip->os - gzbuf->Text(), e );
break;
case FIOC_PASS:
break;
}
delete gzip;
gzip = 0;
delete gzbuf;
gzbuf = 0;
// Rest of normal close
FileIOBinary::Close( e );
}
void
FileIOCompress::Seek( offL_t offset, Error *e )
{
if ( compMode == FIOC_PASS )
FileIOBinary::Seek( offset, e );
// else set error? The FileSys stub method is quiet on this
}
# |
Change |
User |
Description |
Committed |
|
#1
|
18917 |
Liz Lam |
Submitting 15.2 source code. |
|
|