PixelLightAPI  .
ZipHandle.h
Go to the documentation of this file.
00001 /*********************************************************\
00002  *  File: ZipHandle.h                                    *
00003  *
00004  *  Copyright (C) 2002-2012 The PixelLight Team (http://www.pixellight.org/)
00005  *
00006  *  This file is part of PixelLight.
00007  *
00008  *  PixelLight is free software: you can redistribute it and/or modify
00009  *  it under the terms of the GNU Lesser General Public License as published by
00010  *  the Free Software Foundation, either version 3 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  PixelLight is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  *  GNU Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Lesser General Public License
00019  *  along with PixelLight. If not, see <http://www.gnu.org/licenses/>.
00020 \*********************************************************/
00021 
00022 
00023 #ifndef __PLCORE_ZIPHANDLE_H__
00024 #define __PLCORE_ZIPHANDLE_H__
00025 #pragma once
00026 
00027 
00028 //[-------------------------------------------------------]
00029 //[ Includes                                              ]
00030 //[-------------------------------------------------------]
00031 #include "PLCore/File/File.h"
00032 #include "PLCore/Tools/Time.h"
00033 
00034 
00035 //[-------------------------------------------------------]
00036 //[ Forward declarations                                  ]
00037 //[-------------------------------------------------------]
00038 struct z_stream_s;
00039 typedef z_stream_s z_stream;
00040 
00041 
00042 //[-------------------------------------------------------]
00043 //[ Namespace                                             ]
00044 //[-------------------------------------------------------]
00045 namespace PLCore {
00046 
00047 
00048 //[-------------------------------------------------------]
00049 //[ Classes                                               ]
00050 //[-------------------------------------------------------]
00051 /**
00052 *  @brief
00053 *    This class represents a handle for working on a ZIP-file
00054 *
00055 *  @remarks
00056 *    It can be used to navigate inside the ZIP-file and read data from it, but you don't need
00057 *    to use it directly, as ZIP-files can be directly accessed through the File/Directory classes
00058 *    (e.g.: File("C:\\test.zip\\readme.txt") to extract a file from a ZIP-file)
00059 */
00060 class ZipHandle {
00061 
00062 
00063     //[-------------------------------------------------------]
00064     //[ ZIP file entry                                        ]
00065     //[-------------------------------------------------------]
00066     public:
00067         /**
00068         *  @brief
00069         *    Represents an entry (file or directory) in a ZIP-file
00070         */
00071         class ZipEntry {
00072 
00073 
00074             //[-------------------------------------------------------]
00075             //[ Public functions                                      ]
00076             //[-------------------------------------------------------]
00077             public:
00078                 /**
00079                 *  @brief
00080                 *    Constructor
00081                 */
00082                 PLCORE_API ZipEntry();
00083 
00084                 /**
00085                 *  @brief
00086                 *    Copy constructor
00087                 *
00088                 *  @param[in] cZipEntry
00089                 *    ZipEntry to copy
00090                 */
00091                 PLCORE_API ZipEntry(const ZipEntry &cZipEntry);
00092 
00093                 /**
00094                 *  @brief
00095                 *    Destructor
00096                 */
00097                 PLCORE_API ~ZipEntry();
00098 
00099                 /**
00100                 *  @brief
00101                 *    Assignment operator
00102                 *
00103                 *  @param[in] cZipEntry
00104                 *    ZipEntry to copy
00105                 *
00106                 *  @return
00107                 *    Reference to this instance
00108                 */
00109                 PLCORE_API ZipEntry &operator =(const ZipEntry &cZipEntry);
00110 
00111                 /**
00112                 *  @brief
00113                 *    Clear entry
00114                 */
00115                 PLCORE_API void Clear();
00116 
00117                 /**
00118                 *  @brief
00119                 *    Allocate memory for extra-field
00120                 *
00121                 *  @param[in] nSize
00122                 *    Size of extra-field
00123                 */
00124                 PLCORE_API void AllocateExtraField(uint16 nSize);
00125 
00126 
00127             //[-------------------------------------------------------]
00128             //[ Public fields                                         ]
00129             //[-------------------------------------------------------]
00130             public:
00131                 bool    m_bValid;               /**< Is the current entry valid? */
00132                 String  m_sFilename;            /**< Filename */
00133                 String  m_sComment;             /**< File comment */
00134                 uint16  m_nVersion;             /**< Version made by                 2 bytes */
00135                 uint16  m_nVersionNeeded;       /**< Version needed to extract       2 bytes */
00136                 uint16  m_nFlags;               /**< General purpose bit flag        2 bytes */
00137                 uint16  m_nCompressionMethod;   /**< Compression method              2 bytes */
00138                 uint32  m_nDOSDate;             /**< Last mod file date in DOS fmt   4 bytes */
00139                 uint32  m_nCRC;                 /**< Crc-32                          4 bytes */
00140                 uint32  m_nCompressedSize;      /**< Compressed size                 4 bytes */
00141                 uint32  m_nUncompressedSize;    /**< Uncompressed size               4 bytes */
00142                 uint16  m_nSizeFilename;        /**< Filename length                 2 bytes */
00143                 uint16  m_nSizeFileExtra;       /**< Extra field length              2 bytes */
00144                 uint16  m_nSizeFileComment;     /**< File comment length             2 bytes */
00145                 uint16  m_nDiskNumStart;        /**< Disk number start               2 bytes */
00146                 uint16  m_nInternalAttr;        /**< Internal file attributes        2 bytes */
00147                 uint32  m_nExternalAttr;        /**< External file attributes        4 bytes */
00148                 uint32  m_nOffsetCurFile;       /**< Relative offset of local header 4 bytes */
00149                 Time    m_cTime;                /**< Time of the current file */
00150                 uint8  *m_pExtraField;          /**< Extra data, can be a null pointer */
00151 
00152 
00153         };
00154 
00155 
00156     //[-------------------------------------------------------]
00157     //[ Public functions                                      ]
00158     //[-------------------------------------------------------]
00159     public:
00160         //[-------------------------------------------------------]
00161         //[ General                                               ]
00162         //[-------------------------------------------------------]
00163         /**
00164         *  @brief
00165         *    Constructor
00166         */
00167         PLCORE_API ZipHandle();
00168 
00169         /**
00170         *  @brief
00171         *    Destructor
00172         */
00173         PLCORE_API ~ZipHandle();
00174 
00175         /**
00176         *  @brief
00177         *    Check if the ZIP-file is open
00178         *
00179         *  @return
00180         *    'true', if the file is valid, 'false' on error
00181         */
00182         PLCORE_API bool IsOpen() const;
00183 
00184         /**
00185         *  @brief
00186         *    Open the ZIP-file
00187         *
00188         *  @param[in] sFilename
00189         *    Filename of the ZIP-file
00190         *  @param[in] sPassword
00191         *    Password if the file is encrypted, else empty string
00192         *  @param[in] bCaseSensitive
00193         *    Shall the filenames be treated case sensitive?
00194         *  @param[in] bMemBuf
00195         *    Shall the ZIP-file be read into a memory-buffer?
00196         *  @param[in] pAccess
00197         *    Access information to pass through (can be a null pointer)
00198         *
00199         *  @return
00200         *    'true', if the file could be opened, 'false' on error
00201         */
00202         PLCORE_API bool Open(const String &sFilename, const String &sPassword, bool bCaseSensitive = true, bool bMemBuf = true, const FileAccess *pAccess = nullptr);
00203 
00204         /**
00205         *  @brief
00206         *    Close the ZIP file
00207         *
00208         *  @return
00209         *    'true', if the file could be closed, 'false' on error
00210         */
00211         PLCORE_API bool Close();
00212 
00213         /**
00214         *  @brief
00215         *    Returns whether names treated case sensitive
00216         *
00217         *  @return
00218         *    'true' if names treated case sensitive, else 'false'
00219         */
00220         PLCORE_API bool IsCaseSensitive() const;
00221 
00222         //[-------------------------------------------------------]
00223         //[ Enumerate entries in the ZIP-file                     ]
00224         //[-------------------------------------------------------]
00225         /**
00226         *  @brief
00227         *    Sets the pointer to the first entry in the ZIP-file
00228         *
00229         *  @return
00230         *    'true', if the file is valid, 'false' on error
00231         */
00232         PLCORE_API bool LocateFirstFile();
00233 
00234         /**
00235         *  @brief
00236         *    Sets the pointer to the next entry in the ZIP-file
00237         *
00238         *  @return
00239         *    'true', if the file is valid, 'false' on error
00240         */
00241         PLCORE_API bool LocateNextFile();
00242 
00243         /**
00244         *  @brief
00245         *    Sets the pointer to a specific entry in the ZIP-file
00246         *
00247         *  @param[in] sFilename
00248         *    Name of the file
00249         *
00250         *  @return
00251         *    'true', if the file is valid, 'false' on error
00252         */
00253         PLCORE_API bool LocateFile(const String &sFilename);
00254 
00255         /**
00256         *  @brief
00257         *    Get information about the current entry in the ZIP-file
00258         *
00259         *  @return
00260         *    Current ZipEntry, could be invalid (see ZipEntry::IsValid)
00261         */
00262         PLCORE_API const ZipEntry &GetCurrentFile() const;
00263 
00264         //[-------------------------------------------------------]
00265         //[ Read file from ZIP-file                               ]
00266         //[-------------------------------------------------------]
00267         /**
00268         *  @brief
00269         *    Check if a file is currently open
00270         *
00271         *  @return
00272         *    'true' if a file is currently open, else 'false'
00273         */
00274         PLCORE_API bool IsFileOpen() const;
00275 
00276         /**
00277         *  @brief
00278         *    Open the currently selected file
00279         *
00280         *  @return
00281         *    'true' if all went fine, else 'false'
00282         */
00283         PLCORE_API bool OpenFile();
00284 
00285         /**
00286         *  @brief
00287         *    Close file
00288         *
00289         *  @return
00290         *    'true' if all went fine, else 'false'
00291         */
00292         PLCORE_API bool CloseFile();
00293 
00294         /**
00295         *  @brief
00296         *    Reads data from the file
00297         *
00298         *  @param[out] pBuffer
00299         *    Buffer to store the data (MUST be valid and large enough!)
00300         *  @param[in]  nSize
00301         *    Item size in bytes
00302         *  @param[in]  nCount
00303         *    Number of items to read
00304         *
00305         *  @return
00306         *    Number of full read items, if != 'nCount' an error occurred
00307         */
00308         PLCORE_API uint32 Read(void *pBuffer, uint32 nSize, uint32 nCount);
00309 
00310         /**
00311         *  @brief
00312         *    Sets the starting position
00313         *
00314         *  @param[in] nOffset
00315         *    File offset in bytes relative to the given location
00316         *  @param[in] nLocation
00317         *    Location
00318         *
00319         *  @return
00320         *    'true' if all went fine, else 'false'
00321         */
00322         PLCORE_API bool Seek(int32 nOffset, File::ESeek nLocation);
00323 
00324         /**
00325         *  @brief
00326         *    Returns the file position
00327         *
00328         *  @return
00329         *    Current position within the file, or < 0 on error
00330         */
00331         PLCORE_API int32 Tell() const;
00332 
00333         /**
00334         *  @brief
00335         *    Returns whether end of file has been reached
00336         *
00337         *  @return
00338         *    'true', if the end of the file has been reached, else 'false'
00339         */
00340         PLCORE_API bool IsEof() const;
00341 
00342         /**
00343         *  @brief
00344         *    Gets the size of the current file's extra data field
00345         *
00346         *  @return
00347         *    Size of the local data field
00348         */
00349         PLCORE_API uint32 GetLocalExtrafieldSize() const;
00350 
00351         /**
00352         *  @brief
00353         *    Reads the extra data of the current file
00354         *
00355         *  @param[out] pBuffer
00356         *    Buffer to store the data (MUST valid and large enough!)
00357         *  @param[in]  nSize
00358         *    Size of the buffer (MUST be valid!)
00359         *
00360         *  @return
00361         *    'true', if all went fine, else 'false'
00362         */
00363         PLCORE_API bool GetLocalExtrafield(void *pBuffer, uint32 nSize);
00364 
00365 
00366     //[-------------------------------------------------------]
00367     //[ Private functions                                     ]
00368     //[-------------------------------------------------------]
00369     private:
00370         /**
00371         *  @brief
00372         *    Copy constructor
00373         *
00374         *  @param[in] cSource
00375         *    Source to copy from
00376         */
00377         ZipHandle(const ZipHandle &cSource);
00378 
00379         /**
00380         *  @brief
00381         *    Copy operator
00382         *
00383         *  @param[in] cSource
00384         *    Source to copy from
00385         *
00386         *  @return
00387         *    Reference to this instance
00388         */
00389         ZipHandle &operator =(const ZipHandle &cSource);
00390 
00391         /**
00392         *  @brief
00393         *    Opens the ZIP-file
00394         *
00395         *  @return
00396         *    'true', if all went fine, else 'false'
00397         */
00398         bool OpenZipFile();
00399 
00400         /**
00401         *  @brief
00402         *    Search for the central directory entry within the ZIP-file
00403         *
00404         *  @return
00405         *    Position of the central directory, 0 on error
00406         */
00407         uint32 SearchCentralDir();
00408 
00409         /**
00410         *  @brief
00411         *    Reads the information about the current file
00412         *
00413         *  @return
00414         *    'true', if the file is valid, 'false' on error
00415         */
00416         bool ReadCurrentFileInfo();
00417 
00418         /**
00419         *  @brief
00420         *    Checks the local header of the selected file
00421         *
00422         *  @param[out] nSizeVar
00423         *    Will receive the total local header size
00424         *  @param[out] nPosLocalExtra
00425         *    Will receive the position of the local extra
00426         *  @param[out] nSizeLocalExtra
00427         *    Will receive the size of the local extra
00428         *  @param[out] nFlags
00429         *    Will receive the flags
00430         *
00431         *  @return
00432         *    'true' if all went fine, else 'false'
00433         */
00434         bool CheckFileHeader(uint32 &nSizeVar, uint32 &nPosLocalExtra, uint32 &nSizeLocalExtra, uint16 &nFlags);
00435 
00436         /**
00437         *  @brief
00438         *    Reads a byte from the ZIP-file
00439         *
00440         *  @param[out] nByte
00441         *    Will receive the read byte value
00442         *
00443         *  @return
00444         *    'true' if everything went fine, else 'false' ('nByte' is set to 0)
00445         */
00446         bool ReadByte(uint8 &nByte);
00447 
00448         /**
00449         *  @brief
00450         *    Reads a unsigned short from the ZIP-file
00451         *
00452         *  @param[out] nShort
00453         *    Will receive the read unsigned short value
00454         *
00455         *  @return
00456         *    'true' if everything went fine, else 'false' ('nShort' is set to 0)
00457         */
00458         bool ReadShort(uint16 &nShort);
00459 
00460         /**
00461         *  @brief
00462         *    Reads a unsigned long from the ZIP-file
00463         *
00464         *  @param[out] nLong
00465         *    Will receive the read unsigned long value
00466         *
00467         *  @return
00468         *    'true' if everything went fine, else 'false' ('nLong' is set to 0)
00469         */
00470         bool ReadLong(uint32 &nLong);
00471 
00472 
00473     //[-------------------------------------------------------]
00474     //[ Private data                                          ]
00475     //[-------------------------------------------------------]
00476     private:
00477         // General
00478         File        m_cZipFile;             /**< ZIP-file to work on */
00479         bool        m_bCaseSensitive;       /**< Are names treated case sensitive? */
00480         bool        m_bMemBuf;              /**< Read ZIP-file memory-buffered? */
00481 
00482         // Information about the ZIP-file
00483         bool        m_bZipFileValid;        /**< Error flag */
00484         uint16      m_nNumEntries;          /**< Number of directory entries in the ZIP-file */
00485         uint16      m_nCommentSize;         /**< Size of the ZIP-file comment */
00486         uint32      m_nBytesBeforeZip;      /**< Byte before the ZIP-file, (> 0 for sfx) */
00487         uint32      m_nCentralDirPos;       /**< Position of the beginning of the central directory */
00488         uint32      m_nCentralDirSize;      /**< Size of the central directory */
00489         uint32      m_nCentralDirOffset;    /**< Offset of start of central directory with respect to the starting disk number */
00490         uint16      m_nDiskNum;             /**< Disk number (for splitted ZIP-files) */
00491         uint16      m_nMainDisk;            /**< Disk number that contains the central directory */
00492         uint16      m_nMainEntries;         /**< Number of entries in the central directory on this disk */
00493 
00494         // Currently selected file
00495         ZipEntry    m_cCurFile;             /**< Current file entry */
00496         uint32      m_nCurFile;             /**< Number of the current file in the ZIP-file */
00497         uint32      m_nCurCentralDirPos;    /**< Position of the current file in the central directory */
00498 
00499         // Stream data
00500         uint8      *m_pReadBuffer;          /**< Internal buffer for compressed data (always valid!) */
00501         z_stream   *m_pStream;              /**< ZLib stream structure for inflate, can be a null pointer */
00502         uint32      m_nPosInZip;            /**< Position in byte on the ZIP-file, for fseek */
00503         uint32      m_nPosLocalExtra;       /**< Offset of the local extra field */
00504         uint32      m_nSizeLocalExtra;      /**< Size of the local extra field */
00505         uint32      m_nPosInLocalExtra;     /**< Position in the local extra field in read */
00506         uint32      m_nCRC32;               /**< CRC32 of all data uncompressed */
00507         uint32      m_nCRC32Wait;           /**< CRC32 we must obtain after decompress all */
00508         uint32      m_nReadCompressed;      /**< Number of byte to be decompressed */
00509         uint32      m_nReadUncompressed;    /**< Number of byte to be obtained after decompression */
00510         uint16      m_nCompressionMethod;   /**< Currently used compression method (copied from cCurrentFile) */
00511 
00512         // Encryption data
00513         bool        m_bEncrypted;           /**< Is the file encrypted? */
00514         uint32      m_nKeys[3];             /**< Decryption keys, initialized by constructor */
00515         int         m_nEncheadLeft;         /**< The first call(s) to Read() will read this many encryption-header bytes first */
00516         char        m_nCRCEncTest;          /**< If encrypted, we'll check the encryption buffer against this */
00517 
00518 
00519 };
00520 
00521 
00522 //[-------------------------------------------------------]
00523 //[ Namespace                                             ]
00524 //[-------------------------------------------------------]
00525 } // PLCore
00526 
00527 
00528 #endif // __PLCORE_ZIPHANDLE_H__


PixelLight PixelLight 0.9.11-R1
Copyright (C) 2002-2012 by The PixelLight Team
Last modified Thu Feb 23 2012 14:09:02
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported