ScummVM API documentation
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  virtual ~Archive() { }
144 
150  virtual bool hasFile(const Path &path) const = 0;
151 
155  virtual bool isPathDirectory(const Path &path) const;
156 
166  virtual int listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents = false) const;
167 
174  virtual int listMembers(ArchiveMemberList &list) const = 0;
175 
179  virtual const ArchiveMemberPtr getMember(const Path &path) const = 0;
180 
187  virtual SeekableReadStream *createReadStreamForMember(const Path &path) const = 0;
188 
195  virtual SeekableReadStream *createReadStreamForMemberAltStream(const Path &path, AltStreamType altStreamType) const;
196 
201  virtual SeekableReadStream *createReadStreamForMemberNext(const Path &path, const Archive *starting) const {
202  return createReadStreamForMember(path);
203  }
204 
208  Common::Error dumpArchive(const Path &destPath);
209 
213  virtual char getPathSeparator() const;
214 };
215 
217 
218 // This is a shareable reference to a file contents stored in memory.
219 // It can be in 2 states: strong when it holds a strong reference in
220 // the sense of SharedPtr. Another state is weak when it only helds
221 // WeakPtr and thus may expire. Also strong reference is held by
222 // Returned memory stream. Hence once no memory streams and no
223 // strong referenceas are remaining, the block is freed.
225 public:
226  SharedArchiveContents(byte *contents, uint32 contentSize) :
227  _strongRef(contents, ArrayDeleter<byte>()), _weakRef(_strongRef),
228  _contentSize(contentSize), _missingFile(false), _bypass(nullptr) {}
229  SharedArchiveContents() : _strongRef(nullptr), _weakRef(nullptr), _contentSize(0), _missingFile(true), _bypass(nullptr) {}
230  static SharedArchiveContents bypass(SeekableReadStream *stream) {
231  return SharedArchiveContents(stream);
232  }
233 
234 private:
235  SharedArchiveContents(SeekableReadStream *stream) : _strongRef(nullptr), _weakRef(nullptr), _contentSize(0), _missingFile(false), _bypass(stream) {}
236 
237  bool isFileMissing() const { return _missingFile; }
238  SharedPtr<byte> getContents() const { return _strongRef; }
239  uint32 getSize() const { return _contentSize; }
240 
241  bool makeStrong() {
242  if (_strongRef || _contentSize == 0 || _missingFile)
243  return true;
244  _strongRef = SharedPtr<byte>(_weakRef);
245  if (_strongRef)
246  return true;
247  return false;
248  }
249 
250  void makeWeak() {
251  // No need to make weak if we have no contents
252  if (_contentSize == 0)
253  return;
254  _strongRef = nullptr;
255  }
256 
257  SharedPtr<byte> _strongRef;
258  WeakPtr<byte> _weakRef;
259  uint32 _contentSize;
260  bool _missingFile;
261  SeekableReadStream *_bypass;
262 
264 };
265 
270 public:
271  MemcachingCaseInsensitiveArchive(uint32 maxStronglyCachedSize = 512) : _maxStronglyCachedSize(maxStronglyCachedSize) {}
272  SeekableReadStream *createReadStreamForMember(const Path &path) const;
273  SeekableReadStream *createReadStreamForMemberAltStream(const Path &path, Common::AltStreamType altStreamType) const;
274 
275  virtual Path translatePath(const Path &path) const {
276  return path.normalize();
277  }
278 
279  virtual SharedArchiveContents readContentsForPath(const Path &translatedPath) const = 0;
280  virtual SharedArchiveContents readContentsForPathAltStream(const Path &translatedPath, AltStreamType altStreamType) const;
281 
282 private:
283  struct CacheKey {
284  CacheKey();
285 
286  Path path;
287  AltStreamType altStreamType;
288  };
289 
290  struct CacheKey_EqualTo {
291  bool operator()(const CacheKey &x, const CacheKey &y) const;
292  };
293 
294  struct CacheKey_Hash {
295  uint operator()(const CacheKey &x) const;
296  };
297 
298  SeekableReadStream *createReadStreamForMemberImpl(const Path &path, bool isAltStream, Common::AltStreamType altStreamType) const;
299 
301  uint32 _maxStronglyCachedSize;
302 };
303 
312 class SearchSet : public Archive {
313  struct Node {
314  int _priority;
315  String _name;
316  Archive *_arc;
317  bool _autoFree;
318  Node(int priority, const String &name, Archive *arc, bool autoFree)
319  : _priority(priority), _name(name), _arc(arc), _autoFree(autoFree) {
320  }
321  };
322  typedef List<Node> ArchiveNodeList;
323  ArchiveNodeList _list;
324 
326  ArchiveNodeList::const_iterator find(const String &name) const;
327 
328  void insert(const Node& node);
329 
330  bool _ignoreClashes;
331 
332 public:
333  SearchSet() : _ignoreClashes(false) { }
334  virtual ~SearchSet() { clear(); }
335 
339  void add(const String& name, Archive *arch, int priority = 0, bool autoFree = true);
340 
344  void addDirectory(const String &name, const Path &directory, int priority = 0, int depth = 1, bool flat = false);
345 
349  void addDirectory(const String &name, const FSNode &directory, int priority = 0, int depth = 1, bool flat = false);
350 
354  void addDirectory(const Path &directory, int priority = 0, int depth = 1, bool flat = false);
355  void addDirectory(const FSNode &directory, int priority = 0, int depth = 1, bool flat = false);
356 
377  void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority = 0, int depth = 1, bool flat = false) {
378  addSubDirectoriesMatching(directory, caselessName, true, priority, depth, flat);
379  }
380 
399  void addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority = 0, int depth = 1, bool flat = false);
400 
404  void remove(const String& name);
405 
409  bool hasArchive(const String &name) const;
410 
414  Archive *getArchive(const String &name) const;
415 
419  virtual void clear();
420 
424  void setPriority(const String& name, int priority);
425 
426  bool hasFile(const Path &path) const override;
427  bool isPathDirectory(const Path &path) const override;
428  int listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents = false) const override;
429  int listMatchingMembers(ArchiveMemberDetailsList &list, const Path &pattern, bool matchPathComponents = false) const;
430  int listMembers(ArchiveMemberList &list) const override;
431 
432  const ArchiveMemberPtr getMember(const Path &path) const override;
433 
434  const ArchiveMemberPtr getMember(const Path &path, Archive **container) const;
435 
440  SeekableReadStream *createReadStreamForMember(const Path &path) const override;
441 
446  SeekableReadStream *createReadStreamForMemberAltStream(const Path &path, AltStreamType altStreamType) const override;
447 
451  SeekableReadStream *createReadStreamForMemberNext(const Path &path, const Archive *starting) const override;
452 
457  void setIgnoreClashes(bool ignoreClashes) { _ignoreClashes = ignoreClashes; }
458 };
459 
460 
461 class SearchManager : public Singleton<SearchManager>, public SearchSet {
462 public:
463 
468  virtual void clear();
469 
470 private:
471  friend class Singleton<SingletonBaseType>;
472  SearchManager();
473 };
474 
476 #define SearchMan Common::SearchManager::instance()
477 
480 } // namespace Common
481 
482 #endif
virtual SeekableReadStream * createReadStreamForMemberNext(const Path &path, const Archive *starting) const
Definition: archive.h:201
Definition: str.h:59
Path normalize() const
Definition: error.h:84
In find(In first, In last, const T &v)
Definition: algorithm.h:168
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:457
Definition: hashmap.h:85
List< ArchiveMemberDetails > ArchiveMemberDetailsList
Definition: archive.h:95
Definition: ustr.h:57
Definition: archive.h:312
virtual String getName() const =0
Definition: archive.h:68
Definition: algorithm.h:29
Definition: fs.h:69
Definition: archive.h:461
SharedPtr< ArchiveMember > ArchiveMemberPtr
Definition: archive.h:57
Definition: list_intern.h:48
Definition: list_intern.h:51
Definition: archive.h:88
Definition: archive.h:224
void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority=0, int depth=1, bool flat=false)
Definition: archive.h:377
Definition: singleton.h:42
List< ArchiveMemberPtr > ArchiveMemberList
Definition: archive.h:58