////////////////////////////////////////////////////////////////////////// // Declarations of the class used to parse and cache Zipped directory. // This class is actually an auto-pointer to the instance of the cache, so it can // be easily passed by value. // The cache instance contains the optimized for memory usage and fast search tree // of the files/directories inside the zip; each file has a descriptor with the // info about where its compressed data lies within the file #ifndef _ZIP_DIR_CACHE_HDR_ #define _ZIP_DIR_CACHE_HDR_ ///////////////////////////////////////////////////////////// // THe Zip Dir uses a special memory layout for keeping the structure of zip file. // This layout is optimized for small memory footprint (for big zip files) // and quick binary-search access to the individual files. // // The serialized layout consists of a number of directory records. // Each directory record starts with the DirHeader structure, then // it has an array of DirEntry structures (sorted by name), // array of FileEntry structures (sorted by name) and then // the pool of names, followed by pad bytes to align the whole directory // record on 4-byte boundray. namespace ZipDir { // this is the header of the instance data allocated dynamically // it contains the FILE* : it owns it and closes upon destruction struct Cache: public RefCountedDataInstance { // looks for the given file record in the Central Directory. If there's none, returns NULL. // if there is some, returns the pointer to it. // the Path must be the relative path to the file inside the Zip // if the file handle is passed, it will be used to find the file data offset, if one hasn't been initialized yet // if bFull is true, then the full information about the file is returned (the offset to the data may be unknown at this point)- // if needed, the file is accessed and the information is loaded FileEntry* FindFile (const char* szPath, bool bFullInfo = false); // loads the given file into the pCompressed buffer (the actual compressed data) // if the pUncompressed buffer is supplied, uncompresses the data there // buffers must have enough memory allocated, according to the info in the FileEntry // NOTE: there's no need to decompress if the method is 0 (store) // returns 0 if successful or error code if couldn't do something ErrorEnum ReadFile (FileEntry* pFileEntry, void* pCompressed, void* pUncompressed); // loads and unpacks the file into a newly created buffer (that must be subsequently freed with // Free()) Returns NULL if failed void* AllocAndReadFile (FileEntry* pFileEntry); // frees the memory block that was previously allocated by AllocAndReadFile void Free (void*); // refreshes information about the given file entry into this file entry ErrorEnum Refresh (FileEntry* pFileEntry); // returns the root directory record; // through this directory record, user can traverse the whole tree DirHeader* GetRoot()const { return (DirHeader*)(this + 1); } // returns the size of memory occupied by the instance referred to by this cache // must be exact, because it's used by CacheRW to reallocate this cache size_t GetSize()const; // QUICK check to determine whether the file entry belongs to this object bool IsOwnerOf (const FileEntry*pFileEntry)const; // returns the string - path to the zip file from which this object was constructed. // this will be "" if the object was constructed with a factory that wasn't created with FLAGS_MEMORIZE_ZIP_PATH const char* GetFilePath()const { return ((const char*)(this+1)) + m_nZipPathOffset; } friend class CacheFactory; // the factory class creates instances of this class friend class CacheRW; // the Read-Write 2-way cache can modify this cache directly during write operations protected: FILE* m_pFile; // the opened file // the size of the serialized data following this instance (not including the extra fields after the serialized tree data) size_t m_nDataSize; // the offset to the path/name of the zip file relative to (char*)(this+1) pointer in bytes size_t m_nZipPathOffset; // compatible with zlib memory-management functions used both // to allocate/free this instance and for decompression operations CMTSafeHeap* m_pHeap; public: // initializes the instance structure void Construct(FILE* fNew, CMTSafeHeap* pHeap, size_t nDataSize); void Delete(); private: // the constructor/destructor cannot be called at all - everything will go through the factory class Cache(){} ~Cache(){} }; TYPEDEF_AUTOPTR(Cache); typedef Cache_AutoPtr CachePtr; // initializes this object from the given Zip file: caches the central directory // returns 0 if successfully parsed, error code if an error has occured CachePtr NewCache(const char* szFilePath, CMTSafeHeap*pHeap, InitMethodEnum nInitMethod = ZD_INIT_FAST); } #endif