OVR_File.h
Go to the documentation of this file.
00001 /************************************************************************************
00002 
00003 PublicHeader:   Kernel
00004 Filename    :   OVR_File.h
00005 Content     :   Header for all internal file management - functions and structures
00006                 to be inherited by OS specific subclasses.
00007 Created     :   September 19, 2012
00008 Notes       : 
00009 
00010 Notes       :   errno may not be preserved across use of BaseFile member functions
00011             :   Directories cannot be deleted while files opened from them are in use
00012                 (For the GetFullName function)
00013 
00014 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
00015 
00016 Use of this software is subject to the terms of the Oculus license
00017 agreement provided at the time of installation or download, or which
00018 otherwise accompanies this software in either electronic or hard copy form.
00019 
00020 ************************************************************************************/
00021 
00022 #ifndef OVR_File_h
00023 #define OVR_File_h
00024 
00025 #include "OVR_RefCount.h"
00026 #include "OVR_Std.h"
00027 #include "OVR_Alg.h"
00028 
00029 #include <stdio.h>
00030 #include "OVR_String.h"
00031 
00032 namespace OVR {
00033 
00034 // ***** Declared classes
00035 class   FileConstants;
00036 class   File;
00037 class   DelegatedFile;
00038 class   BufferedFile;
00039 
00040 
00041 // ***** Flags for File & Directory accesses
00042 
00043 class FileConstants
00044 {
00045 public:
00046 
00047     // *** File open flags
00048     enum OpenFlags
00049     {
00050         Open_Read       = 1,
00051         Open_Write      = 2,
00052         Open_ReadWrite  = 3,
00053 
00054         // Opens file and truncates it to zero length
00055         // - file must have write permission
00056         // - when used with Create, it opens an existing 
00057         //   file and empties it or creates a new file
00058         Open_Truncate   = 4,
00059 
00060         // Creates and opens new file 
00061         // - does not erase contents if file already
00062         //   exists unless combined with Truncate
00063         Open_Create     = 8,
00064 
00065          // Returns an error value if the file already exists
00066         Open_CreateOnly = 24,
00067 
00068         // Open file with buffering
00069         Open_Buffered    = 32
00070     };
00071 
00072     // *** File Mode flags
00073     enum Modes
00074     {
00075         Mode_Read       = 0444,
00076         Mode_Write      = 0222,
00077         Mode_Execute    = 0111,
00078 
00079         Mode_ReadWrite  = 0666
00080     };
00081 
00082     // *** Seek operations
00083     enum SeekOps
00084     {
00085         Seek_Set        = 0,
00086         Seek_Cur        = 1,
00087         Seek_End        = 2
00088     };
00089 
00090     // *** Errors
00091     enum Errors
00092     {
00093         Error_FileNotFound  = 0x1001,
00094         Error_Access        = 0x1002,
00095         Error_IOError       = 0x1003,
00096         Error_DiskFull      = 0x1004
00097     };
00098 };
00099 
00100 
00101 //-----------------------------------------------------------------------------------
00102 // ***** File Class
00103 
00104 // The pure virtual base random-access file
00105 // This is a base class to all files
00106 
00107 class File : public RefCountBase<File>, public FileConstants
00108 {   
00109 public:
00110     File() { }
00111     // ** Location Information
00112 
00113     // Returns a file name path relative to the 'reference' directory
00114     // This is often a path that was used to create a file
00115     // (this is not a global path, global path can be obtained with help of directory)
00116     virtual const char* GetFilePath() = 0;
00117                                                                                         
00118 
00119     // ** File Information
00120 
00121     // Return 1 if file's usable (open)
00122     virtual bool        IsValid() = 0;
00123     // Return 1 if file's writable, otherwise 0                                         
00124     virtual bool        IsWritable() = 0;
00125                                                                                         
00126     // Return position
00127     virtual int         Tell() = 0;
00128     virtual SInt64      LTell() = 0;
00129     
00130     // File size                                                                        
00131     virtual int         GetLength() = 0;
00132     virtual SInt64      LGetLength() = 0;
00133                                                                                         
00134     // Returns file stats                                                               
00135     // 0 for failure                                                                    
00136     //virtual bool      Stat(FileStats *pfs) = 0;
00137                                                                                         
00138     // Return errno-based error code                                                    
00139     // Useful if any other function failed                                              
00140     virtual int         GetErrorCode() = 0;
00141                                                                                         
00142                                                                                         
00143     // ** Stream implementation & I/O
00144 
00145     // Blocking write, will write in the given number of bytes to the stream
00146     // Returns : -1 for error
00147     //           Otherwise number of bytes read 
00148     virtual int         Write(const UByte *pbufer, int numBytes) = 0;
00149     // Blocking read, will read in the given number of bytes or less from the stream
00150     // Returns : -1 for error
00151     //           Otherwise number of bytes read,
00152     //           if 0 or < numBytes, no more bytes available; end of file or the other side of stream is closed
00153     virtual int         Read(UByte *pbufer, int numBytes) = 0;
00154 
00155     // Skips (ignores) a given # of bytes
00156     // Same return values as Read
00157     virtual int         SkipBytes(int numBytes) = 0;
00158         
00159     // Returns the number of bytes available to read from a stream without blocking
00160     // For a file, this should generally be number of bytes to the end
00161     virtual int         BytesAvailable() = 0;
00162 
00163     // Causes any implementation's buffered data to be delivered to destination
00164     // Return 0 for error
00165     virtual bool        Flush() = 0;
00166                                                                                             
00167 
00168     // Need to provide a more optimized implementation that doe snot necessarily involve a lot of seeking
00169     inline bool         IsEOF() { return !BytesAvailable(); }
00170     
00171 
00172     // Seeking                                                                              
00173     // Returns new position, -1 for error                                                   
00174     virtual int         Seek(int offset, int origin=Seek_Set) = 0;
00175     virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set) = 0;
00176     // Seek simplification
00177     int                 SeekToBegin()           {return Seek(0); }
00178     int                 SeekToEnd()             {return Seek(0,Seek_End); }
00179     int                 Skip(int numBytes)     {return Seek(numBytes,Seek_Cur); }
00180                         
00181 
00182     // Appends other file data from a stream
00183     // Return -1 for error, else # of bytes written
00184     virtual int         CopyFromStream(File *pstream, int byteSize) = 0;
00185 
00186     // Closes the file
00187     // After close, file cannot be accessed 
00188     virtual bool        Close() = 0;
00189 
00190 
00191     // ***** Inlines for convenient primitive type serialization
00192 
00193     // Read/Write helpers
00194 private:
00195     UInt64  PRead64()           { UInt64 v = 0; Read((UByte*)&v, 8); return v; }
00196     UInt32  PRead32()           { UInt32 v = 0; Read((UByte*)&v, 4); return v; }
00197     UInt16  PRead16()           { UInt16 v = 0; Read((UByte*)&v, 2); return v; }
00198     UByte   PRead8()            { UByte  v = 0; Read((UByte*)&v, 1); return v; }
00199     void    PWrite64(UInt64 v)  { Write((UByte*)&v, 8); }
00200     void    PWrite32(UInt32 v)  { Write((UByte*)&v, 4); }
00201     void    PWrite16(UInt16 v)  { Write((UByte*)&v, 2); }
00202     void    PWrite8(UByte v)    { Write((UByte*)&v, 1); }
00203 
00204 public:
00205 
00206     // Writing primitive types - Little Endian
00207     inline void    WriteUByte(UByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
00208     inline void    WriteSByte(SByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
00209     inline void    WriteUInt8(UByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
00210     inline void    WriteSInt8(SByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
00211     inline void    WriteUInt16(UInt16 v)       { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v));   }
00212     inline void    WriteSInt16(SInt16 v)       { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v));   }
00213     inline void    WriteUInt32(UInt32 v)       { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v));   }
00214     inline void    WriteSInt32(SInt32 v)       { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v));   }
00215     inline void    WriteUInt64(UInt64 v)       { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v));   }
00216     inline void    WriteSInt64(SInt64 v)       { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v));   }
00217     inline void    WriteFloat(float v)         { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 4); } 
00218     inline void    WriteDouble(double v)       { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 8); }
00219     // Writing primitive types - Big Endian
00220     inline void    WriteUByteBE(UByte v)       { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
00221     inline void    WriteSByteBE(SByte v)       { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
00222     inline void    WriteUInt8BE(UInt16 v)      { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
00223     inline void    WriteSInt8BE(SInt16 v)      { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
00224     inline void    WriteUInt16BE(UInt16 v)     { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v));   }
00225     inline void    WriteSInt16BE(UInt16 v)     { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v));   }
00226     inline void    WriteUInt32BE(UInt32 v)     { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v));   }
00227     inline void    WriteSInt32BE(UInt32 v)     { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v));   }
00228     inline void    WriteUInt64BE(UInt64 v)     { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v));   }
00229     inline void    WriteSInt64BE(UInt64 v)     { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v));   }
00230     inline void    WriteFloatBE(float v)       { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 4); }
00231     inline void    WriteDoubleBE(double v)     { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 8); }
00232         
00233     // Reading primitive types - Little Endian
00234     inline UByte   ReadUByte()                 { return (UByte)Alg::ByteUtil::LEToSystem(PRead8());    }
00235     inline SByte   ReadSByte()                 { return (SByte)Alg::ByteUtil::LEToSystem(PRead8());    }
00236     inline UByte   ReadUInt8()                 { return (UByte)Alg::ByteUtil::LEToSystem(PRead8());    }
00237     inline SByte   ReadSInt8()                 { return (SByte)Alg::ByteUtil::LEToSystem(PRead8());    }
00238     inline UInt16  ReadUInt16()                { return (UInt16)Alg::ByteUtil::LEToSystem(PRead16());  }
00239     inline SInt16  ReadSInt16()                { return (SInt16)Alg::ByteUtil::LEToSystem(PRead16());  }
00240     inline UInt32  ReadUInt32()                { return (UInt32)Alg::ByteUtil::LEToSystem(PRead32());  }
00241     inline SInt32  ReadSInt32()                { return (SInt32)Alg::ByteUtil::LEToSystem(PRead32());  }
00242     inline UInt64  ReadUInt64()                { return (UInt64)Alg::ByteUtil::LEToSystem(PRead64());  }
00243     inline SInt64  ReadSInt64()                { return (SInt64)Alg::ByteUtil::LEToSystem(PRead64());  }
00244     inline float   ReadFloat()                 { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::LEToSystem(v); }
00245     inline double  ReadDouble()                { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::LEToSystem(v); }
00246     // Reading primitive types - Big Endian
00247     inline UByte   ReadUByteBE()               { return (UByte)Alg::ByteUtil::BEToSystem(PRead8());    }
00248     inline SByte   ReadSByteBE()               { return (SByte)Alg::ByteUtil::BEToSystem(PRead8());    }
00249     inline UByte   ReadUInt8BE()               { return (UByte)Alg::ByteUtil::BEToSystem(PRead8());    }
00250     inline SByte   ReadSInt8BE()               { return (SByte)Alg::ByteUtil::BEToSystem(PRead8());    }
00251     inline UInt16  ReadUInt16BE()              { return (UInt16)Alg::ByteUtil::BEToSystem(PRead16());  }
00252     inline SInt16  ReadSInt16BE()              { return (SInt16)Alg::ByteUtil::BEToSystem(PRead16());  }
00253     inline UInt32  ReadUInt32BE()              { return (UInt32)Alg::ByteUtil::BEToSystem(PRead32());  }
00254     inline SInt32  ReadSInt32BE()              { return (SInt32)Alg::ByteUtil::BEToSystem(PRead32());  }
00255     inline UInt64  ReadUInt64BE()              { return (UInt64)Alg::ByteUtil::BEToSystem(PRead64());  }
00256     inline SInt64  ReadSInt64BE()              { return (SInt64)Alg::ByteUtil::BEToSystem(PRead64());  }
00257     inline float   ReadFloatBE()               { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::BEToSystem(v); }
00258     inline double  ReadDoubleBE()              { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::BEToSystem(v); }
00259 };
00260 
00261 
00262 // *** Delegated File
00263 
00264 class DelegatedFile : public File
00265 {
00266 protected:
00267     // Delegating file pointer
00268     Ptr<File>     pFile;
00269 
00270     // Hidden default constructor
00271     DelegatedFile() : pFile(0)                             { }
00272     DelegatedFile(const DelegatedFile &source) : File()    { OVR_UNUSED(source); }
00273 public:
00274     // Constructors
00275     DelegatedFile(File *pfile) : pFile(pfile)     { }
00276 
00277     // ** Location Information  
00278     virtual const char* GetFilePath()                               { return pFile->GetFilePath(); }    
00279 
00280     // ** File Information                                                      
00281     virtual bool        IsValid()                                   { return pFile && pFile->IsValid(); }   
00282     virtual bool        IsWritable()                                { return pFile->IsWritable(); }
00283 //  virtual bool        IsRecoverable()                             { return pFile->IsRecoverable(); }          
00284                                                                     
00285     virtual int         Tell()                                      { return pFile->Tell(); }
00286     virtual SInt64      LTell()                                     { return pFile->LTell(); }
00287     
00288     virtual int         GetLength()                                 { return pFile->GetLength(); }
00289     virtual SInt64      LGetLength()                                { return pFile->LGetLength(); }
00290     
00291     //virtual bool      Stat(FileStats *pfs)                        { return pFile->Stat(pfs); }
00292     
00293     virtual int         GetErrorCode()                              { return pFile->GetErrorCode(); }
00294     
00295     // ** Stream implementation & I/O
00296     virtual int         Write(const UByte *pbuffer, int numBytes)   { return pFile->Write(pbuffer,numBytes); }  
00297     virtual int         Read(UByte *pbuffer, int numBytes)          { return pFile->Read(pbuffer,numBytes); }   
00298     
00299     virtual int         SkipBytes(int numBytes)                     { return pFile->SkipBytes(numBytes); }      
00300     
00301     virtual int         BytesAvailable()                            { return pFile->BytesAvailable(); } 
00302     
00303     virtual bool        Flush()                                     { return pFile->Flush(); }
00304                                                                     
00305     // Seeking                                                      
00306     virtual int         Seek(int offset, int origin=Seek_Set)       { return pFile->Seek(offset,origin); }
00307     virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set)   { return pFile->LSeek(offset,origin); }
00308 
00309     virtual int         CopyFromStream(File *pstream, int byteSize) { return pFile->CopyFromStream(pstream,byteSize); }
00310                         
00311     // Closing the file 
00312     virtual bool        Close()                                     { return pFile->Close(); }    
00313 };
00314 
00315 
00316 //-----------------------------------------------------------------------------------
00317 // ***** Buffered File
00318 
00319 // This file class adds buffering to an existing file
00320 // Buffered file never fails by itself; if there's not
00321 // enough memory for buffer, no buffer's used
00322 
00323 class BufferedFile : public DelegatedFile
00324 {   
00325 protected:  
00326     enum BufferModeType
00327     {
00328         NoBuffer,
00329         ReadBuffer,
00330         WriteBuffer
00331     };
00332 
00333     // Buffer & the mode it's in
00334     UByte*          pBuffer;
00335     BufferModeType  BufferMode;
00336     // Position in buffer
00337     unsigned        Pos;
00338     // Data in buffer if reading
00339     unsigned        DataSize;
00340     // Underlying file position 
00341     UInt64          FilePos;
00342 
00343     // Initializes buffering to a certain mode
00344     bool    SetBufferMode(BufferModeType mode);
00345     // Flushes buffer
00346     // WriteBuffer - write data to disk, ReadBuffer - reset buffer & fix file position  
00347     void    FlushBuffer();
00348     // Loads data into ReadBuffer
00349     // WARNING: Right now LoadBuffer() assumes the buffer's empty
00350     void    LoadBuffer();
00351 
00352     // Hidden constructor
00353     BufferedFile();
00354     inline BufferedFile(const BufferedFile &source) : DelegatedFile() { OVR_UNUSED(source); }
00355 public:
00356 
00357     // Constructor
00358     // - takes another file as source
00359     BufferedFile(File *pfile);
00360     ~BufferedFile();
00361     
00362     
00363     // ** Overridden functions
00364 
00365     // We override all the functions that can possibly
00366     // require buffer mode switch, flush, or extra calculations
00367     virtual int         Tell();
00368     virtual SInt64      LTell();
00369 
00370     virtual int         GetLength();
00371     virtual SInt64      LGetLength();
00372 
00373 //  virtual bool        Stat(GFileStats *pfs);  
00374 
00375     virtual int         Write(const UByte *pbufer, int numBytes);
00376     virtual int         Read(UByte *pbufer, int numBytes);
00377 
00378     virtual int         SkipBytes(int numBytes);
00379 
00380     virtual int         BytesAvailable();
00381 
00382     virtual bool        Flush();
00383 
00384     virtual int         Seek(int offset, int origin=Seek_Set);
00385     virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set);
00386 
00387     virtual int         CopyFromStream(File *pstream, int byteSize);
00388     
00389     virtual bool        Close();    
00390 };                          
00391 
00392 
00393 //-----------------------------------------------------------------------------------
00394 // ***** Memory File
00395 
00396 class MemoryFile : public File
00397 {
00398 public:
00399 
00400     const char* GetFilePath()       { return FilePath.ToCStr(); }
00401 
00402     bool        IsValid()           { return Valid; }
00403     bool        IsWritable()        { return false; }
00404 
00405     bool        Flush()             { return true; }
00406     int         GetErrorCode()      { return 0; }
00407 
00408     int         Tell()              { return FileIndex; }
00409     SInt64      LTell()             { return (SInt64) FileIndex; }
00410 
00411     int         GetLength()         { return FileSize; }
00412     SInt64      LGetLength()        { return (SInt64) FileSize; }
00413 
00414     bool        Close()
00415     {
00416         Valid = false;
00417         return false;
00418     }
00419 
00420     int         CopyFromStream(File *pstream, int byteSize)
00421     {   OVR_UNUSED2(pstream, byteSize);
00422         return 0;
00423     }
00424 
00425     int         Write(const UByte *pbuffer, int numBytes)
00426     {   OVR_UNUSED2(pbuffer, numBytes);
00427         return 0;
00428     }
00429 
00430     int         Read(UByte *pbufer, int numBytes)
00431     {
00432         if (FileIndex + numBytes > FileSize)
00433         {
00434             numBytes = FileSize - FileIndex;
00435         }
00436 
00437         if (numBytes > 0)
00438         {
00439             ::memcpy (pbufer, &FileData [FileIndex], numBytes);
00440 
00441             FileIndex += numBytes;
00442         }
00443 
00444         return numBytes;
00445     }
00446 
00447     int         SkipBytes(int numBytes)
00448     {
00449         if (FileIndex + numBytes > FileSize)
00450         {
00451             numBytes = FileSize - FileIndex;
00452         }
00453 
00454         FileIndex += numBytes;
00455 
00456         return numBytes;
00457     }
00458 
00459     int         BytesAvailable()
00460     {
00461         return (FileSize - FileIndex);
00462     }
00463 
00464     int         Seek(int offset, int origin = Seek_Set)
00465     {
00466         switch (origin)
00467         {
00468         case Seek_Set : FileIndex  = offset;               break;
00469         case Seek_Cur : FileIndex += offset;               break;
00470         case Seek_End : FileIndex  = FileSize - offset;  break;
00471         }
00472 
00473         return FileIndex;
00474     }
00475 
00476     SInt64      LSeek(SInt64 offset, int origin = Seek_Set)
00477     {
00478         return (SInt64) Seek((int) offset, origin);
00479     }
00480 
00481 public:
00482 
00483     MemoryFile (const String& fileName, const UByte *pBuffer, int buffSize)
00484         : FilePath(fileName)
00485     {
00486         FileData  = pBuffer;
00487         FileSize  = buffSize;
00488         FileIndex = 0;
00489         Valid     = (!fileName.IsEmpty() && pBuffer && buffSize > 0) ? true : false;
00490     }
00491 
00492     // pfileName should be encoded as UTF-8 to support international file names.
00493     MemoryFile (const char* pfileName, const UByte *pBuffer, int buffSize)
00494         : FilePath(pfileName)
00495     {
00496         FileData  = pBuffer;
00497         FileSize  = buffSize;
00498         FileIndex = 0;
00499         Valid     = (pfileName && pBuffer && buffSize > 0) ? true : false;
00500     }
00501 private:
00502 
00503     String       FilePath;
00504     const UByte *FileData;
00505     int          FileSize;
00506     int          FileIndex;
00507     bool         Valid;
00508 };
00509 
00510 
00511 // ***** Global path helpers
00512 
00513 // Find trailing short filename in a path.
00514 const char* OVR_CDECL GetShortFilename(const char* purl);
00515 
00516 } // OVR
00517 
00518 #endif


oculus_sdk
Author(s):
autogenerated on Mon Oct 6 2014 03:01:18