GZipFile Class Reference

A file stream compressor and decompressor. Allows the CCDiskFile to offer compression of files. At present just used to compress the native file format. More...

#include <zstream.h>

List of all members.

Public Member Functions

 GZipFile ()
 GZipFile constructor.
 ~GZipFile ()
 GZipFile destructor.
GZipStreamgz_init (iostream *pFileStream, TCHAR *mode, BOOL Header=FALSE)
 Initialises the compression system and tries to grab the memory required. gz_init returns NULL if there was insufficient memory to allocate the (de)compression state; errno can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR). Graeme ( 15/11/99) : Added the Header parameter to the parameter list. This enables the GZipStream to be initialised so that it writes the ZLib header, which was previously supressed.
GZipStreamgz_open (iostream *pFileStream, TCHAR *mode, TCHAR *path)
 Opens a gzip file for reading or writing. The mode parameter is as in fopen ("rb" or "wb"). The stream is given at present by the iostream class, the patname is optional and is just used for debugging.
INT32 gz_open (GZipStream *s)
 The form of open if we have already called init. At present, this is fairly simple and just checks out a few things.
INT32 gzpeek (GZipStream *s, char *data)
 Reads the next byte from the input stream and returns this to the caller. It then remembers this value for the next read. gzread returns the number of uncompressed bytes actually read (0 for end of file, -1 for error).
INT32 gzread (GZipStream *s, char *data, unsigned len)
 Reads the given number of uncompressed bytes from the compressed file. If the input file was not in gzip format, gzread copies the given number of bytes into the buffer. gzread returns the number of uncompressed bytes actually read (0 for end of file, -1 for error).
INT32 gzwrite (GZipStream *s, const char *data, unsigned len)
 Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of bytes actually written (0 in case of error).
INT32 gzflush (GZipStream *s, INT32 flush)
 Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function gzerror below). gzflush returns Z_OK if the flush parameter is Z_FINISH and all output could be flushed. gzflush should be called only when strictly necessary because it can degrade compression.
INT32 gzclose (GZipStream *s)
 Flushes all pending output if necessary, closes the compressed file and deallocates all the (de)compression state. The return value is the zlib error number (see function gzerror below).
INT32 destroy (GZipStream *file)
 Cleanup then free the given GZipStream. Return a zlib error code. Assume caller will close the file.
FilePos GetCurrentFilePos (GZipStream *s)
 Allows the progress bar to be updated with the current position in the compressed file.

Static Public Member Functions

static double GetStreamVersionNo ()
 To find out the current version number of the stream and hence files which it can recoknise. The verison is of the form 0.92.
static uLong crc32 (uLong crc, Bytef *buf, uInt len)
 Update a running crc with the bytes buf[0..len-1] and return the updated crc. If buf is NULL, this function returns the required initial value for the crc. Pre- and post-conditioning (one's complement) is performed within this function so it shouldn't be done by the application. Usage example:.
static uLong adler32 (uLong adler, const Bytef *buf, uInt len)
 Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is NULL, this function returns the required initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much faster. Usage example:.
static uLongfget_crc_table ()
static void * zcalloc (void *opaque, unsigned items, unsigned size)
 Allocate memory of size items and with size bytes per item.
static void zcfree (void *opaque, void *ptr)
 A wrapper round the free function.

Protected Member Functions

void putLong (iostream *file, uLong x)
 Outputs an INT32 in LSB order to the given file.
uLong getLong (Byte *buf)
 Reads an INT32 in LSB order from the given buffer.

Protected Attributes

ZipDeflatedeflate
ZipInflateinflate

Private Member Functions

 CC_DECLARE_MEMDUMP (GZipFile)


Detailed Description

A file stream compressor and decompressor. Allows the CCDiskFile to offer compression of files. At present just used to compress the native file format.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> Humprhys
Date:
23/5/95

Definition at line 240 of file zstream.h.


Constructor & Destructor Documentation

GZipFile::GZipFile  ) 
 

GZipFile constructor.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
34/05/95

Definition at line 289 of file zstream.cpp.

00290 {
00291     deflate = NULL;   
00292     inflate = NULL;   
00293 }   

GZipFile::~GZipFile  ) 
 

GZipFile destructor.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
34/05/95

Definition at line 305 of file zstream.cpp.

00306 {
00307 #ifdef DO_EXPORT
00308     // Remove the deflate class, if present
00309     if (deflate != NULL)
00310     {
00311         delete deflate;
00312         deflate = NULL;   
00313     }
00314 #endif
00315 
00316     // Remove the inflate class, if present
00317     if (inflate != NULL)
00318     {
00319         delete inflate;
00320         inflate = NULL;   
00321     }
00322 }   


Member Function Documentation

uLong GZipFile::adler32 uLong  adler,
const Bytef buf,
uInt  len
[static]
 

Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is NULL, this function returns the required initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much faster. Usage example:.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95
Parameters:
crc previous checksum value??? [INPUTS] buf pointer to the buffer to check len length of the buffer
Returns:
the checksum value
uLong adler = adler32(0L, Z_NULL, 0);

while (read_buffer(buffer, length) != EOF) { adler = adler32(adler, buffer, length); } if (adler != original_adler) error();

Definition at line 1624 of file zstream.cpp.

01625 {
01626     UINT32 s1 = adler & 0xffff;
01627     UINT32 s2 = (adler >> 16) & 0xffff;
01628     INT32 k;
01629 
01630     if (buf == Z_NULL) return 1L;
01631 
01632     while (len > 0) {
01633         k = len < NMAX ? len : NMAX;
01634         len -= k;
01635         while (k >= 16) {
01636             A_DO16(buf);
01637         buf += 16;
01638             k -= 16;
01639         }
01640         if (k != 0) do {
01641             s1 += *buf++;
01642         s2 += s1;
01643         } while (--k);
01644         s1 %= BASE;
01645         s2 %= BASE;
01646     }
01647     return (s2 << 16) | s1;}

GZipFile::CC_DECLARE_MEMDUMP GZipFile   )  [private]
 

uLong GZipFile::crc32 uLong  crc,
Bytef buf,
uInt  len
[static]
 

Update a running crc with the bytes buf[0..len-1] and return the updated crc. If buf is NULL, this function returns the required initial value for the crc. Pre- and post-conditioning (one's complement) is performed within this function so it shouldn't be done by the application. Usage example:.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95
Parameters:
crc previous checksum value??? [INPUTS] buf pointer to the buffer to check len length of the buffer
Returns:
the checksum value
uLong crc = crc32(0L, Z_NULL, 0);

while (read_buffer(buffer, length) != EOF) { crc = crc32(crc, buffer, length); } if (crc != original_crc) error();

Definition at line 1550 of file zstream.cpp.

01551 {
01552     if (buf == Z_NULL) return 0L;
01553 #ifdef DYNAMIC_CRC_TABLE
01554     if (crc_table_empty)
01555       make_crc_table();
01556 #endif
01557     crc = crc ^ 0xffffffffL;
01558     while (len >= 8)
01559     {
01560       DO8(buf);
01561       len -= 8;
01562     }
01563     if (len) do {
01564       DO1(buf);
01565     } while (--len);
01566     return crc ^ 0xffffffffL;
01567 }

INT32 GZipFile::destroy GZipStream s  ) 
 

Cleanup then free the given GZipStream. Return a zlib error code. Assume caller will close the file.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95

Definition at line 352 of file zstream.cpp.

00353 {
00354     TRACEUSER( "Neville", _T("GZipFile::gzflush\n"));
00355 
00356     // Check that a valid stream has been passed in
00357     if (!s) return Z_STREAM_ERROR;
00358 
00359     INT32 err = Z_OK;
00360 
00361     // Try and free up the buffers that we have allocated 
00362     TRYFREE(s->inbuf);
00363     TRYFREE(s->outbuf);
00364     TRYFREE(s->path);
00365     TRYFREE(s->msg);
00366 
00367     if (s->mode == 'w')
00368     {
00369 #ifdef DO_EXPORT
00370         if (s->stream.De_state != NULL && deflate != NULL)
00371             err = deflate->End(&(s->stream));
00372 
00373         // Now remove the deflate class, if present
00374         if (deflate != NULL)
00375         {
00376             delete deflate;
00377             deflate = NULL;   
00378         }
00379 #endif
00380     }
00381     else if (s->mode == 'r')
00382     {
00383         if (s->stream.In_state != NULL && inflate != NULL)
00384            err = inflate->End(&(s->stream));
00385         
00386         // Now remove the inflate class, if present
00387         if (inflate != NULL)
00388         {
00389             delete inflate;
00390             inflate = NULL;   
00391         }
00392     }
00393 
00394     // If we had a file claimed then try and close it
00395     // Assume this is done by the caller as in the native file save we still have some
00396     // bits to write out to the file.
00397     // Assume pointer is of no use anymore so set to NULL.
00398     s->file = NULL;
00399 
00400     if (s->z_err < 0)
00401         err = s->z_err;
00402 
00403     // free up our ZipStream object
00404     delete s;
00405     s = NULL;
00406 
00407     return err;
00408 }

uLongf * GZipFile::get_crc_table  )  [static]
 

Definition at line 1572 of file zstream.cpp.

01573 {
01574 #ifdef DYNAMIC_CRC_TABLE
01575   if (crc_table_empty) make_crc_table();
01576 #endif
01577   return (uLongf *)crc_table;
01578 }

FilePos GZipFile::GetCurrentFilePos GZipStream s  ) 
 

Allows the progress bar to be updated with the current position in the compressed file.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/05/95
Parameters:
s the zip stream that we should be using [INPUTS]
Returns:
the current file position

Definition at line 1056 of file zstream.cpp.

01057 {
01058     if (s == NULL || s->file == NULL) return 0;
01059     
01060     // Get the current file position, this will be ready to read in the next chunk of data
01061     // into the input buffer.
01062     // Take off the position that we started at
01063     FilePos             Pos = FilePos(s->file->tellg()) - s->InitialPos;
01064 
01065     // Take off the current amount left in the input buffer. This is our current position.
01066     Pos -= (FilePos)s->stream.avail_in;
01067 
01068     return Pos;
01069 }

uLong GZipFile::getLong Byte buf  )  [protected]
 

Reads an INT32 in LSB order from the given buffer.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95

Definition at line 1228 of file zstream.cpp.

01229 {
01230     uLong x = 0;
01231     Byte *p = buf+4;
01232 
01233     do
01234     {
01235         x <<= 8;
01236         x |= *--p; 
01237     } while (p != buf);
01238 
01239     return x;
01240 }

double GZipFile::GetStreamVersionNo  )  [static]
 

To find out the current version number of the stream and hence files which it can recoknise. The verison is of the form 0.92.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/05/95
Returns:
the current version number of the stream in the form 0.92

Definition at line 336 of file zstream.cpp.

00337 {
00338     return ZLIB_VERSIONNO;
00339 }

GZipStream * GZipFile::gz_init iostream *  pFileStream,
TCHAR mode,
BOOL  Header = FALSE
 

Initialises the compression system and tries to grab the memory required. gz_init returns NULL if there was insufficient memory to allocate the (de)compression state; errno can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR). Graeme ( 15/11/99) : Added the Header parameter to the parameter list. This enables the GZipStream to be initialised so that it writes the ZLib header, which was previously supressed.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/06/95
Parameters:
pFileStream the iostream class to use for reading/writing [INPUTS] mode rw mode for this file

Definition at line 432 of file zstream.cpp.

00433 {
00434     TRACEUSER( "Neville", _T("GZipFile::gz_init\n"));
00435 
00436     if (pFileStream == NULL)
00437     {
00438         ERROR3("GZipFile::gz_open Expects file class to be supplied and open as of yet!");
00439         return NULL;
00440     }
00441 
00442     GZipStream *s = new GZipStream;
00443     if (!s) return NULL;
00444 
00445     s->stream.zalloc = (alloc_func)0;
00446     s->stream.zfree = (free_func)0;
00447     s->stream.next_in = NULL;
00448     s->inbuf = NULL;
00449     s->stream.next_out = NULL;
00450     s->outbuf = NULL;
00451     s->stream.avail_in = 0;
00452     s->stream.avail_out = 0;
00453     s->file = pFileStream;      // will be NULL if wanting it to be opened
00454     s->z_err = Z_OK;
00455     s->z_eof = 0;
00456     s->crc = crc32(0L, NULL, 0);
00457     s->msg = NULL;
00458     s->transparent = 0;
00459     s->Peek = FALSE;        // no value peeked
00460     s->PeekedValue = '#';   // random value
00461     s->PeekStatus = 0;      // status 0 bytes present
00462 
00463     // Work our whether we are reading or writing from the supplied mode
00464     TCHAR              *p = mode;
00465     s->mode = '\0';
00466     do
00467     {
00468         if( *p == _T('r') ) 
00469             s->mode = _T('r');
00470         if( *p == _T('w') )
00471             s->mode = _T('w');
00472     } while (*p++);
00473     
00474     if( s->mode == _T('\0') )
00475     {
00476         destroy(s);
00477         return NULL;
00478     }
00479     
00480     INT32 err;
00481     if( s->mode == _T('w') )
00482     {
00483 #ifdef DO_EXPORT
00484         // First, create the deflate class ready for use
00485         deflate = new ZipDeflate;
00486         if (deflate == NULL)
00487         {
00488             destroy(s);
00489             return NULL;
00490         }
00491 
00492         // Now initialise it, ready for use.
00493         // Graeme ( 15/11/99 ) - Added the switch on Header to allow for the
00494         // zlib header.
00495         if ( Header )
00496         {
00497             // Initialise using MAX_WBITS, so that the ZLib header is created.
00498             err = deflate->Init(&(s->stream), Z_DEFAULT_COMPRESSION,
00499                                DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, 0);
00500         }
00501         else
00502         {
00503             // windowBits is passed < 0 to suppress zlib header.
00504             err = deflate->Init(&(s->stream), Z_DEFAULT_COMPRESSION,
00505                                DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
00506         }
00507 
00508         s->stream.next_out = (Byte*) ALLOC(Z_BUFSIZE);
00509         s->outbuf = s->stream.next_out; 
00510         s->stream.avail_out = Z_BUFSIZE;
00511 
00512         if (err != Z_OK || s->outbuf == NULL)
00513         {
00514             destroy(s);
00515             return NULL;
00516         }
00517 
00518         /* err = deflate->SetDictionary(&(s->stream), dictionary, dictionary_size);
00519         if (err != Z_OK)
00520         {
00521             destroy(s);
00522             return NULL;
00523         } */
00524 #else
00525         return NULL;
00526 #endif
00527     }
00528     else
00529     {
00530         // First, create the inflate class ready for use
00531         inflate = new ZipInflate;
00532         if (inflate == NULL)
00533         {
00534             destroy(s);
00535             return NULL;
00536         }
00537 
00538         err = inflate->Init(&(s->stream), -MAX_WBITS);
00539         s->inbuf = (Byte*) ALLOC(Z_BUFSIZE);
00540         s->stream.next_in  = s->inbuf;
00541 
00542         if (err != Z_OK || s->inbuf == NULL)
00543         {
00544             destroy(s);
00545             return NULL;
00546         }
00547 
00548         /* err = inflate->SetDictionary(&(s->stream), dictionary, dictionary_size);
00549         if (err != Z_OK)
00550         {
00551             destroy(s);
00552             return NULL;
00553         } */
00554     }
00555 
00556     s->Inited = TRUE;
00557 
00558     return s;
00559 }

INT32 GZipFile::gz_open GZipStream s  ) 
 

The form of open if we have already called init. At present, this is fairly simple and just checks out a few things.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/06/95
Parameters:
s the zip stream that we should be using [INPUTS]

Definition at line 574 of file zstream.cpp.

00575 {
00576     TRACEUSER( "Neville", _T("GZipFile::gz_open init already called\n"));
00577 
00578     // check that everyhting is valid before preceeding
00579     if (s == NULL) return Z_STREAM_ERROR;
00580 
00581     // Check if init has been called
00582     if (!s->Inited)
00583         return Z_STREAM_ERROR;
00584  
00585     // Note the current position in the file for later use
00586     s->InitialPos = s->file->tellg();
00587     
00588     // check if there is an actual file stream class attached
00589     if (s->file == NULL)
00590     {
00591         destroy(s);
00592         return 0;
00593     }
00594 
00595     // Check if reading and already at end of file
00596     if (s->mode == 'r' && s->file->eof())
00597     {
00598         s->z_err = Z_DATA_ERROR;
00599         return Z_DATA_ERROR;
00600     }
00601 
00602     // Check if reading and the next bytes are not compressed
00603     if (s->mode == 'r')
00604     {
00605         s->stream.avail_in = 15;
00606         s->file->read( (char *)s->inbuf, s->stream.avail_in );
00607         // Seek back to where we were before we started this test
00608         s->file->seekp(s->InitialPos);
00609         if (s->stream.avail_in == 15)
00610         {
00611             // If we find the following words then the data is not compressed  
00612             // We must fail but cleanly as all we need to do is read it uncomrpessed
00613             if( strncmp( (PCSTR)s->inbuf, "%%AWColourTable", 15 ) == 0 )
00614             {
00615                 s->stream.avail_in = 0;
00616                 s->z_err = Z_UNCOMPRESSED_ERROR;
00617                 return Z_UNCOMPRESSED_ERROR;
00618             }
00619             s->stream.avail_in = 0;
00620         }
00621         else
00622         {
00623             s->z_err = Z_DATA_ERROR;
00624             return Z_DATA_ERROR;
00625         }
00626     }
00627 
00628     // Everything went ok
00629     return Z_OK;
00630 }

GZipStream * GZipFile::gz_open iostream *  pFileStream,
TCHAR mode,
TCHAR path
 

Opens a gzip file for reading or writing. The mode parameter is as in fopen ("rb" or "wb"). The stream is given at present by the iostream class, the patname is optional and is just used for debugging.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95
Parameters:
pFileStream the iostream class to use for reading/writing [INPUTS] mode rw mode for this file path pathname for this file (optional)
gz_open return NULL if the stream could not be opened or if there was insufficient memory to allocate the (de)compression state; errno can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR).

Definition at line 654 of file zstream.cpp.

00655 {
00656     TRACEUSER( "Neville", _T("GZipFile::gz_open\n"));
00657 
00658     if (pFileStream == NULL)
00659     {
00660         ERROR3("GZipFile::gz_open Expects file class to be supplied and open as of yet!");
00661         return NULL;
00662     }
00663 
00664     INT32 err;
00665     TCHAR              *p = mode;
00666 
00667     GZipStream *s = new GZipStream;
00668     if (!s) return NULL;
00669 
00670     s->stream.zalloc = (alloc_func) 0;
00671     s->stream.zfree = (free_func) 0;
00672     s->stream.next_in = NULL;
00673     s->inbuf = NULL;
00674     s->stream.next_out = NULL;
00675     s->outbuf = NULL;
00676     s->stream.avail_in = 0;
00677     s->stream.avail_out = 0;
00678     s->file = pFileStream;      // will be NULL if wanting it to be opened
00679     s->z_err = Z_OK;
00680     s->z_eof = 0;
00681     s->crc = crc32(0L, NULL, 0);
00682     s->msg = NULL;
00683     s->transparent = 0;
00684 
00685     // Our extra bits
00686     s->Peek = FALSE;        // no value peeked
00687     s->PeekedValue = '#';   // random value
00688     s->PeekStatus = 0;      // status 0 bytes present
00689     s->path = NULL;
00690 
00691     if (path != NULL)
00692     {
00693         s->path = (TCHAR*) ALLOC((camStrlen(path) + 1) * sizeof(TCHAR));
00694         if (s->path == NULL)
00695         {
00696             destroy(s);
00697             return NULL;
00698         }
00699 
00700         camStrcpy(s->path, path); /* do this early for debugging */
00701     }
00702 
00703     // Note the current position in the file for later use
00704     s->InitialPos = s->file->tellg();
00705 
00706     // Work our whether we are reading or writing from the supplied mode
00707     s->mode = '\0';
00708     do
00709     {
00710         if (*p == 'r') s->mode = 'r';
00711         if (*p == 'w') s->mode = 'w';
00712     } while (*p++);
00713     
00714     if (s->mode == '\0')
00715     {
00716         destroy(s);
00717         return NULL;
00718     }
00719     
00720     if (s->mode == 'w')
00721     {
00722 #ifdef DO_EXPORT
00723         // First, create the deflate class ready for use
00724         deflate = new ZipDeflate;
00725         if (deflate == NULL)
00726         {
00727             destroy(s);
00728             return NULL;
00729         }
00730 
00731         // Now initialise it, ready for use
00732         err = deflate->Init(&(s->stream), Z_DEFAULT_COMPRESSION,
00733                            DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
00734         /* windowBits is passed < 0 to suppress zlib header */
00735  
00736         s->stream.next_out = (Byte*) ALLOC(Z_BUFSIZE);
00737         s->outbuf = s->stream.next_out; 
00738 
00739         if (err != Z_OK || s->outbuf == NULL)
00740         {
00741             destroy(s);
00742             return NULL;
00743         }
00744 
00745         s->stream.avail_out = Z_BUFSIZE;
00746 
00747         /* err = deflate->SetDictionary(&(s->stream), dictionary, dictionary_size);
00748         if (err != Z_OK)
00749         {
00750             destroy(s);
00751             return NULL;
00752         } */
00753 #else
00754         return NULL;
00755 #endif
00756     }
00757     else
00758     {
00759         // First, create the inflate class ready for use
00760         inflate = new ZipInflate;
00761         if (inflate == NULL)
00762         {
00763             destroy(s);
00764             return NULL;
00765         }
00766 
00767         err = inflate->Init(&(s->stream), -MAX_WBITS);
00768         s->inbuf = (Byte*) ALLOC(Z_BUFSIZE);
00769         s->stream.next_in  = s->inbuf;
00770 
00771         if (err != Z_OK || s->inbuf == NULL)
00772         {
00773             destroy(s);
00774             return NULL;
00775         }
00776 
00777         /*err = inflate->SetDictionary(&(s->stream), dictionary, dictionary_size);
00778         if (err != Z_OK)
00779         {
00780             destroy(s);
00781             return NULL;
00782         } */
00783     }
00784     // Moved from inside write clause by 0.99 upgrade
00785     //s->stream.avail_out = Z_BUFSIZE;
00786 
00787     if (s->file == NULL)
00788     {
00789         destroy(s);
00790         return NULL;
00791     }
00792     
00793     // All simple header writing code is done by the native file class
00794     // All header/compression verison checking is done by the native file class
00795     if (s->mode == 'r')
00796     {
00797         // This is all done in the native file filter so need to do it here
00798         // reset buffer back to zero ready for the true data itself
00799         s->stream.avail_in = 0;
00800 
00801         if (s->file->eof())
00802         {
00803             s->z_err = Z_DATA_ERROR;
00804         }
00805 
00806         // Check if reading and the next bytes are not compressed
00807         s->stream.avail_in = 15;
00808         s->file->read( (char *)s->inbuf, s->stream.avail_in );
00809         // Seek back to where we were before we started this test
00810         s->file->seekg(s->InitialPos);
00811         if (s->stream.avail_in == 15)
00812         {
00813             // If we find the following words then the data is not compressed  
00814             // We must fail but cleanly as all we need to do is read it uncomrpessed
00815             if( strncmp( (char *)s->inbuf, "%%AWColourTable", 15 ) == 0 )
00816             {
00817                 s->stream.avail_in = 0;
00818                 s->z_err = Z_UNCOMPRESSED_ERROR;
00819                 return s;
00820             }
00821             s->stream.avail_in = 0;
00822         }
00823         else
00824         {
00825             s->z_err = Z_DATA_ERROR;
00826             return s;
00827         }
00828     }
00829 
00830     s->Inited = TRUE;
00831 
00832     return s;
00833 }

INT32 GZipFile::gzclose GZipStream s  ) 
 

Flushes all pending output if necessary, closes the compressed file and deallocates all the (de)compression state. The return value is the zlib error number (see function gzerror below).

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95
Parameters:
s the z stream to be used [INPUTS]
Returns:
Z_OK or an error number if there has been a problem

Definition at line 1256 of file zstream.cpp.

01257 {
01258     TRACEUSER( "Neville", _T("GZipFile::gzclose\n"));
01259 
01260     uInt n;
01261 
01262     if (s == NULL) return Z_STREAM_ERROR;
01263 
01264     if (s->mode == 'w')
01265     {
01266 #ifdef DO_EXPORT
01267         INT32 err;
01268         err = gzflush(s, Z_FINISH);
01269         if (err != Z_OK) return destroy(s);
01270 
01271         putLong (s->file, s->crc);
01272         putLong (s->file, s->stream.total_in);
01273 
01274         TRACEUSER( "Neville", _T("gzclose calc'd crc = %d\n"),s->crc);
01275         TRACEUSER( "Neville", _T("gzclose bytes written = %d\n"),s->stream.total_out);
01276 #endif
01277     }
01278     else if (s->mode == 'r' && s->z_err == Z_STREAM_END)
01279     {
01280 
01281         /* slide CRC and original size if they are at the end of inbuf */
01282         if ((n = s->stream.avail_in) < 8  && !s->z_eof)
01283         {
01284             Byte *p = s->inbuf;
01285             Byte *q = s->stream.next_in;
01286             while (n--)
01287             {
01288                 *p++ = *q++;
01289             };
01290 
01291             n = s->stream.avail_in;
01292 //            n += fread(p, 1, 8, s->file);
01293             INT32 len = 8;
01294             s->file->read( (char *)p, len );
01295             n += len; 
01296             s->stream.next_in = s->inbuf;
01297         }
01298 
01299         // check CRC and original size
01300         uLong FileCrc  = getLong(s->stream.next_in);
01301         uLong FileSize = getLong(s->stream.next_in + 4);
01302         TRACEUSER( "Neville", _T("check stored crc %d, against calc'd crc = %d\n"), FileCrc, s->crc);
01303         TRACEUSER( "Neville", _T("check stored bytes written %d, against count = %d\n"), FileSize, s->stream.total_out);
01304         TRACEUSER( "Neville", _T("bytes left in buffer %d\n"), n);
01305         if (n < 8 || FileCrc != s->crc || FileSize != s->stream.total_out)
01306         {
01307 
01308             s->z_err = Z_DATA_ERROR;
01309         }
01310 
01311         // Quick bodge here. We now have n bytes left in the buffer, this will include 8 for the CRC etc.
01312         // If we close down compression then the file pointer will be sitting n - 8 bytes on from the
01313         // position where we actually want it. Therefore, we must skip back to the correct position.
01314         FilePos Pos = s->file->tellg();
01315         Pos = Pos - (n - 8);
01316         s->file->seekg(Pos);
01317     }
01318 
01319     return destroy(s);
01320 }

INT32 GZipFile::gzflush GZipStream s,
INT32  flush
 

Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function gzerror below). gzflush returns Z_OK if the flush parameter is Z_FINISH and all output could be flushed. gzflush should be called only when strictly necessary because it can degrade compression.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95
Parameters:
s the zip stream that is to be used [INPUTS] flush

Definition at line 1149 of file zstream.cpp.

01150 {
01151 #ifdef DO_EXPORT
01152     TRACEUSER( "Neville", _T("GZipFile::gzflush\n"));
01153 
01154     uInt len;
01155     INT32 done = 0;
01156 
01157     if (s == NULL || s->mode != 'w' || deflate == NULL)
01158          return Z_STREAM_ERROR;
01159 
01160     s->stream.avail_in = 0; /* should be zero already anyway */
01161 
01162     for (;;)
01163     {
01164         len = Z_BUFSIZE - s->stream.avail_out;
01165 
01166         if (len != 0)
01167         {
01168 //            if (fwrite(s->outbuf, 1, len, s->file) != len)
01169             uInt len2 = len;
01170             s->file->write((const char*)s->outbuf, len2);
01171             if ( len2 != len)
01172             {
01173                 s->z_err = Z_ERRNO;
01174                 return Z_ERRNO;
01175             }
01176             s->stream.next_out = s->outbuf;
01177             s->stream.avail_out = Z_BUFSIZE;
01178         }
01179         if (done) break;
01180         s->z_err = deflate->deflate(&(s->stream), flush);
01181 
01182         /* deflate has finished flushing only when it hasn't used up
01183          * all the available space in the output buffer: 
01184          */
01185         done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
01186  
01187         if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
01188     }
01189     return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
01190 #else
01191     return Z_STREAM_ERROR;
01192 #endif
01193 }

INT32 GZipFile::gzpeek GZipStream s,
char *  buf
 

Reads the next byte from the input stream and returns this to the caller. It then remembers this value for the next read. gzread returns the number of uncompressed bytes actually read (0 for end of file, -1 for error).

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95
Parameters:
s the zip stream that we should be using [INPUTS] buf the character that we are to return
Returns:
number of uncompressed bytes actually read (0 for end of file, -1 for error)

Definition at line 851 of file zstream.cpp.

00852 {
00853     // check that everyhting is valid before preceeding
00854     if (s == NULL || s->mode != 'r' || inflate == NULL || buf == NULL) return Z_STREAM_ERROR;
00855 
00856     // First check for problem states from last reading/peeking
00857     if (s->z_err == Z_DATA_ERROR) return -1; /* bad .gz file */
00858     if (s->z_err == Z_STREAM_END) return 0;  /* don't read crc as data */
00859 
00860     // first check if we are in the peeked state already
00861     if (s->PeekStatus > 0)
00862     {
00863         // just return the peeked character
00864         // add in the values from the peeks
00865         ERROR3IF(s->PeekStatus > 1,"peek with status > 1");
00866         buf[0] = s->PeekedValue;    // set first byte to be the peeked value
00867 
00868         // return amount read to caller 
00869         return 1;   
00870     }
00871 
00872     Byte *b = (Byte*)buf;
00873     s->stream.next_out = b;
00874 
00875     // remember the current uncompressed buffer size as this will give us where
00876     unsigned offset = s->stream.avail_out;
00877     if(offset !=0)
00878         ERROR3IF(offset != 0,"peek offset not zero");
00879     s->stream.avail_out += 1;   // we want 1 character
00880 
00881     while (s->stream.avail_out != 0)
00882     {
00883         if (s->stream.avail_in == 0 && !s->z_eof)
00884         {
00885             s->stream.avail_in = Z_BUFSIZE;
00886             // Note the current file position
00887             FilePos Pos = s->file->tellg();
00888             s->file->read((char *) s->inbuf, s->stream.avail_in );
00889             FilePos PosAfter = s->file->tellg();
00890             s->stream.avail_in = PosAfter- Pos;
00891 TRACEUSER( "Neville", _T("GZipFile::gz_peek filled buffer size %d\n"),s->stream.avail_in);
00892             if (s->stream.avail_in == 0)
00893             {
00894                 s->z_eof = 1;
00895             //  s->file->setf(s->file->eofbit);
00896 
00897             }
00898           /*  else if (s->stream.avail_in == (uInt)EOF)
00899             {
00900             //    s->stream.avail_in = 0;
00901                 s->z_eof = 1;
00902             //    s->z_err = Z_ERRNO;
00903             //    break;
00904             }*/
00905             else if (s->stream.avail_in < Z_BUFSIZE || s->file->eof())
00906             {
00907                 // We are at the end of the file but have read some data in
00908                 // We must set the goodbit to clear the eof and fail bits as otherwise
00909                 // all the checks in the diskfile will then fail.
00910                 s->z_eof = 1;
00911                 s->file->clear(s->file->goodbit);
00912             }
00913             s->stream.next_in = s->inbuf;
00914         }
00915         s->z_err = inflate->inflate(&(s->stream), Z_NO_FLUSH);
00916 
00917         if (s->z_err == Z_STREAM_END ||
00918             s->z_err != Z_OK  || s->z_eof) break;
00919     }
00920 
00921     // Update len with the bytes left in the uncompressed stream, should be 0 if everything ok
00922     unsigned len = 1 - s->stream.avail_out;
00923 
00924     s->PeekedValue = *buf;      // remember the value that was read in      
00925     s->PeekStatus += 1;         // increment peek count
00926     s->stream.avail_out += 1;   // say that we have peeked 1 character
00927 
00928     // return the actual amount read in back to the caller
00929     return len;
00930 }   

INT32 GZipFile::gzread GZipStream s,
char *  buf,
unsigned  len
 

Reads the given number of uncompressed bytes from the compressed file. If the input file was not in gzip format, gzread copies the given number of bytes into the buffer. gzread returns the number of uncompressed bytes actually read (0 for end of file, -1 for error).

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95
Parameters:
s the zip stream that we should be using [INPUTS] buf the buffer that needs the data reading into
Returns:
number of uncompressed bytes actually read (0 for end of file, -1 for error)

Definition at line 949 of file zstream.cpp.

00950 {
00951     //TRACEUSER( "Neville", _T("GZipFile::gz_read\n"));
00952     // check that everyhting is valid before preceeding
00953     if (s == NULL || s->mode != 'r' || inflate == NULL || buf == NULL) return Z_STREAM_ERROR;
00954 
00955     Byte *b = (Byte*)buf;
00956 
00957     // Section added by version 0.99 update
00958     if (s->transparent)
00959     {
00960         TRACEUSER( "Neville", _T("GZipFile::gz_read trying transparent!\n"));
00961         return 0;
00962     }
00963 
00964     // First check for problem states from last reading/peeking
00965     if (s->z_err == Z_DATA_ERROR) return -1; /* bad .gz file */
00966     if (s->z_err == Z_STREAM_END) return 0;  /* don't read crc as data */
00967 
00968     // use the supplied buffer to read the characters into
00969     s->stream.next_out = b;
00970 
00971     // if we have peeked then avail_out will be equal to the number of peeks made 
00972     if (s->stream.avail_out > 0)
00973     {
00974         // add in the values from the peeks
00975         ERROR3IF(s->stream.avail_out > 1,"read with peek > 1");
00976         buf[0] = s->PeekedValue;        // set first byte to be the peeked value
00977         s->PeekStatus -= 1;             // decrement peek count 
00978         s->stream.avail_out -= 1;       // need one less byte for input
00979 
00980         if (len == 1)
00981         {
00982             // only 1 byte wanted and we have just supplied this
00983             // checksum the byte that we have just read in
00984             s->crc = crc32(s->crc, b, len);
00985             return len;             
00986         }
00987         // otherwise we require some more input
00988         s->stream.avail_out = len - 1;  // need one less byte for input
00989         s->stream.next_out = b + 1;     // move buffer pointer on by one
00990     }
00991     else
00992         s->stream.avail_out = len;
00993 
00994     while (s->stream.avail_out != 0)
00995     {
00996         if (s->stream.avail_in == 0 && !s->z_eof)
00997         {
00998             s->stream.avail_in = Z_BUFSIZE;
00999             // Note the current file position
01000             FilePos Pos = s->file->tellg();
01001             s->file->read((char *) s->inbuf, s->stream.avail_in );
01002             FilePos PosAfter = s->file->rdbuf()->pubseekoff( 0, iostream::cur, iostream::in );
01003             s->stream.avail_in = PosAfter- Pos;
01004 TRACEUSER( "Neville", _T("GZipFile::gz_read filled buffer size %d\n"),s->stream.avail_in);
01005             if (s->stream.avail_in == 0)
01006             {
01007                 //s->file->setf(s->file->eofbit);
01008                 s->z_eof = 1;
01009             }
01010             /*else if (s->stream.avail_in == (uInt)EOF)
01011             {
01012             //    s->stream.avail_in = 0;
01013                 s->z_eof = 1;
01014             //    s->z_err = Z_ERRNO;
01015             //    break;
01016             } */
01017             else if (s->stream.avail_in < Z_BUFSIZE || s->file->eof())
01018             {
01019                 // We are at the end of the file but have read some data in
01020                 // We must set the goodbit to clear the eof and fail bits as otherwise
01021                 // all the checks in the diskfile will then fail.
01022                 s->z_eof = 1;
01023                 s->file->clear(s->file->goodbit);
01024             }
01025             s->stream.next_in = s->inbuf;
01026         }
01027         s->z_err = inflate->inflate(&(s->stream), Z_NO_FLUSH);
01028 
01029         if (s->z_err == Z_STREAM_END ||
01030             s->z_err != Z_OK  || s->z_eof) break;
01031     }
01032 
01033     // Update len with the bytes left in the uncompressed stream, should be 0 if everything ok
01034     len -= s->stream.avail_out;
01035 
01036     // checksum the data that we have just read in
01037     s->crc = crc32(s->crc, b, len);
01038 
01039     // return the actual amount read in back to the caller
01040     return len;
01041 }

INT32 GZipFile::gzwrite GZipStream s,
const char *  buf,
unsigned  len
 

Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of bytes actually written (0 in case of error).

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95
Parameters:
s the zip stream that we should be using [INPUTS] buf the buffer that needs exporting len the length of the buffer
Returns:
the number of uncompressed bytes actually written (0 in case of error)

Definition at line 1088 of file zstream.cpp.

01089 {
01090 #ifdef DO_EXPORT
01091     //TRACEUSER( "Neville", _T("GZipFile::gz_write\n"));
01092     
01093     if (s == NULL || s->mode != 'w' || deflate == NULL || buf == NULL)
01094         return Z_STREAM_ERROR;
01095 
01096     Byte* b = (Byte*)buf;
01097 
01098     s->stream.next_in = b;
01099     s->stream.avail_in = len;
01100 
01101     while (s->stream.avail_in != 0)
01102     {
01103         if (s->stream.avail_out == 0)
01104         {
01105             s->stream.next_out = s->outbuf;
01106             INT32 len = Z_BUFSIZE;
01107             s->file->write((const char*)s->outbuf, len);
01108             if (len != Z_BUFSIZE)
01109             {
01110                 s->z_err = Z_ERRNO;
01111                 break;
01112             }
01113             s->stream.avail_out = Z_BUFSIZE;
01114         }
01115         s->z_err = deflate->deflate(&(s->stream), Z_NO_FLUSH);
01116         
01117         // Check if we had a problem or not 
01118         if (s->z_err != Z_OK)
01119             break;
01120     }
01121 
01122     // Update our checksum of the data
01123     s->crc = crc32(s->crc, b, len);
01124 
01125     // Return the number of bytes that we actually wrote
01126     return len - s->stream.avail_in;
01127 #else
01128     return Z_STREAM_ERROR;
01129 #endif
01130 }

void GZipFile::putLong iostream *  file,
uLong  x
[protected]
 

Outputs an INT32 in LSB order to the given file.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95

Definition at line 1205 of file zstream.cpp.

01206 {
01207 #ifdef DO_EXPORT
01208     INT32 n;
01209     for (n = 0; n < 4; n++)
01210     {
01211 //        _fputtc((INT32)(x & 0xff), file);
01212         file->put((TCHAR)(x & 0xff));
01213         x >>= 8;
01214     }
01215 #endif
01216 }

void * GZipFile::zcalloc void *  opaque,
unsigned  items,
unsigned  size
[static]
 

Allocate memory of size items and with size bytes per item.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95
Parameters:
opaque random memory handle/checksum value, never used [INPUTS] items number of items required size size of each buffer item
Returns:
the checksum value

Definition at line 1664 of file zstream.cpp.

01665 {
01666     // allocate memory of size items and with size bytes per item
01667     //return calloc(items, size);
01668     return CCMalloc(items * size);
01669 }

void GZipFile::zcfree void *  opaque,
void *  ptr
[static]
 

A wrapper round the free function.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95
Parameters:
opaque random memory handle/checksum value, never used [INPUTS] ptr memory pointer to free, must have been allocated by zcalloc

Definition at line 1683 of file zstream.cpp.

01684 {
01685     //free(ptr);
01686     if (ptr)
01687         CCFree(ptr);
01688 }


Member Data Documentation

ZipDeflate* GZipFile::deflate [protected]
 

Definition at line 255 of file zstream.h.

ZipInflate* GZipFile::inflate [protected]
 

Definition at line 256 of file zstream.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:55:05 2007 for Camelot by  doxygen 1.4.4