gwnavruntime/kernel/SF_File.h Source File

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