@ -17,7 +17,6 @@
# include "compress_lz4.h"
# ifdef USE_LZ4
# include <lz4.h>
# include <lz4frame.h>
/*
@ -28,134 +27,290 @@
# define LZ4F_HEADER_SIZE_MAX 32
# endif
/*---------------------------------
* Common to both compression APIs
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
/*
* ( de ) compression state used by both the Compressor and Stream APIs .
*/
typedef struct LZ4State
{
/*
* Used by the Stream API to keep track of the file stream .
*/
FILE * fp ;
LZ4F_preferences_t prefs ;
LZ4F_compressionContext_t ctx ;
LZ4F_decompressionContext_t dtx ;
/*
* Used by the Stream API ' s lazy initialization .
*/
bool inited ;
/*
* Used by the Stream API to distinguish between compression and
* decompression operations .
*/
bool compressing ;
/*
* Used by the Compressor API to mark if the compression headers have been
* written after initialization .
*/
bool needs_header_flush ;
size_t buflen ;
char * buffer ;
/*
* Used by the Stream API to store already uncompressed data that the
* caller has not consumed .
*/
size_t overflowalloclen ;
size_t overflowlen ;
char * overflowbuf ;
/*
* Used by both APIs to keep track of the compressed data length stored in
* the buffer .
*/
size_t compressedlen ;
/*
* Used by both APIs to keep track of error codes .
*/
size_t errcode ;
} LZ4State ;
/*
* LZ4State_compression_init
* Initialize the required LZ4State members for compression .
*
* Write the LZ4 frame header in a buffer keeping track of its length . Users of
* this function can choose when and how to write the header to a file stream .
*
* Returns true on success . In case of a failure returns false , and stores the
* error code in state - > errcode .
*/
static bool
LZ4State_compression_init ( LZ4State * state )
{
size_t status ;
state - > buflen = LZ4F_compressBound ( DEFAULT_IO_BUFFER_SIZE , & state - > prefs ) ;
/*
* LZ4F_compressBegin requires a buffer that is greater or equal to
* LZ4F_HEADER_SIZE_MAX . Verify that the requirement is met .
*/
if ( state - > buflen < LZ4F_HEADER_SIZE_MAX )
state - > buflen = LZ4F_HEADER_SIZE_MAX ;
status = LZ4F_createCompressionContext ( & state - > ctx , LZ4F_VERSION ) ;
if ( LZ4F_isError ( status ) )
{
state - > errcode = status ;
return false ;
}
state - > buffer = pg_malloc ( state - > buflen ) ;
status = LZ4F_compressBegin ( state - > ctx ,
state - > buffer , state - > buflen ,
& state - > prefs ) ;
if ( LZ4F_isError ( status ) )
{
state - > errcode = status ;
return false ;
}
state - > compressedlen = status ;
return true ;
}
/*----------------------
* Compressor API
* - - - - - - - - - - - - - - - - - - - - - -
*/
typedef struct LZ4CompressorState
{
char * outbuf ;
size_t outsize ;
} LZ4CompressorState ;
/* Private routines that support LZ4 compressed data I/O */
static void ReadDataFromArchiveLZ4 ( ArchiveHandle * AH , CompressorState * cs ) ;
static void WriteDataToArchiveLZ4 ( ArchiveHandle * AH , CompressorState * cs ,
const void * data , size_t dLen ) ;
static void EndCompressorLZ4 ( ArchiveHandle * AH , CompressorState * cs ) ;
static void
ReadDataFromArchiveLZ4 ( ArchiveHandle * AH , CompressorState * cs )
{
LZ4_streamDecode_t lz4StreamDecode ;
char * buf ;
char * decbuf ;
size_t buflen ;
size_t cnt ;
buflen = DEFAULT_IO_BUFFER_SIZE ;
buf = pg_malloc ( buflen ) ;
decbuf = pg_malloc ( buflen ) ;
size_t r ;
size_t readbuflen ;
char * outbuf ;
char * readbuf ;
LZ4F_decompressionContext_t ctx = NULL ;
LZ4F_decompressOptions_t dec_opt ;
LZ4F_errorCode_t status ;
memset ( & dec_opt , 0 , sizeof ( dec_opt ) ) ;
status = LZ4F_createDecompressionContext ( & ctx , LZ4F_VERSION ) ;
if ( LZ4F_isError ( status ) )
pg_fatal ( " could not create LZ4 decompression context: %s " ,
LZ4F_getErrorName ( status ) ) ;
outbuf = pg_malloc0 ( DEFAULT_IO_BUFFER_SIZE ) ;
readbuf = pg_malloc0 ( DEFAULT_IO_BUFFER_SIZE ) ;
readbuflen = DEFAULT_IO_BUFFER_SIZE ;
while ( ( r = cs - > readF ( AH , & readbuf , & readbuflen ) ) > 0 )
{
char * readp ;
char * readend ;
LZ4_setStreamDecode ( & lz4StreamDecode , NULL , 0 ) ;
/* Process one chunk */
readp = readbuf ;
readend = readbuf + r ;
while ( readp < readend )
{
size_t out_size = DEFAULT_IO_BUFFER_SIZE ;
size_t read_size = readend - readp ;
while ( ( cnt = cs - > readF ( AH , & buf , & buflen ) ) )
{
int decBytes = LZ4_decompress_safe_continue ( & lz4StreamDecode ,
buf , decbuf ,
cnt , buflen ) ;
memset ( outbuf , 0 , DEFAULT_IO_BUFFER_SIZE ) ;
status = LZ4F_decompress ( ctx , outbuf , & out_size ,
readp , & read_size , & dec_opt ) ;
if ( LZ4F_isError ( status ) )
pg_fatal ( " could not decompress: %s " ,
LZ4F_getErrorName ( status ) ) ;
ahwrite ( decbuf , 1 , decBytes , AH ) ;
ahwrite ( outbuf , 1 , out_size , AH ) ;
readp + = read_size ;
}
}
pg_free ( buf ) ;
pg_free ( decbuf ) ;
pg_free ( outbuf ) ;
pg_free ( readbuf ) ;
status = LZ4F_freeDecompressionContext ( ctx ) ;
if ( LZ4F_isError ( status ) )
pg_fatal ( " could not free LZ4 decompression context: %s " ,
LZ4F_getErrorName ( status ) ) ;
}
static void
WriteDataToArchiveLZ4 ( ArchiveHandle * AH , CompressorState * cs ,
const void * data , size_t dLen )
{
LZ4CompressorState * LZ4cs = ( LZ4CompressorState * ) cs - > private_data ;
size_t compressed ;
size_t requiredsize = LZ4_compressBound ( dLen ) ;
LZ4State * state = ( LZ4State * ) cs - > private_data ;
size_t remaining = dLen ;
size_t status ;
size_t chunk ;
if ( requiredsize > LZ4cs - > outsize )
/* Write the header if not yet written. */
if ( state - > needs_header_flush )
{
LZ4cs - > outbuf = pg_realloc ( LZ4cs - > outbuf , requiredsize ) ;
LZ4cs - > outsize = requiredsize ;
cs - > writeF ( AH , state - > buffer , state - > compressedlen ) ;
state - > needs_header_flush = fals e;
}
compressed = LZ4_compress_default ( data , LZ4cs - > outbuf ,
dLen , LZ4cs - > outsize ) ;
while ( remaining > 0 )
{
if ( compressed < = 0 )
pg_fatal ( " failed to LZ4 compress data " ) ;
if ( remaining > DEFAULT_IO_BUFFER_SIZE )
chunk = DEFAULT_IO_BUFFER_SIZE ;
else
chunk = remaining ;
cs - > writeF ( AH , LZ4cs - > outbuf , compressed ) ;
remaining - = chunk ;
status = LZ4F_compressUpdate ( state - > ctx ,
state - > buffer , state - > buflen ,
data , chunk , NULL ) ;
if ( LZ4F_isError ( status ) )
pg_fatal ( " failed to LZ4 compress data: %s " ,
LZ4F_getErrorName ( status ) ) ;
cs - > writeF ( AH , state - > buffer , status ) ;
data = ( ( char * ) data ) + chunk ;
}
}
static void
EndCompressorLZ4 ( ArchiveHandle * AH , CompressorState * cs )
{
LZ4CompressorState * LZ4cs ;
LZ4State * state = ( LZ4State * ) cs - > private_data ;
size_t status ;
LZ4cs = ( LZ4CompressorState * ) cs - > private_data ;
if ( LZ4cs )
{
pg_free ( LZ4cs - > outbuf ) ;
pg_free ( LZ4cs ) ;
cs - > private_data = NULL ;
}
/* Nothing needs to be done */
if ( ! state )
return ;
/*
* Write the header if not yet written . The caller is not required to call
* writeData if the relation does not contain any data . Thus it is
* possible to reach here without having flushed the header . Do it before
* ending the compression .
*/
if ( state - > needs_header_flush )
cs - > writeF ( AH , state - > buffer , state - > compressedlen ) ;
status = LZ4F_compressEnd ( state - > ctx ,
state - > buffer , state - > buflen ,
NULL ) ;
if ( LZ4F_isError ( status ) )
pg_fatal ( " failed to end compression: %s " ,
LZ4F_getErrorName ( status ) ) ;
cs - > writeF ( AH , state - > buffer , status ) ;
status = LZ4F_freeCompressionContext ( state - > ctx ) ;
if ( LZ4F_isError ( status ) )
pg_fatal ( " failed to end compression: %s " ,
LZ4F_getErrorName ( status ) ) ;
pg_free ( state - > buffer ) ;
pg_free ( state ) ;
cs - > private_data = NULL ;
}
/*
* Public routines that support LZ4 compressed data I / O
*/
void
InitCompressorLZ4 ( CompressorState * cs , const pg_compress_specification compression_spec )
{
LZ4State * state ;
cs - > readData = ReadDataFromArchiveLZ4 ;
cs - > writeData = WriteDataToArchiveLZ4 ;
cs - > end = EndCompressorLZ4 ;
cs - > compression_spec = compression_spec ;
/* Will be lazy init'd */
cs - > private_data = pg_malloc0 ( sizeof ( LZ4CompressorState ) ) ;
/*
* Read operations have access to the whole input . No state needs to be
* carried between calls .
*/
if ( cs - > readF )
return ;
state = pg_malloc0 ( sizeof ( * state ) ) ;
if ( cs - > compression_spec . level > = 0 )
state - > prefs . compressionLevel = cs - > compression_spec . level ;
if ( ! LZ4State_compression_init ( state ) )
pg_fatal ( " could not initialize LZ4 compression: %s " ,
LZ4F_getErrorName ( state - > errcode ) ) ;
/* Remember that the header has not been written. */
state - > needs_header_flush = true ;
cs - > private_data = state ;
}
/*----------------------
* Compress File API
* Compress Stream API
* - - - - - - - - - - - - - - - - - - - - - -
*/
/*
* State needed for LZ4 ( de ) compression using the CompressFileHandle API .
*/
typedef struct LZ4File
{
FILE * fp ;
LZ4F_preferences_t prefs ;
LZ4F_compressionContext_t ctx ;
LZ4F_decompressionContext_t dtx ;
bool inited ;
bool compressing ;
size_t buflen ;
char * buffer ;
size_t overflowalloclen ;
size_t overflowlen ;
char * overflowbuf ;
size_t errcode ;
} LZ4File ;
/*
* LZ4 equivalent to feof ( ) or gzeof ( ) . Return true iff there is no
@ -163,21 +318,21 @@ typedef struct LZ4File
* is reached .
*/
static bool
LZ4File _eof ( CompressFileHandle * CFH )
LZ4Stream _eof ( CompressFileHandle * CFH )
{
LZ4File * fs = ( LZ4Fil e * ) CFH - > private_data ;
LZ4State * state = ( LZ4Stat e * ) CFH - > private_data ;
return f s- > overflowlen = = 0 & & feof ( f s- > fp ) ;
return state - > overflowlen = = 0 & & feof ( state - > fp ) ;
}
static const char *
LZ4File _get_error ( CompressFileHandle * CFH )
LZ4Stream _get_error ( CompressFileHandle * CFH )
{
LZ4File * fs = ( LZ4Fil e * ) CFH - > private_data ;
LZ4State * state = ( LZ4Stat e * ) CFH - > private_data ;
const char * errmsg ;
if ( LZ4F_isError ( f s- > errcode ) )
errmsg = LZ4F_getErrorName ( f s- > errcode ) ;
if ( LZ4F_isError ( state - > errcode ) )
errmsg = LZ4F_getErrorName ( state - > errcode ) ;
else
errmsg = strerror ( errno ) ;
@ -185,57 +340,34 @@ LZ4File_get_error(CompressFileHandle *CFH)
}
/*
* Prepare an already alloc ' ed LZ4File struct for subsequent calls ( either
* compression or decompression ) .
* Initialize an already alloc ' ed LZ4State struct for subsequent calls .
*
* It c reates the necessary contexts for the operations . When compressing data
* ( indicated by compressing = true ) , it additionally writes the LZ4 header in the
* output stream .
* C reates the necessary contexts for either compresion or decompression . When
* compressing data ( indicated by compressing = true ) , it additionally writes the
* LZ4 header in the output stream .
*
* Returns true on success . In case of a failure returns false , and stores the
* error code in f s- > errcode .
* error code in state - > errcode .
*/
static bool
LZ4File_init ( LZ4File * fs , int size , bool compressing )
LZ4Stream_init ( LZ4State * state , int size , bool compressing )
{
size_t status ;
if ( f s- > inited )
if ( state - > inited )
return true ;
f s- > compressing = compressing ;
f s- > inited = true ;
state - > compressing = compressing ;
state - > inited = true ;
/* When compressing, write LZ4 header to the output stream. */
if ( f s- > compressing )
if ( state - > compressing )
{
fs - > buflen = LZ4F_compressBound ( DEFAULT_IO_BUFFER_SIZE , & fs - > prefs ) ;
/*
* LZ4F_compressBegin requires a buffer that is greater or equal to
* LZ4F_HEADER_SIZE_MAX . Verify that the requirement is met .
*/
if ( fs - > buflen < LZ4F_HEADER_SIZE_MAX )
fs - > buflen = LZ4F_HEADER_SIZE_MAX ;
status = LZ4F_createCompressionContext ( & fs - > ctx , LZ4F_VERSION ) ;
if ( LZ4F_isError ( status ) )
{
fs - > errcode = status ;
if ( ! LZ4State_compression_init ( state ) )
return false ;
}
fs - > buffer = pg_malloc ( fs - > buflen ) ;
status = LZ4F_compressBegin ( fs - > ctx , fs - > buffer , fs - > buflen ,
& fs - > prefs ) ;
if ( LZ4F_isError ( status ) )
{
fs - > errcode = status ;
return false ;
}
if ( fwrite ( f s- > buffer , 1 , status , fs - > fp ) ! = status )
if ( fwrite ( state - > buffer , 1 , state - > compressedlen , state - > fp ) ! = state - > compressedlen )
{
errno = ( errno ) ? errno : ENOSPC ;
return false ;
@ -243,19 +375,19 @@ LZ4File_init(LZ4File *fs, int size, bool compressing)
}
else
{
status = LZ4F_createDecompressionContext ( & f s- > dtx , LZ4F_VERSION ) ;
status = LZ4F_createDecompressionContext ( & state - > dtx , LZ4F_VERSION ) ;
if ( LZ4F_isError ( status ) )
{
f s- > errcode = status ;
state - > errcode = status ;
return false ;
}
f s- > buflen = Max ( size , DEFAULT_IO_BUFFER_SIZE ) ;
f s- > buffer = pg_malloc ( f s- > buflen ) ;
state - > buflen = Max ( size , DEFAULT_IO_BUFFER_SIZE ) ;
state - > buffer = pg_malloc ( state - > buflen ) ;
f s- > overflowalloclen = f s- > buflen ;
f s- > overflowbuf = pg_malloc ( f s- > overflowalloclen ) ;
f s- > overflowlen = 0 ;
state - > overflowalloclen = state - > buflen ;
state - > overflowbuf = pg_malloc ( state - > overflowalloclen ) ;
state - > overflowlen = 0 ;
}
return true ;
@ -272,28 +404,28 @@ LZ4File_init(LZ4File *fs, int size, bool compressing)
* the ' ptr ' buffer ) , or 0 if the overflow buffer is empty .
*/
static int
LZ4File_read_overflow ( LZ4File * fs , void * ptr , int size , bool eol_flag )
LZ4Stream_read_overflow ( LZ4State * state , void * ptr , int size , bool eol_flag )
{
char * p ;
int readlen = 0 ;
if ( f s- > overflowlen = = 0 )
if ( state - > overflowlen = = 0 )
return 0 ;
if ( f s- > overflowlen > = size )
if ( state - > overflowlen > = size )
readlen = size ;
else
readlen = f s- > overflowlen ;
readlen = state - > overflowlen ;
if ( eol_flag & & ( p = memchr ( f s- > overflowbuf , ' \n ' , readlen ) ) )
if ( eol_flag & & ( p = memchr ( state - > overflowbuf , ' \n ' , readlen ) ) )
/* Include the line terminating char */
readlen = p - f s- > overflowbuf + 1 ;
readlen = p - state - > overflowbuf + 1 ;
memcpy ( ptr , f s- > overflowbuf , readlen ) ;
f s- > overflowlen - = readlen ;
memcpy ( ptr , state - > overflowbuf , readlen ) ;
state - > overflowlen - = readlen ;
if ( f s- > overflowlen > 0 )
memmove ( f s- > overflowbuf , f s- > overflowbuf + readlen , f s- > overflowlen ) ;
if ( state - > overflowlen > 0 )
memmove ( state - > overflowbuf , state - > overflowbuf + readlen , state - > overflowlen ) ;
return readlen ;
}
@ -306,7 +438,7 @@ LZ4File_read_overflow(LZ4File *fs, void *ptr, int size, bool eol_flag)
* char if found first when the eol_flag is set . It is possible that the
* decompressed output generated by reading any compressed input via the
* LZ4F API , exceeds ' ptrsize ' . Any exceeding decompressed content is stored
* at an overflow buffer within LZ4Fil e . Of course , when the function is
* at an overflow buffer within LZ4Stat e . Of course , when the function is
* called , it will first try to consume any decompressed content already
* present in the overflow buffer , before decompressing new content .
*
@ -314,7 +446,7 @@ LZ4File_read_overflow(LZ4File *fs, void *ptr, int size, bool eol_flag)
* buffer , or - 1 in case of error .
*/
static int
LZ4File_read_internal ( LZ4File * fs , void * ptr , int ptrsize , bool eol_flag )
LZ4Stream_read_internal ( LZ4State * state , void * ptr , int ptrsize , bool eol_flag )
{
int dsize = 0 ;
int rsize ;
@ -324,18 +456,18 @@ LZ4File_read_internal(LZ4File *fs, void *ptr, int ptrsize, bool eol_flag)
void * readbuf ;
/* Lazy init */
if ( ! LZ4File _init ( f s, size , false /* decompressing */ ) )
if ( ! LZ4Stream _init ( state , size , false /* decompressing */ ) )
return - 1 ;
/* Verify that there is enough space in the outbuf */
if ( size > f s- > buflen )
if ( size > state - > buflen )
{
f s- > buflen = size ;
f s- > buffer = pg_realloc ( f s- > buffer , size ) ;
state - > buflen = size ;
state - > buffer = pg_realloc ( state - > buffer , size ) ;
}
/* use already decompressed content if available */
dsize = LZ4File _read_overflow ( f s, ptr , size , eol_flag ) ;
dsize = LZ4Stream _read_overflow ( state , ptr , size , eol_flag ) ;
if ( dsize = = size | | ( eol_flag & & memchr ( ptr , ' \n ' , dsize ) ) )
return dsize ;
@ -346,8 +478,8 @@ LZ4File_read_internal(LZ4File *fs, void *ptr, int ptrsize, bool eol_flag)
char * rp ;
char * rend ;
rsize = fread ( readbuf , 1 , size , f s- > fp ) ;
if ( rsize < size & & ! feof ( f s- > fp ) )
rsize = fread ( readbuf , 1 , size , state - > fp ) ;
if ( rsize < size & & ! feof ( state - > fp ) )
return - 1 ;
rp = ( char * ) readbuf ;
@ -356,15 +488,15 @@ LZ4File_read_internal(LZ4File *fs, void *ptr, int ptrsize, bool eol_flag)
while ( rp < rend )
{
size_t status ;
size_t outlen = f s- > buflen ;
size_t outlen = state - > buflen ;
size_t read_remain = rend - rp ;
memset ( f s- > buffer , 0 , outlen ) ;
status = LZ4F_decompress ( f s- > dtx , f s- > buffer , & outlen ,
memset ( state - > buffer , 0 , outlen ) ;
status = LZ4F_decompress ( state - > dtx , state - > buffer , & outlen ,
rp , & read_remain , NULL ) ;
if ( LZ4F_isError ( status ) )
{
f s- > errcode = status ;
state - > errcode = status ;
return - 1 ;
}
@ -382,34 +514,34 @@ LZ4File_read_internal(LZ4File *fs, void *ptr, int ptrsize, bool eol_flag)
size_t len = outlen < lib ? outlen : lib ;
if ( eol_flag & &
( p = memchr ( f s- > buffer , ' \n ' , outlen ) ) & &
( size_t ) ( p - f s- > buffer + 1 ) < = len )
( p = memchr ( state - > buffer , ' \n ' , outlen ) ) & &
( size_t ) ( p - state - > buffer + 1 ) < = len )
{
len = p - f s- > buffer + 1 ;
len = p - state - > buffer + 1 ;
eol_found = true ;
}
memcpy ( ( char * ) ptr + dsize , f s- > buffer , len ) ;
memcpy ( ( char * ) ptr + dsize , state - > buffer , len ) ;
dsize + = len ;
/* move what did not fit, if any, at the beginning of the buf */
if ( len < outlen )
memmove ( f s- > buffer , f s- > buffer + len , outlen - len ) ;
memmove ( state - > buffer , state - > buffer + len , outlen - len ) ;
outlen - = len ;
}
/* if there is available output, save it */
if ( outlen > 0 )
{
while ( f s- > overflowlen + outlen > f s- > overflowalloclen )
while ( state - > overflowlen + outlen > state - > overflowalloclen )
{
f s- > overflowalloclen * = 2 ;
f s- > overflowbuf = pg_realloc ( f s- > overflowbuf ,
fs - > overflowalloclen ) ;
state - > overflowalloclen * = 2 ;
state - > overflowbuf = pg_realloc ( state - > overflowbuf ,
state - > overflowalloclen ) ;
}
memcpy ( f s- > overflowbuf + f s- > overflowlen , f s- > buffer , outlen ) ;
f s- > overflowlen + = outlen ;
memcpy ( state - > overflowbuf + state - > overflowlen , state - > buffer , outlen ) ;
state - > overflowlen + = outlen ;
}
}
} while ( rsize = = size & & dsize < size & & eol_found = = false ) ;
@ -423,14 +555,14 @@ LZ4File_read_internal(LZ4File *fs, void *ptr, int ptrsize, bool eol_flag)
* Compress size bytes from ptr and write them to the stream .
*/
static bool
LZ4File _write ( const void * ptr , size_t size , CompressFileHandle * CFH )
LZ4Stream _write ( const void * ptr , size_t size , CompressFileHandle * CFH )
{
LZ4File * fs = ( LZ4Fil e * ) CFH - > private_data ;
LZ4State * state = ( LZ4Stat e * ) CFH - > private_data ;
size_t status ;
int remaining = size ;
/* Lazy init */
if ( ! LZ4File _init ( f s, size , true ) )
if ( ! LZ4Stream _init ( state , size , true ) )
return false ;
while ( remaining > 0 )
@ -439,15 +571,15 @@ LZ4File_write(const void *ptr, size_t size, CompressFileHandle *CFH)
remaining - = chunk ;
status = LZ4F_compressUpdate ( f s- > ctx , f s- > buffer , f s- > buflen ,
status = LZ4F_compressUpdate ( state - > ctx , state - > buffer , state - > buflen ,
ptr , chunk , NULL ) ;
if ( LZ4F_isError ( status ) )
{
f s- > errcode = status ;
state - > errcode = status ;
return false ;
}
if ( fwrite ( f s- > buffer , 1 , status , f s- > fp ) ! = status )
if ( fwrite ( state - > buffer , 1 , status , state - > fp ) ! = status )
{
errno = ( errno ) ? errno : ENOSPC ;
return false ;
@ -461,13 +593,13 @@ LZ4File_write(const void *ptr, size_t size, CompressFileHandle *CFH)
* fread ( ) equivalent implementation for LZ4 compressed files .
*/
static bool
LZ4File _read ( void * ptr , size_t size , size_t * rsize , CompressFileHandle * CFH )
LZ4Stream _read ( void * ptr , size_t size , size_t * rsize , CompressFileHandle * CFH )
{
LZ4File * fs = ( LZ4Fil e * ) CFH - > private_data ;
LZ4State * state = ( LZ4Stat e * ) CFH - > private_data ;
int ret ;
if ( ( ret = LZ4File _read_internal ( f s, ptr , size , false ) ) < 0 )
pg_fatal ( " could not read from input file: %s " , LZ4File _get_error ( CFH ) ) ;
if ( ( ret = LZ4Stream _read_internal ( state , ptr , size , false ) ) < 0 )
pg_fatal ( " could not read from input file: %s " , LZ4Stream _get_error ( CFH ) ) ;
if ( rsize )
* rsize = ( size_t ) ret ;
@ -479,15 +611,15 @@ LZ4File_read(void *ptr, size_t size, size_t *rsize, CompressFileHandle *CFH)
* fgetc ( ) equivalent implementation for LZ4 compressed files .
*/
static int
LZ4File _getc ( CompressFileHandle * CFH )
LZ4Stream _getc ( CompressFileHandle * CFH )
{
LZ4File * fs = ( LZ4Fil e * ) CFH - > private_data ;
LZ4State * state = ( LZ4Stat e * ) CFH - > private_data ;
unsigned char c ;
if ( LZ4File _read_internal ( f s, & c , 1 , false ) < = 0 )
if ( LZ4Stream _read_internal ( state , & c , 1 , false ) < = 0 )
{
if ( ! LZ4File _eof ( CFH ) )
pg_fatal ( " could not read from input file: %s " , LZ4File _get_error ( CFH ) ) ;
if ( ! LZ4Stream _eof ( CFH ) )
pg_fatal ( " could not read from input file: %s " , LZ4Stream _get_error ( CFH ) ) ;
else
pg_fatal ( " could not read from input file: end of file " ) ;
}
@ -499,14 +631,14 @@ LZ4File_getc(CompressFileHandle *CFH)
* fgets ( ) equivalent implementation for LZ4 compressed files .
*/
static char *
LZ4File _gets ( char * ptr , int size , CompressFileHandle * CFH )
LZ4Stream _gets ( char * ptr , int size , CompressFileHandle * CFH )
{
LZ4File * fs = ( LZ4Fil e * ) CFH - > private_data ;
LZ4State * state = ( LZ4Stat e * ) CFH - > private_data ;
int ret ;
ret = LZ4File _read_internal ( f s, ptr , size , true ) ;
if ( ret < 0 | | ( ret = = 0 & & ! LZ4File _eof ( CFH ) ) )
pg_fatal ( " could not read from input file: %s " , LZ4File _get_error ( CFH ) ) ;
ret = LZ4Stream _read_internal ( state , ptr , size , true ) ;
if ( ret < 0 | | ( ret = = 0 & & ! LZ4Stream _eof ( CFH ) ) )
pg_fatal ( " could not read from input file: %s " , LZ4Stream _get_error ( CFH ) ) ;
/* Done reading */
if ( ret = = 0 )
@ -520,55 +652,55 @@ LZ4File_gets(char *ptr, int size, CompressFileHandle *CFH)
* remaining content and / or generated footer from the LZ4 API .
*/
static bool
LZ4File _close ( CompressFileHandle * CFH )
LZ4Stream _close ( CompressFileHandle * CFH )
{
FILE * fp ;
LZ4File * fs = ( LZ4Fil e * ) CFH - > private_data ;
LZ4State * state = ( LZ4Stat e * ) CFH - > private_data ;
size_t status ;
fp = f s- > fp ;
if ( f s- > inited )
fp = state - > fp ;
if ( state - > inited )
{
if ( f s- > compressing )
if ( state - > compressing )
{
status = LZ4F_compressEnd ( f s- > ctx , f s- > buffer , f s- > buflen , NULL ) ;
status = LZ4F_compressEnd ( state - > ctx , state - > buffer , state - > buflen , NULL ) ;
if ( LZ4F_isError ( status ) )
pg_fatal ( " failed to end compression: %s " ,
LZ4F_getErrorName ( status ) ) ;
else if ( fwrite ( f s- > buffer , 1 , status , f s- > fp ) ! = status )
else if ( fwrite ( state - > buffer , 1 , status , state - > fp ) ! = status )
{
errno = ( errno ) ? errno : ENOSPC ;
WRITE_ERROR_EXIT ;
}
status = LZ4F_freeCompressionContext ( f s- > ctx ) ;
status = LZ4F_freeCompressionContext ( state - > ctx ) ;
if ( LZ4F_isError ( status ) )
pg_fatal ( " failed to end compression: %s " ,
LZ4F_getErrorName ( status ) ) ;
}
else
{
status = LZ4F_freeDecompressionContext ( f s- > dtx ) ;
status = LZ4F_freeDecompressionContext ( state - > dtx ) ;
if ( LZ4F_isError ( status ) )
pg_fatal ( " failed to end decompression: %s " ,
LZ4F_getErrorName ( status ) ) ;
pg_free ( f s- > overflowbuf ) ;
pg_free ( state - > overflowbuf ) ;
}
pg_free ( f s- > buffer ) ;
pg_free ( state - > buffer ) ;
}
pg_free ( f s) ;
pg_free ( state ) ;
return fclose ( fp ) = = 0 ;
}
static bool
LZ4File _open ( const char * path , int fd , const char * mode ,
CompressFileHandle * CFH )
LZ4Stream _open ( const char * path , int fd , const char * mode ,
CompressFileHandle * CFH )
{
FILE * fp ;
LZ4File * lz4fp = ( LZ4Fil e * ) CFH - > private_data ;
LZ4State * state = ( LZ4Stat e * ) CFH - > private_data ;
if ( fd > = 0 )
fp = fdopen ( fd , mode ) ;
@ -576,17 +708,17 @@ LZ4File_open(const char *path, int fd, const char *mode,
fp = fopen ( path , mode ) ;
if ( fp = = NULL )
{
lz4fp - > errcode = errno ;
state - > errcode = errno ;
return false ;
}
lz4fp - > fp = fp ;
state - > fp = fp ;
return true ;
}
static bool
LZ4File _open_write ( const char * path , const char * mode , CompressFileHandle * CFH )
LZ4Stream _open_write ( const char * path , const char * mode , CompressFileHandle * CFH )
{
char * fname ;
int save_errno ;
@ -609,24 +741,24 @@ void
InitCompressFileHandleLZ4 ( CompressFileHandle * CFH ,
const pg_compress_specification compression_spec )
{
LZ4File * lz4fp ;
CFH - > open_func = LZ4File _open ;
CFH - > open_write_func = LZ4File _open_write ;
CFH - > read_func = LZ4File _read ;
CFH - > write_func = LZ4File _write ;
CFH - > gets_func = LZ4File _gets ;
CFH - > getc_func = LZ4File _getc ;
CFH - > eof_func = LZ4File _eof ;
CFH - > close_func = LZ4File _close ;
CFH - > get_error_func = LZ4File _get_error ;
LZ4State * state ;
CFH - > open_func = LZ4Stream _open ;
CFH - > open_write_func = LZ4Stream _open_write ;
CFH - > read_func = LZ4Stream _read ;
CFH - > write_func = LZ4Stream _write ;
CFH - > gets_func = LZ4Stream _gets ;
CFH - > getc_func = LZ4Stream _getc ;
CFH - > eof_func = LZ4Stream _eof ;
CFH - > close_func = LZ4Stream _close ;
CFH - > get_error_func = LZ4Stream _get_error ;
CFH - > compression_spec = compression_spec ;
lz4fp = pg_malloc0 ( sizeof ( * lz4fp ) ) ;
state = pg_malloc0 ( sizeof ( * state ) ) ;
if ( CFH - > compression_spec . level > = 0 )
lz4fp - > prefs . compressionLevel = CFH - > compression_spec . level ;
state - > prefs . compressionLevel = CFH - > compression_spec . level ;
CFH - > private_data = lz4fp ;
CFH - > private_data = state ;
}
# else /* USE_LZ4 */
void