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
34namespace Common {
35
46class ArchiveMember;
47class FSNode;
48class SeekableReadStream;
49
50enum class AltStreamType {
51 Invalid,
52
53 MacFinderInfo,
54 MacResourceFork,
55};
56
69public:
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
106class Archive;
107
118public:
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;
126 SeekableReadStream *createReadStreamForAltStream(AltStreamType altStreamType) const override;
127 bool isDirectory() const override;
128 void listChildren(ArchiveMemberList &childList, const char *pattern) const override;
129
130private:
131 const Archive &_parent;
132 const Common::Path _path;
133};
134
135
141class Archive {
142public:
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
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
225private:
226 void prepareMaps() const;
227
228 mutable bool _mapsAreReady;
231 mutable AllfileMap _directoryMap, _fileMap;
232};
233
234class MemcachingCaseInsensitiveArchive;
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.
243public:
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
252private:
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
288public:
289 MemcachingCaseInsensitiveArchive(uint32 maxStronglyCachedSize = 512) : _maxStronglyCachedSize(maxStronglyCachedSize) {}
291 SeekableReadStream *createReadStreamForMemberAltStream(const Path &path, Common::AltStreamType altStreamType) const override;
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
300private:
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
318 mutable HashMap<CacheKey, SharedArchiveContents, CacheKey_Hash, CacheKey_EqualTo> _cache;
319 uint32 _maxStronglyCachedSize;
320};
321
330class SearchSet : public Archive {
331 struct Node {
332 int _priority;
333 String _name;
334 Archive *_arc;
335 bool _autoFree;
336 Node(int priority, const String &name, Archive *arc, bool autoFree)
337 : _priority(priority), _name(name), _arc(arc), _autoFree(autoFree) {
338 }
339 };
341 ArchiveNodeList _list;
342
343 ArchiveNodeList::iterator find(const String &name);
345
346 void insert(const Node& node);
347
348 bool _ignoreClashes;
349
350public:
351 SearchSet() : _ignoreClashes(false) { }
352 virtual ~SearchSet() { clear(); }
353
354 char getPathSeparator() const override { return '/'; }
355
359 void add(const String& name, Archive *arch, int priority = 0, bool autoFree = true);
360
364 void addDirectory(const String &name, const Path &directory, int priority = 0, int depth = 1, bool flat = false);
365
369 void addDirectory(const String &name, const FSNode &directory, int priority = 0, int depth = 1, bool flat = false);
370
374 void addDirectory(const Path &directory, int priority = 0, int depth = 1, bool flat = false);
375 void addDirectory(const FSNode &directory, int priority = 0, int depth = 1, bool flat = false);
376
397 void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority = 0, int depth = 1, bool flat = false) {
398 addSubDirectoriesMatching(directory, caselessName, true, priority, depth, flat);
399 }
400
419 void addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority = 0, int depth = 1, bool flat = false);
420
424 void remove(const String& name);
425
429 bool hasArchive(const String &name) const;
430
434 Archive *getArchive(const String &name) const;
435
439 virtual void clear();
440
444 void setPriority(const String& name, int priority);
445
446 bool hasFile(const Path &path) const override;
447 bool isPathDirectory(const Path &path) const override;
448 int listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents = false) const override;
449 int listMatchingMembers(ArchiveMemberDetailsList &list, const Path &pattern, bool matchPathComponents = false) const;
450 int listMembers(ArchiveMemberList &list) const override;
451
452 const ArchiveMemberPtr getMember(const Path &path) const override;
453
454 const ArchiveMemberPtr getMember(const Path &path, Archive **container) const;
455
461
466 SeekableReadStream *createReadStreamForMemberAltStream(const Path &path, AltStreamType altStreamType) const override;
467
471 SeekableReadStream *createReadStreamForMemberNext(const Path &path, const Archive *starting) const override;
472
477 void setIgnoreClashes(bool ignoreClashes) { _ignoreClashes = ignoreClashes; }
478
479 bool getChildren(const Common::Path &path, Common::Array<Common::String> &list, ListMode mode = kListDirectoriesOnly, bool hidden = true) const override;
480};
481
482
483class SearchManager : public Singleton<SearchManager>, public SearchSet {
484public:
485
490 void clear() override;
491
492private:
493 friend class Singleton<SingletonBaseType>;
495};
496
498#define SearchMan Common::SearchManager::instance()
499
502} // namespace Common
503
504#endif
Definition: archive.h:141
virtual bool hasFile(const Path &path) const =0
virtual SeekableReadStream * createReadStreamForMember(const Path &path) const =0
virtual int listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents=false) const
virtual const ArchiveMemberPtr getMember(const Path &path) const =0
virtual char getPathSeparator() const
virtual SeekableReadStream * createReadStreamForMemberAltStream(const Path &path, AltStreamType altStreamType) const
virtual bool isPathDirectory(const Path &path) const
Common::Error dumpArchive(const Path &destPath)
virtual int listMembers(ArchiveMemberList &list) const =0
virtual SeekableReadStream * createReadStreamForMemberNext(const Path &path, const Archive *starting) const
Definition: archive.h:203
Definition: archive.h:68
virtual Path getPathInArchive() const =0
virtual bool isDirectory() const
virtual SeekableReadStream * createReadStreamForAltStream(AltStreamType altStreamType) const =0
virtual U32String getDisplayName() const
virtual SeekableReadStream * createReadStream() const =0
virtual void listChildren(ArchiveMemberList &childList, const char *pattern=nullptr) const
virtual String getFileName() const =0
virtual String getName() const =0
virtual bool isInMacArchive() const
Definition: error.h:81
Definition: fs.h:69
Definition: archive.h:117
void listChildren(ArchiveMemberList &childList, const char *pattern) const override
String getFileName() const override
bool isDirectory() const override
GenericArchiveMember(const Common::Path &path, const Archive &parent)
SeekableReadStream * createReadStreamForAltStream(AltStreamType altStreamType) const override
GenericArchiveMember(const Common::String &pathStr, const Archive &parent)
String getName() const override
Path getPathInArchive() const override
SeekableReadStream * createReadStream() const override
Definition: hashmap.h:85
Definition: list.h:44
SeekableReadStream * createReadStreamForMember(const Path &path) const override
SeekableReadStream * createReadStreamForMemberAltStream(const Path &path, Common::AltStreamType altStreamType) const override
Definition: path.h:52
Path normalize() const
Definition: archive.h:483
void clear() override
Definition: archive.h:330
SeekableReadStream * createReadStreamForMember(const Path &path) const override
SeekableReadStream * createReadStreamForMemberNext(const Path &path, const Archive *starting) const override
void addDirectory(const String &name, const FSNode &directory, int priority=0, int depth=1, bool flat=false)
void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority=0, int depth=1, bool flat=false)
Definition: archive.h:397
void addDirectory(const Path &directory, int priority=0, int depth=1, bool flat=false)
SeekableReadStream * createReadStreamForMemberAltStream(const Path &path, AltStreamType altStreamType) const override
bool hasFile(const Path &path) const override
virtual void clear()
void setPriority(const String &name, int priority)
int listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents=false) const override
void addDirectory(const String &name, const Path &directory, int priority=0, int depth=1, bool flat=false)
const ArchiveMemberPtr getMember(const Path &path) const override
void addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority=0, int depth=1, bool flat=false)
bool isPathDirectory(const Path &path) const override
int listMembers(ArchiveMemberList &list) const override
char getPathSeparator() const override
Definition: archive.h:354
void add(const String &name, Archive *arch, int priority=0, bool autoFree=true)
void remove(const String &name)
void setIgnoreClashes(bool ignoreClashes)
Definition: archive.h:477
bool hasArchive(const String &name) const
Archive * getArchive(const String &name) const
Definition: stream.h:745
Definition: archive.h:242
Definition: singleton.h:42
Definition: str.h:59
Definition: ustr.h:57
In find(In first, In last, const T &v)
Definition: algorithm.h:225
List< ArchiveMemberPtr > ArchiveMemberList
Definition: archive.h:58
SharedPtr< ArchiveMember > ArchiveMemberPtr
Definition: archive.h:57
List< ArchiveMemberDetails > ArchiveMemberDetailsList
Definition: archive.h:95
Definition: algorithm.h:29
Definition: archive.h:88
Definition: archive.h:100
Definition: ptr.h:564
Definition: list_intern.h:108
Definition: list_intern.h:54