ScummVM API documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
archive.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef COMMON_ARCHIVE_H
23 #define COMMON_ARCHIVE_H
24 
25 #include "common/error.h"
26 #include "common/hashmap.h"
27 #include "common/hash-str.h"
28 #include "common/list.h"
29 #include "common/path.h"
30 #include "common/ptr.h"
31 #include "common/singleton.h"
32 #include "common/str.h"
33 
34 namespace Common {
35 
46 class ArchiveMember;
47 class FSNode;
48 class SeekableReadStream;
49 
50 enum class AltStreamType {
51  Invalid,
52 
53  MacFinderInfo,
54  MacResourceFork,
55 };
56 
69 public:
70  virtual ~ArchiveMember();
71  virtual SeekableReadStream *createReadStream() const = 0;
72  virtual SeekableReadStream *createReadStreamForAltStream(AltStreamType altStreamType) const = 0;
78  virtual String getName() const = 0;
79 
80  virtual Path getPathInArchive() const = 0;
81  virtual String getFileName() const = 0;
82  virtual bool isDirectory() const;
83  virtual void listChildren(ArchiveMemberList &childList, const char *pattern = nullptr) const;
84  virtual U32String getDisplayName() const;
85  virtual bool isInMacArchive() const;
86 };
87 
89  ArchiveMemberPtr arcMember;
90  Common::String arcName;
91 
92  ArchiveMemberDetails(const ArchiveMemberPtr &arcMember_, const Common::String &_arcName) : arcMember(arcMember_), arcName(_arcName) {
93  }
94 };
101  bool operator()(const ArchiveMemberPtr &a, const ArchiveMemberPtr &b) {
102  return a->getName() < b->getName();
103  }
104 };
105 
106 class Archive;
107 
118 public:
119  GenericArchiveMember(const Common::String &pathStr, const Archive &parent);
120  GenericArchiveMember(const Common::Path &path, const Archive &parent);
122  String getName() const override;
123  Path getPathInArchive() const override;
124  String getFileName() const override;
125  SeekableReadStream *createReadStream() const override;
126  SeekableReadStream *createReadStreamForAltStream(AltStreamType altStreamType) const override;
127  bool isDirectory() const override;
128  void listChildren(ArchiveMemberList &childList, const char *pattern) const override;
129 
130 private:
131  const Archive &_parent;
132  const Common::Path _path;
133 };
134 
135 
141 class Archive {
142 public:
143  Archive() : _mapsAreReady(false) { }
144 
145  virtual ~Archive() { }
146 
152  virtual bool hasFile(const Path &path) const = 0;
153 
157  virtual bool isPathDirectory(const Path &path) const;
158 
168  virtual int listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents = false) const;
169 
176  virtual int listMembers(ArchiveMemberList &list) const = 0;
177 
181  virtual const ArchiveMemberPtr getMember(const Path &path) const = 0;
182 
189  virtual SeekableReadStream *createReadStreamForMember(const Path &path) const = 0;
190 
197  virtual SeekableReadStream *createReadStreamForMemberAltStream(const Path &path, AltStreamType altStreamType) const;
198 
203  virtual SeekableReadStream *createReadStreamForMemberNext(const Path &path, const Archive *starting) const {
204  return createReadStreamForMember(path);
205  }
206 
210  Common::Error dumpArchive(const Path &destPath);
211 
215  virtual char getPathSeparator() const;
216 
217  enum ListMode {
218  kListFilesOnly = 1,
219  kListDirectoriesOnly = 2,
220  kListAll = 3
221  };
222 
223  virtual bool getChildren(const Common::Path &path, Common::Array<Common::String> &list, ListMode mode = kListDirectoriesOnly, bool hidden = true) const;
224 
225 private:
226  void prepareMaps() const;
227 
228  mutable bool _mapsAreReady;
231  mutable AllfileMap _directoryMap, _fileMap;
232 };
233 
235 
236 // This is a shareable reference to a file contents stored in memory.
237 // It can be in 2 states: strong when it holds a strong reference in
238 // the sense of SharedPtr. Another state is weak when it only helds
239 // WeakPtr and thus may expire. Also strong reference is held by
240 // Returned memory stream. Hence once no memory streams and no
241 // strong referenceas are remaining, the block is freed.
243 public:
244  SharedArchiveContents(byte *contents, uint32 contentSize) :
245  _strongRef(contents, ArrayDeleter<byte>()), _weakRef(_strongRef),
246  _contentSize(contentSize), _missingFile(false), _bypass(nullptr) {}
247  SharedArchiveContents() : _strongRef(nullptr), _weakRef(nullptr), _contentSize(0), _missingFile(true), _bypass(nullptr) {}
248  static SharedArchiveContents bypass(SeekableReadStream *stream) {
249  return SharedArchiveContents(stream);
250  }
251 
252 private:
253  SharedArchiveContents(SeekableReadStream *stream) : _strongRef(nullptr), _weakRef(nullptr), _contentSize(0), _missingFile(false), _bypass(stream) {}
254 
255  bool isFileMissing() const { return _missingFile; }
256  SharedPtr<byte> getContents() const { return _strongRef; }
257  uint32 getSize() const { return _contentSize; }
258 
259  bool makeStrong() {
260  if (_strongRef || _contentSize == 0 || _missingFile)
261  return true;
262  _strongRef = SharedPtr<byte>(_weakRef);
263  if (_strongRef)
264  return true;
265  return false;
266  }
267 
268  void makeWeak() {
269  // No need to make weak if we have no contents
270  if (_contentSize == 0)
271  return;
272  _strongRef = nullptr;
273  }
274 
275  SharedPtr<byte> _strongRef;
276  WeakPtr<byte> _weakRef;
277  uint32 _contentSize;
278  bool _missingFile;
279  SeekableReadStream *_bypass;
280 
282 };
283 
288 public:
289  MemcachingCaseInsensitiveArchive(uint32 maxStronglyCachedSize = 512) : _maxStronglyCachedSize(maxStronglyCachedSize) {}
290  SeekableReadStream *createReadStreamForMember(const Path &path) const;
291  SeekableReadStream *createReadStreamForMemberAltStream(const Path &path, Common::AltStreamType altStreamType) const;
292 
293  virtual Path translatePath(const Path &path) const {
294  return path.normalize();
295  }
296 
297  virtual SharedArchiveContents readContentsForPath(const Path &translatedPath) const = 0;
298  virtual SharedArchiveContents readContentsForPathAltStream(const Path &translatedPath, AltStreamType altStreamType) const;
299 
300 private:
301  struct CacheKey {
302  CacheKey();
303 
304  Path path;
305  AltStreamType altStreamType;
306  };
307 
308  struct CacheKey_EqualTo {
309  bool operator()(const CacheKey &x, const CacheKey &y) const;
310  };
311 
312  struct CacheKey_Hash {
313  uint operator()(const CacheKey &x) const;
314  };
315 
316  SeekableReadStream *createReadStreamForMemberImpl(const Path &path, bool isAltStream, Common::AltStreamType altStreamType) const;
317 
319  uint32 _maxStronglyCachedSize;
320  char _separator = '\0';
321 };
322 
331 class SearchSet : public Archive {
332  struct Node {
333  int _priority;
334  String _name;
335  Archive *_arc;
336  bool _autoFree;
337  Node(int priority, const String &name, Archive *arc, bool autoFree)
338  : _priority(priority), _name(name), _arc(arc), _autoFree(autoFree) {
339  }
340  };
341  typedef List<Node> ArchiveNodeList;
342  ArchiveNodeList _list;
343 
345  ArchiveNodeList::const_iterator find(const String &name) const;
346 
347  void insert(const Node& node);
348 
349  bool _ignoreClashes;
350 
351 public:
352  SearchSet() : _ignoreClashes(false) { }
353  virtual ~SearchSet() { clear(); }
354 
355  char getPathSeparator() const override { return '/'; }
356 
360  void add(const String& name, Archive *arch, int priority = 0, bool autoFree = true);
361 
365  void addDirectory(const String &name, const Path &directory, int priority = 0, int depth = 1, bool flat = false);
366 
370  void addDirectory(const String &name, const FSNode &directory, int priority = 0, int depth = 1, bool flat = false);
371 
375  void addDirectory(const Path &directory, int priority = 0, int depth = 1, bool flat = false);
376  void addDirectory(const FSNode &directory, int priority = 0, int depth = 1, bool flat = false);
377 
398  void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority = 0, int depth = 1, bool flat = false) {
399  addSubDirectoriesMatching(directory, caselessName, true, priority, depth, flat);
400  }
401 
420  void addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority = 0, int depth = 1, bool flat = false);
421 
425  void remove(const String& name);
426 
430  bool hasArchive(const String &name) const;
431 
435  Archive *getArchive(const String &name) const;
436 
440  virtual void clear();
441 
445  void setPriority(const String& name, int priority);
446 
447  bool hasFile(const Path &path) const override;
448  bool isPathDirectory(const Path &path) const override;
449  int listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents = false) const override;
450  int listMatchingMembers(ArchiveMemberDetailsList &list, const Path &pattern, bool matchPathComponents = false) const;
451  int listMembers(ArchiveMemberList &list) const override;
452 
453  const ArchiveMemberPtr getMember(const Path &path) const override;
454 
455  const ArchiveMemberPtr getMember(const Path &path, Archive **container) const;
456 
461  SeekableReadStream *createReadStreamForMember(const Path &path) const override;
462 
467  SeekableReadStream *createReadStreamForMemberAltStream(const Path &path, AltStreamType altStreamType) const override;
468 
472  SeekableReadStream *createReadStreamForMemberNext(const Path &path, const Archive *starting) const override;
473 
478  void setIgnoreClashes(bool ignoreClashes) { _ignoreClashes = ignoreClashes; }
479 
480  bool getChildren(const Common::Path &path, Common::Array<Common::String> &list, ListMode mode = kListDirectoriesOnly, bool hidden = true) const override;
481 };
482 
483 
484 class SearchManager : public Singleton<SearchManager>, public SearchSet {
485 public:
486 
491  virtual void clear();
492 
493 private:
494  friend class Singleton<SingletonBaseType>;
495  SearchManager();
496 };
497 
499 #define SearchMan Common::SearchManager::instance()
500 
503 } // namespace Common
504 
505 #endif
virtual SeekableReadStream * createReadStreamForMemberNext(const Path &path, const Archive *starting) const
Definition: archive.h:203
Definition: str.h:59
Path normalize() const
Definition: error.h:84
In find(In first, In last, const T &v)
Definition: algorithm.h:225
Definition: list.h:44
Definition: archive.h:117
Definition: path.h:52
Definition: ptr.h:564
Definition: stream.h:745
Definition: archive.h:141
Definition: archive.h:100
void setIgnoreClashes(bool ignoreClashes)
Definition: archive.h:478
Definition: hashmap.h:85
List< ArchiveMemberDetails > ArchiveMemberDetailsList
Definition: archive.h:95
Definition: ustr.h:57
Definition: archive.h:331
virtual String getName() const =0
Definition: archive.h:68
Definition: algorithm.h:29
Definition: fs.h:69
Definition: archive.h:484
SharedPtr< ArchiveMember > ArchiveMemberPtr
Definition: archive.h:57
Definition: list_intern.h:51
Definition: list_intern.h:54
Definition: archive.h:88
char getPathSeparator() const override
Definition: archive.h:355
Definition: archive.h:242
void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority=0, int depth=1, bool flat=false)
Definition: archive.h:398
Definition: singleton.h:42
List< ArchiveMemberPtr > ArchiveMemberList
Definition: archive.h:58