diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/archive.cpp | 29 | ||||
-rw-r--r-- | common/archive.h | 20 | ||||
-rw-r--r-- | common/file.cpp | 39 | ||||
-rw-r--r-- | common/str.cpp | 27 | ||||
-rw-r--r-- | common/str.h | 4 | ||||
-rw-r--r-- | common/system.h | 2 | ||||
-rw-r--r-- | common/unarj.cpp | 6 | ||||
-rw-r--r-- | common/unarj.h | 8 | ||||
-rw-r--r-- | common/unzip.cpp | 556 | ||||
-rw-r--r-- | common/unzip.h | 326 | ||||
-rw-r--r-- | common/util.h | 8 | ||||
-rw-r--r-- | common/xmlparser.h | 4 |
12 files changed, 499 insertions, 530 deletions
diff --git a/common/archive.cpp b/common/archive.cpp index 7e17fdca32..49e43a5973 100644 --- a/common/archive.cpp +++ b/common/archive.cpp @@ -26,6 +26,7 @@ #include "common/archive.h" #include "common/fs.h" #include "common/util.h" +#include "common/system.h" namespace Common { @@ -231,7 +232,7 @@ void SearchSet::insert(const Node &node) { _list.insert(it, node); } -void SearchSet::add(const String& name, ArchivePtr archive, uint priority) { +void SearchSet::add(const String& name, ArchivePtr archive, int priority) { if (find(name) == _list.end()) { Node node = { priority, name, archive }; insert(node); @@ -256,7 +257,7 @@ void SearchSet::clear() { _list.clear(); } -void SearchSet::setPriority(const String& name, uint priority) { +void SearchSet::setPriority(const String& name, int priority) { ArchiveList::iterator it = find(name); if (it == _list.end()) { warning("SearchSet::setPriority: archive '%s' is not present", name.c_str()); @@ -328,17 +329,29 @@ SeekableReadStream *SearchSet::openFile(const String &name) { DECLARE_SINGLETON(SearchManager); -void SearchManager::addArchive(const String &name, ArchivePtr archive) { - add(name, archive); +SearchManager::SearchManager() { + clear(); // Force a reset } -void SearchManager::addDirectory(const String &name, const String &directory) { - addDirectoryRecursive(name, 1); +void SearchManager::addArchive(const String &name, ArchivePtr archive, int priority) { + add(name, archive, priority); } -void SearchManager::addDirectoryRecursive(const String &name, const String &directory, int depth) { - add(name, SharedPtr<FSDirectory>(new FSDirectory(directory, depth))); +void SearchManager::addDirectory(const String &name, const String &directory, int priority) { + addDirectoryRecursive(name, directory, 1, priority); } +void SearchManager::addDirectoryRecursive(const String &name, const String &directory, int depth, int priority) { + add(name, ArchivePtr(new FSDirectory(directory, depth)), priority); +} + +void SearchManager::clear() { + SearchSet::clear(); + + // Always keep system specific archives in the SearchManager. + // But we give them a lower priority than the default priority (which is 0), + // so that archives added by client code are searched first. + g_system->addSysArchivesToSearchSet(*this, -1); +} } // namespace Common diff --git a/common/archive.h b/common/archive.h index 89ea6a5ce2..246d9da8cf 100644 --- a/common/archive.h +++ b/common/archive.h @@ -153,7 +153,7 @@ public: */ class SearchSet : public Archive { struct Node { - uint _priority; + int _priority; String _name; ArchivePtr _arc; }; @@ -169,7 +169,7 @@ public: /** * Add a new archive to the searchable set. */ - void add(const String& name, ArchivePtr archive, uint priority = 0); + void add(const String& name, ArchivePtr archive, int priority = 0); /** * Remove an archive from the searchable set. @@ -184,12 +184,12 @@ public: /** * Empties the searchable set. */ - void clear(); + virtual void clear(); /** * Change the order of searches. */ - void setPriority(const String& name, uint priority); + void setPriority(const String& name, int priority); virtual bool hasFile(const String &name); virtual int matchPattern(StringList &list, const String &pattern); @@ -205,22 +205,28 @@ public: class SearchManager : public Singleton<SearchManager>, public SearchSet { public: + SearchManager(); + /** * Add an existing Archive. This is meant to support searching in system-specific * archives, namely the MACOSX/IPHONE bundles. */ - void addArchive(const String &name, ArchivePtr archive); + void addArchive(const String &name, ArchivePtr archive, int priority = 0); /** * Create and add a FSDirectory by name */ - void addDirectory(const String &name, const String &directory); + void addDirectory(const String &name, const String &directory, int priority = 0); /** * Create and add a FSDirectory and its subdirectories by name */ - void addDirectoryRecursive(const String &name, const String &directory, int depth = 4); + void addDirectoryRecursive(const String &name, const String &directory, int depth = 4, int priority = 0); + /** + * TODO + */ + virtual void clear(); }; /** Shortcut for accessing the search manager. */ diff --git a/common/file.cpp b/common/file.cpp index cf396a32cd..6558dfea33 100644 --- a/common/file.cpp +++ b/common/file.cpp @@ -31,9 +31,6 @@ namespace Common { -static Common::SearchSet *s_searchSet = 0; - - void File::addDefaultDirectory(const String &directory) { FilesystemNode dir(directory); addDefaultDirectoryRecursive(dir, 1); @@ -52,18 +49,12 @@ void File::addDefaultDirectoryRecursive(const FilesystemNode &dir, int level) { if (level <= 0 || !dir.exists() || !dir.isDirectory()) return; - if (!s_searchSet) { - s_searchSet = new Common::SearchSet(); - g_system->addSysArchivesToSearchSet(*s_searchSet); - } - Common::ArchivePtr dataArchive(new Common::FSDirectory(dir, level)); - s_searchSet->add(dir.getPath(), dataArchive, 1); + SearchMan.add(dir.getPath(), dataArchive); } void File::resetDefaultDirectories() { - delete s_searchSet; - s_searchSet = 0; + SearchMan.clear(); } File::File() @@ -82,23 +73,18 @@ bool File::open(const String &filename) { _name.clear(); clearIOFailed(); - if (s_searchSet && s_searchSet->hasFile(filename)) { + if (SearchMan.hasFile(filename)) { debug(3, "Opening hashed: %s", filename.c_str()); - _handle = s_searchSet->openFile(filename); - } else if (s_searchSet && s_searchSet->hasFile(filename + ".")) { + _handle = SearchMan.openFile(filename); + } else if (SearchMan.hasFile(filename + ".")) { // WORKAROUND: Bug #1458388: "SIMON1: Game Detection fails" // sometimes instead of "GAMEPC" we get "GAMEPC." (note trailing dot) debug(3, "Opening hashed: %s.", filename.c_str()); - _handle = s_searchSet->openFile(filename); - } else { - // Last resort: try the current directory - FilesystemNode file(filename); - if (file.exists() && !file.isDirectory()) - _handle = file.openForReading(); + _handle = SearchMan.openFile(filename + "."); } if (_handle == NULL) - debug(2, "File %s not opened", filename.c_str()); + debug(2, "File::open: '%s' not found", filename.c_str()); else _name = filename; @@ -127,7 +113,7 @@ bool File::open(const FilesystemNode &node) { _handle = node.openForReading(); if (_handle == NULL) - debug(2, "File %s not found", filename.c_str()); + debug(2, "File::open: '%s' not found", node.getPath().c_str()); else _name = filename; @@ -135,17 +121,12 @@ bool File::open(const FilesystemNode &node) { } bool File::exists(const String &filename) { - if (s_searchSet && s_searchSet->hasFile(filename)) { + if (SearchMan.hasFile(filename)) { return true; - } else if (s_searchSet && s_searchSet->hasFile(filename + ".")) { + } else if (SearchMan.hasFile(filename + ".")) { // WORKAROUND: Bug #1458388: "SIMON1: Game Detection fails" // sometimes instead of "GAMEPC" we get "GAMEPC." (note trailing dot) return true; - } else { - // Last resort: try the current directory - FilesystemNode file(filename); - if (file.exists() && !file.isDirectory()) - return true; } return false; diff --git a/common/str.cpp b/common/str.cpp index a415e376c9..6c48738533 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -26,6 +26,13 @@ #include "common/hash-str.h" #include "common/util.h" +#include "common/memorypool.h" + +#if !defined(__SYMBIAN32__) +#include <new> +#endif + + namespace Common { #if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__)) @@ -34,6 +41,9 @@ const String String::emptyString; const char *String::emptyString = ""; #endif + +MemoryPool *g_refCountPool = 0; // FIXME: This is never freed right now + static uint32 computeCapacity(uint32 len) { // By default, for the capacity we use the next multiple of 32 return ((len + 32 - 1) & ~0x1F); @@ -79,15 +89,17 @@ void String::initWithCStr(const char *str, uint32 len) { } String::String(const String &str) - : _size(str._size), _str(str.isStorageIntern() ? _storage : str._str) { + : _size(str._size) { if (str.isStorageIntern()) { // String in internal storage: just copy it - memcpy(_storage, str._storage, sizeof(_storage)); + memcpy(_storage, str._storage, _builtinCapacity); + _str = _storage; } else { // String in external storage: use refcount mechanism str.incRefCount(); _extern._refCount = str._extern._refCount; _extern._capacity = str._extern._capacity; + _str = str._str; } assert(_str != 0); } @@ -178,7 +190,11 @@ void String::ensureCapacity(uint32 new_size, bool keep_old) { void String::incRefCount() const { assert(!isStorageIntern()); if (_extern._refCount == 0) { - _extern._refCount = new int(2); + if (g_refCountPool == 0) + g_refCountPool = new MemoryPool(sizeof(int)); + + _extern._refCount = (int *)g_refCountPool->malloc(); + *_extern._refCount = 2; } else { ++(*_extern._refCount); } @@ -194,7 +210,10 @@ void String::decRefCount(int *oldRefCount) { if (!oldRefCount || *oldRefCount <= 0) { // The ref count reached zero, so we free the string storage // and the ref count storage. - delete oldRefCount; + if (oldRefCount) { + assert(g_refCountPool); + g_refCountPool->free(oldRefCount); + } free(_str); // Even though _str points to a freed memory block now, diff --git a/common/str.h b/common/str.h index 20914c1f1f..c3e773c3e4 100644 --- a/common/str.h +++ b/common/str.h @@ -54,7 +54,7 @@ protected: * than 8 makes no sense, since that's the size of member _extern * (on 32 bit machines; 12 bytes on systems with 64bit pointers). */ - static const uint32 _builtinCapacity = 32; + static const uint32 _builtinCapacity = 32 - sizeof(uint32) - sizeof(char*); /** * Length of the string. Stored to avoid having to call strlen @@ -112,7 +112,7 @@ public: String(const String &str); /** Construct a string consisting of the given character. */ - String(char c); + explicit String(char c); ~String(); diff --git a/common/system.h b/common/system.h index cb9dbedad7..176e53ddb4 100644 --- a/common/system.h +++ b/common/system.h @@ -917,7 +917,7 @@ public: * @param s the SearchSet to which the system specific dirs, if any, are added * @param priority the priority with which those dirs are added */ - virtual void addSysArchivesToSearchSet(Common::SearchSet &s, uint priority = 0) {} + virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0) {} /** * Open the default config file for reading, by returning a suitable diff --git a/common/unarj.cpp b/common/unarj.cpp index 244a296efb..00f51ac252 100644 --- a/common/unarj.cpp +++ b/common/unarj.cpp @@ -324,15 +324,15 @@ uint32 ArjFile::read(void *dataPtr, uint32 dataSize) { return _uncompressed->read(dataPtr, dataSize); } -bool ArjFile::eos() { +bool ArjFile::eos() const { return _uncompressed->eos(); } -int32 ArjFile::pos() { +int32 ArjFile::pos() const { return _uncompressed->pos(); } -int32 ArjFile::size() { +int32 ArjFile::size() const { return _uncompressed->size(); } diff --git a/common/unarj.h b/common/unarj.h index 52e0d13948..d16d748ad3 100644 --- a/common/unarj.h +++ b/common/unarj.h @@ -85,7 +85,7 @@ struct ArjHeader { typedef HashMap<String, int, IgnoreCase_Hash, IgnoreCase_EqualTo> ArjFilesMap; -class ArjFile : public File { +class ArjFile : public SeekableReadStream, public NonCopyable { public: ArjFile(); ~ArjFile(); @@ -98,9 +98,9 @@ public: void close(); uint32 read(void *dataPtr, uint32 dataSize); - bool eos(); - int32 pos(); - int32 size(); + bool eos() const; + int32 pos() const; + int32 size() const; bool seek(int32 offset, int whence = SEEK_SET); bool isOpen() { return _isOpen; } diff --git a/common/unzip.cpp b/common/unzip.cpp index 93fb60f41c..27001519a1 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,111 @@ 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) { + if (!_zipFile) + return 0; + + if (unzGoToFirstFile(_zipFile) != UNZ_OK) + return 0; + + char fileNameBuffer[UNZ_MAXFILENAMEINZIP+1]; + list.clear(); + + do { + unzOpenCurrentFile(_zipFile); + unzGetCurrentFileInfo(_zipFile, 0, fileNameBuffer, UNZ_MAXFILENAMEINZIP+1, 0, 0, 0, 0); + + list.push_back(Common::String(fileNameBuffer)); + + unzCloseCurrentFile(_zipFile); + + } while (unzGoToNextFile(_zipFile) == UNZ_OK); + + return list.size(); +} + +/* +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 diff --git a/common/unzip.h b/common/unzip.h index 43faaf4a74..e4eb754eee 100644 --- a/common/unzip.h +++ b/common/unzip.h @@ -22,332 +22,34 @@ * $Id$ */ -/* 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 */ - -#ifndef _unz_H -#define _unz_H +#ifndef COMMON_UNZIP_H +#define COMMON_UNZIP_H #ifdef USE_ZLIB #include "common/scummsys.h" #include "common/archive.h" -#include "common/stream.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __SYMBIAN32__ -#include <zlib\zlib.h> -#else -#include <zlib.h> -#endif - -#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 -typedef voidp unzFile; -#endif - - -#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 tm_unz_s -{ - 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 unz_global_info_s -{ - 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 unz_file_info_s -{ - 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; - -extern int ZEXPORT unzStringFileNameCompare OF ((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) -*/ - - -extern unzFile ZEXPORT unzOpen OF((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. -*/ - -extern int ZEXPORT unzClose OF((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. */ -extern int ZEXPORT unzGetGlobalInfo OF((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. */ +typedef void *unzFile; +namespace Common { -extern int ZEXPORT unzGetGlobalComment OF((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 */ - -extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ - -extern int ZEXPORT unzGoToNextFile OF((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. -*/ - -extern int ZEXPORT unzLocateFile OF((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 -*/ - - -extern int ZEXPORT unzGetCurrentFileInfo OF((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) - */ - -extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); -/* - Open for reading data the current file in the zipfile. - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzCloseCurrentFile OF((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 -*/ - - -extern int ZEXPORT unzReadCurrentFile OF((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) -*/ - -extern z_off_t ZEXPORT unztell OF((unzFile file)); -/* - Give the current position in uncompressed data -*/ - -extern int ZEXPORT unzeof OF((unzFile file)); -/* - return 1 if the end of file was reached, 0 elsewhere -*/ - -extern int ZEXPORT unzGetLocalExtrafield OF((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 -*/ - -#ifdef __cplusplus -} -#endif - - -class ZipArchive : Common::Archive { - unzFile _zipFile; +class ZipArchive : public Archive { + void *_zipFile; public: - ZipArchive(const Common::String &name) { - _zipFile = unzOpen(name.c_str()); - } - ~ZipArchive() { - unzClose(_zipFile); - } - - virtual bool hasFile(const Common::String &name) { - return (_zipFile && unzLocateFile(_zipFile, name.c_str(), 2) == UNZ_OK); - } - - virtual int getAllNames(Common::StringList &list) { - // TODO - return 0; - } - - virtual Common::SeekableReadStream *openFile(const Common::String &name) { - if (!_zipFile) - return 0; + ZipArchive(const String &name); + ~ZipArchive(); - unzLocateFile(_zipFile, name.c_str(), 2); + bool isOpen() const; - 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. - } + virtual bool hasFile(const String &name); + virtual int getAllNames(StringList &list); + virtual Common::SeekableReadStream *openFile(const Common::String &name); }; +} // End of namespace Common + #endif // USE_ZLIB #endif /* _unz_H */ diff --git a/common/util.h b/common/util.h index 32f07181c4..573004c437 100644 --- a/common/util.h +++ b/common/util.h @@ -106,20 +106,20 @@ public: /** * Generates a random unsigned integer in the interval [0, max]. * @param max the upper bound - * @return a random number in the interval [0, max]. + * @return a random number in the interval [0, max] */ uint getRandomNumber(uint max); /** - * Generates a random unsigned integer in the interval [0, 1]. + * Generates a random bit, i.e. either 0 or 1. * Identical to getRandomNumber(1), but faster, hopefully. - * @return a random number in the interval [0, max]. + * @return a random bit, either 0 or 1 */ uint getRandomBit(void); /** * Generates a random unsigned integer in the interval [min, max]. * @param min the lower bound * @param max the upper bound - * @return a random number in the interval [min, max]. + * @return a random number in the interval [min, max] */ uint getRandomNumberRng(uint min, uint max); }; diff --git a/common/xmlparser.h b/common/xmlparser.h index 967b73535b..4b76278d47 100644 --- a/common/xmlparser.h +++ b/common/xmlparser.h @@ -217,9 +217,9 @@ public: return true; } - bool loadStream(MemoryReadStream *stream) { + bool loadStream(Common::SeekableReadStream *stream) { _stream = stream; - _fileName = "Compressed File Stream"; + _fileName = "File Stream"; return true; } |