zstream.cpp

Go to the documentation of this file.
00001 // $Id: zstream.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 //
00099 // A file which encapsulates the zipped file streaming routines and data.
00100 // Used to compress/uncompress the native files.
00101 
00102 /*
00103 */
00104 
00105 #include "camtypes.h"
00106 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00107 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 
00109 #include "zstream.h"
00110 #include "zdeflate.h"
00111 #include "zinflate.h"
00112 
00113 // This is not compulsory, but you may as well put it in so that the correct version
00114 // of your file can be registered in the .exe
00115 DECLARE_SOURCE("$Revision: 1282 $");
00116 
00117 // An implement to match the Declare in the .h file.
00118 // If you have many classes, it is recommended to place them all together, here at the start of the file
00119 CC_IMPLEMENT_MEMDUMP(ZStream, CC_CLASS_MEMDUMP)
00120 CC_IMPLEMENT_MEMDUMP(GZipStream, CC_CLASS_MEMDUMP)
00121 CC_IMPLEMENT_MEMDUMP(GZipFile, CC_CLASS_MEMDUMP)
00122 
00123 // This will get Camelot to display the filename and linenumber of any memory allocations
00124 // that are not released at program exit
00125 // Declare smart memory handling in Debug builds
00126 #define new CAM_DEBUG_NEW
00127 
00128 // Some useful zip bits
00129 #if RALPH
00130     #define Z_BUFSIZE 32 // was 4096
00131 #else
00132     #define Z_BUFSIZE 32*1024 // was 4096
00133 #endif
00134 
00135 //#define ALLOC(size) zcalloc((voidp)0, 1, size)
00136 //#define TRYFREE(p) {if (p) zcfree((voidp)0, p);}
00137 #define ALLOC(size) CCMalloc(size)
00138 #define TRYFREE(p) {if (p) { CCFree(p); p = NULL; } }
00139 
00140 //#define GZ_MAGIC_1 0x1f
00141 //#define GZ_MAGIC_2 0x8b
00142 
00143 //static INT32 gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
00144 
00145 /* gzip flag byte */
00146 #define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
00147 #define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
00148 #define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
00149 #define ORIG_NAME    0x08 /* bit 3 set: original file name present */
00150 #define COMMENT      0x10 /* bit 4 set: file comment present */
00151 #define RESERVED     0xE0 /* bits 5..7: reserved */
00152 
00153 #ifndef SEEK_CUR
00154 #  define SEEK_CUR 1
00155 #endif
00156 
00157 /* ---------------------------------- ZStream class -------------------------------------- */
00158 
00159 /********************************************************************************************
00160 
00161 >   ZStream::ZStream()
00162 
00163     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00164     Created:    34/05/95
00165     Purpose:    ZStream constructor.
00166 
00167 ********************************************************************************************/
00168 
00169 ZStream::ZStream()
00170 {
00171     next_in = NULL;
00172     avail_in = 0;
00173     total_in = 0;   
00174 
00175     next_out = NULL;
00176     avail_out = 0;
00177     total_out = 0;  
00178 
00179     msg = NULL;
00180 
00181     In_state = NULL;
00182     De_state = NULL;
00183 
00184     zalloc = (alloc_func)0;
00185     zfree = (free_func)0;
00186 
00187     data_type = Z_BINARY;
00188     adler = 0;
00189     reserved = 0;
00190 
00191     zlib_version = ZLIB_VERSION;
00192 }   
00193 
00194 /********************************************************************************************
00195 
00196 >   ZStream::ZStream()
00197 
00198     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00199     Created:    34/05/95
00200     Purpose:    ZStream destructor.
00201 
00202 ********************************************************************************************/
00203 
00204 ZStream::~ZStream()
00205 {
00206     if (In_state)
00207     {
00208         delete In_state;
00209         In_state = NULL;        
00210     }
00211 #ifdef DO_EXPORT
00212     if (De_state)
00213     {
00214         delete De_state;
00215         De_state = NULL;        
00216     }
00217 #endif
00218 }   
00219 
00220 
00221 /* ------------------------------- GZipStream class -------------------------------------- */
00222 
00223 /********************************************************************************************
00224 
00225 >   GZipStream::GZipStream()
00226 
00227     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00228     Created:    34/05/95
00229     Purpose:    GZipStream constructor.
00230 
00231 ********************************************************************************************/
00232 
00233 GZipStream::GZipStream()
00234 {
00235     z_err = Z_OK;
00236     z_eof = 0;
00237 
00238     file = NULL;
00239     inbuf = NULL;
00240     outbuf = NULL;
00241 
00242     crc = 0;
00243     crc = GZipFile::crc32(0L, NULL, 0);
00244     msg = NULL;
00245     path = NULL;
00246     transparent = 0;
00247 
00248     Peek = FALSE;       // no value peeked
00249     PeekedValue = '#';  // random value
00250     PeekStatus = Z_OK;  // status ok
00251 
00252     InitialPos = 0;
00253 
00254     Inited = FALSE;
00255 }   
00256 
00257 /********************************************************************************************
00258 
00259 >   GZipStream::~GZipStream()
00260 
00261     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00262     Created:    34/05/95
00263     Purpose:    GZipStream destructor.
00264 
00265 ********************************************************************************************/
00266 
00267 GZipStream::~GZipStream()
00268 {
00269     // Try and free up the buffers that we have allocated 
00270     TRYFREE(inbuf);
00271     TRYFREE(outbuf);
00272     TRYFREE(path);
00273     TRYFREE(msg);
00274 }   
00275 
00276 
00277 /* --------------------------------- GZipFile class -------------------------------------- */
00278 
00279 /********************************************************************************************
00280 
00281 >   GZipFile::GZipFile()
00282 
00283     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00284     Created:    34/05/95
00285     Purpose:    GZipFile constructor.
00286 
00287 ********************************************************************************************/
00288 
00289 GZipFile::GZipFile()
00290 {
00291     deflate = NULL;   
00292     inflate = NULL;   
00293 }   
00294 
00295 /********************************************************************************************
00296 
00297 >   GZipFile::~GZipFile()
00298 
00299     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00300     Created:    34/05/95
00301     Purpose:    GZipFile destructor.
00302 
00303 ********************************************************************************************/
00304 
00305 GZipFile::~GZipFile()
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 }   
00323 
00324 /********************************************************************************************
00325 
00326 >   static double GZipFile::GetStreamVersionNo()
00327 
00328     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00329     Created:    30/05/95
00330     Returns:    the current version number of the stream in the form 0.92
00331     Purpose:    To find out the current version number of the stream and hence files which
00332                 it can recoknise. The verison is of the form 0.92.
00333 
00334 ********************************************************************************************/
00335 
00336 double GZipFile::GetStreamVersionNo()
00337 {
00338     return ZLIB_VERSIONNO;
00339 }
00340 
00341 /********************************************************************************************
00342 
00343 >   INT32 GZipFile::destroy(GZipStream *s)
00344 
00345     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00346     Created:    24/05/95
00347     Purpose:    Cleanup then free the given GZipStream. Return a zlib error code.
00348                 Assume caller will close the file.
00349 
00350 ********************************************************************************************/
00351 
00352 INT32 GZipFile::destroy(GZipStream *s)
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 }
00409 
00410 //static const Bytef dictionary[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00411 //static const uInt dictionary_size = 8;
00412     
00413 /********************************************************************************************
00414 
00415 >   GZipStream *GZipFile::gz_init(iostream *pFileStream, TCHAR *mode, BOOL Header = FALSE)
00416 
00417     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00418     Created:    1/06/95
00419     Inputs:     pFileStream     the iostream class to use for reading/writing
00420                 mode            rw mode for this file
00421                     
00422     Purpose:    Initialises the compression system and tries to grab the memory required.
00423                 gz_init returns NULL if there was insufficient memory to allocate the
00424                 (de)compression state; errno can be checked to distinguish the two cases
00425                 (if errno is zero, the zlib error is Z_MEM_ERROR).
00426                 Graeme ( 15/11/99) : Added the Header parameter to the parameter list.
00427                 This enables the GZipStream to be initialised so that it writes the ZLib
00428                 header, which was previously supressed.
00429 
00430 ********************************************************************************************/
00431 
00432 GZipStream *GZipFile::gz_init(iostream *pFileStream, TCHAR *mode, BOOL Header)
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 }
00560 
00561 /********************************************************************************************
00562 
00563 >   INT32 GZipFile::gz_open(GZipStream *s)
00564 
00565     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00566     Created:    1/06/95
00567     Inputs:     s       the zip stream that we should be using
00568                     
00569     Purpose:    The form of open if we have already called init.
00570                 At present, this is fairly simple and just checks out a few things
00571 
00572 ********************************************************************************************/
00573 
00574 INT32 GZipFile::gz_open(GZipStream *s)
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 }
00631 
00632 /********************************************************************************************
00633 
00634 >   GZipStream *GZipFile::gz_open(iostream* pFileStream, TCHAR *mode, TCHAR *path)
00635 
00636     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00637     Created:    24/05/95
00638     Inputs:     pFileStream     the iostream class to use for reading/writing
00639                 mode            rw mode for this file
00640                 path            pathname for this file (optional)
00641                     
00642     Purpose:    Opens a gzip file for reading or writing. The mode parameter is as in fopen
00643                 ("rb" or "wb").
00644                 The stream is given at present by the iostream class, the patname is
00645                 optional and is just used for debugging.
00646 
00647                 gz_open return NULL if the stream could not be opened or if there was
00648                 insufficient memory to allocate the (de)compression state; errno
00649                 can be checked to distinguish the two cases (if errno is zero, the
00650                 zlib error is Z_MEM_ERROR).
00651 
00652 ********************************************************************************************/
00653 
00654 GZipStream *GZipFile::gz_open(iostream* pFileStream, TCHAR *mode, TCHAR *path )
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 }
00834 
00835 /********************************************************************************************
00836 
00837 >   INT32    GZipFile::gzpeek(GZipStream *file, TCHAR data)
00838 
00839     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00840     Created:    24/05/95
00841     Inputs:     s       the zip stream that we should be using
00842                 buf     the character that we are to return
00843     Returns:    number of uncompressed bytes actually read (0 for end of file, -1 for error)
00844     Purpose:    Reads the next byte from the input stream and returns this to the caller.
00845                 It then remembers this value for the next read.
00846                 gzread returns the number of uncompressed bytes actually read (0 for
00847                 end of file, -1 for error).
00848 
00849 ********************************************************************************************/
00850 
00851 INT32    GZipFile::gzpeek( GZipStream *s, char *buf )
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 }   
00931 
00932 /********************************************************************************************
00933 
00934 >   INT32 GZipFile::gzread(GZipStream *s, Byte *buf, unsigned len)
00935 
00936     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00937     Created:    24/05/95
00938     Inputs:     s       the zip stream that we should be using
00939                 buf     the buffer that needs the data reading into
00940     Returns:    number of uncompressed bytes actually read (0 for end of file, -1 for error)
00941     Purpose:    Reads the given number of uncompressed bytes from the compressed file.
00942                 If the input file was not in gzip format, gzread copies the given number
00943                 of bytes into the buffer.
00944                 gzread returns the number of uncompressed bytes actually read (0 for
00945                 end of file, -1 for error).
00946 
00947 ********************************************************************************************/
00948 
00949 INT32 GZipFile::gzread( GZipStream *s, char *buf, unsigned len )
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 }
01042 
01043 /********************************************************************************************
01044 
01045 >   FilePos GZipFile::GetCurrentFilePos(GZipStream *s)
01046 
01047     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01048     Created:    30/05/95
01049     Inputs:     s       the zip stream that we should be using
01050     Returns:    the current file position
01051     Purpose:    Allows the progress bar to be updated with the current position in
01052                 the compressed file.
01053 
01054 ********************************************************************************************/
01055 
01056 FilePos GZipFile::GetCurrentFilePos(GZipStream *s)
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 }
01070 
01071 
01072 
01073 /********************************************************************************************
01074 
01075 >   INT32 GZipFile::gzwrite(GZipStream *s, const TCHAR *buf, unsigned len)
01076 
01077     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01078     Created:    24/05/95
01079     Inputs:     s       the zip stream that we should be using
01080                 buf     the buffer that needs exporting
01081                 len     the length of the buffer 
01082     Returns:    the number of uncompressed bytes actually written (0 in case of error)
01083     Purpose:    Writes the given number of uncompressed bytes into the compressed file.
01084                 gzwrite returns the number of bytes actually written (0 in case of error).
01085 
01086 ********************************************************************************************/
01087 
01088 INT32 GZipFile::gzwrite(GZipStream *s, const char *buf, unsigned len)
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 }
01131 
01132 /********************************************************************************************
01133 
01134 >   INT32 GZipFile::gzflush(GZipStream *s, INT32 flush)
01135 
01136     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01137     Created:    24/05/95
01138     Inputs:     s       the zip stream that is to be used
01139                 flush   
01140     Purpose:    Flushes all pending output into the compressed file. The parameter
01141                 flush is as in the deflate() function. The return value is the zlib
01142                 error number (see function gzerror below). gzflush returns Z_OK if the
01143                 flush parameter is Z_FINISH and all output could be flushed.
01144                 gzflush should be called only when strictly necessary because it can
01145                 degrade compression.
01146 
01147 ********************************************************************************************/
01148 
01149 INT32 GZipFile::gzflush(GZipStream *s, INT32 flush)
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 }
01194 
01195 /********************************************************************************************
01196 
01197 >   void GZipFile::putLong(iostream *file, uLong x)
01198 
01199     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01200     Created:    24/05/95
01201     Purpose:    Outputs an INT32 in LSB order to the given file
01202 
01203 ********************************************************************************************/
01204 
01205 void GZipFile::putLong(iostream *file, uLong x)
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 }
01217 
01218 /********************************************************************************************
01219 
01220 >   uLong GZipFile::getLong (Byte *buf)
01221 
01222     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01223     Created:    24/05/95
01224     Purpose:    Reads an INT32 in LSB order from the given buffer
01225 
01226 ********************************************************************************************/
01227 
01228 uLong GZipFile::getLong (Byte *buf)
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 }
01241 
01242 /********************************************************************************************
01243 
01244 >   INT32 GZipFile::gzclose(GZipStream *s)
01245 
01246     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01247     Created:    24/05/95
01248     Inputs:     s   the z stream to be used  
01249     Returns:    Z_OK or an error number if there has been a problem
01250     Purpose:    Flushes all pending output if necessary, closes the compressed file
01251                 and deallocates all the (de)compression state.
01252                 The return value is the zlib error number (see function gzerror below).
01253 
01254 ********************************************************************************************/
01255 
01256 INT32 GZipFile::gzclose(GZipStream *s)
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 }
01321 
01322 /********************************************************************************************
01323 ********************************************************************************************/
01324 //static char *z_errmsg[] =
01325 //  {
01326 //      "stream end",          /* Z_STREAM_END    1 */
01327 //      "",                    /* Z_OK            0 */
01328 //      "file error",          /* Z_ERRNO        (-1) */
01329 //      "stream error",        /* Z_STREAM_ERROR (-2) */
01330 //      "data error",          /* Z_DATA_ERROR   (-3) */
01331 //      "insufficient memory", /* Z_MEM_ERROR    (-4) */
01332 //      "buffer error",        /* Z_BUF_ERROR    (-5) */
01333 //      ""
01334 //  };
01335 
01336 /********************************************************************************************
01337 
01338 >   char*  GZipFile::gzerror(GZipStream *s, INT32 *errnum)
01339 
01340     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01341     Created:    24/05/95
01342     Purpose:    Returns the error message for the last error which occured on the
01343                 given compressed file. errnum is set to zlib error number. If an
01344                 error occured in the file system and not in the compression library,
01345                 errnum is set to Z_ERRNO and the application may consult errno
01346                 to get the exact error code.
01347 
01348 ********************************************************************************************/
01349 
01350 //char*  GZipFile::gzerror(GZipStream *s, INT32 *errnum)
01351 //{
01352 //  TRACEUSER( "Neville", _T("GZipFile::gzerror\n"));
01353 //
01354 //    char *m;
01355 //
01356 //    if (s == NULL)
01357 //    {
01358 //        *errnum = Z_STREAM_ERROR;
01359 //        return z_errmsg[1-Z_STREAM_ERROR];
01360 //    }
01361 //
01362 //    *errnum = s->z_err;
01363 //    if (*errnum == Z_OK) return "";
01364 //
01365 //    if (*errnum == Z_ERRNO)
01366 //    {
01367 //      _stprintf(m, "Disc error number %d", errno);  //zstrerror(errno);   
01368 //    }
01369 //  else
01370 //  {
01371 //      m = s->stream.msg;  
01372 //  }
01373 //
01374 //    if (m == NULL || *m == '\0') m = z_errmsg[1-s->z_err];
01375 //
01376 //    TRYFREE(s->msg);
01377 //    s->msg = (char*)ALLOC(_tcsclen(s->path) + strlen(m) + 3);
01378 //  if (s->msg)
01379 //  {
01380 //      camStrcpy(s->msg, s->path);
01381 //      strcat(s->msg, ": ");
01382 //      strcat(s->msg, m);
01383 //  }
01384 //
01385 //    return s->msg;
01386 //}
01387 
01388 //-------------------------------------------------------------------------------------------
01389 // Contents of file CRC32.c
01390 //-------------------------------------------------------------------------------------------
01391 
01392 /********************************************************************************************
01393 
01394     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01395     Created:    24/05/95
01396     Purpose:    Table of CRC-32's of all single-byte values (made by make_crc_table)
01397 
01398 ********************************************************************************************/
01399 #if 0 //def DYNAMIC_CRC_TABLE
01400 
01401 static INT32 crc_table_empty = 1;
01402 static uLongf crc_table[256];
01403 static void make_crc_table OF((void));
01404 
01405 /*
01406   Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
01407   x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
01408 
01409   Polynomials over GF(2) are represented in binary, one bit per coefficient,
01410   with the lowest powers in the most significant bit.  Then adding polynomials
01411   is just exclusive-or, and multiplying a polynomial by x is a right shift by
01412   one.  If we call the above polynomial p, and represent a byte as the
01413   polynomial q, also with the lowest power in the most significant bit (so the
01414   byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
01415   where a mod b means the remainder after dividing a by b.
01416 
01417   This calculation is done using the shift-register method of multiplying and
01418   taking the remainder.  The register is initialized to zero, and for each
01419   incoming bit, x^32 is added mod p to the register if the bit is a one (where
01420   x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
01421   x (which is shifting right by one and adding x^32 mod p if the bit shifted
01422   out is a one).  We start with the highest power (least significant bit) of
01423   q and repeat for all eight bits of q.
01424 
01425   The table is simply the CRC of all possible eight bit values.  This is all
01426   the information needed to generate CRC's on data a byte at a time for all
01427   combinations of CRC register values and incoming bytes.
01428 */
01429 
01430 /* =========================================================================
01431  * Make the crc table. This function is needed only if you want to compute
01432  * the table dynamically.
01433 */
01434 
01435 void make_crc_table()
01436 {
01437   uLong c;
01438   INT32 n, k;
01439   uLong poly;            /* polynomial exclusive-or pattern */
01440   /* terms of polynomial defining this crc (except x^32): */
01441   static Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
01442 
01443   /* make exclusive-or pattern from polynomial (0xedb88320L) */
01444   poly = 0L;
01445   for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
01446     poly |= 1L << (31 - p[n]);
01447  
01448   for (n = 0; n < 256; n++)
01449   {
01450     c = (uLong)n;
01451     for (k = 0; k < 8; k++)
01452       c = c & 1 ? poly ^ (c >> 1) : c >> 1;
01453     crc_table[n] = c;
01454   }
01455   crc_table_empty = 0;
01456 }
01457 #else
01458 /* ========================================================================
01459  * Table of CRC-32's of all single-byte values (made by make_crc_table)
01460  */
01461 static uLongf crc_table[256] = {
01462   0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
01463   0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
01464   0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
01465   0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
01466   0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
01467   0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
01468   0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
01469   0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
01470   0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
01471   0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
01472   0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
01473   0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
01474   0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
01475   0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
01476   0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
01477   0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
01478   0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
01479   0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
01480   0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
01481   0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
01482   0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
01483   0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
01484   0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
01485   0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
01486   0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
01487   0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
01488   0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
01489   0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
01490   0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
01491   0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
01492   0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
01493   0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
01494   0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
01495   0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
01496   0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
01497   0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
01498   0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
01499   0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
01500   0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
01501   0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
01502   0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
01503   0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
01504   0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
01505   0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
01506   0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
01507   0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
01508   0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
01509   0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
01510   0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
01511   0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
01512   0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
01513   0x2d02ef8dL
01514 };
01515 #endif
01516 
01517 /* ========================================================================= */
01518 #define DO1(buf) crc = crc_table[((INT32)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
01519 #define DO2(buf)  DO1(buf); DO1(buf);
01520 #define DO4(buf)  DO2(buf); DO2(buf);
01521 #define DO8(buf)  DO4(buf); DO4(buf);
01522 
01523 /* ========================================================================= */
01524 
01525 /********************************************************************************************
01526 
01527 >   uLong GZipFile::crc32(uLong crc, Bytef *buf, uInt len)
01528 
01529     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01530     Created:    24/05/95
01531     Inputs:     crc     previous checksum value???
01532                 buf     pointer to the buffer to check
01533                 len     length of the buffer
01534     Returns:    the checksum value
01535     Purpose:    Update a running crc with the bytes buf[0..len-1] and return the updated
01536                 crc. If buf is NULL, this function returns the required initial value
01537                 for the crc. Pre- and post-conditioning (one's complement) is performed
01538                 within this function so it shouldn't be done by the application.
01539                 Usage example:
01540 
01541                 uLong crc = crc32(0L, Z_NULL, 0);
01542 
01543                 while (read_buffer(buffer, length) != EOF)
01544                 {
01545                     crc = crc32(crc, buffer, length);
01546                 }
01547                 if (crc != original_crc) error();
01548 
01549 ********************************************************************************************/
01550 uLong GZipFile::crc32(uLong crc, Bytef *buf, uInt len)
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 }
01568 
01569 /* =========================================================================
01570  * This function can be used by asm versions of crc32()
01571  */
01572 uLongf *GZipFile::get_crc_table()
01573 {
01574 #ifdef DYNAMIC_CRC_TABLE
01575   if (crc_table_empty) make_crc_table();
01576 #endif
01577   return (uLongf *)crc_table;
01578 }
01579 
01580 /********************************************************************************************
01581 ********************************************************************************************/
01582 
01583 //-------------------------------------------------------------------------------------------
01584 // Contents of file CRC32.c
01585 //-------------------------------------------------------------------------------------------
01586 
01587 #define BASE 65521L /* largest prime smaller than 65536 */
01588 #define NMAX 5552
01589 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
01590 
01591 #define A_DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
01592 #define A_DO2(buf,i)  A_DO1(buf,i); A_DO1(buf,i+1);
01593 #define A_DO4(buf,i)  A_DO2(buf,i); A_DO2(buf,i+2);
01594 #define A_DO8(buf,i)  A_DO4(buf,i); A_DO4(buf,i+4);
01595 #define A_DO16(buf)   A_DO8(buf,0); A_DO8(buf,8);
01596 
01597 /********************************************************************************************
01598 
01599 >   uLong GZipFile::adler32(uLong adler, const Bytef *buf, uInt len)
01600 
01601     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01602     Created:    24/05/95
01603     Inputs:     crc     previous checksum value???
01604                 buf     pointer to the buffer to check
01605                 len     length of the buffer
01606     Returns:    the checksum value
01607     Purpose:    Update a running Adler-32 checksum with the bytes buf[0..len-1] and
01608                 return the updated checksum. If buf is NULL, this function returns
01609                 the required initial value for the checksum.
01610                 An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
01611                 much faster. Usage example:
01612 
01613                 uLong adler = adler32(0L, Z_NULL, 0);
01614 
01615                 while (read_buffer(buffer, length) != EOF)
01616                 {
01617                     adler = adler32(adler, buffer, length);
01618                 }
01619                 if (adler != original_adler) error();
01620 
01621 ********************************************************************************************/
01622 
01623 /* ========================================================================= */
01624 uLong GZipFile::adler32(uLong adler, const Bytef *buf, uInt len)
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;}
01648 
01649 
01650 /********************************************************************************************
01651 
01652 >   void *GZipFile::zcalloc (opaque, items, size)
01653 
01654     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01655     Created:    24/05/95
01656     Inputs:     opaque  random memory handle/checksum value, never used
01657                 items   number of items required
01658                 size    size of each buffer item
01659     Returns:    the checksum value
01660     Purpose:    Allocate memory of size items and with size bytes per item
01661 
01662 ********************************************************************************************/
01663 
01664 void *GZipFile::zcalloc(void *opaque, unsigned items, unsigned size)
01665 {
01666     // allocate memory of size items and with size bytes per item
01667     //return calloc(items, size);
01668     return CCMalloc(items * size);
01669 }
01670 
01671 /********************************************************************************************
01672 
01673 >   void  GZipFile::zcfree(opaque, ptr)
01674 
01675     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01676     Created:    24/05/95
01677     Inputs:     opaque  random memory handle/checksum value, never used
01678                 ptr     memory pointer to free, must have been allocated by zcalloc
01679     Purpose:    A wrapper round the free function
01680 
01681 ********************************************************************************************/
01682 
01683 void  GZipFile::zcfree(void *opaque, void *ptr)
01684 {
01685     //free(ptr);
01686     if (ptr)
01687         CCFree(ptr);
01688 }

Generated on Sat Nov 10 03:47:28 2007 for Camelot by  doxygen 1.4.4