You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Tools/CryCommonTools/ZipDir/ZipDirCache.h

141 lines
6.1 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// 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 CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRCACHE_H
#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRCACHE_H
#pragma once
/////////////////////////////////////////////////////////////
// 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
{
void AddRef() { ++m_nRefCount; }
void Release()
{
if (--m_nRefCount <= 0)
{
Delete();
}
}
int NumRefs() const { return m_nRefCount; }
// 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);
// Return FileEntity data offset inside zip file.
uint32 GetFileDataOffset(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;
}
// Unpak the file into a destination folder
bool UnpakToDisk(const string& destFolder);
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:
volatile signed int m_nRefCount; // the reference count
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;
// tells if encryption used for zip-file
EncryptionKey m_encryptionKey;
bool m_bEncryptHeaders;
public:
// initializes the instance structure
void Construct(FILE* fNew, size_t nDataSize, const EncryptionKey& key);
void Delete();
private:
bool ReadCompressedData(char* data, size_t size);
bool UnpakToDiskInternal(ZipDir::DirHeader* dirHeader, const string& destFolder);
// the constructor/destructor cannot be called at all - everything will go through the factory class
Cache() { m_nRefCount = 0; }
~Cache(){}
};
TYPEDEF_AUTOPTR(Cache);
typedef Cache_AutoPtr CachePtr;
}
#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRCACHE_H