rev |
line source |
nuclear@0
|
1 /************************************************************************************
|
nuclear@0
|
2
|
nuclear@0
|
3 PublicHeader: Kernel
|
nuclear@0
|
4 Filename : OVR_File.h
|
nuclear@0
|
5 Content : Header for all internal file management - functions and structures
|
nuclear@0
|
6 to be inherited by OS specific subclasses.
|
nuclear@0
|
7 Created : September 19, 2012
|
nuclear@0
|
8 Notes :
|
nuclear@0
|
9
|
nuclear@0
|
10 Notes : errno may not be preserved across use of BaseFile member functions
|
nuclear@0
|
11 : Directories cannot be deleted while files opened from them are in use
|
nuclear@0
|
12 (For the GetFullName function)
|
nuclear@0
|
13
|
nuclear@0
|
14 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
|
nuclear@0
|
15
|
nuclear@0
|
16 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
|
nuclear@0
|
17 you may not use the Oculus VR Rift SDK except in compliance with the License,
|
nuclear@0
|
18 which is provided at the time of installation or download, or which
|
nuclear@0
|
19 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@0
|
20
|
nuclear@0
|
21 You may obtain a copy of the License at
|
nuclear@0
|
22
|
nuclear@0
|
23 http://www.oculusvr.com/licenses/LICENSE-3.2
|
nuclear@0
|
24
|
nuclear@0
|
25 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
|
nuclear@0
|
26 distributed under the License is distributed on an "AS IS" BASIS,
|
nuclear@0
|
27 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
nuclear@0
|
28 See the License for the specific language governing permissions and
|
nuclear@0
|
29 limitations under the License.
|
nuclear@0
|
30
|
nuclear@0
|
31 ************************************************************************************/
|
nuclear@0
|
32
|
nuclear@0
|
33 #ifndef OVR_File_h
|
nuclear@0
|
34 #define OVR_File_h
|
nuclear@0
|
35
|
nuclear@0
|
36 #include "OVR_RefCount.h"
|
nuclear@0
|
37 #include "OVR_Std.h"
|
nuclear@0
|
38 #include "OVR_Alg.h"
|
nuclear@0
|
39
|
nuclear@0
|
40 #include <stdio.h>
|
nuclear@0
|
41 #include "OVR_String.h"
|
nuclear@0
|
42
|
nuclear@0
|
43 namespace OVR {
|
nuclear@0
|
44
|
nuclear@0
|
45 // ***** Declared classes
|
nuclear@0
|
46 class FileConstants;
|
nuclear@0
|
47 class File;
|
nuclear@0
|
48 class DelegatedFile;
|
nuclear@0
|
49 class BufferedFile;
|
nuclear@0
|
50
|
nuclear@0
|
51
|
nuclear@0
|
52 // ***** Flags for File & Directory accesses
|
nuclear@0
|
53
|
nuclear@0
|
54 class FileConstants
|
nuclear@0
|
55 {
|
nuclear@0
|
56 public:
|
nuclear@0
|
57
|
nuclear@0
|
58 // *** File open flags
|
nuclear@0
|
59 enum OpenFlags
|
nuclear@0
|
60 {
|
nuclear@0
|
61 Open_Read = 1,
|
nuclear@0
|
62 Open_Write = 2,
|
nuclear@0
|
63 Open_ReadWrite = 3,
|
nuclear@0
|
64
|
nuclear@0
|
65 // Opens file and truncates it to zero length
|
nuclear@0
|
66 // - file must have write permission
|
nuclear@0
|
67 // - when used with Create, it opens an existing
|
nuclear@0
|
68 // file and empties it or creates a new file
|
nuclear@0
|
69 Open_Truncate = 4,
|
nuclear@0
|
70
|
nuclear@0
|
71 // Creates and opens new file
|
nuclear@0
|
72 // - does not erase contents if file already
|
nuclear@0
|
73 // exists unless combined with Truncate
|
nuclear@0
|
74 Open_Create = 8,
|
nuclear@0
|
75
|
nuclear@0
|
76 // Returns an error value if the file already exists
|
nuclear@0
|
77 Open_CreateOnly = 24,
|
nuclear@0
|
78
|
nuclear@0
|
79 // Open file with buffering
|
nuclear@0
|
80 Open_Buffered = 32
|
nuclear@0
|
81 };
|
nuclear@0
|
82
|
nuclear@0
|
83 // *** File Mode flags
|
nuclear@0
|
84 enum Modes
|
nuclear@0
|
85 {
|
nuclear@0
|
86 Mode_Read = 0444,
|
nuclear@0
|
87 Mode_Write = 0222,
|
nuclear@0
|
88 Mode_Execute = 0111,
|
nuclear@0
|
89
|
nuclear@0
|
90 Mode_ReadWrite = 0666
|
nuclear@0
|
91 };
|
nuclear@0
|
92
|
nuclear@0
|
93 // *** Seek operations
|
nuclear@0
|
94 enum SeekOps
|
nuclear@0
|
95 {
|
nuclear@0
|
96 Seek_Set = 0,
|
nuclear@0
|
97 Seek_Cur = 1,
|
nuclear@0
|
98 Seek_End = 2
|
nuclear@0
|
99 };
|
nuclear@0
|
100
|
nuclear@0
|
101 // *** Errors
|
nuclear@0
|
102 enum Errors
|
nuclear@0
|
103 {
|
nuclear@0
|
104 Error_FileNotFound = 0x1001,
|
nuclear@0
|
105 Error_Access = 0x1002,
|
nuclear@0
|
106 Error_IOError = 0x1003,
|
nuclear@0
|
107 Error_DiskFull = 0x1004
|
nuclear@0
|
108 };
|
nuclear@0
|
109 };
|
nuclear@0
|
110
|
nuclear@0
|
111
|
nuclear@0
|
112 //-----------------------------------------------------------------------------------
|
nuclear@0
|
113 // ***** File Class
|
nuclear@0
|
114
|
nuclear@0
|
115 // The pure virtual base random-access file
|
nuclear@0
|
116 // This is a base class to all files
|
nuclear@0
|
117
|
nuclear@0
|
118 class File : public RefCountBase<File>, public FileConstants
|
nuclear@0
|
119 {
|
nuclear@0
|
120 public:
|
nuclear@0
|
121 File() { }
|
nuclear@0
|
122 // ** Location Information
|
nuclear@0
|
123
|
nuclear@0
|
124 // Returns a file name path relative to the 'reference' directory
|
nuclear@0
|
125 // This is often a path that was used to create a file
|
nuclear@0
|
126 // (this is not a global path, global path can be obtained with help of directory)
|
nuclear@0
|
127 virtual const char* GetFilePath() = 0;
|
nuclear@0
|
128
|
nuclear@0
|
129
|
nuclear@0
|
130 // ** File Information
|
nuclear@0
|
131
|
nuclear@0
|
132 // Return 1 if file's usable (open)
|
nuclear@0
|
133 virtual bool IsValid() = 0;
|
nuclear@0
|
134 // Return 1 if file's writable, otherwise 0
|
nuclear@0
|
135 virtual bool IsWritable() = 0;
|
nuclear@0
|
136
|
nuclear@0
|
137 // Return position
|
nuclear@0
|
138 virtual int Tell() = 0;
|
nuclear@0
|
139 virtual int64_t LTell() = 0;
|
nuclear@0
|
140
|
nuclear@0
|
141 // File size
|
nuclear@0
|
142 virtual int GetLength() = 0;
|
nuclear@0
|
143 virtual int64_t LGetLength() = 0;
|
nuclear@0
|
144
|
nuclear@0
|
145 // Returns file stats
|
nuclear@0
|
146 // 0 for failure
|
nuclear@0
|
147 //virtual bool Stat(FileStats *pfs) = 0;
|
nuclear@0
|
148
|
nuclear@0
|
149 // Return errno-based error code
|
nuclear@0
|
150 // Useful if any other function failed
|
nuclear@0
|
151 virtual int GetErrorCode() = 0;
|
nuclear@0
|
152
|
nuclear@0
|
153
|
nuclear@0
|
154 // ** Stream implementation & I/O
|
nuclear@0
|
155
|
nuclear@0
|
156 // Blocking write, will write in the given number of bytes to the stream
|
nuclear@0
|
157 // Returns : -1 for error
|
nuclear@0
|
158 // Otherwise number of bytes read
|
nuclear@0
|
159 virtual int Write(const uint8_t *pbufer, int numBytes) = 0;
|
nuclear@0
|
160 // Blocking read, will read in the given number of bytes or less from the stream
|
nuclear@0
|
161 // Returns : -1 for error
|
nuclear@0
|
162 // Otherwise number of bytes read,
|
nuclear@0
|
163 // if 0 or < numBytes, no more bytes available; end of file or the other side of stream is closed
|
nuclear@0
|
164 virtual int Read(uint8_t *pbufer, int numBytes) = 0;
|
nuclear@0
|
165
|
nuclear@0
|
166 // Skips (ignores) a given # of bytes
|
nuclear@0
|
167 // Same return values as Read
|
nuclear@0
|
168 virtual int SkipBytes(int numBytes) = 0;
|
nuclear@0
|
169
|
nuclear@0
|
170 // Returns the number of bytes available to read from a stream without blocking
|
nuclear@0
|
171 // For a file, this should generally be number of bytes to the end
|
nuclear@0
|
172 virtual int BytesAvailable() = 0;
|
nuclear@0
|
173
|
nuclear@0
|
174 // Causes any implementation's buffered data to be delivered to destination
|
nuclear@0
|
175 // Return 0 for error
|
nuclear@0
|
176 virtual bool Flush() = 0;
|
nuclear@0
|
177
|
nuclear@0
|
178
|
nuclear@0
|
179 // Need to provide a more optimized implementation that doe snot necessarily involve a lot of seeking
|
nuclear@0
|
180 inline bool IsEOF() { return !BytesAvailable(); }
|
nuclear@0
|
181
|
nuclear@0
|
182
|
nuclear@0
|
183 // Seeking
|
nuclear@0
|
184 // Returns new position, -1 for error
|
nuclear@0
|
185 virtual int Seek(int offset, int origin=Seek_Set) = 0;
|
nuclear@0
|
186 virtual int64_t LSeek(int64_t offset, int origin=Seek_Set) = 0;
|
nuclear@0
|
187 // Seek simplification
|
nuclear@0
|
188 int SeekToBegin() {return Seek(0); }
|
nuclear@0
|
189 int SeekToEnd() {return Seek(0,Seek_End); }
|
nuclear@0
|
190 int Skip(int numBytes) {return Seek(numBytes,Seek_Cur); }
|
nuclear@0
|
191
|
nuclear@0
|
192
|
nuclear@0
|
193 // Appends other file data from a stream
|
nuclear@0
|
194 // Return -1 for error, else # of bytes written
|
nuclear@0
|
195 virtual int CopyFromStream(File *pstream, int byteSize) = 0;
|
nuclear@0
|
196
|
nuclear@0
|
197 // Closes the file
|
nuclear@0
|
198 // After close, file cannot be accessed
|
nuclear@0
|
199 virtual bool Close() = 0;
|
nuclear@0
|
200
|
nuclear@0
|
201
|
nuclear@0
|
202 // ***** Inlines for convenient primitive type serialization
|
nuclear@0
|
203
|
nuclear@0
|
204 // Read/Write helpers
|
nuclear@0
|
205 private:
|
nuclear@0
|
206 uint64_t PRead64() { uint64_t v = 0; Read((uint8_t*)&v, 8); return v; }
|
nuclear@0
|
207 uint32_t PRead32() { uint32_t v = 0; Read((uint8_t*)&v, 4); return v; }
|
nuclear@0
|
208 uint16_t PRead16() { uint16_t v = 0; Read((uint8_t*)&v, 2); return v; }
|
nuclear@0
|
209 uint8_t PRead8() { uint8_t v = 0; Read((uint8_t*)&v, 1); return v; }
|
nuclear@0
|
210 void PWrite64(uint64_t v) { Write((uint8_t*)&v, 8); }
|
nuclear@0
|
211 void PWrite32(uint32_t v) { Write((uint8_t*)&v, 4); }
|
nuclear@0
|
212 void PWrite16(uint16_t v) { Write((uint8_t*)&v, 2); }
|
nuclear@0
|
213 void PWrite8(uint8_t v) { Write((uint8_t*)&v, 1); }
|
nuclear@0
|
214
|
nuclear@0
|
215 public:
|
nuclear@0
|
216
|
nuclear@0
|
217 // Writing primitive types - Little Endian
|
nuclear@0
|
218 inline void WriteUByte(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); }
|
nuclear@0
|
219 inline void WriteSByte(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); }
|
nuclear@0
|
220 inline void WriteUInt8(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); }
|
nuclear@0
|
221 inline void WriteSInt8(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); }
|
nuclear@0
|
222 inline void WriteUInt16(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToLE(v)); }
|
nuclear@0
|
223 inline void WriteSInt16(int16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToLE(v)); }
|
nuclear@0
|
224 inline void WriteUInt32(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToLE(v)); }
|
nuclear@0
|
225 inline void WriteSInt32(int32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToLE(v)); }
|
nuclear@0
|
226 inline void WriteUInt64(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToLE(v)); }
|
nuclear@0
|
227 inline void WriteSInt64(int64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToLE(v)); }
|
nuclear@0
|
228 inline void WriteFloat(float v) { v = Alg::ByteUtil::SystemToLE(v); Write((uint8_t*)&v, 4); }
|
nuclear@0
|
229 inline void WriteDouble(double v) { v = Alg::ByteUtil::SystemToLE(v); Write((uint8_t*)&v, 8); }
|
nuclear@0
|
230 // Writing primitive types - Big Endian
|
nuclear@0
|
231 inline void WriteUByteBE(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); }
|
nuclear@0
|
232 inline void WriteSByteBE(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); }
|
nuclear@0
|
233 inline void WriteUInt8BE(uint16_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); }
|
nuclear@0
|
234 inline void WriteSInt8BE(int16_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); }
|
nuclear@0
|
235 inline void WriteUInt16BE(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToBE(v)); }
|
nuclear@0
|
236 inline void WriteSInt16BE(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToBE(v)); }
|
nuclear@0
|
237 inline void WriteUInt32BE(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToBE(v)); }
|
nuclear@0
|
238 inline void WriteSInt32BE(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToBE(v)); }
|
nuclear@0
|
239 inline void WriteUInt64BE(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToBE(v)); }
|
nuclear@0
|
240 inline void WriteSInt64BE(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToBE(v)); }
|
nuclear@0
|
241 inline void WriteFloatBE(float v) { v = Alg::ByteUtil::SystemToBE(v); Write((uint8_t*)&v, 4); }
|
nuclear@0
|
242 inline void WriteDoubleBE(double v) { v = Alg::ByteUtil::SystemToBE(v); Write((uint8_t*)&v, 8); }
|
nuclear@0
|
243
|
nuclear@0
|
244 // Reading primitive types - Little Endian
|
nuclear@0
|
245 inline uint8_t ReadUByte() { return (uint8_t)Alg::ByteUtil::LEToSystem(PRead8()); }
|
nuclear@0
|
246 inline int8_t ReadSByte() { return (int8_t)Alg::ByteUtil::LEToSystem(PRead8()); }
|
nuclear@0
|
247 inline uint8_t ReadUInt8() { return (uint8_t)Alg::ByteUtil::LEToSystem(PRead8()); }
|
nuclear@0
|
248 inline int8_t ReadSInt8() { return (int8_t)Alg::ByteUtil::LEToSystem(PRead8()); }
|
nuclear@0
|
249 inline uint16_t ReadUInt16() { return (uint16_t)Alg::ByteUtil::LEToSystem(PRead16()); }
|
nuclear@0
|
250 inline int16_t ReadSInt16() { return (int16_t)Alg::ByteUtil::LEToSystem(PRead16()); }
|
nuclear@0
|
251 inline uint32_t ReadUInt32() { return (uint32_t)Alg::ByteUtil::LEToSystem(PRead32()); }
|
nuclear@0
|
252 inline int32_t ReadSInt32() { return (int32_t)Alg::ByteUtil::LEToSystem(PRead32()); }
|
nuclear@0
|
253 inline uint64_t ReadUInt64() { return (uint64_t)Alg::ByteUtil::LEToSystem(PRead64()); }
|
nuclear@0
|
254 inline int64_t ReadSInt64() { return (int64_t)Alg::ByteUtil::LEToSystem(PRead64()); }
|
nuclear@0
|
255 inline float ReadFloat() { float v = 0.0f; Read((uint8_t*)&v, 4); return Alg::ByteUtil::LEToSystem(v); }
|
nuclear@0
|
256 inline double ReadDouble() { double v = 0.0; Read((uint8_t*)&v, 8); return Alg::ByteUtil::LEToSystem(v); }
|
nuclear@0
|
257 // Reading primitive types - Big Endian
|
nuclear@0
|
258 inline uint8_t ReadUByteBE() { return (uint8_t)Alg::ByteUtil::BEToSystem(PRead8()); }
|
nuclear@0
|
259 inline int8_t ReadSByteBE() { return (int8_t)Alg::ByteUtil::BEToSystem(PRead8()); }
|
nuclear@0
|
260 inline uint8_t ReadUInt8BE() { return (uint8_t)Alg::ByteUtil::BEToSystem(PRead8()); }
|
nuclear@0
|
261 inline int8_t ReadSInt8BE() { return (int8_t)Alg::ByteUtil::BEToSystem(PRead8()); }
|
nuclear@0
|
262 inline uint16_t ReadUInt16BE() { return (uint16_t)Alg::ByteUtil::BEToSystem(PRead16()); }
|
nuclear@0
|
263 inline int16_t ReadSInt16BE() { return (int16_t)Alg::ByteUtil::BEToSystem(PRead16()); }
|
nuclear@0
|
264 inline uint32_t ReadUInt32BE() { return (uint32_t)Alg::ByteUtil::BEToSystem(PRead32()); }
|
nuclear@0
|
265 inline int32_t ReadSInt32BE() { return (int32_t)Alg::ByteUtil::BEToSystem(PRead32()); }
|
nuclear@0
|
266 inline uint64_t ReadUInt64BE() { return (uint64_t)Alg::ByteUtil::BEToSystem(PRead64()); }
|
nuclear@0
|
267 inline int64_t ReadSInt64BE() { return (int64_t)Alg::ByteUtil::BEToSystem(PRead64()); }
|
nuclear@0
|
268 inline float ReadFloatBE() { float v = 0.0f; Read((uint8_t*)&v, 4); return Alg::ByteUtil::BEToSystem(v); }
|
nuclear@0
|
269 inline double ReadDoubleBE() { double v = 0.0; Read((uint8_t*)&v, 8); return Alg::ByteUtil::BEToSystem(v); }
|
nuclear@0
|
270 };
|
nuclear@0
|
271
|
nuclear@0
|
272
|
nuclear@0
|
273 // *** Delegated File
|
nuclear@0
|
274
|
nuclear@0
|
275 class DelegatedFile : public File
|
nuclear@0
|
276 {
|
nuclear@0
|
277 protected:
|
nuclear@0
|
278 // Delegating file pointer
|
nuclear@0
|
279 Ptr<File> pFile;
|
nuclear@0
|
280
|
nuclear@0
|
281 // Hidden default constructor
|
nuclear@0
|
282 DelegatedFile() : pFile(0) { }
|
nuclear@0
|
283 DelegatedFile(const DelegatedFile &source) : File() { OVR_UNUSED(source); }
|
nuclear@0
|
284 public:
|
nuclear@0
|
285 // Constructors
|
nuclear@0
|
286 DelegatedFile(File *pfile) : pFile(pfile) { }
|
nuclear@0
|
287
|
nuclear@0
|
288 // ** Location Information
|
nuclear@0
|
289 virtual const char* GetFilePath() { return pFile->GetFilePath(); }
|
nuclear@0
|
290
|
nuclear@0
|
291 // ** File Information
|
nuclear@0
|
292 virtual bool IsValid() { return pFile && pFile->IsValid(); }
|
nuclear@0
|
293 virtual bool IsWritable() { return pFile->IsWritable(); }
|
nuclear@0
|
294 // virtual bool IsRecoverable() { return pFile->IsRecoverable(); }
|
nuclear@0
|
295
|
nuclear@0
|
296 virtual int Tell() { return pFile->Tell(); }
|
nuclear@0
|
297 virtual int64_t LTell() { return pFile->LTell(); }
|
nuclear@0
|
298
|
nuclear@0
|
299 virtual int GetLength() { return pFile->GetLength(); }
|
nuclear@0
|
300 virtual int64_t LGetLength() { return pFile->LGetLength(); }
|
nuclear@0
|
301
|
nuclear@0
|
302 //virtual bool Stat(FileStats *pfs) { return pFile->Stat(pfs); }
|
nuclear@0
|
303
|
nuclear@0
|
304 virtual int GetErrorCode() { return pFile->GetErrorCode(); }
|
nuclear@0
|
305
|
nuclear@0
|
306 // ** Stream implementation & I/O
|
nuclear@0
|
307 virtual int Write(const uint8_t *pbuffer, int numBytes) { return pFile->Write(pbuffer,numBytes); }
|
nuclear@0
|
308 virtual int Read(uint8_t *pbuffer, int numBytes) { return pFile->Read(pbuffer,numBytes); }
|
nuclear@0
|
309
|
nuclear@0
|
310 virtual int SkipBytes(int numBytes) { return pFile->SkipBytes(numBytes); }
|
nuclear@0
|
311
|
nuclear@0
|
312 virtual int BytesAvailable() { return pFile->BytesAvailable(); }
|
nuclear@0
|
313
|
nuclear@0
|
314 virtual bool Flush() { return pFile->Flush(); }
|
nuclear@0
|
315
|
nuclear@0
|
316 // Seeking
|
nuclear@0
|
317 virtual int Seek(int offset, int origin=Seek_Set) { return pFile->Seek(offset,origin); }
|
nuclear@0
|
318 virtual int64_t LSeek(int64_t offset, int origin=Seek_Set) { return pFile->LSeek(offset,origin); }
|
nuclear@0
|
319
|
nuclear@0
|
320 virtual int CopyFromStream(File *pstream, int byteSize) { return pFile->CopyFromStream(pstream,byteSize); }
|
nuclear@0
|
321
|
nuclear@0
|
322 // Closing the file
|
nuclear@0
|
323 virtual bool Close() { return pFile->Close(); }
|
nuclear@0
|
324 };
|
nuclear@0
|
325
|
nuclear@0
|
326
|
nuclear@0
|
327 //-----------------------------------------------------------------------------------
|
nuclear@0
|
328 // ***** Buffered File
|
nuclear@0
|
329
|
nuclear@0
|
330 // This file class adds buffering to an existing file
|
nuclear@0
|
331 // Buffered file never fails by itself; if there's not
|
nuclear@0
|
332 // enough memory for buffer, no buffer's used
|
nuclear@0
|
333
|
nuclear@0
|
334 class BufferedFile : public DelegatedFile
|
nuclear@0
|
335 {
|
nuclear@0
|
336 protected:
|
nuclear@0
|
337 enum BufferModeType
|
nuclear@0
|
338 {
|
nuclear@0
|
339 NoBuffer,
|
nuclear@0
|
340 ReadBuffer,
|
nuclear@0
|
341 WriteBuffer
|
nuclear@0
|
342 };
|
nuclear@0
|
343
|
nuclear@0
|
344 // Buffer & the mode it's in
|
nuclear@0
|
345 uint8_t* pBuffer;
|
nuclear@0
|
346 BufferModeType BufferMode;
|
nuclear@0
|
347 // Position in buffer
|
nuclear@0
|
348 unsigned Pos;
|
nuclear@0
|
349 // Data in buffer if reading
|
nuclear@0
|
350 unsigned DataSize;
|
nuclear@0
|
351 // Underlying file position
|
nuclear@0
|
352 uint64_t FilePos;
|
nuclear@0
|
353
|
nuclear@0
|
354 // Initializes buffering to a certain mode
|
nuclear@0
|
355 bool SetBufferMode(BufferModeType mode);
|
nuclear@0
|
356 // Flushes buffer
|
nuclear@0
|
357 // WriteBuffer - write data to disk, ReadBuffer - reset buffer & fix file position
|
nuclear@0
|
358 void FlushBuffer();
|
nuclear@0
|
359 // Loads data into ReadBuffer
|
nuclear@0
|
360 // WARNING: Right now LoadBuffer() assumes the buffer's empty
|
nuclear@0
|
361 void LoadBuffer();
|
nuclear@0
|
362
|
nuclear@0
|
363 // Hidden constructor
|
nuclear@0
|
364 BufferedFile();
|
nuclear@0
|
365 BufferedFile(const BufferedFile &) : DelegatedFile(), pBuffer(NULL), BufferMode(NoBuffer), Pos(0), DataSize(0), FilePos(0) { }
|
nuclear@0
|
366
|
nuclear@0
|
367 public:
|
nuclear@0
|
368
|
nuclear@0
|
369 // Constructor
|
nuclear@0
|
370 // - takes another file as source
|
nuclear@0
|
371 BufferedFile(File *pfile);
|
nuclear@0
|
372 ~BufferedFile();
|
nuclear@0
|
373
|
nuclear@0
|
374
|
nuclear@0
|
375 // ** Overridden functions
|
nuclear@0
|
376
|
nuclear@0
|
377 // We override all the functions that can possibly
|
nuclear@0
|
378 // require buffer mode switch, flush, or extra calculations
|
nuclear@0
|
379 virtual int Tell();
|
nuclear@0
|
380 virtual int64_t LTell();
|
nuclear@0
|
381
|
nuclear@0
|
382 virtual int GetLength();
|
nuclear@0
|
383 virtual int64_t LGetLength();
|
nuclear@0
|
384
|
nuclear@0
|
385 // virtual bool Stat(GFileStats *pfs);
|
nuclear@0
|
386
|
nuclear@0
|
387 virtual int Write(const uint8_t *pbufer, int numBytes);
|
nuclear@0
|
388 virtual int Read(uint8_t *pbufer, int numBytes);
|
nuclear@0
|
389
|
nuclear@0
|
390 virtual int SkipBytes(int numBytes);
|
nuclear@0
|
391
|
nuclear@0
|
392 virtual int BytesAvailable();
|
nuclear@0
|
393
|
nuclear@0
|
394 virtual bool Flush();
|
nuclear@0
|
395
|
nuclear@0
|
396 virtual int Seek(int offset, int origin=Seek_Set);
|
nuclear@0
|
397 virtual int64_t LSeek(int64_t offset, int origin=Seek_Set);
|
nuclear@0
|
398
|
nuclear@0
|
399 virtual int CopyFromStream(File *pstream, int byteSize);
|
nuclear@0
|
400
|
nuclear@0
|
401 virtual bool Close();
|
nuclear@0
|
402 };
|
nuclear@0
|
403
|
nuclear@0
|
404
|
nuclear@0
|
405 //-----------------------------------------------------------------------------------
|
nuclear@0
|
406 // ***** Memory File
|
nuclear@0
|
407
|
nuclear@0
|
408 class MemoryFile : public File
|
nuclear@0
|
409 {
|
nuclear@0
|
410 public:
|
nuclear@0
|
411
|
nuclear@0
|
412 const char* GetFilePath() { return FilePath.ToCStr(); }
|
nuclear@0
|
413
|
nuclear@0
|
414 bool IsValid() { return Valid; }
|
nuclear@0
|
415 bool IsWritable() { return false; }
|
nuclear@0
|
416
|
nuclear@0
|
417 bool Flush() { return true; }
|
nuclear@0
|
418 int GetErrorCode() { return 0; }
|
nuclear@0
|
419
|
nuclear@0
|
420 int Tell() { return FileIndex; }
|
nuclear@0
|
421 int64_t LTell() { return (int64_t) FileIndex; }
|
nuclear@0
|
422
|
nuclear@0
|
423 int GetLength() { return FileSize; }
|
nuclear@0
|
424 int64_t LGetLength() { return (int64_t) FileSize; }
|
nuclear@0
|
425
|
nuclear@0
|
426 bool Close()
|
nuclear@0
|
427 {
|
nuclear@0
|
428 Valid = false;
|
nuclear@0
|
429 return false;
|
nuclear@0
|
430 }
|
nuclear@0
|
431
|
nuclear@0
|
432 int CopyFromStream(File *pstream, int byteSize)
|
nuclear@0
|
433 { OVR_UNUSED2(pstream, byteSize);
|
nuclear@0
|
434 return 0;
|
nuclear@0
|
435 }
|
nuclear@0
|
436
|
nuclear@0
|
437 int Write(const uint8_t *pbuffer, int numBytes)
|
nuclear@0
|
438 { OVR_UNUSED2(pbuffer, numBytes);
|
nuclear@0
|
439 return 0;
|
nuclear@0
|
440 }
|
nuclear@0
|
441
|
nuclear@0
|
442 int Read(uint8_t *pbufer, int numBytes)
|
nuclear@0
|
443 {
|
nuclear@0
|
444 if (FileIndex + numBytes > FileSize)
|
nuclear@0
|
445 {
|
nuclear@0
|
446 numBytes = FileSize - FileIndex;
|
nuclear@0
|
447 }
|
nuclear@0
|
448
|
nuclear@0
|
449 if (numBytes > 0)
|
nuclear@0
|
450 {
|
nuclear@0
|
451 ::memcpy (pbufer, &FileData [FileIndex], numBytes);
|
nuclear@0
|
452
|
nuclear@0
|
453 FileIndex += numBytes;
|
nuclear@0
|
454 }
|
nuclear@0
|
455
|
nuclear@0
|
456 return numBytes;
|
nuclear@0
|
457 }
|
nuclear@0
|
458
|
nuclear@0
|
459 int SkipBytes(int numBytes)
|
nuclear@0
|
460 {
|
nuclear@0
|
461 if (FileIndex + numBytes > FileSize)
|
nuclear@0
|
462 {
|
nuclear@0
|
463 numBytes = FileSize - FileIndex;
|
nuclear@0
|
464 }
|
nuclear@0
|
465
|
nuclear@0
|
466 FileIndex += numBytes;
|
nuclear@0
|
467
|
nuclear@0
|
468 return numBytes;
|
nuclear@0
|
469 }
|
nuclear@0
|
470
|
nuclear@0
|
471 int BytesAvailable()
|
nuclear@0
|
472 {
|
nuclear@0
|
473 return (FileSize - FileIndex);
|
nuclear@0
|
474 }
|
nuclear@0
|
475
|
nuclear@0
|
476 int Seek(int offset, int origin = Seek_Set)
|
nuclear@0
|
477 {
|
nuclear@0
|
478 switch (origin)
|
nuclear@0
|
479 {
|
nuclear@0
|
480 case Seek_Set : FileIndex = offset; break;
|
nuclear@0
|
481 case Seek_Cur : FileIndex += offset; break;
|
nuclear@0
|
482 case Seek_End : FileIndex = FileSize - offset; break;
|
nuclear@0
|
483 }
|
nuclear@0
|
484
|
nuclear@0
|
485 return FileIndex;
|
nuclear@0
|
486 }
|
nuclear@0
|
487
|
nuclear@0
|
488 int64_t LSeek(int64_t offset, int origin = Seek_Set)
|
nuclear@0
|
489 {
|
nuclear@0
|
490 return (int64_t) Seek((int) offset, origin);
|
nuclear@0
|
491 }
|
nuclear@0
|
492
|
nuclear@0
|
493 public:
|
nuclear@0
|
494
|
nuclear@0
|
495 MemoryFile (const String& fileName, const uint8_t *pBuffer, int buffSize)
|
nuclear@0
|
496 : FilePath(fileName)
|
nuclear@0
|
497 {
|
nuclear@0
|
498 FileData = pBuffer;
|
nuclear@0
|
499 FileSize = buffSize;
|
nuclear@0
|
500 FileIndex = 0;
|
nuclear@0
|
501 Valid = (!fileName.IsEmpty() && pBuffer && buffSize > 0) ? true : false;
|
nuclear@0
|
502 }
|
nuclear@0
|
503
|
nuclear@0
|
504 // pfileName should be encoded as UTF-8 to support international file names.
|
nuclear@0
|
505 MemoryFile (const char* pfileName, const uint8_t *pBuffer, int buffSize)
|
nuclear@0
|
506 : FilePath(pfileName)
|
nuclear@0
|
507 {
|
nuclear@0
|
508 FileData = pBuffer;
|
nuclear@0
|
509 FileSize = buffSize;
|
nuclear@0
|
510 FileIndex = 0;
|
nuclear@0
|
511 Valid = (pfileName && pBuffer && buffSize > 0) ? true : false;
|
nuclear@0
|
512 }
|
nuclear@0
|
513 private:
|
nuclear@0
|
514
|
nuclear@0
|
515 String FilePath;
|
nuclear@0
|
516 const uint8_t *FileData;
|
nuclear@0
|
517 int FileSize;
|
nuclear@0
|
518 int FileIndex;
|
nuclear@0
|
519 bool Valid;
|
nuclear@0
|
520 };
|
nuclear@0
|
521
|
nuclear@0
|
522
|
nuclear@0
|
523 // ***** Global path helpers
|
nuclear@0
|
524
|
nuclear@0
|
525 // Find trailing short filename in a path.
|
nuclear@0
|
526 const char* OVR_CDECL GetShortFilename(const char* purl);
|
nuclear@0
|
527
|
nuclear@0
|
528 } // OVR
|
nuclear@0
|
529
|
nuclear@0
|
530 #endif
|