diff options
author | Stephen Kennedy | 2008-09-26 21:53:08 +0000 |
---|---|---|
committer | Stephen Kennedy | 2008-09-26 21:53:08 +0000 |
commit | a7bb113e83c88fad3a23d408caa99f918fdb610a (patch) | |
tree | 698dd9d85abaa6a20957bfb9c0e006e9dd1dc8b3 /common/unzip.cpp | |
parent | 11c0a3bdedcdf5eb2618b9db67b559663fb93320 (diff) | |
parent | c1385076cbc57f1a4a52946a46b3ea06ecf37f37 (diff) | |
download | scummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.tar.gz scummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.tar.bz2 scummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.zip |
Merged revisions 33452-33453,33455-33459,33463-33464,33466-33471,33473-33474,33478,33490,33492,33495-33496,33509-33512,33518-33519,33522-33527,33529-33530,33537,33541,33544,33546,33550,33552-33554,33556,33558,33561-33562,33565,33568,33570,33574,33576,33578-33581,33584-33587,33590,33596,33604-33611,33614-33615,33617-33618,33620-33621,33623,33626-33627,33632-33633,33635,33637,33639-33640,33642-33645,33648,33654-33655,33664,33667-33670,33673-33674,33678,33682,33686-33691,33693,33696,33698,33700,33703,33708,33710,33712-33714,33716,33719,33721-33723,33725-33727,33729-33730,33733,33736,33742,33754,33756,33758,33761,33763,33766,33777,33781-33788,33790,33792-33793,33795,33797,33805,33807-33812,33815-33817,33819,33822,33826,33829,33837,33839,33844,33847,33858-33861,33864,33871-33873,33875,33877-33879,33886,33889-33892,33894,33896,33900,33902-33903,33919,33928,33930,33932-33936,33938-33940,33942-33943,33948,33950,33953,33967,33973,33976,33978,33980,33985,33991,33993,33999-34000,34006,34009,34011,34013,34015,34019,34021-34023,34025,34027-34028,34030,34032-34034,34036,34038-34039,34041,34046-34048,34050-34055,34057,34059-34065,34067,34072,34074,34076,34078-34081,34084,34086-34087,34089-34090,34093,34096-34102,34104,34107,34113,34116,34119,34122,34124,34126,34128,34131-34132,34135,34138,34141,34144,34146,34149,34152-34154,34156-34157,34160,34163-34164,34169,34173,34179-34194,34196-34198,34200-34201,34205-34206,34208-34217,34219-34225,34227-34228,34234-34237,34239-34249,34251-34279,34281-34284,34286-34288,34290-34320,34323-34324,34326,34328-34329,34332,34334,34336,34338-34340,34343-34353,34356-34357,34359-34371,34373,34375,34378,34381-34382,34384-34385,34389-34391,34393-34394,34396-34397,34399-34405,34407-34409,34411,34413,34415,34417-34420,34423-34426,34428-34438,34440-34454,34456-34458,34460,34462-34469,34472,34474,34479-34481,34483-34498,34501-34505,34508,34511-34518,34520-34524,34526-34563,34566-34569,34571-34590,34592,34595-34599,34602-34603,34605,34613-34615,34617,34619-34624,34627-34628,34630-34639,34642-34649 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk
svn-id: r34654
Diffstat (limited to 'common/unzip.cpp')
-rw-r--r-- | common/unzip.cpp | 537 |
1 files changed, 383 insertions, 154 deletions
diff --git a/common/unzip.cpp b/common/unzip.cpp index 93fb60f41c..054200e7a2 100644 --- a/common/unzip.cpp +++ b/common/unzip.cpp @@ -28,14 +28,51 @@ Read unzip.h for more info */ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Copyright (C) 1998 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + Encryption and multi volume ZipFile (span) are not supported. + Old compressions used by old PKZip 1.x are not supported + + THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE + CAN CHANGE IN FUTURE VERSION !! + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm 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 + ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip */ + + #include "common/scummsys.h" #ifdef USE_ZLIB -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - #ifdef __SYMBIAN32__ #include <zlib\zlib.h> #else @@ -45,24 +82,213 @@ #include "common/unzip.h" #include "common/file.h" -#ifdef STDC -# include <stddef.h> -# include <string.h> -# include <stdlib.h> -#endif -#ifdef NO_ERRNO_H - extern int errno; +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; #else -# include <errno.h> +typedef voidp unzFile; #endif -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct { + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct { + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct { + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +int unzStringFileNameCompare(const char* fileName1, + const char* fileName2, + int iCaseSensitivity); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +unzFile unzOpen(const char *path); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer + "zlib/zlib111.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +int unzClose(unzFile file); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +int unzGetGlobalInfo(unzFile file, + unz_global_info *pglobal_info); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +int unzGetGlobalComment(unzFile file, char *szComment, uLong uSizeBuf); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +int unzGoToFirstFile(unzFile file); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +int unzGoToNextFile(unzFile file); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +int unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +int unzGetCurrentFileInfo(unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +int unzOpenCurrentFile(unzFile file); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +int unzCloseCurrentFile(unzFile file); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + + +int unzReadCurrentFile(unzFile file, voidp buf, unsigned len); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +z_off_t unztell(unzFile file); +/* + Give the current position in uncompressed data +*/ + +int unzeof(unzFile file); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +int unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + if buf==NULL, it return the size of the local extra field + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ !defined(CASESENSITIVITYDEFAULT_NO) @@ -78,45 +304,22 @@ #define UNZ_MAXFILENAMEINZIP (256) #endif -#ifndef ALLOC -# define ALLOC(size) (malloc(size)) -#endif -#ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} -#endif - #define SIZECENTRALDIRITEM (0x2e) #define SIZEZIPLOCALHEADER (0x1e) -/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ - -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - const char unz_copyright[] = " unzip 0.15 Copyright 1998 Gilles Vollant "; /* unz_file_info_interntal contain internal info about a file in zipfile*/ -typedef struct unz_file_info_internal_s -{ +typedef struct { uLong offset_curfile;/* relative offset of local header 4 bytes */ } unz_file_info_internal; /* file_in_zip_read_info_s contain internal information about a file in zipfile, when reading and decompress it */ -typedef struct -{ +typedef struct { char *read_buffer; /* internal buffer for compressed data */ z_stream stream; /* zLib stream structure for inflate */ @@ -139,8 +342,7 @@ typedef struct /* unz_s contain internal information about the zipfile */ -typedef struct -{ +typedef struct { Common::File file; /* io structore of the zipfile */ unz_global_info gi; /* public global information */ uLong byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ @@ -166,14 +368,11 @@ typedef struct */ -/*local int unzlocal_getByte(Common::File &fin, int *pi) -{ +/*static int unzlocal_getByte(Common::File &fin, int *pi) { unsigned char c = fin.readByte(); *pi = (int)c; return UNZ_OK; - } - else - { + } else { if (fin.ioFailed()) return UNZ_ERRNO; else @@ -185,37 +384,14 @@ typedef struct /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */ -local int unzlocal_getShort (Common::File &fin, uLong *pX) -{ +static int unzlocal_getShort(Common::File &fin, uLong *pX) { *pX = fin.readUint16LE(); - return UNZ_OK; + return fin.ioFailed() ? UNZ_ERRNO : UNZ_OK; } -local int unzlocal_getLong (Common::File &fin, uLong *pX) -{ +static int unzlocal_getLong(Common::File &fin, uLong *pX) { *pX = fin.readUint32LE(); - return UNZ_OK; -} - -/* My own strcmpi / strcasecmp */ -local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) { - for (;;) - { - char c1=*(fileName1++); - char c2=*(fileName2++); - if ((c1>='a') && (c1<='z')) - c1 -= 0x20; - if ((c2>='a') && (c2<='z')) - c2 -= 0x20; - if (c1=='\0') - return ((c2=='\0') ? 0 : -1); - if (c2=='\0') - return 1; - if (c1<c2) - return -1; - if (c1>c2) - return 1; - } + return fin.ioFailed() ? UNZ_ERRNO : UNZ_OK; } @@ -225,10 +401,6 @@ local int strcmpcasenosensitive_internal (const char* fileName1, const char* fil #define CASESENSITIVITYDEFAULTVALUE 1 #endif -#ifndef STRCMPCASENOSENTIVEFUNCTION -#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal -#endif - /* Compare two filename (fileName1,fileName2). If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) @@ -238,15 +410,14 @@ local int strcmpcasenosensitive_internal (const char* fileName1, const char* fil (like 1 on Unix, 2 on Windows) */ -extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, const char* fileName2, int iCaseSensitivity) -{ +int unzStringFileNameCompare(const char* fileName1, const char* fileName2, int iCaseSensitivity) { if (iCaseSensitivity==0) iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; if (iCaseSensitivity==1) return strcmp(fileName1,fileName2); - return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); + return scumm_stricmp(fileName1,fileName2); } #define BUFREADCOMMENT (0x400) @@ -255,8 +426,7 @@ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, const char* Locate the Central directory of a zipfile (at the end, just before the global comment) */ -local uLong unzlocal_SearchCentralDir(Common::File &fin) -{ +static uLong unzlocal_SearchCentralDir(Common::File &fin) { unsigned char* buf; uLong uSizeFile; uLong uBackRead; @@ -270,13 +440,12 @@ local uLong unzlocal_SearchCentralDir(Common::File &fin) if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + buf = (unsigned char*)malloc(BUFREADCOMMENT+4); if (buf==NULL) return 0; uBackRead = 4; - while (uBackRead<uMaxBack) - { + while (uBackRead<uMaxBack) { uLong uReadSize,uReadPos ; int i; if (uBackRead+BUFREADCOMMENT>uMaxBack) @@ -305,7 +474,7 @@ local uLong unzlocal_SearchCentralDir(Common::File &fin) if (uPosFound!=0) break; } - TRYFREE(buf); + free(buf); return uPosFound; } @@ -318,8 +487,7 @@ local uLong unzlocal_SearchCentralDir(Common::File &fin) Else, the return value is a unzFile Handle, usable with other function of this unzip package. */ -extern unzFile ZEXPORT unzOpen (const char *path) -{ +unzFile unzOpen(const char *path) { unz_s *us = new unz_s; uLong central_pos,uL; @@ -408,8 +576,7 @@ extern unzFile ZEXPORT unzOpen (const char *path) If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), these files MUST be closed with unzipCloseCurrentFile before call unzipClose. return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzClose (unzFile file) -{ +int unzClose(unzFile file) { unz_s* s; if (file==NULL) return UNZ_PARAMERROR; @@ -428,8 +595,7 @@ extern int ZEXPORT unzClose (unzFile file) Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info) -{ +int unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info) { unz_s* s; if (file==NULL) return UNZ_PARAMERROR; @@ -442,8 +608,7 @@ extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info /* Translate date/time from Dos format to tm_unz (readable more easilty) */ -local void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm) -{ +static void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm) { uLong uDate; uDate = (uLong)(ulDosDate>>16); ptm->tm_mday = (uInt)(uDate&0x1f) ; @@ -458,7 +623,7 @@ local void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm) /* Get Info about the current file in the zipfile, with internal only info */ -local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, +static int unzlocal_GetCurrentFileInfoInternal(unzFile file, unz_file_info *pfile_info, unz_file_info_internal *pfile_info_internal, @@ -467,9 +632,9 @@ local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, void *extraField, uLong extraFieldBufferSize, char *szComment, - uLong commentBufferSize)); + uLong commentBufferSize); -local int unzlocal_GetCurrentFileInfoInternal (unzFile file, +static int unzlocal_GetCurrentFileInfoInternal(unzFile file, unz_file_info *pfile_info, unz_file_info_internal *pfile_info_internal, char *szFileName, uLong fileNameBufferSize, @@ -492,8 +657,7 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, /* we check the magic */ - if (err==UNZ_OK) - { + if (err==UNZ_OK) { if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) err=UNZ_ERRNO; else if (uMagic!=0x02014b50) @@ -548,15 +712,12 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, err=UNZ_ERRNO; lSeek+=file_info.size_filename; - if ((err==UNZ_OK) && (szFileName!=NULL)) - { + if ((err==UNZ_OK) && (szFileName!=NULL)) { uLong uSizeRead ; - if (file_info.size_filename<fileNameBufferSize) - { + if (file_info.size_filename<fileNameBufferSize) { *(szFileName+file_info.size_filename)='\0'; uSizeRead = file_info.size_filename; - } - else + } else uSizeRead = fileNameBufferSize; if ((file_info.size_filename>0) && (fileNameBufferSize>0)) @@ -566,16 +727,14 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, } - if ((err==UNZ_OK) && (extraField!=NULL)) - { + if ((err==UNZ_OK) && (extraField!=NULL)) { uLong uSizeRead ; if (file_info.size_file_extra<extraFieldBufferSize) uSizeRead = file_info.size_file_extra; else uSizeRead = extraFieldBufferSize; - if (lSeek!=0) - { + if (lSeek!=0) { s->file.seek(lSeek, SEEK_CUR); if (s->file.ioFailed()) lSeek=0; @@ -591,19 +750,15 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, lSeek+=file_info.size_file_extra; - if ((err==UNZ_OK) && (szComment!=NULL)) - { + if ((err==UNZ_OK) && (szComment!=NULL)) { uLong uSizeRead ; - if (file_info.size_file_comment<commentBufferSize) - { + if (file_info.size_file_comment<commentBufferSize) { *(szComment+file_info.size_file_comment)='\0'; uSizeRead = file_info.size_file_comment; - } - else + } else uSizeRead = commentBufferSize; - if (lSeek!=0) - { + if (lSeek!=0) { s->file.seek(lSeek, SEEK_CUR); if (s->file.ioFailed()) lSeek=0; @@ -614,8 +769,7 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, if (s->file.read(szComment,(uInt)uSizeRead)!=uSizeRead) err=UNZ_ERRNO; lSeek+=file_info.size_file_comment - uSizeRead; - } - else + } else lSeek+=file_info.size_file_comment; if ((err==UNZ_OK) && (pfile_info!=NULL)) @@ -634,7 +788,7 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, No preparation of the structure is needed return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, +int unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, @@ -650,8 +804,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, Set the current file of the zipfile to the first file. return UNZ_OK if there is no problem */ -extern int ZEXPORT unzGoToFirstFile (unzFile file) -{ +int unzGoToFirstFile(unzFile file) { int err=UNZ_OK; unz_s* s; if (file==NULL) @@ -672,8 +825,7 @@ extern int ZEXPORT unzGoToFirstFile (unzFile file) return UNZ_OK if there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ -extern int ZEXPORT unzGoToNextFile (unzFile file) -{ +int unzGoToNextFile(unzFile file) { unz_s* s; int err; @@ -704,8 +856,7 @@ extern int ZEXPORT unzGoToNextFile (unzFile file) UNZ_OK if the file is found. It becomes the current file. UNZ_END_OF_LIST_OF_FILE if the file is not found */ -extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) -{ +int unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity) { unz_s* s; int err; @@ -729,8 +880,7 @@ extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCas err = unzGoToFirstFile(file); - while (err == UNZ_OK) - { + while (err == UNZ_OK) { char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; unzGetCurrentFileInfo(file,NULL, szCurrentFileName,sizeof(szCurrentFileName)-1, @@ -754,10 +904,9 @@ extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCas store in *piSizeVar the size of extra info in local header (filename and size of extra field data) */ -local int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar, +static int unzlocal_CheckCurrentFileCoherencyHeader(unz_s* s, uInt* piSizeVar, uLong *poffset_local_extrafield, - uInt *psize_local_extrafield) -{ + uInt *psize_local_extrafield) { uLong uMagic,uData,uFlags; uLong size_filename; uLong size_extra_field; @@ -773,8 +922,7 @@ local int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar, return UNZ_ERRNO; - if (err==UNZ_OK) - { + if (err==UNZ_OK) { if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) err=UNZ_ERRNO; else if (uMagic!=0x04034b50) @@ -843,8 +991,7 @@ local int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar, Open for reading data the current file in the zipfile. If there is no error and the file is opened, the return value is UNZ_OK. */ -extern int ZEXPORT unzOpenCurrentFile (unzFile file) -{ +int unzOpenCurrentFile (unzFile file) { int err=UNZ_OK; int Store; uInt iSizeVar; @@ -866,19 +1013,19 @@ extern int ZEXPORT unzOpenCurrentFile (unzFile file) &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) return UNZ_BADZIPFILE; - pfile_in_zip_read_info = (file_in_zip_read_info_s*) ALLOC(sizeof(file_in_zip_read_info_s)); + pfile_in_zip_read_info = (file_in_zip_read_info_s*) malloc(sizeof(file_in_zip_read_info_s)); if (pfile_in_zip_read_info==NULL) return UNZ_INTERNALERROR; - pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->read_buffer=(char*)malloc(UNZ_BUFSIZE); pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; pfile_in_zip_read_info->pos_local_extrafield=0; if (pfile_in_zip_read_info->read_buffer==NULL) { - TRYFREE(pfile_in_zip_read_info); + free(pfile_in_zip_read_info); return UNZ_INTERNALERROR; } @@ -938,8 +1085,7 @@ extern int ZEXPORT unzOpenCurrentFile (unzFile file) return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ -extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) -{ +int unzReadCurrentFile(unzFile file, voidp buf, unsigned len) { int err=UNZ_OK; uInt iRead = 0; unz_s* s; @@ -1051,8 +1197,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) /* Give the current position in uncompressed data */ -extern z_off_t ZEXPORT unztell (unzFile file) -{ +z_off_t unztell(unzFile file) { unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; if (file==NULL) @@ -1070,8 +1215,7 @@ extern z_off_t ZEXPORT unztell (unzFile file) /* return 1 if the end of file was reached, 0 elsewhere */ -extern int ZEXPORT unzeof (unzFile file) -{ +int unzeof(unzFile file) { unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; if (file==NULL) @@ -1102,8 +1246,7 @@ extern int ZEXPORT unzeof (unzFile file) the return value is the number of bytes copied in buf, or (if <0) the error code */ -extern int ZEXPORT unzGetLocalExtrafield (unzFile file,voidp buf,unsigned len) -{ +int unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) { unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; uInt read_now; @@ -1146,8 +1289,7 @@ extern int ZEXPORT unzGetLocalExtrafield (unzFile file,voidp buf,unsigned len) Close the file in zip opened with unzipOpenCurrentFile Return UNZ_CRCERROR if all the file was read but the CRC is not good */ -extern int ZEXPORT unzCloseCurrentFile (unzFile file) -{ +int unzCloseCurrentFile(unzFile file) { int err=UNZ_OK; unz_s* s; @@ -1167,13 +1309,13 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file) } - TRYFREE(pfile_in_zip_read_info->read_buffer); + free(pfile_in_zip_read_info->read_buffer); pfile_in_zip_read_info->read_buffer = NULL; if (pfile_in_zip_read_info->stream_initialised) inflateEnd(&pfile_in_zip_read_info->stream); pfile_in_zip_read_info->stream_initialised = 0; - TRYFREE(pfile_in_zip_read_info); + free(pfile_in_zip_read_info); s->pfile_in_zip_read=NULL; @@ -1186,8 +1328,7 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file) uSizeBuf is the size of the szComment buffer. return the number of byte copied or an error code <0 */ -extern int ZEXPORT unzGetGlobalComment (unzFile file, char *szComment, uLong uSizeBuf) -{ +int unzGetGlobalComment(unzFile file, char *szComment, uLong uSizeBuf) { unz_s* s; uLong uReadThis ; if (file==NULL) @@ -1213,4 +1354,92 @@ extern int ZEXPORT unzGetGlobalComment (unzFile file, char *szComment, uLong uSi return (int)uReadThis; } + +namespace Common { + + +/* +class ZipArchiveMember : public ArchiveMember { + unzFile _zipFile; + +public: + ZipArchiveMember(FilesystemNode &node) : _node(node) { + } + + String getName() const { + ... + } + + SeekableReadStream *open() { + ... + } +}; +*/ + +ZipArchive::ZipArchive(const Common::String &name) { + _zipFile = unzOpen(name.c_str()); +} + +ZipArchive::~ZipArchive() { + unzClose(_zipFile); +} + +bool ZipArchive::isOpen() const { + return _zipFile != 0; +} + +bool ZipArchive::hasFile(const Common::String &name) { + return (_zipFile && unzLocateFile(_zipFile, name.c_str(), 2) == UNZ_OK); +} + +int ZipArchive::getAllNames(Common::StringList &list) { + return 0; +} + +/* +int ZipArchive::listMembers(Common::ArchiveMemberList &list) { + if (!_zipFile) + return 0; + + int matches = 0; + int err = unzGoToFirstFile(_zipFile); + + while (err == UNZ_OK) { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + unzGetCurrentFileInfo(_zipFile, NULL, + szCurrentFileName, sizeof(szCurrentFileName)-1, + NULL, 0, NULL, 0); + + szCurrentFileName + matches++; + err = unzGoToNextFile(file); + } + return 0; +} +*/ + +Common::SeekableReadStream *ZipArchive::openFile(const Common::String &name) { + if (!_zipFile) + return 0; + + unzLocateFile(_zipFile, name.c_str(), 2); + + unz_file_info fileInfo; + unzOpenCurrentFile(_zipFile); + unzGetCurrentFileInfo(_zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0); + byte *buffer = (byte *)calloc(fileInfo.uncompressed_size+1, 1); + assert(buffer); + unzReadCurrentFile(_zipFile, buffer, fileInfo.uncompressed_size); + unzCloseCurrentFile(_zipFile); + return new Common::MemoryReadStream(buffer, fileInfo.uncompressed_size+1, true); + + // FIXME: instead of reading all into a memory stream, we could + // instead create a new ZipStream class. But then we have to be + // careful to handle the case where the client code opens multiple + // files in the archive and tries to use them indepenendtly. +} + +} // End of namespace Common + + #endif |