123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055 |
- /*
- ===========================================================================
- Doom 3 BFG Edition GPL Source Code
- Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
- Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #include "../idlib/precompiled.h"
- #pragma hdrstop
- /*
- ================================================================================================
- Contains external code for building ZipFiles.
- ================================================================================================
- */
- #include "Zip.h"
- #include "Unzip.h"
- #undef STDC
- #include "zlib/zutil.h"
- /* zip.c -- IO on .zip files using zlib
- Version 1.01e, February 12th, 2005
- 27 Dec 2004 Rolf Kalbermatter
- Modification to zipOpen2 to support globalComment retrieval.
- Copyright (C) 1998-2005 Gilles Vollant
- This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
- WinZip, InfoZip tools and compatible.
- Multi volume ZipFile (span) are not supported.
- Encryption compatible with pkzip 2.04g only supported
- Old compressions used by old PKZip 1.x are not supported
- For uncompress .zip file, look at unzip.h
- I WAIT FEEDBACK at mail info@winimage.com
- Visit also http://www.winimage.com/zLibDll/unzip.html for evolution
- Condition of use and distribution are the same than zlib :
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- For more info about .ZIP format, see
- http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
- http://www.info-zip.org/pub/infozip/doc/
- PkWare has also a specification at :
- ftp://ftp.pkware.com/probdesc.zip
- */
- #ifndef Z_MAXFILENAMEINZIP
- #define Z_MAXFILENAMEINZIP (256)
- #endif
- #ifndef ALLOC
- #define ALLOC( size ) ( Mem_Alloc( size, TAG_ZIP ) )
- #endif
- #ifndef TRYFREE
- #define TRYFREE( p ) { if (p) { Mem_Free(p); } }
- #endif
- /*
- #define SIZECENTRALDIRITEM (0x2e)
- #define SIZEZIPLOCALHEADER (0x1e)
- */
- const char zip_copyright[] =
- " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
- #define LOCALHEADERMAGIC (0x04034b50)
- #define CENTRALHEADERMAGIC (0x02014b50)
- #define ENDHEADERMAGIC (0x06054b50)
- #define FLAG_LOCALHEADER_OFFSET (0x06)
- #define CRC_LOCALHEADER_OFFSET (0x0e)
- #define SIZECENTRALHEADER (0x2e) /* 46 */
- #define DEFAULT_COMPRESSION_LEVEL (5) /* 1 == Compress faster, 9 == Compress better */
- #define DEFAULT_WRITEBUFFERSIZE (16384)
- #ifndef NOCRYPT
- #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
- #include "crypt.h"
- #endif
- idCVar zip_verbosity( "zip_verbosity", "0", CVAR_BOOL, "1 = verbose logging when building zip files" );
- /*
- ========================
- allocate_new_datablock
- ========================
- */
- linkedlist_datablock_internal* allocate_new_datablock() {
- linkedlist_datablock_internal* ldi = NULL;
- ldi = (linkedlist_datablock_internal*) ALLOC( sizeof( linkedlist_datablock_internal ) );
- if ( ldi != NULL ) {
- ldi->next_datablock = NULL;
- ldi->filled_in_this_block = 0;
- ldi->avail_in_this_block = SIZEDATA_INDATABLOCK;
- }
- return ldi;
- }
- /*
- ========================
- free_datablock
- ========================
- */
- void free_datablock( linkedlist_datablock_internal* ldi ) {
- while ( ldi != NULL ) {
- linkedlist_datablock_internal* ldinext = ldi->next_datablock;
- TRYFREE( ldi );
- ldi = ldinext;
- }
- }
- /*
- ========================
- init_linkedlist
- ========================
- */
- void init_linkedlist( linkedlist_data* ll ) {
- ll->first_block = ll->last_block = NULL;
- }
- /*
- ========================
- free_linkedlist
- ========================
- */
- void free_linkedlist( linkedlist_data* ll ) {
- free_datablock( ll->first_block );
- ll->first_block = ll->last_block = NULL;
- }
- /*
- ========================
- add_data_in_datablock
- ========================
- */
- int add_data_in_datablock( linkedlist_data* ll, const void* buf, unsigned long len ) {
- linkedlist_datablock_internal* ldi;
- const unsigned char* from_copy;
- if ( ll == NULL ) {
- return ZIP_INTERNALERROR;
- }
- if ( ll->last_block == NULL ) {
- ll->first_block = ll->last_block = allocate_new_datablock();
- if ( ll->first_block == NULL ) {
- return ZIP_INTERNALERROR;
- }
- }
- ldi = ll->last_block;
- from_copy = (unsigned char*)buf;
- while ( len > 0 ) {
- unsigned int copy_this;
- unsigned char* to_copy;
- if ( ldi->avail_in_this_block == 0 ) {
- ldi->next_datablock = allocate_new_datablock();
- if ( ldi->next_datablock == NULL ) {
- return ZIP_INTERNALERROR;
- }
- ldi = ldi->next_datablock;
- ll->last_block = ldi;
- }
- if ( ldi->avail_in_this_block < len ) {
- copy_this = (unsigned int)ldi->avail_in_this_block;
- } else {
- copy_this = (unsigned int)len;
- }
- to_copy = &( ldi->data[ ldi->filled_in_this_block ] );
- for ( unsigned int i = 0; i < copy_this; i++ ) {
- *( to_copy + i ) =* ( from_copy + i );
- }
- ldi->filled_in_this_block += copy_this;
- ldi->avail_in_this_block -= copy_this;
- from_copy += copy_this;
- len -= copy_this;
- }
- return ZIP_OK;
- }
- #ifndef NO_ADDFILEINEXISTINGZIP
- /*
- ========================
- ziplocal_putValue
- Inputs a long in LSB order to the given file
- nbByte == 1, 2 or 4 (byte, short or long)
- ========================
- */
- int ziplocal_putValue( idFile* filestream, unsigned long x, int nbByte ) {
- unsigned char buf[4];
- for ( int n = 0; n < nbByte; n++ ) {
- buf[n] = (unsigned char)( x & 0xff );
- x >>= 8;
- }
- if ( x != 0 ) {
- /* data overflow - hack for ZIP64 (X Roche) */
- for ( int n = 0; n < nbByte; n++ ) {
- buf[n] = 0xff;
- }
- }
- if ( filestream->Write( buf, nbByte ) != nbByte ) {
- return ZIP_ERRNO;
- } else {
- return ZIP_OK;
- }
- }
- /*
- ========================
- ziplocal_putValue_inmemory
- ========================
- */
- void ziplocal_putValue_inmemory( void* dest, unsigned long x, int nbByte ){
- unsigned char* buf = (unsigned char*)dest;
- for ( int n = 0; n < nbByte; n++ ) {
- buf[n] = (unsigned char)( x & 0xff );
- x >>= 8;
- }
- if ( x != 0 ) {
- /* data overflow - hack for ZIP64 */
- for ( int n = 0; n < nbByte; n++ ) {
- buf[n] = 0xff;
- }
- }
- }
- /*
- ========================
- ziplocal_TmzDateToDosDate
- ========================
- */
- unsigned long ziplocal_TmzDateToDosDate( const tm_zip* ptm, unsigned long dosDate ) {
- unsigned long year = (unsigned long)ptm->tm_year;
- if ( year > 1980 ) {
- year-=1980;
- } else if ( year > 80 ) {
- year -= 80;
- }
- return (unsigned long)( ( ( ptm->tm_mday ) + ( 32 * ( ptm->tm_mon + 1 ) ) + ( 512 * year ) ) << 16 ) |
- ( ( ptm->tm_sec / 2 ) + ( 32 * ptm->tm_min ) + ( 2048 * (unsigned long)ptm->tm_hour ) );
- }
- /*
- ========================
- ziplocal_getByte
- ========================
- */
- int ziplocal_getByte( idFile* filestream, int *pi ) {
- unsigned char c;
- int err = (int)filestream->Read( &c, 1 );
- if ( err == 1 ) {
- *pi = (int)c;
- return ZIP_OK;
- } else {
- return ZIP_ERRNO;
- }
- /*
- unsigned char c;
- int err = (int)ZREAD( filestream, &c, 1 );
- if ( err == 1 ) {
- *pi = (int)c;
- return ZIP_OK;
- } else {
- if ( ZERROR( filestream ) ) {
- return ZIP_ERRNO;
- } else {
- return ZIP_EOF;
- }
- }
- */
- }
- /*
- ========================
- ziplocal_getShort
- Reads a long in LSB order from the given gz_stream. Sets
- ========================
- */
- int ziplocal_getShort( idFile* filestream, unsigned long *pX ) {
- short v;
- if ( filestream->Read( &v, sizeof( v ) ) == sizeof( v ) ) {
- idSwap::Little( v );
- *pX = v;
- return ZIP_OK;
- } else {
- return ZIP_ERRNO;
- }
- /*
- unsigned long x ;
- int i;
- int err;
- err = ziplocal_getByte( filestream, &i );
- x = (unsigned long)i;
- if ( err == ZIP_OK ) {
- err = ziplocal_getByte( filestream, &i );
- }
- x += ( (unsigned long)i ) << 8;
- if ( err == ZIP_OK ) {
- *pX = x;
- } else {
- *pX = 0;
- }
- return err;
- */
- }
- /*
- ========================
- ziplocal_getLong
- ========================
- */
- int ziplocal_getLong( idFile* filestream, unsigned long *pX ) {
- int v;
- if ( filestream->Read( &v, sizeof( v ) ) == sizeof( v ) ) {
- idSwap::Little( v );
- *pX = v;
- return ZIP_OK;
- } else {
- return ZIP_ERRNO;
- }
- /*
- unsigned long x ;
- int i;
- int err;
- err = ziplocal_getByte( filestream, &i );
- x = (unsigned long)i;
- if ( err == ZIP_OK ) {
- err = ziplocal_getByte( filestream, &i );
- }
- x += ( (unsigned long)i ) << 8;
- if ( err == ZIP_OK ) {
- err = ziplocal_getByte( filestream, &i );
- }
- x += ( (unsigned long)i) << 16;
- if ( err == ZIP_OK ) {
- err = ziplocal_getByte( filestream, &i );
- }
- x += ( (unsigned long)i ) << 24;
- if ( err == ZIP_OK ) {
- *pX = x;
- } else {
- *pX = 0;
- }
- return err;
- */
- }
- #ifndef BUFREADCOMMENT
- #define BUFREADCOMMENT (0x400)
- #endif
- /*
- ========================
- ziplocal_SearchCentralDir
- Locate the Central directory of a zipfile (at the end, just before
- the global comment)
- ========================
- */
- unsigned long ziplocal_SearchCentralDir( idFile* filestream ) {
- unsigned char* buf;
- unsigned long uSizeFile;
- unsigned long uBackRead;
- unsigned long uMaxBack = 0xffff; /* maximum size of global comment */
- unsigned long uPosFound = 0;
- if ( filestream->Seek( 0, FS_SEEK_END ) != 0 ) {
- return 0;
- }
- uSizeFile = (unsigned long)filestream->Tell();
- if ( uMaxBack > uSizeFile ) {
- uMaxBack = uSizeFile;
- }
- buf = (unsigned char*)ALLOC( BUFREADCOMMENT + 4 );
- if ( buf == NULL ) {
- return 0;
- }
- uBackRead = 4;
- while ( uBackRead < uMaxBack ) {
- unsigned long uReadSize,uReadPos;
- if ( uBackRead + BUFREADCOMMENT > uMaxBack ) {
- uBackRead = uMaxBack;
- } else {
- uBackRead += BUFREADCOMMENT;
- }
- uReadPos = uSizeFile - uBackRead ;
- uReadSize = ( ( BUFREADCOMMENT + 4 ) < ( uSizeFile - uReadPos ) ) ? ( BUFREADCOMMENT + 4 ) : ( uSizeFile - uReadPos );
- if ( filestream->Seek( uReadPos, FS_SEEK_SET ) != 0 ) {
- break;
- }
- if ( filestream->Read( buf, uReadSize ) != ( int )uReadSize ) {
- break;
- }
- for ( int i = (int)uReadSize - 3; ( i -- ) > 0; ) {
- if ( ( ( *( buf + i ) ) == 0x50 ) && ( ( *( buf + i + 1 ) ) == 0x4b ) && ( ( *( buf + i + 2 ) ) == 0x05 ) && ( ( *( buf + i + 3 ) ) == 0x06 ) ) {
- uPosFound = uReadPos + i;
- break;
- }
- }
- if ( uPosFound != 0 ) {
- break;
- }
- }
- TRYFREE( buf );
- return uPosFound;
- }
- #endif /* !NO_ADDFILEINEXISTINGZIP*/
- /*
- ========================
- zipOpen2
- ========================
- */
- zipFile zipOpen2( const char *pathname, int append, char* globalcomment ) {
- zip_internal ziinit;
- zip_internal* zi;
- int err = ZIP_OK;
- ziinit.filestream = fileSystem->OpenExplicitFileWrite( pathname );
- /*
- ziinit.filestream = ZOPEN( pathname, ( append == APPEND_STATUS_CREATE ) ?
- ( ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE ) :
- ( ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING ) );
- */
- if ( ziinit.filestream == NULL ) {
- return NULL;
- }
- ziinit.begin_pos = (unsigned long)ziinit.filestream->Tell();
- ziinit.in_opened_file_inzip = 0;
- ziinit.ci.stream_initialised = 0;
- ziinit.number_entry = 0;
- ziinit.add_position_when_writting_offset = 0;
- init_linkedlist( &(ziinit.central_dir) );
- zi = (zip_internal*)ALLOC( sizeof( zip_internal ) );
- if ( zi == NULL ) {
- delete ziinit.filestream;
- ziinit.filestream = NULL;
- return NULL;
- }
- /* now we add file in a zipfile */
- #ifndef NO_ADDFILEINEXISTINGZIP
- ziinit.globalcomment = NULL;
- if ( append == APPEND_STATUS_ADDINZIP ) {
- unsigned long byte_before_the_zipfile; // byte before the zipfile, ( > 0 for sfx )
- unsigned long size_central_dir; // size of the central directory
- unsigned long offset_central_dir; // offset of start of central directory
- unsigned long central_pos,uL;
- unsigned long number_disk; // number of the current dist, used for spaning ZIP, unsupported, always 0
- unsigned long number_disk_with_CD; // number the the disk with central dir, used for spaning ZIP, unsupported, always 0
- unsigned long number_entry;
- unsigned long number_entry_CD; // total number of entries in the central dir ( same than number_entry on nospan )
- unsigned long size_comment;
- central_pos = ziplocal_SearchCentralDir( ziinit.filestream );
- if ( central_pos == 0 ) {
- err = ZIP_ERRNO;
- }
- if ( ziinit.filestream->Seek( central_pos, FS_SEEK_SET ) != 0 ) {
- err = ZIP_ERRNO;
- }
- /* the signature, already checked */
- if ( ziplocal_getLong( ziinit.filestream, &uL ) != ZIP_OK ) {
- err = ZIP_ERRNO;
- }
- /* number of this disk */
- if ( ziplocal_getShort( ziinit.filestream, &number_disk ) != ZIP_OK ) {
- err = ZIP_ERRNO;
- }
- /* number of the disk with the start of the central directory */
- if ( ziplocal_getShort( ziinit.filestream, &number_disk_with_CD ) != ZIP_OK ) {
- err = ZIP_ERRNO;
- }
- /* total number of entries in the central dir on this disk */
- if ( ziplocal_getShort( ziinit.filestream, &number_entry ) != ZIP_OK ) {
- err = ZIP_ERRNO;
- }
- /* total number of entries in the central dir */
- if ( ziplocal_getShort( ziinit.filestream, &number_entry_CD ) != ZIP_OK ) {
- err = ZIP_ERRNO;
- }
- if ( ( number_entry_CD != number_entry ) || ( number_disk_with_CD != 0 ) || ( number_disk != 0 ) ) {
- err = ZIP_BADZIPFILE;
- }
- /* size of the central directory */
- if ( ziplocal_getLong( ziinit.filestream, &size_central_dir ) != ZIP_OK ) {
- err = ZIP_ERRNO;
- }
- /* offset of start of central directory with respect to the starting disk number */
- if ( ziplocal_getLong( ziinit.filestream, &offset_central_dir ) != ZIP_OK ) {
- err = ZIP_ERRNO;
- }
- /* zipfile global comment length */
- if ( ziplocal_getShort( ziinit.filestream, &size_comment ) != ZIP_OK ) {
- err = ZIP_ERRNO;
- }
- if ( ( central_pos < ( offset_central_dir + size_central_dir ) ) && ( err == ZIP_OK ) ) {
- err = ZIP_BADZIPFILE;
- }
- if ( err != ZIP_OK ) {
- delete ziinit.filestream;
- ziinit.filestream = NULL;
- return NULL;
- }
- if ( size_comment > 0 ) {
- ziinit.globalcomment = (char*)ALLOC( size_comment + 1 );
- if ( ziinit.globalcomment ) {
- size_comment = (unsigned long)ziinit.filestream->Read( ziinit.globalcomment, size_comment );
- ziinit.globalcomment[size_comment] = 0;
- }
- }
- byte_before_the_zipfile = central_pos - ( offset_central_dir + size_central_dir );
- ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
- {
- unsigned long size_central_dir_to_read = size_central_dir;
- size_t buf_size = SIZEDATA_INDATABLOCK;
- void* buf_read = (void*)ALLOC( buf_size );
- if ( ziinit.filestream->Seek( offset_central_dir + byte_before_the_zipfile, FS_SEEK_SET ) != 0 ) {
- err = ZIP_ERRNO;
- }
- while ( ( size_central_dir_to_read > 0 ) && ( err == ZIP_OK ) ) {
- unsigned long read_this = SIZEDATA_INDATABLOCK;
- if ( read_this > size_central_dir_to_read ) {
- read_this = size_central_dir_to_read;
- }
- if ( ziinit.filestream->Read( buf_read, read_this ) != ( int )read_this ) {
- err = ZIP_ERRNO;
- }
- if ( err == ZIP_OK ) {
- err = add_data_in_datablock( &ziinit.central_dir, buf_read, (unsigned long)read_this );
- }
- size_central_dir_to_read -= read_this;
- }
- TRYFREE( buf_read );
- }
- ziinit.begin_pos = byte_before_the_zipfile;
- ziinit.number_entry = number_entry_CD;
- if ( ziinit.filestream->Seek( offset_central_dir + byte_before_the_zipfile, FS_SEEK_SET ) != 0 ) {
- err = ZIP_ERRNO;
- }
- }
- if ( globalcomment ) {
- /// ??
- globalcomment = ziinit.globalcomment;
- }
- #endif /* !NO_ADDFILEINEXISTINGZIP*/
- if ( err != ZIP_OK ) {
- #ifndef NO_ADDFILEINEXISTINGZIP
- TRYFREE( ziinit.globalcomment );
- #endif /* !NO_ADDFILEINEXISTINGZIP*/
- TRYFREE( zi );
- return NULL;
- } else {
- *zi = ziinit;
- return (zipFile)zi;
- }
- }
- /*
- ========================
- zipOpen
- ========================
- */
- zipFile zipOpen( const char *pathname, int append ) {
- return zipOpen2( pathname, append, NULL );
- }
- /*
- ========================
- zipOpenNewFileInZip3
- ========================
- */
- int zipOpenNewFileInZip3( zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, unsigned int size_extrafield_local, const void* extrafield_global,
- unsigned int size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char* password, unsigned long crcForCrypting ) {
- unsigned int size_filename;
- unsigned int size_comment;
- int err = ZIP_OK;
- #ifdef NOCRYPT
- if ( password != NULL ) {
- return ZIP_PARAMERROR;
- }
- #endif
- if ( file == NULL ) {
- return ZIP_PARAMERROR;
- }
- if ( ( method != 0 ) && ( method != Z_DEFLATED ) ) {
- return ZIP_PARAMERROR;
- }
- zip_internal* zi = (zip_internal*)file;
- if ( zi->in_opened_file_inzip == 1 ) {
- err = zipCloseFileInZip( file );
- if ( err != ZIP_OK ) {
- return err;
- }
- }
- if ( filename == NULL ) {
- filename = "-";
- }
- if ( comment == NULL ) {
- size_comment = 0;
- } else {
- size_comment = (unsigned int)idStr::Length( comment );
- }
- size_filename = (unsigned int)idStr::Length( filename );
- if ( zipfi == NULL ) {
- zi->ci.dosDate = 0;
- } else {
- if ( zipfi->dosDate != 0 ) {
- zi->ci.dosDate = zipfi->dosDate;
- } else {
- zi->ci.dosDate = ziplocal_TmzDateToDosDate( &zipfi->tmz_date, zipfi->dosDate );
- }
- }
- zi->ci.flag = 0;
- if ( ( level == 8 ) || ( level == 9 ) ) {
- zi->ci.flag |= 2;
- }
- if ( ( level == 2 ) ) {
- zi->ci.flag |= 4;
- }
- if ( ( level == 1 ) ) {
- zi->ci.flag |= 6;
- }
- if ( password != NULL ) {
- zi->ci.flag |= 1;
- }
- zi->ci.crc32 = 0;
- zi->ci.method = method;
- zi->ci.encrypt = 0;
- zi->ci.stream_initialised = 0;
- zi->ci.pos_in_buffered_data = 0;
- zi->ci.raw = raw;
- zi->ci.pos_local_header = (unsigned long)zi->filestream->Tell();
- zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
- zi->ci.central_header = (char*)ALLOC( (unsigned int)zi->ci.size_centralheader );
- ziplocal_putValue_inmemory( zi->ci.central_header, (unsigned long)CENTRALHEADERMAGIC, 4 );
- /* version info */
- ziplocal_putValue_inmemory( zi->ci.central_header + 4, (unsigned long)0, 2 );
- ziplocal_putValue_inmemory( zi->ci.central_header + 6, (unsigned long)20, 2 );
- ziplocal_putValue_inmemory( zi->ci.central_header + 8, (unsigned long)zi->ci.flag, 2 );
- ziplocal_putValue_inmemory( zi->ci.central_header + 10, (unsigned long)zi->ci.method, 2 );
- ziplocal_putValue_inmemory( zi->ci.central_header + 12, (unsigned long)zi->ci.dosDate, 4 );
- ziplocal_putValue_inmemory( zi->ci.central_header + 16, (unsigned long)0, 4 ); /*crc*/
- ziplocal_putValue_inmemory( zi->ci.central_header + 20, (unsigned long)0, 4 ); /*compr size*/
- ziplocal_putValue_inmemory( zi->ci.central_header + 24, (unsigned long)0, 4 ); /*uncompr size*/
- ziplocal_putValue_inmemory( zi->ci.central_header + 28, (unsigned long)size_filename, 2 );
- ziplocal_putValue_inmemory( zi->ci.central_header + 30, (unsigned long)size_extrafield_global, 2 );
- ziplocal_putValue_inmemory( zi->ci.central_header + 32, (unsigned long)size_comment, 2 );
- ziplocal_putValue_inmemory( zi->ci.central_header + 34, (unsigned long)0, 2 ); /*disk nm start*/
- if ( zipfi == NULL ) {
- ziplocal_putValue_inmemory( zi->ci.central_header + 36, (unsigned long)0, 2 );
- } else {
- ziplocal_putValue_inmemory( zi->ci.central_header + 36, (unsigned long)zipfi->internal_fa, 2 );
- }
- if ( zipfi == NULL ) {
- ziplocal_putValue_inmemory( zi->ci.central_header + 38,(unsigned long)0, 4);
- } else {
- ziplocal_putValue_inmemory( zi->ci.central_header + 38,(unsigned long)zipfi->external_fa, 4);
- }
- ziplocal_putValue_inmemory( zi->ci.central_header + 42, (unsigned long)zi->ci.pos_local_header - zi->add_position_when_writting_offset, 4 );
- for ( unsigned int i = 0; i < size_filename; i++ ) {
- *( zi->ci.central_header + SIZECENTRALHEADER + i ) = *( filename + i );
- }
- for ( unsigned int i = 0; i < size_extrafield_global; i++ ) {
- *( zi->ci.central_header + SIZECENTRALHEADER + size_filename + i ) = *( ( ( const char* )extrafield_global ) + i );
- }
- for ( unsigned int i = 0; i < size_comment; i++ ) {
- *( zi->ci.central_header + SIZECENTRALHEADER + size_filename + size_extrafield_global + i ) = *( comment + i );
- }
- if ( zi->ci.central_header == NULL ) {
- return ZIP_INTERNALERROR;
- }
- /* write the local header */
- err = ziplocal_putValue( zi->filestream, (unsigned long)LOCALHEADERMAGIC, 4 );
- if ( err == ZIP_OK ) {
- err = ziplocal_putValue( zi->filestream, (unsigned long)20, 2 ); /* version needed to extract */
- }
- if ( err == ZIP_OK ) {
- err = ziplocal_putValue( zi->filestream, (unsigned long)zi->ci.flag, 2 );
- }
- if ( err == ZIP_OK ) {
- err = ziplocal_putValue( zi->filestream, (unsigned long)zi->ci.method, 2 );
- }
- if ( err == ZIP_OK ) {
- err = ziplocal_putValue( zi->filestream, (unsigned long)zi->ci.dosDate, 4 );
- }
- if ( err == ZIP_OK ) {
- err = ziplocal_putValue( zi->filestream, (unsigned long)0, 4 ); /* crc 32, unknown */
- }
-
- if ( err == ZIP_OK ) {
- err = ziplocal_putValue( zi->filestream, (unsigned long)0, 4 ); /* compressed size, unknown */
- }
- if ( err == ZIP_OK ) {
- err = ziplocal_putValue( zi->filestream, (unsigned long)0, 4 ); /* uncompressed size, unknown */
- }
- if ( err == ZIP_OK ) {
- err = ziplocal_putValue( zi->filestream, (unsigned long)size_filename, 2 );
- }
- if ( err == ZIP_OK ) {
- err = ziplocal_putValue( zi->filestream, (unsigned long)size_extrafield_local, 2 );
- }
- if ( ( err == ZIP_OK ) && ( size_filename > 0 ) ) {
- if ( zi->filestream->Write( filename, size_filename ) != ( int )size_filename ) {
- err = ZIP_ERRNO;
- }
- }
- if ( ( err == ZIP_OK ) && ( size_extrafield_local > 0 ) ) {
- if ( zi->filestream->Write( extrafield_local, size_extrafield_local ) != ( int )size_extrafield_local ) {
- err = ZIP_ERRNO;
- }
- }
- zi->ci.stream.avail_in = (unsigned int)0;
- zi->ci.stream.avail_out = (unsigned int)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- zi->ci.stream.total_in = 0;
- zi->ci.stream.total_out = 0;
- if ( ( err == ZIP_OK ) && ( zi->ci.method == Z_DEFLATED ) && ( !zi->ci.raw ) ) {
- zi->ci.stream.zalloc = (alloc_func)0;
- zi->ci.stream.zfree = (free_func)0;
- zi->ci.stream.opaque = (voidpf)0;
- if ( windowBits > 0 ) {
- windowBits = -windowBits;
- }
- err = deflateInit2( &zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy );
- if ( err == Z_OK ) {
- zi->ci.stream_initialised = 1;
- }
- }
- #ifndef NOCRYPT
- zi->ci.crypt_header_size = 0;
- if ( ( err == Z_OK ) && ( password != NULL ) ) {
- unsigned char bufHead[RAND_HEAD_LEN];
- unsigned int sizeHead;
- zi->ci.encrypt = 1;
- zi->ci.pcrc_32_tab = get_crc_table();
- /*init_keys( password, zi->ci.keys, zi->ci.pcrc_32_tab );*/
- sizeHead=crypthead( password, bufHead, RAND_HEAD_LEN, zi->ci.keys, zi->ci.pcrc_32_tab, crcForCrypting );
- zi->ci.crypt_header_size = sizeHead;
- if ( ZWRITE( zi->z_filefunc, zi->filestream, bufHead, sizeHead ) != sizeHead ) {
- err = ZIP_ERRNO;
- }
- }
- #endif
- if ( err == Z_OK ) {
- zi->in_opened_file_inzip = 1;
- }
- return err;
- }
- /*
- ========================
- zipOpenNewFileInZip2
- ========================
- */
- int zipOpenNewFileInZip2( zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, unsigned int size_extrafield_local,
- const void* extrafield_global, unsigned int size_extrafield_global, const char* comment, int method, int level, int raw ) {
- return zipOpenNewFileInZip3( file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global,
- comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0 );
- }
- /*
- ========================
- zipOpenNewFileInZip
- ========================
- */
- int zipOpenNewFileInZip( zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, unsigned int size_extrafield_local, const void* extrafield_global,
- unsigned int size_extrafield_global, const char* comment, int method, int level ) {
- return zipOpenNewFileInZip2( file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, 0 );
- }
- /*
- ========================
- zipFlushWriteBuffer
- ========================
- */
- int zipFlushWriteBuffer( zip_internal* zi ) {
- int err = ZIP_OK;
- if ( zi->ci.encrypt != 0 ) {
- #ifndef NOCRYPT
- int t;
- for ( int i = 0; i < zi->ci.pos_in_buffered_data; i++ ) {
- zi->ci.buffered_data[i] = zencode( zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i], t );
- }
- #endif
- }
- if ( zi->filestream->Write( zi->ci.buffered_data, zi->ci.pos_in_buffered_data ) != (int)zi->ci.pos_in_buffered_data ) {
- err = ZIP_ERRNO;
- }
- zi->ci.pos_in_buffered_data = 0;
- return err;
- }
- /*
- ========================
- zipWriteInFileInZip
- ========================
- */
- int zipWriteInFileInZip( zipFile file, const void* buf, unsigned int len ) {
- zip_internal* zi;
- int err = ZIP_OK;
- if ( file == NULL ) {
- return ZIP_PARAMERROR;
- }
- zi = (zip_internal*)file;
- if ( zi->in_opened_file_inzip == 0 ) {
- return ZIP_PARAMERROR;
- }
- zi->ci.stream.next_in = (Bytef*)buf;
- zi->ci.stream.avail_in = len;
- zi->ci.crc32 = crc32( zi->ci.crc32, (byte*)buf, len );
- while ( ( err == ZIP_OK ) && ( zi->ci.stream.avail_in > 0 ) ) {
- if ( zi->ci.stream.avail_out == 0 ) {
- if ( zipFlushWriteBuffer( zi ) == ZIP_ERRNO ) {
- err = ZIP_ERRNO;
- }
- zi->ci.stream.avail_out = (unsigned int)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- }
- if ( err != ZIP_OK ) {
- break;
- }
- if ( ( zi->ci.method == Z_DEFLATED ) && ( !zi->ci.raw ) ) {
- unsigned long uTotalOutBefore = zi->ci.stream.total_out;
- err = deflate( &zi->ci.stream, Z_NO_FLUSH );
- zi->ci.pos_in_buffered_data += (unsigned int)( zi->ci.stream.total_out - uTotalOutBefore );
- } else {
- unsigned int copy_this;
- if ( zi->ci.stream.avail_in < zi->ci.stream.avail_out ) {
- copy_this = zi->ci.stream.avail_in;
- } else {
- copy_this = zi->ci.stream.avail_out;
- }
- for ( unsigned int i = 0; i < copy_this; i++ ) {
- *( ( (char*)zi->ci.stream.next_out ) + i ) = *( ( (const char*)zi->ci.stream.next_in ) + i );
- }
- zi->ci.stream.avail_in -= copy_this;
- zi->ci.stream.avail_out-= copy_this;
- zi->ci.stream.next_in+= copy_this;
- zi->ci.stream.next_out+= copy_this;
- zi->ci.stream.total_in+= copy_this;
- zi->ci.stream.total_out+= copy_this;
- zi->ci.pos_in_buffered_data += copy_this;
- }
- }
- return err;
- }
- /*
- ========================
- zipCloseFileInZipRaw
- ========================
- */
- int zipCloseFileInZipRaw( zipFile file, unsigned long uncompressed_size, unsigned long crc32 ) {
- zip_internal* zi;
- unsigned long compressed_size;
- int err = ZIP_OK;
- if ( file == NULL ) {
- return ZIP_PARAMERROR;
- }
- zi = (zip_internal*)file;
- if ( zi->in_opened_file_inzip == 0 ) {
- return ZIP_PARAMERROR;
- }
- zi->ci.stream.avail_in = 0;
- if ( ( zi->ci.method == Z_DEFLATED ) && !zi->ci.raw ) {
- while ( err == ZIP_OK ) {
- unsigned long uTotalOutBefore;
- if ( zi->ci.stream.avail_out == 0 ) {
- if ( zipFlushWriteBuffer( zi ) == ZIP_ERRNO ) {
- err = ZIP_ERRNO;
- }
- zi->ci.stream.avail_out = (unsigned int)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- }
- uTotalOutBefore = zi->ci.stream.total_out;
- err = deflate( &zi->ci.stream, Z_FINISH );
- zi->ci.pos_in_buffered_data += (unsigned int)( zi->ci.stream.total_out - uTotalOutBefore );
- }
- }
- if ( err == Z_STREAM_END ) {
- err = ZIP_OK; /* this is normal */
- }
- if ( ( zi->ci.pos_in_buffered_data > 0 ) && ( err == ZIP_OK ) ) {
- if ( zipFlushWriteBuffer( zi ) == ZIP_ERRNO ) {
- err = ZIP_ERRNO;
- }
- }
- if ( ( zi->ci.method == Z_DEFLATED ) && !zi->ci.raw ) {
- err = deflateEnd( &zi->ci.stream );
- zi->ci.stream_initialised = 0;
- }
- if ( !zi->ci.raw ) {
- crc32 = (unsigned long)zi->ci.crc32;
- uncompressed_size = (unsigned long)zi->ci.stream.total_in;
- }
- compressed_size = (unsigned long)zi->ci.stream.total_out;
- #ifndef NOCRYPT
- compressed_size += zi->ci.crypt_header_size;
- #endif
- ziplocal_putValue_inmemory( zi->ci.central_header + 16, crc32, 4); /*crc*/
- ziplocal_putValue_inmemory( zi->ci.central_header + 20, compressed_size, 4 ); /*compr size*/
- if ( zi->ci.stream.data_type == Z_ASCII ) {
- ziplocal_putValue_inmemory( zi->ci.central_header + 36, (unsigned long)Z_ASCII, 2 );
- }
- ziplocal_putValue_inmemory( zi->ci.central_header + 24, uncompressed_size, 4 ); /*uncompr size*/
- if ( err == ZIP_OK ) {
- err = add_data_in_datablock( &zi->central_dir, zi->ci.central_header, (unsigned long)zi->ci.size_centralheader );
- }
- TRYFREE( zi->ci.central_header );
- if ( err == ZIP_OK ) {
- long cur_pos_inzip = (long)zi->filestream->Tell();
- if ( zi->filestream->Seek( zi->ci.pos_local_header + 14, FS_SEEK_SET ) != 0 ) {
- err = ZIP_ERRNO;
- }
- if ( err == ZIP_OK ) {
- err = ziplocal_putValue( zi->filestream, crc32, 4 ); /* crc 32, unknown */
- }
- if ( err == ZIP_OK ) { /* compressed size, unknown */
- err = ziplocal_putValue( zi->filestream, compressed_size, 4 );
- }
- if ( err == ZIP_OK ) { /* uncompressed size, unknown */
- err = ziplocal_putValue( zi->filestream, uncompressed_size, 4 );
- }
- if ( zi->filestream->Seek( cur_pos_inzip, FS_SEEK_SET ) != 0 ) {
- err = ZIP_ERRNO;
- }
- }
- zi->number_entry++;
- zi->in_opened_file_inzip = 0;
- return err;
- }
- /*
- ========================
- zipCloseFileInZip
- ========================
- */
- int zipCloseFileInZip( zipFile file ) {
- return zipCloseFileInZipRaw( file, 0, 0 );
- }
- /*
- ========================
- zipClose
- ========================
- */
- int zipClose( zipFile file, const char* global_comment ) {
- zip_internal* zi;
- int err = 0;
- unsigned long size_centraldir = 0;
- unsigned long centraldir_pos_inzip;
- unsigned int size_global_comment;
- if ( file == NULL ) {
- return ZIP_PARAMERROR;
- }
- zi = (zip_internal*)file;
- if ( zi->in_opened_file_inzip == 1 ) {
- err = zipCloseFileInZip( file );
- }
- #ifndef NO_ADDFILEINEXISTINGZIP
- if ( global_comment == NULL ) {
- global_comment = zi->globalcomment;
- }
- #endif
- if ( global_comment == NULL ) {
- size_global_comment = 0;
- } else {
- size_global_comment = (unsigned int)idStr::Length( global_comment );
- }
- centraldir_pos_inzip = (unsigned long)zi->filestream->Tell();
- if ( err == ZIP_OK ) {
- linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
- while ( ldi != NULL ) {
- if ( ( err == ZIP_OK ) && ( ldi->filled_in_this_block > 0 ) ) {
- if ( zi->filestream->Write( ldi->data, ldi->filled_in_this_block ) != (int)ldi->filled_in_this_block ) {
- err = ZIP_ERRNO;
- }
- }
- size_centraldir += ldi->filled_in_this_block;
- ldi = ldi->next_datablock;
- }
- }
- free_datablock( zi->central_dir.first_block );
- if ( err == ZIP_OK ) { /* Magic End */
- err = ziplocal_putValue( zi->filestream, (unsigned long)ENDHEADERMAGIC, 4 );
- }
- if ( err == ZIP_OK ) { /* number of this disk */
- err = ziplocal_putValue( zi->filestream, (unsigned long)0, 2 );
- }
- if ( err == ZIP_OK ) { /* number of the disk with the start of the central directory */
- err = ziplocal_putValue( zi->filestream, (unsigned long)0, 2 );
- }
- if ( err == ZIP_OK ) { /* total number of entries in the central dir on this disk */
- err = ziplocal_putValue( zi->filestream, (unsigned long)zi->number_entry, 2 );
- }
- if ( err == ZIP_OK ) { /* total number of entries in the central dir */
- err = ziplocal_putValue( zi->filestream, (unsigned long)zi->number_entry, 2 );
- }
- if ( err == ZIP_OK ) { /* size of the central directory */
- err = ziplocal_putValue( zi->filestream, (unsigned long)size_centraldir, 4 );
- }
- if ( err == ZIP_OK ) { /* offset of start of central directory with respect to the starting disk number */
- err = ziplocal_putValue( zi->filestream, (unsigned long)( centraldir_pos_inzip - zi->add_position_when_writting_offset ), 4 );
- }
- if ( err == ZIP_OK ) { /* zipfile comment length */
- err = ziplocal_putValue( zi->filestream, (unsigned long)size_global_comment, 2 );
- }
- if ( ( err == ZIP_OK ) && ( size_global_comment > 0 ) ) {
- if ( zi->filestream->Write( global_comment, size_global_comment ) != (int)size_global_comment ) {
- err = ZIP_ERRNO;
- }
- }
- delete zi->filestream;
- zi->filestream = NULL;
- #ifndef NO_ADDFILEINEXISTINGZIP
- TRYFREE( zi->globalcomment );
- #endif
- TRYFREE( zi );
- return err;
- }
- /*
- ========================
- idZipBuilder::AddFileFilters
- ========================
- */
- void idZipBuilder::AddFileFilters( const char *filters ) {
- #if 0
- idStrList exts;
- idStrListBreakupString( exts, filters, "|" );
- if ( ( exts.Num() > 0 ) && ( exts[ exts.Num() - 1 ] == "" ) ) {
- exts.RemoveIndex( exts.Num() - 1 );
- }
- filterExts.Append( exts );
- #endif
- }
- /*
- ========================
- idZipBuilder::AddUncompressedFileFilters
- ========================
- */
- void idZipBuilder::AddUncompressedFileFilters( const char *filters ) {
- #if 0
- idStrList exts;
- idStrListBreakupString( exts, filters, "|" );
- if ( ( exts.Num() > 0 ) && ( exts[ exts.Num() - 1 ] == "" ) ) {
- exts.RemoveIndex( exts.Num() - 1 );
- }
- uncompressedFilterExts.Append( exts );
- #endif
- }
- /*
- ========================
- idZipBuilder::Build
- builds a zip file of all the files in the specified folder, overwriting if necessary
- ========================
- */
- bool idZipBuilder::Build( const char* zipPath, const char *folder, bool cleanFolder ) {
- zipFileName = zipPath;
- sourceFolderName = folder;
- if ( !CreateZipFile( false ) ) {
- // don't clean the folder if the zip fails
- return false;
- }
- if ( cleanFolder ) {
- CleanSourceFolder();
- }
- return true;
- }
- /*
- ========================
- idZipBuilder::Update
- updates a zip file with the files in the specified folder
- ========================
- */
- bool idZipBuilder::Update( const char* zipPath, const char *folder, bool cleanFolder ) {
- // if this file doesn't exist, just build it
- if ( fileSystem->GetTimestamp( zipPath ) == FILE_NOT_FOUND_TIMESTAMP ) {
- return Build( zipPath, folder, cleanFolder );
- }
- zipFileName = zipPath;
- sourceFolderName = folder;
- if ( !CreateZipFile( true ) ) {
- // don't clean the folder if the zip fails
- return false;
- }
- if ( cleanFolder ) {
- CleanSourceFolder();
- }
- return true;
- }
- /*
- ========================
- idZipBuilder::GetFileTime
- ========================
- */
- bool idZipBuilder::GetFileTime( const idStr &filename, unsigned long *dostime ) const {
- {
- FILETIME filetime;
- WIN32_FIND_DATA fileData;
- HANDLE findHandle = FindFirstFile( filename.c_str(), &fileData );
- if ( findHandle != INVALID_HANDLE_VALUE ) {
- FileTimeToLocalFileTime( &(fileData.ftLastWriteTime), &filetime );
- FileTimeToDosDateTime( &filetime, ((LPWORD)dostime) + 1, ((LPWORD)dostime) + 0 );
- FindClose( findHandle );
- return true;
- }
- FindClose( findHandle );
- }
- return false;
- }
- /*
- ========================
- idZipBuilder::IsFiltered
- ========================
- */
- bool idZipBuilder::IsFiltered( const idStr &filename ) const {
- if ( filterExts.Num() == 0 && uncompressedFilterExts.Num() == 0 ) {
- return false;
- }
- for ( int j = 0; j < filterExts.Num(); j++ ) {
- idStr fileExt = idStr( "." + filterExts[j] );
- if ( filename.Right( fileExt.Length() ).Icmp( fileExt ) == 0 ) {
- return false;
- }
- }
- for ( int j = 0; j < uncompressedFilterExts.Num(); j++ ) {
- idStr fileExt = idStr( "." + uncompressedFilterExts[j] );
- if ( filename.Right( fileExt.Length() ).Icmp( fileExt ) == 0 ) {
- return false;
- }
- }
- return true;
- }
- /*
- ========================
- idZipBuilder::IsUncompressed
- ========================
- */
- bool idZipBuilder::IsUncompressed( const idStr &filename ) const {
- if ( uncompressedFilterExts.Num() == 0 ) {
- return false;
- }
- for ( int j = 0; j < uncompressedFilterExts.Num(); j++ ) {
- idStr fileExt = idStr( "." + uncompressedFilterExts[j] );
- if ( filename.Right( fileExt.Length() ).Icmp( fileExt ) == 0 ) {
- return true;
- }
- }
- return false;
- }
- /*
- ========================
- idZipBuilder::CreateZipFile
- ========================
- */
- bool idZipBuilder::CreateZipFile( bool appendFiles ) {
- #if 0
- //#ifdef ID_PC
- if ( zipFileName.IsEmpty() || sourceFolderName.IsEmpty() ) {
- idLib::Warning( "[%s] - invalid parameters!", __FUNCTION__ );
- return false;
- }
- // need to clear the filesystem's zip cache before we can open and write
- //fileSystem->ClearZipCache();
- idLib::Printf( "Building zip file: '%s'\n", zipFileName.c_str() );
- sourceFolderName.StripTrailing( "\\" );
- sourceFolderName.StripTrailing( "/" );
- #if 0
- // attempt to check the file out
- if ( !Sys_IsFileWritable( zipFileName ) ) {
- if ( ( idLib::sourceControl == NULL ) || !idLib::sourceControl->CheckOut( zipFileName ) ) {
- idLib::Warning( "READONLY zip file couldn't be checked out: %s", zipFileName.c_str() );
- } else {
- idLib::Printf( "Checked out: %s\n", zipFileName.c_str() );
- }
- }
- #endif
- // if not appending, set the file size to zero to "create it from scratch"
- if ( !appendFiles ) {
- idLib::PrintfIf( zip_verbosity.GetBool(), "Overwriting zip file: '%s'\n", zipFileName.c_str() );
- idFile *zipFile = fileSystem->OpenExplicitFileWrite( zipFileName );
- if ( zipFile != NULL ) {
- delete zipFile;
- zipFile = NULL;
- }
- } else {
- idLib::PrintfIf( zip_verbosity.GetBool(), "Appending to zip file: '%s'\n", zipFileName.c_str() );
- }
- // enumerate the files to zip up in the source folder
- idStrStatic< MAX_OSPATH > relPath;
- relPath =
- fileSystem->OSPathToRelativePath( sourceFolderName );
- idFileList *files = fileSystem->ListFilesTree( relPath, "*.*" );
- // check to make sure that at least one file will be added to the package
- int atLeastOneFilteredFile = false;
- for ( int i = 0; i < files->GetNumFiles(); i++ ) {
- idStr filename = files->GetFile( i );
- if ( !IsFiltered( filename ) ) {
- atLeastOneFilteredFile = true;
- break;
- }
- }
- if ( !atLeastOneFilteredFile ) {
- // although we didn't actually update/create a zip file, it's because no files would be added anyway, which would result in a corrupted zip
- idLib::Printf( "Skipping zip creation/modification, no additional changes need to be made...\n" );
- return true;
- }
- // open the zip file
- zipFile zf = zipOpen( zipFileName, appendFiles ? APPEND_STATUS_ADDINZIP : 0 );
- if ( zf == NULL ) {
- idLib::Warning( "[%s] - error opening file '%s'!", __FUNCTION__, zipFileName.c_str() );
- return false;
- }
- // add the files to the zip file
- for ( int i = 0; i < files->GetNumFiles(); i++ ) {
- // add each file to the zip file
- zip_fileinfo zi;
- memset( &zi, 0, sizeof( zip_fileinfo ) );
-
- idStr filename = files->GetFile( i );
- if ( IsFiltered( filename ) ) {
- idLib::PrintfIf( zip_verbosity.GetBool(), "...Skipping: '%s'\n", filename.c_str() );
- continue;
- }
-
- idStr filenameInZip = filename;
- filenameInZip.Strip( relPath );
- filenameInZip.StripLeading( "/" );
- idStrStatic< MAX_OSPATH > ospath;
- ospath = fileSystem->RelativePathToOSPath( filename );
- GetFileTime( ospath, &zi.dosDate );
- idLib::PrintfIf( zip_verbosity.GetBool(), "...Adding: '%s' ", filenameInZip.c_str() );
- int compressionMethod = Z_DEFLATED;
- if ( IsUncompressed( filenameInZip ) ) {
- compressionMethod = 0;
- }
- int errcode = zipOpenNewFileInZip3( zf, filenameInZip, &zi, NULL, 0, NULL, 0, NULL /* comment*/,
- compressionMethod, DEFAULT_COMPRESSION_LEVEL, 0, -MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, NULL /*password*/, 0 /*fileCRC*/ );
- if ( errcode != ZIP_OK ) {
- idLib::Warning( "Error opening file in zipfile!" );
- continue;
- } else {
- // open the source file
- idFile_Permanent src( filename, ospath, FS_READ );
- if ( !src.IsOpen() ) {
- idLib::Warning( "Error opening source file!" );
- continue;
- }
- // copy the file data into the zip file
- idTempArray<byte> buffer( DEFAULT_WRITEBUFFERSIZE );
- size_t total = 0;
- while ( size_t bytesRead = src.Read( buffer.Ptr(), buffer.Size() ) ) {
- if ( bytesRead > 0 ) {
- errcode = zipWriteInFileInZip( zf, buffer.Ptr(), (unsigned int)bytesRead );
- if ( errcode != ZIP_OK ) {
- idLib::Warning( "Error writing to zipfile (%i bytes)!", bytesRead );
- continue;
- }
- }
- total += bytesRead;
- }
- assert( total == (size_t)src.Length() );
- }
- errcode = zipCloseFileInZip( zf );
- if ( errcode != ZIP_OK ) {
- idLib::Warning( "Error zipping source file!" );
- continue;
- }
- idLib::PrintfIf( zip_verbosity.GetBool(), "\n" );
- }
- // free the file list
- if ( files != NULL ) {
- fileSystem->FreeFileList( files );
- }
- // close the zip file
- int closeError = zipClose( zf, NULL );
- if ( closeError != ZIP_OK ) {
- idLib::Warning( "[%s] - error closing file '%s'!", __FUNCTION__, zipFileName.c_str() );
- return false;
- }
- idLib::Printf( "Done.\n" );
- return true;
- #else
- return false;
- #endif
- }
- /*
- ========================
- idZipBuilder::CreateZipFileFromFileList
- ========================
- */
- bool idZipBuilder::CreateZipFileFromFileList( const char *name, const idList< idFile_Memory * > & srcFiles ) {
- zipFileName = name;
- return CreateZipFileFromFiles( srcFiles );
- }
- /*
- ========================
- idZipBuilder::CreateZipFileFromFiles
- ========================
- */
- bool idZipBuilder::CreateZipFileFromFiles( const idList< idFile_Memory * > & srcFiles ) {
- if ( zipFileName.IsEmpty() ) {
- idLib::Warning( "[%s] - invalid parameters!", __FUNCTION__ );
- return false;
- }
- // need to clear the filesystem's zip cache before we can open and write
- //fileSystem->ClearZipCache();
- idLib::Printf( "Building zip file: '%s'\n", zipFileName.c_str() );
- // do not allow overwrite as this should be a tempfile attempt to check the file out
- if ( !Sys_IsFileWritable( zipFileName ) ) {
- idLib::PrintfIf( zip_verbosity.GetBool(), "File %s not writeable, cannot proceed.\n", zipFileName.c_str() );
- return false;
- }
- // open the zip file
- zipFile zf = zipOpen( zipFileName, 0 );
- if ( zf == NULL ) {
- idLib::Warning( "[%s] - error opening file '%s'!", __FUNCTION__, zipFileName.c_str() );
- return false;
- }
- // add the files to the zip file
- for ( int i = 0; i < srcFiles.Num(); i++ ) {
- // add each file to the zip file
- zip_fileinfo zi;
- memset( &zi, 0, sizeof( zip_fileinfo ) );
- idFile_Memory * src = srcFiles[i];
- src->MakeReadOnly();
- idLib::PrintfIf( zip_verbosity.GetBool(), "...Adding: '%s' ", src->GetName() );
- int compressionMethod = Z_DEFLATED;
- if ( IsUncompressed( src->GetName() ) ) {
- compressionMethod = 0;
- }
- int errcode = zipOpenNewFileInZip3( zf, src->GetName(), &zi, NULL, 0, NULL, 0, NULL /* comment*/,
- compressionMethod, DEFAULT_COMPRESSION_LEVEL, 0, -MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, NULL /*password*/, 0 /*fileCRC*/ );
- if ( errcode != ZIP_OK ) {
- idLib::Warning( "Error opening file in zipfile!" );
- continue;
- } else {
- // copy the file data into the zip file
- idTempArray<byte> buffer( DEFAULT_WRITEBUFFERSIZE );
- size_t total = 0;
- while ( size_t bytesRead = src->Read( buffer.Ptr(), buffer.Size() ) ) {
- if ( bytesRead > 0 ) {
- errcode = zipWriteInFileInZip( zf, buffer.Ptr(), (unsigned int)bytesRead );
- if ( errcode != ZIP_OK ) {
- idLib::Warning( "Error writing to zipfile (%i bytes)!", bytesRead );
- continue;
- }
- }
- total += bytesRead;
- }
- assert( total == (size_t)src->Length() );
- }
- errcode = zipCloseFileInZip( zf );
- if ( errcode != ZIP_OK ) {
- idLib::Warning( "Error zipping source file!" );
- continue;
- }
- idLib::PrintfIf( zip_verbosity.GetBool(), "\n" );
- }
- // close the zip file
- int closeError = zipClose( zf, zipFileName );
- if ( closeError != ZIP_OK ) {
- idLib::Warning( "[%s] - error closing file '%s'!", __FUNCTION__, zipFileName.c_str() );
- return false;
- }
- idLib::PrintfIf( zip_verbosity.GetBool(), "Done.\n" );
- return true;
- }
- /*
- ========================
- idZipBuilder::CleanSourceFolder
- this folder is assumed to be a path under FSPATH_BASE
- ========================
- */
- zipFile idZipBuilder::CreateZipFile( const char *name ) {
- idLib::Printf( "Creating zip file: '%s'\n", name );
- // do not allow overwrite as this should be a tempfile attempt to check the file out
- if ( !Sys_IsFileWritable( name ) ) {
- idLib::PrintfIf( zip_verbosity.GetBool(), "File %s not writeable, cannot proceed.\n", name );
- return NULL;
- }
- // open the zip file
- zipFile zf = zipOpen( name, 0 );
- if ( zf == NULL ) {
- idLib::Warning( "[%s] - error opening file '%s'!", __FUNCTION__, name );
- }
- return zf;
- }
- /*
- ========================
- idZipBuilder::CleanSourceFolder
- this folder is assumed to be a path under FSPATH_BASE
- ========================
- */
- bool idZipBuilder::AddFile( zipFile zf, idFile_Memory *src, bool deleteFile ) {
- // add each file to the zip file
- zip_fileinfo zi;
- memset( &zi, 0, sizeof( zip_fileinfo ) );
- src->MakeReadOnly();
- idLib::PrintfIf( zip_verbosity.GetBool(), "...Adding: '%s' ", src->GetName() );
- int compressionMethod = Z_DEFLATED;
- if ( IsUncompressed( src->GetName() ) ) {
- compressionMethod = Z_NO_COMPRESSION;
- }
- int errcode = zipOpenNewFileInZip3( zf, src->GetName(), &zi, NULL, 0, NULL, 0, NULL /* comment*/,
- compressionMethod, DEFAULT_COMPRESSION_LEVEL, 0, -MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, NULL /*password*/, 0 /*fileCRC*/ );
- if ( errcode != ZIP_OK ) {
- idLib::Warning( "Error opening file in zipfile!" );
- if ( deleteFile ) {
- src->Clear( true );
- delete src;
- }
- return false;
- } else {
- // copy the file data into the zip file
- idTempArray<byte> buffer( DEFAULT_WRITEBUFFERSIZE );
- size_t total = 0;
- while ( size_t bytesRead = src->Read( buffer.Ptr(), buffer.Size() ) ) {
- if ( bytesRead > 0 ) {
- errcode = zipWriteInFileInZip( zf, buffer.Ptr(), (unsigned int)bytesRead );
- if ( errcode != ZIP_OK ) {
- idLib::Warning( "Error writing to zipfile (%i bytes)!", bytesRead );
- continue;
- }
- }
- total += bytesRead;
- }
- assert( total == (size_t)src->Length() );
- }
- errcode = zipCloseFileInZip( zf );
- if ( errcode != ZIP_OK ) {
- idLib::Warning( "Error zipping source file!" );
- if ( deleteFile ) {
- src->Clear( true );
- delete src;
- }
- return false;
- }
- idLib::PrintfIf( zip_verbosity.GetBool(), "\n" );
- if ( deleteFile ) {
- src->Clear( true );
- delete src;
- }
- return true;
- }
- /*
- ========================
- idZipBuilder::CleanSourceFolder
- this folder is assumed to be a path under FSPATH_BASE
- ========================
- */
- void idZipBuilder::CloseZipFile( zipFile zf ) {
- // close the zip file
- int closeError = zipClose( zf, zipFileName );
- if ( closeError != ZIP_OK ) {
- idLib::Warning( "[%s] - error closing file '%s'!", __FUNCTION__, zipFileName.c_str() );
- }
- idLib::PrintfIf( zip_verbosity.GetBool(), "Done.\n" );
- }
- /*
- ========================
- idZipBuilder::CleanSourceFolder
- this folder is assumed to be a path under FSPATH_BASE
- ========================
- */
- void idZipBuilder::CleanSourceFolder() {
- #if 0
- //#ifdef ID_PC_WIN
- idStrList deletedFiles;
- // make sure this is a valid path, we don't want to go nuking
- // some user path or something else unintentionally
- idStr ospath = sourceFolderName;
- ospath.SlashesToBackSlashes();
- ospath.ToLower();
- char relPath[MAX_OSPATH];
- fileSystem->OSPathToRelativePath( ospath, relPath, MAX_OSPATH );
- // get the game's base path
- idStr basePath = fileSystem->GetBasePathStr( FSPATH_BASE );
- basePath.AppendPath( BASE_GAMEDIR );
- basePath.AppendPath( "maps" );
- basePath.SlashesToBackSlashes();
- basePath.ToLower();
- // path must be off of our base path, ospath can't have .map on the end, and
- // do some additional sanity checks
- if ( ( ospath.Find( basePath ) == 0 ) && ( ospath.Right( 4 ) != ".map" ) &&
- ( ospath != "c:\\" ) && ( ospath.Length() > basePath.Length() ) ) {
- // get the files in the current directory
- idFileList *files = fileSystem->ListFilesTree( relPath, "*.*" );
- if ( files->GetNumFiles() && zip_verbosity.GetBool() ) {
- idLib::Printf( "Deleting files in '%s'...\n", relPath );
- }
- for ( int i = 0; i < files->GetNumFiles(); i++ ) {
- if ( IsFiltered( files->GetFile( i ) ) ) {
- continue;
- }
- // nuke 'em
- if ( zip_verbosity.GetBool() ) {
- idLib::Printf( "\t...%s\n", files->GetFile( i ) );
- }
- fileSystem->RemoveFile( files->GetFile( i ) );
- char ospath2[MAX_OSPATH];
- fileSystem->RelativePathToOSPath( files->GetFile( i ), ospath2, MAX_OSPATH );
- deletedFiles.Append( ospath2 );
- }
- fileSystem->FreeFileList( files );
- fileSystem->RemoveDir( relPath );
- } else {
- idLib::Printf( "Warning: idZipBuilder::CleanSourceFolder - Non-standard path: '%s'!\n", ospath.c_str() );
- return;
- }
- // figure out which deleted files need to be removed from source control, and then remove those files
- idStrList filesToRemoveFromSourceControl;
- for ( int i = 0; i < deletedFiles.Num(); i++ ) {
- scFileStatus_t fileStatus = idLib::sourceControl->GetFileStatus( deletedFiles[ i ] );
- if ( SCF_IS_IN_SOURCE_CONTROL( fileStatus ) ) {
- filesToRemoveFromSourceControl.Append( deletedFiles[ i ] );
- }
- }
- if ( filesToRemoveFromSourceControl.Num() > 0 ) {
- idLib::sourceControl->Delete( filesToRemoveFromSourceControl );
- }
- #endif
- }
- /*
- ========================
- idZipBuilder::BuildMapFolderZip
- ========================
- */
- const char *ZIP_FILE_EXTENSION = "pk4";
- bool idZipBuilder::BuildMapFolderZip( const char *mapFileName ) {
- idStr zipFileName = mapFileName;
- zipFileName.SetFileExtension( ZIP_FILE_EXTENSION );
- idStr pathToZip = mapFileName;
- pathToZip.StripFileExtension();
- idZipBuilder zip;
- zip.AddFileFilters( "bcm|bmodel|proc|" );
- zip.AddUncompressedFileFilters( "genmodel|sbcm|tbcm|" );
- bool success = zip.Build( zipFileName, pathToZip, true );
- // even if the zip build failed we want to clear the source folder so no contributing files are left around
- if ( !success ) {
- zip.CleanSourceFolder();
- }
- return success;
- }
- /*
- ========================
- idZipBuilder::UpdateMapFolderZip
- ========================
- */
- bool idZipBuilder::UpdateMapFolderZip( const char *mapFileName ) {
- idStr zipFileName = mapFileName;
- zipFileName.SetFileExtension( ZIP_FILE_EXTENSION );
- idStr pathToZip = mapFileName;
- pathToZip.StripFileExtension();
- idZipBuilder zip;
- zip.AddFileFilters( "bcm|bmodel|proc|" );
- zip.AddUncompressedFileFilters( "genmodel|sbcm|tbcm|" );
- bool success = zip.Update( zipFileName, pathToZip, true );
- // even if the zip build failed we want to clear the source folder so no contributing files are left around
- if ( !success ) {
- zip.CleanSourceFolder();
- }
- return success;
- }
- /*
- ========================
- idZipBuilder::CombineFiles
- ========================
- */
- idFile_Memory * idZipBuilder::CombineFiles( const idList< idFile_Memory * > & srcFiles ) {
- idFile_Memory * destFile = NULL;
- #if 0
- //#ifdef ID_PC
- // create a new temp file so we can zip into it without refactoring the zip routines
- char ospath[MAX_OSPATH];
- const char * tempName = "temp.tmp";
- fileSystem->RelativePathToOSPath( tempName, ospath, MAX_OSPATH, FSPATH_SAVE );
- fileSystem->RemoveFile( ospath );
- // combine src files into dest filename just specified
- idZipBuilder zip;
- zip.zipFileName = ospath;
- bool ret = zip.CreateZipFileFromFiles( srcFiles );
- // read the temp file created into a memory file to return
- if ( ret ) {
- destFile = new idFile_Memory();
- if ( !destFile->Load( tempName, ospath ) ) {
- assert( false && "couldn't read the combined file" );
- delete destFile;
- destFile = NULL;
- }
- // delete the temp file
- fileSystem->RemoveFile( ospath );
- // make the new file readable
- destFile->MakeReadOnly();
- }
- #endif
- return destFile;
- }
- CONSOLE_COMMAND( testZipBuilderCombineFiles, "test routine for memory zip file building", 0 ) {
- #if 0
- idList< idFile_Memory * > list;
- const char * testString = "test";
- int numFiles = 2;
- if ( args.Argc() > 2 ) {
- idLib::Printf( "usage: testZipBuilderExtractFiles [numFiles]\n" );
- return;
- }
- for ( int arg = 1; arg < args.Argc(); arg++ ) {
- numFiles = atoi( args.Argv( arg ) );
- }
- // allocate all the test files
- for ( int i = 0; i < numFiles; i++ ) {
- idFile_Memory * file = new idFile_Memory( va( "%s%d.txt", testString, i + 1 ) );
- file->MakeWritable();
- idStr str = va( "%s%d", testString, i + 1 );
- file->WriteString( str );
- list.Append( file );
- }
- // combine the files into a single memory file
- idZipBuilder zip;
- idFile_Memory * file = zip.CombineFiles( list );
- if ( file != NULL ) {
- file->MakeReadOnly();
- char ospath[MAX_OSPATH];
- const char * tempName = "temp.zip";
- fileSystem->RelativePathToOSPath( tempName, ospath, MAX_OSPATH, FSPATH_SAVE );
- // remove previous file if it exists
- fileSystem->RemoveFile( ospath );
- if ( file->Save( tempName, ospath ) ) {
- idLib::PrintfIf( zip_verbosity.GetBool(), va( "File written: %s.\n", ospath ) );
- } else {
- idLib::Error( "Could not save the file." );
- }
- delete file;
- }
- list.DeleteContents();
- #endif
- // Now look at the temp.zip, unzip it to see if it works
- }
- /*
- ========================
- idZipBuilder::ExtractFiles
- ========================
- */
- bool idZipBuilder::ExtractFiles( idFile_Memory * & srcFile, idList< idFile_Memory * > & destFiles ) {
- bool ret = false;
- #if 0
- //#ifdef ID_PC
- destFiles.Clear();
- // write the memory file to temp storage so we can unzip it without refactoring the unzip routines
- char ospath[MAX_OSPATH];
- const char * tempName = "temp.tmp";
- fileSystem->RelativePathToOSPath( tempName, ospath, MAX_OSPATH, FSPATH_SAVE );
- ret = srcFile->Save( tempName, ospath );
- assert( ret && "couldn't create temp file" );
- if ( ret ) {
- idLib::PrintfIf( zip_verbosity.GetBool(), "Opening archive %s:\n", ospath );
- unzFile zip = unzOpen( ospath );
- int numFiles = 0;
- int result = unzGoToFirstFile( zip );
- while( result == UNZ_OK ) {
- numFiles++;
- unz_file_info curFileInfo;
- char fileName[MAX_OSPATH];
- unzGetCurrentFileInfo( zip, &curFileInfo, fileName, MAX_OSPATH, NULL, 0, NULL, 0 );
- idLib::PrintfIf( zip_verbosity.GetBool(), "%d: %s, size: %d \\ %d\n", numFiles, fileName, curFileInfo.compressed_size, curFileInfo.uncompressed_size );
- // create a buffer big enough to hold the entire uncompressed file
- void * buff = Mem_Alloc( curFileInfo.uncompressed_size, TAG_TEMP );
- result = unzOpenCurrentFile( zip );
- if ( result == UNZ_OK ) {
- result = unzReadCurrentFile( zip, buff, curFileInfo.uncompressed_size );
- unzCloseCurrentFile( zip );
- }
- // create the new memory file
- idFile_Memory * outFile = new idFile_Memory( fileName );
- outFile->SetReadOnlyData( (const char *)buff, curFileInfo.uncompressed_size );
- destFiles.Append( outFile );
- result = unzGoToNextFile( zip );
- }
- // close it so we can delete the zip file and create a new one
- unzClose( zip );
- // delete the temp zipfile
- fileSystem->RemoveFile( ospath );
- }
- #endif
- return ret;
- }
- CONSOLE_COMMAND( testZipBuilderExtractFiles, "test routine for memory zip file extraction", 0 ) {
- #if 0
- idList< idFile_Memory * > list;
- idFile_Memory * zipfile;
- const char * testString = "test";
- int numFiles = 2;
- bool overallSuccess = true;
- bool success = true;
- if ( args.Argc() > 2 ) {
- idLib::Printf( "usage: testZipBuilderExtractFiles [numFiles]\n" );
- return;
- }
- for ( int arg = 1; arg < args.Argc(); arg++ ) {
- numFiles = atoi( args.Argv( arg ) );
- }
- // create a temp.zip file with string files
- {
- // allocate all the test files
- for ( int i = 0; i < numFiles; i++ ) {
- idFile_Memory * file = new idFile_Memory( va( "%s%d.txt", testString, i + 1 ) );
- file->MakeWritable();
- idStr str = va( "%s%d", testString, i + 1 );
- file->WriteString( str );
- list.Append( file );
- }
- // combine the files into a single memory file
- idZipBuilder zip;
- zipfile = zip.CombineFiles( list );
-
- success = ( zipfile != NULL );
- overallSuccess &= success;
- idLib::Printf( "Zip file created: %s\n", success ? "^2PASS" : "^1FAIL" );
- // destroy all the test files
- list.DeleteContents();
- }
- // unzip the file into separate memory files
- if ( overallSuccess ) {
- // extract all the test files using the single zip file from above
- idZipBuilder zip;
- if ( !zip.ExtractFiles( zipfile, list ) ) {
- idLib::Error( "Could not extract files." );
- }
- success = ( list.Num() == numFiles );
- overallSuccess &= success;
- idLib::Printf( "Number of files: %s\n", success ? "^2PASS" : "^1FAIL" );
- for ( int i = 0; i < list.Num(); i++ ) {
- idStr str;
- idFile_Memory * file = list[i];
- file->MakeReadOnly();
- file->ReadString( str );
- idStr filename = va( "%s%d.txt", testString, i + 1 );
- idStr contents = va( "%s%d", testString, i + 1 );
- // test the filename
- bool nameSuccess = ( file->GetName() == filename );
- overallSuccess &= nameSuccess;
- // test the string
- bool contentSuccess = ( str == contents );
- overallSuccess &= contentSuccess;
- idLib::Printf( "Extraction of file, %s: %s^0, contents check: %s\n", filename.c_str(), nameSuccess ? "^2PASS" : "^1FAIL", contentSuccess ? "^2PASS" : "^1FAIL" );
- }
- list.DeleteContents();
- }
- if ( zipfile != NULL ) {
- delete zipfile;
- }
- idLib::Printf( "[%s] overall tests: %s\n", __FUNCTION__, overallSuccess ? "^2PASS" : "^1FAIL" );
- #endif
- }
|