OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4Group.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Handles group files */
19 
20 #ifndef INC_C4Group
21 #define INC_C4Group
22 
23 #ifdef HAVE_IO_H
24 #include <io.h>
25 #endif
26 #include "c4group/CStdFile.h"
27 
28 // C4Group-Rewind-warning:
29 // The current C4Group-implementation cannot handle random file access very well,
30 // because all files are written within a single zlib-stream.
31 // For every out-of-order-file accessed a group-rewind must be performed, and every
32 // single file up to the accessed file unpacked. As a workaround, all C4Groups are
33 // packed in a file order matching the reading order of the engine.
34 // If the reading order doesn't match the packing order, and a rewind has to be performed,
35 // a warning is issued in Debug-builds of the engine. But since some components require
36 // random access because they are loaded on-demand at runtime (e.g. global sounds), the
37 // warning may be temp disabled for those files using C4GRP_DISABLE_REWINDWARN and
38 // C4GRP_ENABLE_REWINDWARN. A ref counter keeps track of nested calls to those functions.
39 //
40 // If you add any new components to scenario or definition files, remember to adjust the
41 // sort order lists in C4Components.h accordingly, and enforce a reading order for that
42 // component.
43 //
44 // Maybe some day, someone will write a C4Group-implementation that is probably capable of
45 // random access...
46 #ifdef _DEBUG
47 extern int iC4GroupRewindFilePtrNoWarn;
48 #define C4GRP_DISABLE_REWINDWARN ++iC4GroupRewindFilePtrNoWarn;
49 #define C4GRP_ENABLE_REWINDWARN --iC4GroupRewindFilePtrNoWarn;
50 #else
51 #define C4GRP_DISABLE_REWINDWARN ;
52 #define C4GRP_ENABLE_REWINDWARN ;
53 #endif
54 
56 
57 const int C4GroupMaxError = 100;
58 
59 const int32_t C4GroupSwapThreshold = 10 * 1024 * 1024;
60 
61 #define C4GroupFileID "RedWolf Design GrpFolder"
62 
63 bool C4Group_TestIgnore(const char *szFilename);
64 void C4Group_SetTempPath(const char *szPath);
65 const char* C4Group_GetTempPath();
66 void C4Group_SetSortList(const char **ppSortList);
67 void C4Group_SetProcessCallback(bool (*fnCallback)(const char *, int));
68 bool C4Group_IsGroup(const char *szFilename);
69 bool C4Group_CopyItem(const char *szSource, const char *szTarget, bool fNoSort=false, bool fResetAttributes=false);
70 bool C4Group_MoveItem(const char *szSource, const char *szTarget, bool fNoSort=false);
71 bool C4Group_DeleteItem(const char *szItem, bool fRecycle=false);
72 bool C4Group_PackDirectoryTo(const char *szFilename, const char *szFilenameTo);
73 bool C4Group_PackDirectory(const char *szFilename);
74 bool C4Group_UnpackDirectory(const char *szFilename);
75 bool C4Group_ExplodeDirectory(const char *szFilename);
76 bool C4Group_ReadFile(const char *szFilename, char **pData, size_t *iSize);
77 
78 extern const char *C4CFN_FLS[];
79 
80 #pragma pack (push, 1)
81 
83 {
84  char id[24+4] = C4GroupFileID;
87  int Entries = 0;
88  char reserved[164] = { 0 };
89 };
90 
92 {
93  char FileName[260] = { 0 };
94  int32_t Packed = 0, ChildGroup = 0;
95  int32_t Size = 0, reserved1 = 0, Offset = 0;
96  int32_t reserved2 = 0;
97  char reserved3 = '\0';
98  unsigned int reserved4 = 0;
99  char Executable = '\0';
100  BYTE fbuf[26] = { 0 };
101 };
102 
103 #pragma pack (pop)
104 
106 {
107 public:
108  ~C4GroupEntry();
109 
111  {
116  };
117 
118 public:
119  char DiskPath[_MAX_PATH + 1] = { 0 };
121  bool DeleteOnDisk = false;
122  bool HoldBuffer = false;
123  bool BufferIsStdbuf = false;
124  bool NoSort = false;
125  BYTE *bpMemBuf = nullptr;
126  C4GroupEntry *Next = nullptr;
127 public:
128  void Set(const DirectoryIterator & iter, const char * szPath);
129 };
130 
131 class C4Group : public CStdStream
132 {
133  struct P;
134  std::unique_ptr<P> p;
135 public:
136  C4Group();
137  ~C4Group() override;
138  C4Group(C4Group &&) = default;
139  C4Group &operator=(C4Group &&) = default;
140 
141 protected:
142  // C4Update requires these to be available by a subclass (C4GroupEx)
144  C4GroupEntry *GetEntry(const char *szName);
145  void Clear();
146 
147 public:
148  bool Open(const char *szGroupName, bool fCreate=false);
149  bool Close();
150  bool Save(bool fReOpen);
151  bool OpenAsChild(C4Group *pMother, const char *szEntryName, bool fExclusive=false, bool fCreate=false);
152  bool OpenChild(const char* strEntry);
153  bool OpenMother();
154  bool Add(const char *szFile, const char *szAddAs);
155  bool Add(const char *szName, void *pBuffer, int iSize, bool fChild = false, bool fHoldBuffer = false, bool fExecutable = false);
156  bool Add(const char *szName, StdBuf &pBuffer, bool fChild = false, bool fHoldBuffer = false, bool fExecutable = false);
157  bool Add(const char *szName, StdStrBuf &pBuffer, bool fChild = false, bool fHoldBuffer = false, bool fExecutable = false);
158  bool Merge(const char *szFolders);
159  bool Move(const char *szFile, const char *szAddAs);
160  bool Extract(const char *szFiles, const char *szExtractTo=nullptr, const char *szExclude=nullptr);
161  bool ExtractEntry(const char *szFilename, const char *szExtractTo=nullptr);
162  bool Delete(const char *szFiles, bool fRecursive = false);
163  bool DeleteEntry(const char *szFilename, bool fRecycle=false);
164  bool Rename(const char *szFile, const char *szNewName);
165  bool Sort(const char *szSortList);
166  bool SortByList(const char **ppSortList, const char *szFilename=nullptr);
167  bool AccessEntry(const char *szWildCard,
168  size_t *iSize=nullptr, char *sFileName=nullptr,
169  bool NeedsToBeAGroup = false);
170  bool AccessNextEntry(const char *szWildCard,
171  size_t *iSize=nullptr, char *sFileName=nullptr,
172  bool fStartAtFilename=false);
173  bool LoadEntry(const char *szEntryName, char **lpbpBuf,
174  size_t *ipSize=nullptr, int iAppendZeros=0);
175  bool LoadEntry(const char *szEntryName, StdBuf * Buf);
176  bool LoadEntry(const StdStrBuf & name, StdBuf * Buf) { return LoadEntry(name.getData(), Buf); }
177  bool LoadEntryString(const char *szEntryName, StdStrBuf * Buf);
178  bool LoadEntryString(const StdStrBuf & name, StdStrBuf * Buf) { return LoadEntryString(name.getData(), Buf); }
179  bool FindEntry(const char *szWildCard,
180  StdStrBuf *sFileName=nullptr,
181  size_t *iSize=nullptr);
182  bool FindEntry(const char *szWildCard,
183  char *sFileName)
184  {
185  StdStrBuf name;
186  bool r = FindEntry(szWildCard, &name);
187  if(sFileName) SCopy(name.getData(),sFileName);
188  return r;
189  }
190  bool FindNextEntry(const char *szWildCard,
191  StdStrBuf *sFileName=nullptr,
192  size_t *iSize=nullptr,
193  bool fStartAtFilename=false);
194  bool FindNextEntry(const char *szWildCard,
195  char *sFileName,
196  size_t *iSize=nullptr,
197  bool fStartAtFilename=false)
198  {
199  StdStrBuf name(fStartAtFilename ? sFileName : "");
200  bool r = FindNextEntry(szWildCard, &name, iSize, fStartAtFilename);
201  if (r && sFileName) SCopy(name.getData(),sFileName);
202  return r;
203  }
204  bool Read(void *pBuffer, size_t iSize) override;
205  bool Advance(int iOffset) override;
206  void SetStdOutput(bool fStatus);
207  void ResetSearch(bool reload_contents=false); // reset search pointer so calls to FindNextEntry find first entry again. if reload_contents is set, the file list for directories is also refreshed.
208  const char *GetError();
209  const char *GetName() const;
210  StdStrBuf GetFullName() const;
211  int EntryCount(const char *szWildCard=nullptr);
212  size_t EntrySize(const char *szWildCard=nullptr);
213  size_t AccessedEntrySize() const override; // retrieve size of last accessed entry
214  unsigned int EntryCRC32(const char *szWildCard=nullptr);
215  bool IsOpen() const;
216  C4Group *GetMother();
217  bool IsPacked() const;
218  bool HasPackedMother() const;
219  bool SetNoSort(bool fNoSort);
220  int PreCacheEntries(const char *szSearchPattern, bool cache_previous=false); // pre-load entries to memory. return number of loaded entries.
221 
222  const C4GroupHeader &GetHeader() const;
223  const C4GroupEntry *GetFirstEntry() const;
224 
225 private:
226  void Init();
227  bool EnsureChildFilePtr(C4Group *pChild);
228  bool CloseExclusiveMother();
229  bool Error(const char *szStatus);
230  bool OpenReal(const char *szGroupName);
231  bool OpenRealGrpFile();
232  bool SetFilePtr(int iOffset);
233  bool RewindFilePtr();
234  bool AdvanceFilePtr(int iOffset);
235  bool AddEntry(C4GroupEntry::EntryStatus status,
236  bool childgroup,
237  const char *fname,
238  long size,
239  const char *entryname = nullptr,
240  BYTE *membuf = nullptr,
241  bool fDeleteOnDisk = false,
242  bool fHoldBuffer = false,
243  bool fExecutable = false,
244  bool fBufferIsStdbuf = false);
245  bool AddEntryOnDisk(const char *szFilename, const char *szAddAs=nullptr, bool fMove=false);
246  bool SetFilePtr2Entry(const char *szName, bool NeedsToBeAGroup = false);
247  bool AppendEntry2StdFile(C4GroupEntry *centry, CStdFile &stdfile);
248  C4GroupEntry *SearchNextEntry(const char *szName);
249  C4GroupEntry *GetNextFolderEntry();
250  uint32_t CalcCRC32(C4GroupEntry *pEntry);
251  void PreCacheEntry(C4GroupEntry * p);
252 };
253 
254 #endif
bool SetNoSort(bool fNoSort)
Definition: C4Group.cpp:2013
const char * getData() const
Definition: StdBuf.h:442
bool BufferIsStdbuf
Definition: C4Group.h:123
bool FindEntry(const char *szWildCard, StdStrBuf *sFileName=nullptr, size_t *iSize=nullptr)
Definition: C4Group.cpp:1774
bool C4Group_MoveItem(const char *szSource, const char *szTarget, bool fNoSort=false)
Definition: C4Group.cpp:144
Definition: StdBuf.h:29
const int C4GroupFileVer2
Definition: C4Group.h:55
Definition: C4Group.h:115
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
int EntryCount(const char *szWildCard=nullptr)
Definition: C4Group.cpp:1850
const int C4GroupMaxError
Definition: C4Group.h:57
bool HoldBuffer
Definition: C4Group.h:122
C4Group * GetMother()
Definition: C4Group.cpp:2004
char Executable
Definition: C4Group.h:99
bool Merge(const char *szFolders)
Definition: C4Group.cpp:1229
unsigned int reserved4
Definition: C4Group.h:98
bool AccessEntry(const char *szWildCard, size_t *iSize=nullptr, char *sFileName=nullptr, bool NeedsToBeAGroup=false)
Definition: C4Group.cpp:1695
void C4Group_SetProcessCallback(bool(*fnCallback)(const char *, int))
Definition: C4Group.cpp:64
void C4Group_SetSortList(const char **ppSortList)
Definition: C4Group.cpp:69
BYTE fbuf[26]
Definition: C4Group.h:100
bool AccessNextEntry(const char *szWildCard, size_t *iSize=nullptr, char *sFileName=nullptr, bool fStartAtFilename=false)
Definition: C4Group.cpp:1719
char FileName[260]
Definition: C4Group.h:93
bool C4Group_CopyItem(const char *szSource, const char *szTarget, bool fNoSort=false, bool fResetAttributes=false)
Definition: C4Group.cpp:100
~C4Group() override
Definition: C4Group.cpp:493
int32_t reserved1
Definition: C4Group.h:95
bool LoadEntry(const char *szEntryName, char **lpbpBuf, size_t *ipSize=nullptr, int iAppendZeros=0)
Definition: C4Group.cpp:1893
uint8_t BYTE
bool Rename(const char *szFile, const char *szNewName)
Definition: C4Group.cpp:1424
bool Delete(const char *szFiles, bool fRecursive=false)
Definition: C4Group.cpp:1334
#define _MAX_PATH
Definition: C4Group.h:91
bool C4Group_ExplodeDirectory(const char *szFilename)
Definition: C4Group.cpp:351
const C4GroupEntry * GetFirstEntry() const
Definition: C4Group.cpp:2247
EntryStatus
Definition: C4Group.h:110
const int C4GroupFileVer1
Definition: C4Group.h:55
C4GroupEntry * Next
Definition: C4Group.h:126
int32_t reserved2
Definition: C4Group.h:96
void C4Group_SetTempPath(const char *szPath)
Definition: C4Group.cpp:74
bool Save(bool fReOpen)
Definition: C4Group.cpp:797
bool OpenMother()
Definition: C4Group.cpp:2197
int32_t Packed
Definition: C4Group.h:94
void Set(const DirectoryIterator &iter, const char *szPath)
Definition: C4Group.cpp:462
bool SortByList(const char **ppSortList, const char *szFilename=nullptr)
Definition: C4Group.cpp:2027
bool IsOpen() const
Definition: C4Group.cpp:1891
#define C4GroupFileID
Definition: C4Group.h:61
const char * GetName() const
Definition: C4Group.cpp:1845
bool C4Group_PackDirectory(const char *szFilename)
Definition: C4Group.cpp:284
StdStrBuf GetFullName() const
Definition: C4Group.cpp:2078
bool C4Group_TestIgnore(const char *szFilename)
Definition: C4Group.cpp:85
bool Move(const char *szFile, const char *szAddAs)
Definition: C4Group.cpp:1325
bool Open(const char *szGroupName, bool fCreate=false)
Definition: C4Group.cpp:514
void SetStdOutput(bool fStatus)
Definition: C4Group.cpp:509
const C4GroupHeader & GetHeader() const
Definition: C4Group.cpp:2245
unsigned int EntryCRC32(const char *szWildCard=nullptr)
Definition: C4Group.cpp:1877
bool fRecursive
Definition: C4GroupMain.cpp:34
size_t AccessedEntrySize() const override
Definition: C4Group.cpp:1875
bool Close()
Definition: C4Group.cpp:755
int32_t Offset
Definition: C4Group.h:95
const char * C4CFN_FLS[]
Definition: C4Group.cpp:32
~C4GroupEntry()
Definition: C4Group.cpp:450
int32_t ChildGroup
Definition: C4Group.h:94
bool OpenChild(const char *strEntry)
Definition: C4Group.cpp:2161
int32_t Size
Definition: C4Group.h:95
C4GroupEntry * GetEntry(const char *szName)
Definition: C4Group.cpp:744
bool DeleteOnDisk
Definition: C4Group.h:121
C4GroupHeader Head
Definition: C4Group.h:143
bool LoadEntry(const StdStrBuf &name, StdBuf *Buf)
Definition: C4Group.h:176
const char * GetError()
Definition: C4Group.cpp:504
Definition: C4Group.h:112
int PreCacheEntries(const char *szSearchPattern, bool cache_previous=false)
Definition: C4Group.cpp:2222
bool DeleteEntry(const char *szFilename, bool fRecycle=false)
Definition: C4Group.cpp:1384
Definition: C4Group.h:113
C4Group & operator=(C4Group &&)=default
bool NoSort
Definition: C4Group.h:124
bool LoadEntryString(const char *szEntryName, StdStrBuf *Buf)
Definition: C4Group.cpp:1932
bool FindNextEntry(const char *szWildCard, StdStrBuf *sFileName=nullptr, size_t *iSize=nullptr, bool fStartAtFilename=false)
Definition: C4Group.cpp:1780
bool C4Group_IsGroup(const char *szFilename)
Definition: C4Group.cpp:94
bool HasPackedMother() const
Definition: C4Group.cpp:2011
bool C4Group_DeleteItem(const char *szItem, bool fRecycle=false)
Definition: C4Group.cpp:194
Definition: C4Group.h:114
bool LoadEntryString(const StdStrBuf &name, StdStrBuf *Buf)
Definition: C4Group.h:178
const int32_t C4GroupSwapThreshold
Definition: C4Group.h:59
bool ExtractEntry(const char *szFilename, const char *szExtractTo=nullptr)
Definition: C4Group.cpp:1518
bool Add(const char *szFile, const char *szAddAs)
Definition: C4Group.cpp:1316
bool C4Group_ReadFile(const char *szFilename, char **pData, size_t *iSize)
Definition: C4Group.cpp:366
bool IsPacked() const
Definition: C4Group.cpp:2009
size_t EntrySize(const char *szWildCard=nullptr)
Definition: C4Group.cpp:1862
void ResetSearch(bool reload_contents=false)
Definition: C4Group.cpp:1013
bool FindNextEntry(const char *szWildCard, char *sFileName, size_t *iSize=nullptr, bool fStartAtFilename=false)
Definition: C4Group.h:194
bool Sort(const char *szSortList)
Definition: C4Group.cpp:1963
EntryStatus Status
Definition: C4Group.h:120
char DiskPath[_MAX_PATH+1]
Definition: C4Group.h:119
void Clear()
Definition: C4Group.cpp:898
bool Extract(const char *szFiles, const char *szExtractTo=nullptr, const char *szExclude=nullptr)
Definition: C4Group.cpp:1471
const char * C4Group_GetTempPath()
Definition: C4Group.cpp:80
bool C4Group_UnpackDirectory(const char *szFilename)
Definition: C4Group.cpp:306
char reserved[164]
Definition: C4Group.h:88
bool FindEntry(const char *szWildCard, char *sFileName)
Definition: C4Group.h:182
int Entries
Definition: C4Group.h:87
bool Advance(int iOffset) override
Definition: C4Group.cpp:1105
bool OpenAsChild(C4Group *pMother, const char *szEntryName, bool fExclusive=false, bool fCreate=false)
Definition: C4Group.cpp:1585
C4Group()
Definition: C4Group.cpp:477
Definition: C4Group.h:105
int iSize
Definition: TstC4NetIO.cpp:32
bool C4Group_PackDirectoryTo(const char *szFilename, const char *szFilenameTo)
Definition: C4Group.cpp:221
BYTE * bpMemBuf
Definition: C4Group.h:125
char reserved3
Definition: C4Group.h:97
bool Read(void *pBuffer, size_t iSize) override
Definition: C4Group.cpp:1125