/
abstractfile.h
346 lines (290 loc) · 10.5 KB
/
abstractfile.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
/**
* @file abstractfile.h
*
* Abstract base for all classes which represent opened files.
*
* @ingroup fs
*
* @author Copyright © 2003-2012 Jaakko Keränen <jaakko.keranen@iki.fi>
* @author Copyright © 2005-2012 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/
#ifndef LIBDENG_FILESYS_ABSTRACTFILE_H
#define LIBDENG_FILESYS_ABSTRACTFILE_H
#ifdef __cplusplus
extern "C" {
#endif
// File types.
/// @todo Refactor away.
typedef enum {
FT_GENERICFILE,
FT_ZIPFILE,
FT_WADFILE,
FT_LUMPFILE,
FILETYPE_COUNT
} filetype_t;
#define VALID_FILETYPE(v) ((v) >= FT_GENERICFILE && (v) < FILETYPE_COUNT)
#ifdef __cplusplus
} // extern "C"
#endif
#ifdef __cplusplus
#include <de/str.h>
#include "dfile.h"
#include "lumpinfo.h"
namespace de {
class LumpIndex;
class PathDirectoryNode;
/**
* Abstract File. Abstract File is a core component of the filesystem
* intended for use as the base for all types of (pseudo-)file resources.
*
* @ingroup fs
*/
class AbstractFile
{
public:
/// Categorization flags.
enum Flag
{
/// Flagged as having been loaded during the game startup process.
Startup = 0x1,
/// Flagged as a non-original game resource.
Custom = 0x2,
/// All resources are by default flagged as "custom".
DefaultFlags = Custom
};
Q_DECLARE_FLAGS(Flags, Flag)
private:
AbstractFile();
public:
/**
* @param type File type identifier.
* @param path Path to this file in the virtual file system.
* @param file Handle to the file. Ownership of the handle is given to this instance.
* @param info Lump info descriptor for the file. A copy is made.
*/
AbstractFile(filetype_t _type, char const* _path, DFile& file, LumpInfo const& _info);
/**
* Release all memory acquired for objects linked with this resource.
*/
virtual ~AbstractFile();
/**
* @return Type of this resource @see filetype_t
*/
filetype_t type() const;
/// @return Absolute (i.e., resolved but possibly virtual/mapped) path to this resource.
ddstring_t const* path() const;
/// @return @c true= this file is contained within another.
bool isContained() const;
/// @return The file instance which contains this.
AbstractFile& container() const;
/// @return Load order index for this resource.
uint loadOrderIndex() const;
/**
* @return Immutable copy of the info descriptor for this resource.
*/
LumpInfo const& info() const;
// Convenient lookup method for when only the last-modified property is needed from info().
/// @return "Last modified" timestamp of the resource.
inline uint lastModified() const {
return info().lastModified;
}
// Convenient lookup method for when only the size property is needed from info().
/// @return Size of the uncompressed resource.
inline uint size() const {
return info().size;
}
// Convenient lookup method for when only the is-compressed property is needed from info().
/// @return Size of the uncompressed resource.
inline bool isCompressed() const {
return info().isCompressed();
}
/// @return @c true if the resource is marked "startup".
bool hasStartup() const;
/// Mark this resource as "startup".
AbstractFile& setStartup(bool yes);
/// @return @c true if the resource is marked "custom".
bool hasCustom() const;
/// Mark this resource as "custom".
AbstractFile& setCustom(bool yes);
DFile& handle();
/*
* Access interfaces:
*
* @todo Extract these into one or more interface classes/subcomponents.
*/
/**
* @return @c true= @a lumpIdx is a valid logical index for a lump in this file.
*
* @attention This default implementation assumes there is only one lump in
* the file. Subclasses with multiple lumps should override this function
* accordingly.
*/
virtual bool isValidIndex(int lumpIdx) { return lumpIdx == 0; }
/**
* @return Logical index of the last lump in this file's directory or @c -1 if empty.
*
* @attention This default implementation assumes there is only one lump in
* the file. Subclasses with multiple lumps should override this function
* accordingly.
*/
virtual int lastIndex() { return 0; }
/**
* @return Number of "lumps" contained within this resource.
*
* @attention This default implementation assumes there is only one lump in
* the file. Subclasses with multiple lumps should override this function
* accordingly.
*/
virtual int lumpCount() { return 1; }
/**
* Retrieve the directory node for a lump contained by this file.
*
* @param lumpIdx Logical index for the lump in this file's directory.
*
* @return Directory node for this lump.
*
* @throws de::Error If @a lumpIdx is not valid.
*/
virtual PathDirectoryNode const& lumpDirectoryNode(int lumpIdx) = 0;
/**
* Compose the absolute VFS path to a lump contained by this file.
*
* @note Always returns a valid string object. If @a lumpIdx is not valid a
* zero-length string is returned.
*
* @param lumpIdx Logical index for the lump.
* @param delimiter Delimit directory separators using this character.
*
* @return String containing the absolute path.
*/
virtual AutoStr* composeLumpPath(int lumpIdx, char delimiter = '/') = 0;
/**
* Retrieve the LumpInfo descriptor for a lump contained by this file.
*
* @param lumpIdx Logical index for the lump in this file's directory.
*
* @return Lump info descriptor for the lump.
*
* @throws de::Error If @a lumpIdx is not valid.
*
* @attention This default implementation assumes there is only one lump in
* the file and therefore its decriptor is that of the file itself. Subclasses
* with multiple lumps should override this function accordingly.
*/
virtual LumpInfo const& lumpInfo(int /*lumpIdx*/) { return info(); }
/**
* Lookup the uncompressed size of lump contained by this file.
*
* @param lumpIdx Logical index for the lump in this file's directory.
*
* @return Size of the lump in bytes.
*
* @note This method is intended mainly for convenience. @see lumpInfo() for
* a better method of looking up multiple @ref LumpInfo properties.
*
* @attention This default implementation assumes there is only one lump in
* the file and therefore its decriptor is that of the file itself. Subclasses
* with multiple lumps should override this function accordingly.
*
*/
virtual size_t lumpSize(int lumpIdx) = 0;
/**
* Read the data associated with lump @a lumpIdx into @a buffer.
*
* @param lumpIdx Lump index associated with the data to be read.
* @param buffer Buffer to read into. Must be at least large enough to
* contain the whole lump.
* @param tryCache @c true= try the lump cache first.
*
* @return Number of bytes read.
*
* @see lumpSize() or lumpInfo() to determine the size of buffer needed.
*/
virtual size_t readLump(int lumpIdx, uint8_t* buffer, bool tryCache = true) = 0;
/**
* Read a subsection of the data associated with lump @a lumpIdx into @a buffer.
*
* @param lumpIdx Lump index associated with the data to be read.
* @param buffer Buffer to read into. Must be at least @a length bytes.
* @param startOffset Offset from the beginning of the lump to start reading.
* @param length Number of bytes to read.
* @param tryCache @c true= try the lump cache first.
*
* @return Number of bytes read.
*/
virtual size_t readLump(int lumpIdx, uint8_t* buffer, size_t startOffset, size_t length,
bool tryCache = true) = 0;
/*
* Lump caching interface:
*/
/**
* Read the data associated with lump @a lumpIdx into the cache.
*
* @param lumpIdx Lump index associated with the data to be cached.
*
* @return Pointer to the cached copy of the associated data.
*/
virtual uint8_t const* cacheLump(int lumpIdx) = 0;
/**
* Remove a lock on a cached data lump.
*
* @param lumpIdx Lump index associated with the cached data to be changed.
*
* @return This instance.
*/
virtual AbstractFile& unlockLump(int lumpIdx) = 0;
/**
* Clear any cached data for lump @a lumpIdx from the lump cache.
*
* @param lumpIdx Lump index associated with the cached data to be cleared.
* @param retCleared If not @c NULL write @c true to this address if data was
* present and subsequently cleared from the cache.
*
* @return This instance.
*/
//virtual AbstractFile& clearCachedLump(int lumpIdx, bool* retCleared = 0) = 0;
/**
* Purge the lump cache, clearing all cached data lumps.
*
* @return This instance.
*/
//virtual AbstractFile& clearLumpCache() = 0;
protected:
/// File stream handle/wrapper.
DFile* file;
private:
/// @see filetype_t
filetype_t type_;
/// Categorization flags.
Flags flags;
/// Absolute variable-length path in the vfs.
ddstring_t path_;
/// Info descriptor (file metadata).
LumpInfo info_;
/// Load order depth index.
uint order;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractFile::Flags)
} // namespace de
extern "C" {
#endif // __cplusplus
struct abstractfile_s; // The abstractfile instance (opaque)
typedef struct abstractfile_s AbstractFile;
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* LIBDENG_FILESYS_ABSTRACTFILE_H */