OVR_File.h 21 KB

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