/
file.h
343 lines (292 loc) · 9.34 KB
/
file.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
/*
* The Doomsday Engine Project -- libdeng2
*
* Copyright © 2009-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* LGPL: http://www.gnu.org/licenses/lgpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 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 Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/
#ifndef LIBDENG2_FILE_H
#define LIBDENG2_FILE_H
#include "../IIOStream"
#include "../String"
#include "../Time"
#include "../Record"
#include "../AccessorValue"
#include "../Audience"
#include "../Lockable"
#include <QFlags>
namespace de {
class FileSystem;
class Folder;
class Feed;
/**
* Base class for all files stored in the file system.
*
* All files are Lockable so that multiple threads can use them
* simultaneously. As a general rule, the user of a file does not need to
* lock the file manually; files will lock themselves as appropriate. A
* user may lock the file manually if long-term exclusive access is
* required.
*
* Implements the IIOStream interface to allow files to receive and send
* out a stream of bytes. The default implementation only throws an
* exception -- it is up to subclasses to implement the stream in the
* context of the concrete file class.
*
* Note that the constructor of File is protected: only subclasses can be
* instantiated.
*
* Subclasses have some special requirements for their destructors:
* - deindex() must be called in all subclass destructors so that the
* instances indexed under the subclasses' type are removed from the
* file system's index also.
* - The file must be automatically flushed before it gets destroyed
* (see flush()).
* - The deletion audience must be notified and @c audienceForDeletion
* must be cleared afterwards.
*
* @ingroup fs
*/
class DENG2_PUBLIC File : public Lockable, public IIOStream
{
public:
// Mode flags.
enum Flag
{
ReadOnly = 0,
Write = 0x1,
Truncate = 0x2
};
Q_DECLARE_FLAGS(Flags, Flag)
/**
* The file object is about to be deleted. This may be, e.g., due to pruning or
* because the parent is being deleted.
*
* @param file The file object being deleted.
*/
DENG2_DEFINE_AUDIENCE2(Deletion, void fileBeingDeleted(File const &file))
/**
* Stores the status of a file (size, time of last modification).
*/
class Status
{
public:
/// Type of file.
enum Type {
FILE = 0,
FOLDER = 1
};
public:
Status(dsize s = 0, Time const &modTime = Time())
: size(s), modifiedAt(modTime), _type(FILE) {}
Status(Type t, dsize s = 0, Time const &modTime = Time())
: size(s), modifiedAt(modTime), _type(t) {}
Type type() const { return _type; }
bool operator == (Status const &s) const {
return size == s.size && modifiedAt == s.modifiedAt;
}
bool operator != (Status const &s) const { return !(*this == s); }
public:
dsize size;
Time modifiedAt;
private:
Type _type;
};
/**
* Accesses the properties of a File. Allows using properties of a file
* (like its name, path or size) as a Value, for instance in script
* expressions.
*
* @ingroup fs
*/
class Accessor : public AccessorValue
{
public:
/// Property of the file to access.
enum Property {
NAME,
PATH,
TYPE,
SIZE,
MODIFIED_AT
};
public:
Accessor(File &owner, Property prop);
/// Update the text content of the accessor.
void update() const;
/// Returns a TextValue with the text content of the accessor,
/// except for the SIZE property, which is duplicated as a NumberValue.
Value *duplicateContent() const;
private:
File &_owner;
Property _prop;
};
public:
/**
* When destroyed, a file is automatically removed from its parent folder
* and deindexed from the file system.
*
* The source file of this file will be destroyed also.
*
* @note Subclasses must call deindex() in their destructors so that
* the instances indexed under the subclasses' type are removed
* from the index also. Flushing should also be done automatically
* as necessary in the subclass.
*/
virtual ~File();
/**
* Remove this file from its file system's index.
*/
virtual void deindex();
/**
* Commits any buffered changes to the content of the file. All subclasses
* of File must make sure they flush themselves right before they get deleted.
*/
virtual void flush();
/**
* Empties the contents of the file.
*/
virtual void clear();
/// Returns a reference to the application's file system.
static FileSystem &fileSystem();
/// Returns the name of the file.
String const &name() const;
/**
* Returns a textual description of the file, intended only for humans.
* This attempts to fully describe the file, taking into consideration
* the file's type and possible source.
*
* @return Full human-friendly description of the file.
*/
String description() const;
/**
* Returns a textual description of this file only. Subclasses must
* override this method to provide a description relevant to the
* subclass.
*
* @return Human-friendly description of this file only.
*/
virtual String describe() const;
/**
* Sets the parent folder of this file.
*/
void setParent(Folder *parent);
/**
* Returns the parent folder. May be NULL.
*/
Folder *parent() const;
/**
* Sets the origin Feed of the File. The origin feed is the feed that is able
* to singlehandedly decide whether the File needs to be pruned. Typically
* this is the Feed that generated the File.
*
* @note Folder instances should not have an origin feed as the folder may
* be shared by many feeds.
*
* @param feed The origin feed.
*/
void setOriginFeed(Feed *feed);
/**
* Returns the origin Feed of the File.
* @see setOriginFeed()
*/
Feed *originFeed() const;
/**
* Sets the source file of this file. The source is where this file is
* getting its data from. File interpreters use this to access their
* uninterpreted data. By default all files use themselves as the
* source, so there is always a valid source for every file. If another
* file is being used as the source, the source is not typically
* indexed to the file system.
*
* @param source Source file. The file takes ownership of @a source.
*/
void setSource(File *source);
/**
* Returns the source file.
*
* @return Source file. Always returns a valid pointer.
* @see setSource()
*/
File const *source() const;
/**
* Returns the source file.
*
* @return Source file. Always returns a valid pointer.
* @see setSource()
*/
File *source();
/**
* Updates the status of the file.
*
* @param status New status.
*/
virtual void setStatus(Status const &status);
/**
* Returns the status of the file.
*/
Status const &status() const;
/**
* Returns the size of the file.
*
* @return Size in bytes. If the file does not have a size (purely
* stream-based file), the size is zero.
*/
dsize size() const;
/**
* Forms the complete path of this file object.
*
* @return Path of the object. This is not a native path, but instead
* intended for de::FileSystem.
*/
String const path() const;
/**
* Returns the mode of the file.
*/
Flags const &mode() const;
/**
* Changes the mode of the file. For example, using
* <code>Write|Truncate</code> as the mode would empty the contents of
* the file and open it in writing mode.
*
* @param newMode Mode.
*/
virtual void setMode(Flags const &newMode);
/// Returns the file information (const).
Record const &info() const;
/// Returns the file information.
Record &info();
/**
* Makes sure that the file has write access.
*/
void verifyWriteAccess();
// Implements IIOStream.
IOStream &operator << (IByteArray const &bytes);
IIStream &operator >> (IByteArray &bytes);
IIStream const &operator >> (IByteArray &bytes) const;
// Standard casting methods.
DENG2_AS_IS_METHODS()
protected:
/**
* Constructs a new file. By default files are in read-only mode.
*
* @param name Name of the file.
*/
explicit File(String const &name = "");
private:
DENG2_PRIVATE(d)
};
Q_DECLARE_OPERATORS_FOR_FLAGS(File::Flags)
} // namespace de
#endif /* LIBDENG2_FILE_H */