ovr_sdk

view LibOVR/Src/Kernel/OVR_File.h @ 0:1b39a1b46319

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