My Project
ZipArchive.h
1 #pragma once
2 
4 // #define SAVE_ZIP_HEADER
5 
6 #include "Archive.h"
7 #include "Array.h"
8 #include <vector>
9 #include "util/mutex.h"
10 
11 namespace ParaEngine
12 {
13  using namespace std;
14  class IReadFile;
15 
16  const WORD ZIP_FILE_ENCRYPTED = 0x0001; // set if the file is encrypted
17  const WORD ZIP_INFO_IN_DATA_DESCRITOR = 0x0008; // the fields crc-32, compressed size
19  const int ZIP_CONST_ENDHDR = 22;
21  const int ZIP_CONST_LOCALHEADERSIG = 'P' | ('K' << 8) | (3 << 16) | (4 << 24);
23  const int ZIP_CONST_CENSIG = 'P' | ('K' << 8) | (1 << 16) | (2 << 24);
25  const DWORD ZIP_CONST_ENDSIG = 'P' | ('K' << 8) | (5 << 16) | (6 << 24);
26 
27  // and uncompressed size are set to zero in the local
28  // header
29 
30  // Set byte packing for ZIP file header definition
31 # pragma pack( push, packing )
32 # pragma pack( 1 )
33 
35  {
36  uint16_t thisDiskNumber;
37  uint16_t startCentralDirDisk;
38  uint16_t entriesForThisDisk;
39  uint16_t entriesForWholeCentralDir;
40  uint32_t centralDirSize;
41  uint32_t offsetOfCentralDir;
42  uint16_t commentSize;
43  };
44 
46  {
47  DWORD sig;
48  uint16_t thisDiskNumber;
49  uint16_t startCentralDirDisk;
50  uint16_t entriesForThisDisk;
51  uint16_t entriesForWholeCentralDir;
52  uint32_t centralDirSize;
53  uint32_t offsetOfCentralDir;
54  uint16_t commentSize;
55  };
56 
58  {
59  DWORD Sig;
60  WORD MadeByVersion;
61  WORD ExtractVersion;
62  WORD Flags;
63  WORD CompressionMethod;
64  WORD LastModFileTime;
65  WORD LastModFileDate;
66  DWORD FileCRC;
67  DWORD PackSize;
68  DWORD UnPackSize;
69  WORD NameSize;
70  WORD ExtraSize;
71  WORD CommentSize;
72  WORD DiskNumberStart;
73  WORD InternalAttributes;
74  DWORD ExternalAttributes;
75  DWORD LocalHeaderOffset;
76  };
77 
79  {
80  DWORD CRC32;
81  DWORD CompressedSize;
82  DWORD UncompressedSize;
83  };
84 
86  {
87  DWORD Sig;
88  WORD VersionToExtract;
89  WORD GeneralBitFlag;
90  WORD CompressionMethod;
91  WORD LastModFileTime;
92  WORD LastModFileDate;
93  SZIPFileDataDescriptor DataDescriptor;
94  WORD FilenameLength;
95  WORD ExtraFieldLength;
96  };
97 
98  // Default alignment
99 # pragma pack( pop, packing )
100 
101 
104  {
105  //string zipFileName;
106  WORD fileNameLen;
107  const char* zipFileName;
108  uint32 hashValue;
109  DWORD fileDataPosition; // position of compressed data in file
110 
111  WORD CompressionMethod;
112  DWORD CompressedSize;
113  DWORD UncompressedSize;
114 #ifdef SAVE_ZIP_HEADER
115  SZIPFileHeader header;
116 #endif
117 
118  public:
119  SZipFileEntry()
120  : fileDataPosition(0), CompressedSize(0),UncompressedSize(0),CompressionMethod(0) , hashValue(0), zipFileName(nullptr), fileNameLen(0)
121  {
122 #ifdef SAVE_ZIP_HEADER
123  memset(&header, 0, sizeof(SZIPFileHeader));
124 #endif
125  };
126  ~SZipFileEntry(){};
127 
128  void SetFileName(const char* str, WORD len)
129  {
130  zipFileName = str;
131  fileNameLen = len;
132  }
133 
134  void RefreshHash(bool ignoreCase)
135  {
136  if (zipFileName)
137  hashValue = Hash(zipFileName, ignoreCase);
138  }
139 
140  static uint32 Hash(const char* str, bool ignoreCase)
141  {
142  const size_t seed = 2166136261U;
143  const size_t prime = 16777619U;
144  const char diff = 'a' - 'A';
145 
146  uint32 ret = seed;
147 
148  const char* p = str;
149 
150  if (ignoreCase)
151  {
152  while (*p != 0)
153  {
154  auto cur = *p;
155 
156  if (cur >= 'A' && cur <= 'Z')
157  cur += diff;
158  ret ^= cur;
159  ret *= prime;
160 
161  p++;
162  }
163  }
164  else
165  {
166  while (*p != 0)
167  {
168  auto cur = *p;
169 
170  ret ^= cur;
171  ret *= prime;
172 
173  p++;
174  }
175  }
176 
177  return ret;
178  }
179  };
180 
182  {
183  SZipFileEntry* m_pEntry;
184  public:
185  SZipFileEntryPtr():m_pEntry(NULL){};
186  SZipFileEntryPtr(const SZipFileEntryPtr& entry):m_pEntry(entry.m_pEntry){};
187  SZipFileEntryPtr(SZipFileEntry* pEntry):m_pEntry(pEntry){};
188  };
189 
190  // check src data is zip file data
191  bool IsZipData(const char* src, size_t size);
192  // get first file info in zip file data
193  const SZIPFileHeader* GetFirstFileInfo(const char* src, std::string* filename = nullptr);
194  bool GetFirstFileData(const char* src, std::string& out);
195 
256  class CZipArchive : public CArchive
257  {
258  public:
259  CZipArchive(void);
260  CZipArchive(bool bIgnoreCase);
261  virtual ~CZipArchive(void);
262  inline static DWORD TypeID() { return 2; };
263  virtual DWORD GetType(){ return TypeID(); };
264 
265  ATTRIBUTE_DEFINE_CLASS(CZipArchive);
266  ATTRIBUTE_METHOD1(CZipArchive, SetBaseDirectory_s, const char*) { cls->SetBaseDirectory(p1); return S_OK; }
267 
268  ATTRIBUTE_METHOD1(CZipArchive, GetRootDirectory_s, const char**) { *p1 = cls->GetRootDirectory().c_str(); return S_OK; }
269  ATTRIBUTE_METHOD1(CZipArchive, SetRootDirectory_s, const char*) { cls->SetRootDirectory(p1); return S_OK; }
270 
271 
272  virtual int InstallFields(CAttributeClass* pClass, bool bOverride);
273 
274  public:
276  virtual bool Open(const string& sArchiveName, int nPriority);
277 
279  virtual void Close();
280 
285  virtual bool DoesFileExist(const string& filename);
286 
294  virtual bool OpenFile(const char* filename, FileHandle& handle);
295 
303  virtual bool OpenFile(const ArchiveFileFindItem* item, FileHandle& handle);
304 
305  /* open a zip file in memory
306  * @param buffer:
307  * @param nLen: size in byte of the buffer
308  * @param bDeleteBuffer: true if the zip file will take the ownership of the buffer and will delete it on exit.
309  */
310  bool OpenMemFile(const char* buffer, DWORD nLen, bool bDeleteBuffer=true);
311 
313  virtual DWORD GetFileSize(FileHandle& handle);
314 
316  virtual bool ReadFile(FileHandle& handle,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead);
317 
324  virtual bool ReadFileRaw(FileHandle& handle,LPVOID* lppBuffer,LPDWORD pnCompressedSize, LPDWORD pnUncompressedSize);
325 
327  static bool Decompress(LPVOID lpCompressedBuffer, DWORD nCompressedSize, LPVOID lpUnCompressedBuffer, DWORD nUncompressedSize);
328 
330  virtual bool CloseFile(FileHandle& hFile);
331 
336  virtual void SetRootDirectory(const string& filename);
337 
339  const std::string& GetRootDirectory();
340 
344  virtual void SetBaseDirectory(const char * filename);
345 
355  virtual void FindFiles(CSearchResult& result, const string& sRootPath, const string& sFilePattern, int nSubLevel);
356 
363  bool GeneratePkgFile(const char* filename);
364  bool GeneratePkgFile2(const char* filename);
365 
367  int GetFileCount();
368 
369  virtual bool IsIgnoreCase() const { return m_bIgnoreCase; }
370  private:
371  IReadFile* m_pFile;
372  vector<SZipFileEntryPtr> m_FileList;
373  bool m_bDirty;
374  SZipFileEntry* m_pEntries;
375  // save name block
376  vector<char> m_nameBlock;
377 
378 
379  bool m_bIgnoreCase;
381  bool m_bRelativePath;
383  string m_sRootPath;
384  char* m_zipComment;
386  ParaEngine::mutex m_mutex;
387  private:
389  int findFile(const ArchiveFileFindItem* item);
390 
391 
392  IReadFile* openFile(int index);
393  /* open a zip file. this function is only called inside OpenFile() virtual method */
394  bool OpenZipFile(const string& filename);
395  /* open a pkg file. this function is only called inside OpenFile() virtual method */
396  bool OpenPkgFile(const string& filename);
397 
398  void ReBuild();
403  int LocateBlockWithSignature(DWORD signature, long endLocation, int minimumBlockSize, int maximumVariableData);
404 
408  bool ReadEntries();
409 
411  bool _ReadEntries_pkg();
412  bool ReadEntries_pkg();
413  bool ReadEntries_pkg2();
414  };
415 }
file archiver base class.
Definition: Archive.h:24
an attribute class is a collection of attribute fields.
Definition: AttributeClass.h:10
const DWORD ZIP_CONST_ENDSIG
End of central directory record signature.
Definition: ZipArchive.h:25
Definition: Archive.h:11
a file handle in a Archive
Definition: FileHandle.h:13
Definition: handle.hpp:33
different physics engine has different winding order.
Definition: EventBinding.h:32
const int ZIP_CONST_ENDHDR
Size of end of central record (excluding variable fields)
Definition: ZipArchive.h:19
Definition: ZipArchive.h:181
Definition: ZipArchive.h:57
Both the zip and ParaEngine&#39;s pkg file encryption logics are supported.
Definition: ZipArchive.h:256
const int ZIP_CONST_CENSIG
Signature for central header.
Definition: ZipArchive.h:23
Definition: ZipArchive.h:85
Definition: ZipArchive.h:78
light-weighted file record header in memory.
Definition: ZipArchive.h:103
cross platform mutex
Definition: mutex.h:95
it represents the search result.
Definition: FileSearchResult.h:24
const int ZIP_CONST_LOCALHEADERSIG
local file header
Definition: ZipArchive.h:21
Definition: ZipArchive.h:34
Interface for read access to a file.
Definition: IFile.h:8