17
#include <boost/tr1/memory.hpp>
28
* Struct for wrapping the basic <code>FILE</code> locked functions for
29
* reading and writing defined in <code>stdio.h</code>.
35
static inline void configure(FILE *file_ptr)
39
static inline size_t fwrite(const void *ptr, size_t size, size_t count, FILE *file_ptr)
41
return ::fwrite(ptr, size, count, file_ptr);
44
static inline size_t fread(void * ptr, size_t size, size_t count, FILE *file_ptr)
46
return ::fread(ptr, size, count, file_ptr);
49
static inline int fgetc(FILE *file_ptr)
51
return ::fgetc(file_ptr);
54
static inline int fputc(int c, FILE *file_ptr)
56
return ::fputc(c, file_ptr);
62
* Struct for wrapping the basic <code>FILE</code> unlocked functions for
63
* reading and writing defined in <code>stdio_exts.h</code>.
70
static inline void configure(FILE *file_ptr)
72
__fsetlocking(file_ptr, FSETLOCKING_BYCALLER);
75
static inline size_t fwrite(const void *ptr, size_t size, size_t count, FILE *file_ptr)
77
return ::fwrite_unlocked(ptr, size, count, file_ptr);
80
static inline size_t fread(void * ptr, size_t size, size_t count, FILE *file_ptr)
82
return ::fread_unlocked(ptr, size, count, file_ptr);
85
static inline int fgetc(FILE *file_ptr)
87
return ::fgetc_unlocked(file_ptr);
90
static inline int fputc(int c, FILE *file_ptr)
92
return ::fputc_unlocked(c, file_ptr);
99
* This is a wrapper class for the <code>FILE</code> functions that
100
* provides all the functionality to handle files safely. It is defined
101
* as a template in order to allow to use either the locked or the
102
* unlocked API, by means of the structs <code>LockedAccess</code> and
103
* <code>UnlockedAccess</code>. The unlocked API is not thread-safe,
104
* but it provides faster file operations.
107
* @see UnlockedAccess
109
template<class IO> class BaseFile
113
* Safe pointer to this class.
115
typedef tr1::shared_ptr< BaseFile<IO> > Ptr;
119
* Initialized the internal file pointer to <code>NULL</code>.
127
* Returns <code>true</code> if the given file exists. This
128
* is a wrapper of the system funcion <code>stat</code>.
130
static bool Exists(const char *file_name)
132
struct stat file_stat;
133
return (stat(file_name, &file_stat) == 0);
137
* Opens a file with a specific access mode.
138
* @param file_name Path name of the file to open.
139
* @param access Access mode as a <code>fopen</code>
140
* compatible format string.
141
* @return <code>true</code> if successful.
143
bool Open(const char *file_name, const char *access)
145
assert(file_ptr == NULL);
147
if((file_ptr = fopen(file_name, access)) == NULL) return false;
149
IO::configure(file_ptr);
155
* Opens a file with a specific access mode.
156
* @param file_name Path name of the file to open.
157
* @param access Access mode as a <code>fopen</code>
158
* compatible format string.
159
* @return <code>true</code> if successful.
161
bool Open(const string& file_name, const char *access)
163
return Open(file_name.c_str(), access);
167
* Opens a file with a specific access mode given an already
168
* opened <code>File</code> object. The descriptor of the opened
169
* file is duplicated and re-opened with the access mode given.
170
* @param file Opened file.
171
* @param access Access mode as a <code>fopen</code>
172
* compatible format string.
173
* @return <code>true</code> if successful.
175
template<class IO2> bool Open(const BaseFile<IO2>& file, const char *access)
177
assert((file_ptr == NULL) && file.IsValid());
181
if((new_fd = dup(file.GetDescriptor())) < 0) return false;
183
if((file_ptr = fdopen(new_fd, access)) == NULL) {
188
IO::configure(file_ptr);
195
* Calls the function <code>Open</code> with the <code>"rb"
196
* </code> access mode (reading).
198
bool OpenForReading(const char *file_name)
200
return Open(file_name, "rb");
204
* Calls the function <code>Open</code> with the <code>"rb"
205
* </code> access mode (reading).
207
bool OpenForReading(const string& file_name)
209
return Open(file_name.c_str(), "rb");
213
* Calls the function <code>Open</code> with the <code>"rb"
214
* </code> access mode (reading).
216
template<class IO2> bool OpenForReading(const BaseFile<IO2>& file)
218
return Open(file, "rb");
222
* Calls the function <code>Open</code> with the <code>"wb"
223
* </code> access mode (writing).
225
bool OpenForWriting(const char *file_name)
227
return Open(file_name, "wb");
231
* Calls the function <code>Open</code> with the <code>"wb"
232
* </code> access mode (writing).
234
bool OpenForWriting(const string& file_name)
236
return Open(file_name.c_str(), "wb");
240
* Calls the function <code>Open</code> with the <code>"wb"
241
* </code> access mode (writing).
243
template<class IO2> bool OpenForWriting(const BaseFile<IO2>& file)
245
return Open(file, "wb");
249
* Changes the current position of the file.
250
* @param offset Offset to add to the current position.
251
* @param origin Origin to use for the change (<code>
252
* SEEK_SET</code> by default).
253
* @return <code>true</code> if successful.
255
bool Seek(int offset, int origin = SEEK_SET) const
257
assert(file_ptr != NULL);
259
return !fseek(file_ptr, offset, origin);
267
if(file_ptr != NULL) {
274
* Returns the current file position.
276
uint64_t GetOffset() const
278
assert(file_ptr != NULL);
280
return ftell(file_ptr);
284
* Returns the EOF status (<code>feof</code>) of the file.
288
assert(file_ptr != NULL);
290
return feof(file_ptr);
294
* Returns the file descriptor.
296
int GetDescriptor() const
298
assert(file_ptr != NULL);
300
return fileno(file_ptr);
304
* Return the current size of the file, without modifying
307
uint64_t GetSize() const
309
assert(file_ptr != NULL);
311
uint64_t offset = GetOffset();
313
uint64_t final_offset = GetOffset();
314
Seek(offset, SEEK_SET);
320
* Reads a byte from the file.
324
assert(file_ptr != NULL);
326
return IO::fgetc(file_ptr);
330
* Reads a value from the file.
331
* @param value Pointer to the value where to store.
332
* @param num_bytes Number of bytes to read (by default,
333
* the size of the value).
334
* @return <code>true</code> if successful.
336
template<typename T> bool Read(T *value, int num_bytes = sizeof(T)) const
338
assert(file_ptr != NULL);
340
return (IO::fread((void *) value, num_bytes, 1, file_ptr) == 1);
344
* Reads a value from the file in reverse order.
345
* @param value Pointer to the value where to store.
346
* @param num_bytes Number of bytes to read (by default,
347
* the size of the value).
348
* @return <code>true</code> if successful.
350
template<typename T> bool ReadReverse(T *value, int num_bytes = sizeof(T)) const
352
assert(file_ptr != NULL);
354
for (char *ptr = ((char *) value) + (num_bytes - 1); num_bytes-- > 0; ptr--)
355
if (IO::fread((void *) ptr, 1, 1, file_ptr) != 1) return false;
361
* Writes a byte to the file.
363
int WriteByte(int c) const
365
assert(file_ptr != NULL);
367
return IO::fputc(c, file_ptr);
371
* Writes a value to the file.
372
* @param value Pointer to the value.
373
* @param num_bytes Number of bytes to write (by default,
374
* the size of the value).
375
* @return <code>true</code> if successful.
377
template<typename T> bool Write(T *value, int num_bytes = sizeof(T)) const
379
assert(file_ptr != NULL);
381
return (IO::fwrite((void *) value, num_bytes, 1, file_ptr) == 1);
385
* Writes a value to the file in reverse order.
386
* @param value Pointer to the value.
387
* @param num_bytes Number of bytes to write (by default,
388
* the size of the value).
389
* @return <code>true</code> if successful.
391
template<typename T> bool WriteReverse(T *value, int num_bytes = sizeof(T)) const
393
assert(file_ptr != NULL);
395
for (char *ptr = ((char *) value) + (num_bytes - 1); num_bytes-- > 0; ptr--)
396
if (IO::fwrite((void *) ptr, 1, 1, file_ptr) != 1) return false;
402
* Returns <code>true</code> if the file pointer is not
407
return (file_ptr != NULL);
411
* Returns <code>true</code> if the file pointer is not
414
operator bool() const
416
return (file_ptr != NULL);
420
* The destructor closes the file.
436
* Specialization of the class <code>BaseFile</code> with
442
typedef BaseFile<LockedAccess> File;
446
* Specialization of the class <code>BaseFile</code> with
450
* @see UnlockedAccess
452
#ifndef _NO_FAST_FILE
453
typedef BaseFile<UnlockedAccess> FastFile;
458
#endif /* _DATA_FILE_H_ */