oculus1
diff libovr/Src/Kernel/OVR_FileFILE.cpp @ 3:b069a5c27388
added a couple more stuff, fixed all the LibOVR line endings
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 15 Sep 2013 04:10:05 +0300 |
parents | e2f9e4603129 |
children |
line diff
1.1 --- a/libovr/Src/Kernel/OVR_FileFILE.cpp Sat Sep 14 17:51:03 2013 +0300 1.2 +++ b/libovr/Src/Kernel/OVR_FileFILE.cpp Sun Sep 15 04:10:05 2013 +0300 1.3 @@ -1,1 +1,583 @@ 1.4 -/************************************************************************** 1.5 1.6 Filename : OVR_FileFILE.cpp 1.7 Content : File wrapper class implementation (Win32) 1.8 1.9 Created : April 5, 1999 1.10 Authors : Michael Antonov 1.11 1.12 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. 1.13 1.14 Use of this software is subject to the terms of the Oculus license 1.15 agreement provided at the time of installation or download, or which 1.16 otherwise accompanies this software in either electronic or hard copy form. 1.17 1.18 **************************************************************************/ 1.19 1.20 #define GFILE_CXX 1.21 1.22 #include "OVR_Types.h" 1.23 #include "OVR_Log.h" 1.24 1.25 // Standard C library (Captain Obvious guarantees!) 1.26 #include <stdio.h> 1.27 #ifndef OVR_OS_WINCE 1.28 #include <sys/stat.h> 1.29 #endif 1.30 1.31 #include "OVR_SysFile.h" 1.32 1.33 #ifndef OVR_OS_WINCE 1.34 #include <errno.h> 1.35 #endif 1.36 1.37 namespace OVR { 1.38 1.39 // ***** File interface 1.40 1.41 // ***** FILEFile - C streams file 1.42 1.43 static int SFerror () 1.44 { 1.45 if (errno == ENOENT) 1.46 return FileConstants::Error_FileNotFound; 1.47 else if (errno == EACCES || errno == EPERM) 1.48 return FileConstants::Error_Access; 1.49 else if (errno == ENOSPC) 1.50 return FileConstants::Error_DiskFull; 1.51 else 1.52 return FileConstants::Error_IOError; 1.53 }; 1.54 1.55 #ifdef OVR_OS_WIN32 1.56 #include "windows.h" 1.57 // A simple helper class to disable/enable system error mode, if necessary 1.58 // Disabling happens conditionally only if a drive name is involved 1.59 class SysErrorModeDisabler 1.60 { 1.61 BOOL Disabled; 1.62 UINT OldMode; 1.63 public: 1.64 SysErrorModeDisabler(const char* pfileName) 1.65 { 1.66 if (pfileName && (pfileName[0]!=0) && pfileName[1]==':') 1.67 { 1.68 Disabled = 1; 1.69 OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS); 1.70 } 1.71 else 1.72 Disabled = 0; 1.73 } 1.74 1.75 ~SysErrorModeDisabler() 1.76 { 1.77 if (Disabled) ::SetErrorMode(OldMode); 1.78 } 1.79 }; 1.80 #else 1.81 class SysErrorModeDisabler 1.82 { 1.83 public: 1.84 SysErrorModeDisabler(const char* pfileName) { } 1.85 }; 1.86 #endif // OVR_OS_WIN32 1.87 1.88 1.89 // This macro enables verification of I/O results after seeks against a pre-loaded 1.90 // full file buffer copy. This is generally not necessary, but can been used to debug 1.91 // memory corruptions; we've seen this fail due to EAX2/DirectSound corrupting memory 1.92 // under FMOD with XP64 (32-bit) and Realtek HA Audio driver. 1.93 //#define GFILE_VERIFY_SEEK_ERRORS 1.94 1.95 1.96 // This is the simplest possible file implementation, it wraps around the descriptor 1.97 // This file is delegated to by SysFile. 1.98 1.99 class FILEFile : public File 1.100 { 1.101 protected: 1.102 1.103 // Allocated filename 1.104 String FileName; 1.105 1.106 // File handle & open mode 1.107 bool Opened; 1.108 FILE* fs; 1.109 int OpenFlags; 1.110 // Error code for last request 1.111 int ErrorCode; 1.112 1.113 int LastOp; 1.114 1.115 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.116 UByte* pFileTestBuffer; 1.117 unsigned FileTestLength; 1.118 unsigned TestPos; // File pointer position during tests. 1.119 #endif 1.120 1.121 public: 1.122 1.123 FILEFile() 1.124 { 1.125 Opened = 0; FileName = ""; 1.126 1.127 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.128 pFileTestBuffer =0; 1.129 FileTestLength =0; 1.130 TestPos =0; 1.131 #endif 1.132 } 1.133 // Initialize file by opening it 1.134 FILEFile(const String& fileName, int flags, int Mode); 1.135 // The 'pfileName' should be encoded as UTF-8 to support international file names. 1.136 FILEFile(const char* pfileName, int flags, int Mode); 1.137 1.138 ~FILEFile() 1.139 { 1.140 if (Opened) 1.141 Close(); 1.142 } 1.143 1.144 virtual const char* GetFilePath(); 1.145 1.146 // ** File Information 1.147 virtual bool IsValid(); 1.148 virtual bool IsWritable(); 1.149 1.150 // Return position / file size 1.151 virtual int Tell(); 1.152 virtual SInt64 LTell(); 1.153 virtual int GetLength(); 1.154 virtual SInt64 LGetLength(); 1.155 1.156 // virtual bool Stat(FileStats *pfs); 1.157 virtual int GetErrorCode(); 1.158 1.159 // ** Stream implementation & I/O 1.160 virtual int Write(const UByte *pbuffer, int numBytes); 1.161 virtual int Read(UByte *pbuffer, int numBytes); 1.162 virtual int SkipBytes(int numBytes); 1.163 virtual int BytesAvailable(); 1.164 virtual bool Flush(); 1.165 virtual int Seek(int offset, int origin); 1.166 virtual SInt64 LSeek(SInt64 offset, int origin); 1.167 1.168 virtual int CopyFromStream(File *pStream, int byteSize); 1.169 virtual bool Close(); 1.170 private: 1.171 void init(); 1.172 }; 1.173 1.174 1.175 // Initialize file by opening it 1.176 FILEFile::FILEFile(const String& fileName, int flags, int mode) 1.177 : FileName(fileName), OpenFlags(flags) 1.178 { 1.179 OVR_UNUSED(mode); 1.180 init(); 1.181 } 1.182 1.183 // The 'pfileName' should be encoded as UTF-8 to support international file names. 1.184 FILEFile::FILEFile(const char* pfileName, int flags, int mode) 1.185 : FileName(pfileName), OpenFlags(flags) 1.186 { 1.187 OVR_UNUSED(mode); 1.188 init(); 1.189 } 1.190 1.191 void FILEFile::init() 1.192 { 1.193 // Open mode for file's open 1.194 const char *omode = "rb"; 1.195 1.196 if (OpenFlags & Open_Truncate) 1.197 { 1.198 if (OpenFlags & Open_Read) 1.199 omode = "w+b"; 1.200 else 1.201 omode = "wb"; 1.202 } 1.203 else if (OpenFlags & Open_Create) 1.204 { 1.205 if (OpenFlags & Open_Read) 1.206 omode = "a+b"; 1.207 else 1.208 omode = "ab"; 1.209 } 1.210 else if (OpenFlags & Open_Write) 1.211 omode = "r+b"; 1.212 1.213 #ifdef OVR_OS_WIN32 1.214 SysErrorModeDisabler disabler(FileName.ToCStr()); 1.215 #endif 1.216 1.217 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) 1.218 wchar_t womode[16]; 1.219 wchar_t *pwFileName = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(FileName.ToCStr())+1) * sizeof(wchar_t)); 1.220 UTF8Util::DecodeString(pwFileName, FileName.ToCStr()); 1.221 OVR_ASSERT(strlen(omode) < sizeof(womode)/sizeof(womode[0])); 1.222 UTF8Util::DecodeString(womode, omode); 1.223 _wfopen_s(&fs, pwFileName, womode); 1.224 OVR_FREE(pwFileName); 1.225 #else 1.226 fs = fopen(FileName.ToCStr(), omode); 1.227 #endif 1.228 if (fs) 1.229 rewind (fs); 1.230 Opened = (fs != NULL); 1.231 // Set error code 1.232 if (!Opened) 1.233 ErrorCode = SFerror(); 1.234 else 1.235 { 1.236 // If we are testing file seek correctness, pre-load the entire file so 1.237 // that we can do comparison tests later. 1.238 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.239 TestPos = 0; 1.240 fseek(fs, 0, SEEK_END); 1.241 FileTestLength = ftell(fs); 1.242 fseek(fs, 0, SEEK_SET); 1.243 pFileTestBuffer = (UByte*)OVR_ALLOC(FileTestLength); 1.244 if (pFileTestBuffer) 1.245 { 1.246 OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength)); 1.247 Seek(0, Seek_Set); 1.248 } 1.249 #endif 1.250 1.251 ErrorCode = 0; 1.252 } 1.253 LastOp = 0; 1.254 } 1.255 1.256 1.257 const char* FILEFile::GetFilePath() 1.258 { 1.259 return FileName.ToCStr(); 1.260 } 1.261 1.262 1.263 // ** File Information 1.264 bool FILEFile::IsValid() 1.265 { 1.266 return Opened; 1.267 } 1.268 bool FILEFile::IsWritable() 1.269 { 1.270 return IsValid() && (OpenFlags&Open_Write); 1.271 } 1.272 /* 1.273 bool FILEFile::IsRecoverable() 1.274 { 1.275 return IsValid() && ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC); 1.276 } 1.277 */ 1.278 1.279 // Return position / file size 1.280 int FILEFile::Tell() 1.281 { 1.282 int pos = (int)ftell (fs); 1.283 if (pos < 0) 1.284 ErrorCode = SFerror(); 1.285 return pos; 1.286 } 1.287 1.288 SInt64 FILEFile::LTell() 1.289 { 1.290 SInt64 pos = ftell(fs); 1.291 if (pos < 0) 1.292 ErrorCode = SFerror(); 1.293 return pos; 1.294 } 1.295 1.296 int FILEFile::GetLength() 1.297 { 1.298 int pos = Tell(); 1.299 if (pos >= 0) 1.300 { 1.301 Seek (0, Seek_End); 1.302 int size = Tell(); 1.303 Seek (pos, Seek_Set); 1.304 return size; 1.305 } 1.306 return -1; 1.307 } 1.308 SInt64 FILEFile::LGetLength() 1.309 { 1.310 SInt64 pos = LTell(); 1.311 if (pos >= 0) 1.312 { 1.313 LSeek (0, Seek_End); 1.314 SInt64 size = LTell(); 1.315 LSeek (pos, Seek_Set); 1.316 return size; 1.317 } 1.318 return -1; 1.319 } 1.320 1.321 int FILEFile::GetErrorCode() 1.322 { 1.323 return ErrorCode; 1.324 } 1.325 1.326 // ** Stream implementation & I/O 1.327 int FILEFile::Write(const UByte *pbuffer, int numBytes) 1.328 { 1.329 if (LastOp && LastOp != Open_Write) 1.330 fflush(fs); 1.331 LastOp = Open_Write; 1.332 int written = (int) fwrite(pbuffer, 1, numBytes, fs); 1.333 if (written < numBytes) 1.334 ErrorCode = SFerror(); 1.335 1.336 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.337 if (written > 0) 1.338 TestPos += written; 1.339 #endif 1.340 1.341 return written; 1.342 } 1.343 1.344 int FILEFile::Read(UByte *pbuffer, int numBytes) 1.345 { 1.346 if (LastOp && LastOp != Open_Read) 1.347 fflush(fs); 1.348 LastOp = Open_Read; 1.349 int read = (int) fread(pbuffer, 1, numBytes, fs); 1.350 if (read < numBytes) 1.351 ErrorCode = SFerror(); 1.352 1.353 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.354 if (read > 0) 1.355 { 1.356 // Read-in data must match our pre-loaded buffer data! 1.357 UByte* pcompareBuffer = pFileTestBuffer + TestPos; 1.358 for (int i=0; i< read; i++) 1.359 { 1.360 OVR_ASSERT(pcompareBuffer[i] == pbuffer[i]); 1.361 } 1.362 1.363 //OVR_ASSERT(!memcmp(pFileTestBuffer + TestPos, pbuffer, read)); 1.364 TestPos += read; 1.365 OVR_ASSERT(ftell(fs) == (int)TestPos); 1.366 } 1.367 #endif 1.368 1.369 return read; 1.370 } 1.371 1.372 // Seeks ahead to skip bytes 1.373 int FILEFile::SkipBytes(int numBytes) 1.374 { 1.375 SInt64 pos = LTell(); 1.376 SInt64 newPos = LSeek(numBytes, Seek_Cur); 1.377 1.378 // Return -1 for major error 1.379 if ((pos==-1) || (newPos==-1)) 1.380 { 1.381 return -1; 1.382 } 1.383 //ErrorCode = ((NewPos-Pos)<numBytes) ? errno : 0; 1.384 1.385 return int (newPos-(int)pos); 1.386 } 1.387 1.388 // Return # of bytes till EOF 1.389 int FILEFile::BytesAvailable() 1.390 { 1.391 SInt64 pos = LTell(); 1.392 SInt64 endPos = LGetLength(); 1.393 1.394 // Return -1 for major error 1.395 if ((pos==-1) || (endPos==-1)) 1.396 { 1.397 ErrorCode = SFerror(); 1.398 return 0; 1.399 } 1.400 else 1.401 ErrorCode = 0; 1.402 1.403 return int (endPos-(int)pos); 1.404 } 1.405 1.406 // Flush file contents 1.407 bool FILEFile::Flush() 1.408 { 1.409 return !fflush(fs); 1.410 } 1.411 1.412 int FILEFile::Seek(int offset, int origin) 1.413 { 1.414 int newOrigin = 0; 1.415 switch(origin) 1.416 { 1.417 case Seek_Set: newOrigin = SEEK_SET; break; 1.418 case Seek_Cur: newOrigin = SEEK_CUR; break; 1.419 case Seek_End: newOrigin = SEEK_END; break; 1.420 } 1.421 1.422 if (newOrigin == SEEK_SET && offset == Tell()) 1.423 return Tell(); 1.424 1.425 if (fseek (fs, offset, newOrigin)) 1.426 { 1.427 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.428 OVR_ASSERT(0); 1.429 #endif 1.430 return -1; 1.431 } 1.432 1.433 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.434 // Track file position after seeks for read verification later. 1.435 switch(origin) 1.436 { 1.437 case Seek_Set: TestPos = offset; break; 1.438 case Seek_Cur: TestPos += offset; break; 1.439 case Seek_End: TestPos = FileTestLength + offset; break; 1.440 } 1.441 OVR_ASSERT((int)TestPos == Tell()); 1.442 #endif 1.443 1.444 return (int)Tell(); 1.445 } 1.446 1.447 SInt64 FILEFile::LSeek(SInt64 offset, int origin) 1.448 { 1.449 return Seek((int)offset,origin); 1.450 } 1.451 1.452 int FILEFile::CopyFromStream(File *pstream, int byteSize) 1.453 { 1.454 UByte buff[0x4000]; 1.455 int count = 0; 1.456 int szRequest, szRead, szWritten; 1.457 1.458 while (byteSize) 1.459 { 1.460 szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize; 1.461 1.462 szRead = pstream->Read(buff, szRequest); 1.463 szWritten = 0; 1.464 if (szRead > 0) 1.465 szWritten = Write(buff, szRead); 1.466 1.467 count += szWritten; 1.468 byteSize -= szWritten; 1.469 if (szWritten < szRequest) 1.470 break; 1.471 } 1.472 return count; 1.473 } 1.474 1.475 1.476 bool FILEFile::Close() 1.477 { 1.478 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.479 if (pFileTestBuffer) 1.480 { 1.481 OVR_FREE(pFileTestBuffer); 1.482 pFileTestBuffer = 0; 1.483 FileTestLength = 0; 1.484 } 1.485 #endif 1.486 1.487 bool closeRet = !fclose(fs); 1.488 1.489 if (!closeRet) 1.490 { 1.491 ErrorCode = SFerror(); 1.492 return 0; 1.493 } 1.494 else 1.495 { 1.496 Opened = 0; 1.497 fs = 0; 1.498 ErrorCode = 0; 1.499 } 1.500 1.501 // Handle safe truncate 1.502 /* 1.503 if ((OpenFlags & OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) 1.504 { 1.505 // Delete original file (if it existed) 1.506 DWORD oldAttributes = FileUtilWin32::GetFileAttributes(FileName); 1.507 if (oldAttributes!=0xFFFFFFFF) 1.508 if (!FileUtilWin32::DeleteFile(FileName)) 1.509 { 1.510 // Try to remove the readonly attribute 1.511 FileUtilWin32::SetFileAttributes(FileName, oldAttributes & (~FILE_ATTRIBUTE_READONLY) ); 1.512 // And delete the file again 1.513 if (!FileUtilWin32::DeleteFile(FileName)) 1.514 return 0; 1.515 } 1.516 1.517 // Rename temp file to real filename 1.518 if (!FileUtilWin32::MoveFile(TempName, FileName)) 1.519 { 1.520 //ErrorCode = errno; 1.521 return 0; 1.522 } 1.523 } 1.524 */ 1.525 return 1; 1.526 } 1.527 1.528 /* 1.529 bool FILEFile::CloseCancel() 1.530 { 1.531 bool closeRet = (bool)::CloseHandle(fd); 1.532 1.533 if (!closeRet) 1.534 { 1.535 //ErrorCode = errno; 1.536 return 0; 1.537 } 1.538 else 1.539 { 1.540 Opened = 0; 1.541 fd = INVALID_HANDLE_VALUE; 1.542 ErrorCode = 0; 1.543 } 1.544 1.545 // Handle safe truncate (delete tmp file, leave original unchanged) 1.546 if ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) 1.547 if (!FileUtilWin32::DeleteFile(TempName)) 1.548 { 1.549 //ErrorCode = errno; 1.550 return 0; 1.551 } 1.552 return 1; 1.553 } 1.554 */ 1.555 1.556 File *FileFILEOpen(const String& path, int flags, int mode) 1.557 { 1.558 return new FILEFile(path, flags, mode); 1.559 } 1.560 1.561 // Helper function: obtain file information time. 1.562 bool SysFile::GetFileStat(FileStat* pfileStat, const String& path) 1.563 { 1.564 #if defined(OVR_OS_WIN32) 1.565 // 64-bit implementation on Windows. 1.566 struct __stat64 fileStat; 1.567 // Stat returns 0 for success. 1.568 wchar_t *pwpath = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(path.ToCStr())+1)*sizeof(wchar_t)); 1.569 UTF8Util::DecodeString(pwpath, path.ToCStr()); 1.570 1.571 int ret = _wstat64(pwpath, &fileStat); 1.572 OVR_FREE(pwpath); 1.573 if (ret) return false; 1.574 #else 1.575 struct stat fileStat; 1.576 // Stat returns 0 for success. 1.577 if (stat(path, &fileStat) != 0) 1.578 return false; 1.579 #endif 1.580 pfileStat->AccessTime = fileStat.st_atime; 1.581 pfileStat->ModifyTime = fileStat.st_mtime; 1.582 pfileStat->FileSize = fileStat.st_size; 1.583 return true; 1.584 } 1.585 1.586 } // Scaleform 1.587 \ No newline at end of file 1.588 +/************************************************************************** 1.589 + 1.590 +Filename : OVR_FileFILE.cpp 1.591 +Content : File wrapper class implementation (Win32) 1.592 + 1.593 +Created : April 5, 1999 1.594 +Authors : Michael Antonov 1.595 + 1.596 +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. 1.597 + 1.598 +Use of this software is subject to the terms of the Oculus license 1.599 +agreement provided at the time of installation or download, or which 1.600 +otherwise accompanies this software in either electronic or hard copy form. 1.601 + 1.602 +**************************************************************************/ 1.603 + 1.604 +#define GFILE_CXX 1.605 + 1.606 +#include "OVR_Types.h" 1.607 +#include "OVR_Log.h" 1.608 + 1.609 +// Standard C library (Captain Obvious guarantees!) 1.610 +#include <stdio.h> 1.611 +#ifndef OVR_OS_WINCE 1.612 +#include <sys/stat.h> 1.613 +#endif 1.614 + 1.615 +#include "OVR_SysFile.h" 1.616 + 1.617 +#ifndef OVR_OS_WINCE 1.618 +#include <errno.h> 1.619 +#endif 1.620 + 1.621 +namespace OVR { 1.622 + 1.623 +// ***** File interface 1.624 + 1.625 +// ***** FILEFile - C streams file 1.626 + 1.627 +static int SFerror () 1.628 +{ 1.629 + if (errno == ENOENT) 1.630 + return FileConstants::Error_FileNotFound; 1.631 + else if (errno == EACCES || errno == EPERM) 1.632 + return FileConstants::Error_Access; 1.633 + else if (errno == ENOSPC) 1.634 + return FileConstants::Error_DiskFull; 1.635 + else 1.636 + return FileConstants::Error_IOError; 1.637 +}; 1.638 + 1.639 +#ifdef OVR_OS_WIN32 1.640 +#include "windows.h" 1.641 +// A simple helper class to disable/enable system error mode, if necessary 1.642 +// Disabling happens conditionally only if a drive name is involved 1.643 +class SysErrorModeDisabler 1.644 +{ 1.645 + BOOL Disabled; 1.646 + UINT OldMode; 1.647 +public: 1.648 + SysErrorModeDisabler(const char* pfileName) 1.649 + { 1.650 + if (pfileName && (pfileName[0]!=0) && pfileName[1]==':') 1.651 + { 1.652 + Disabled = 1; 1.653 + OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS); 1.654 + } 1.655 + else 1.656 + Disabled = 0; 1.657 + } 1.658 + 1.659 + ~SysErrorModeDisabler() 1.660 + { 1.661 + if (Disabled) ::SetErrorMode(OldMode); 1.662 + } 1.663 +}; 1.664 +#else 1.665 +class SysErrorModeDisabler 1.666 +{ 1.667 +public: 1.668 + SysErrorModeDisabler(const char* pfileName) { } 1.669 +}; 1.670 +#endif // OVR_OS_WIN32 1.671 + 1.672 + 1.673 +// This macro enables verification of I/O results after seeks against a pre-loaded 1.674 +// full file buffer copy. This is generally not necessary, but can been used to debug 1.675 +// memory corruptions; we've seen this fail due to EAX2/DirectSound corrupting memory 1.676 +// under FMOD with XP64 (32-bit) and Realtek HA Audio driver. 1.677 +//#define GFILE_VERIFY_SEEK_ERRORS 1.678 + 1.679 + 1.680 +// This is the simplest possible file implementation, it wraps around the descriptor 1.681 +// This file is delegated to by SysFile. 1.682 + 1.683 +class FILEFile : public File 1.684 +{ 1.685 +protected: 1.686 + 1.687 + // Allocated filename 1.688 + String FileName; 1.689 + 1.690 + // File handle & open mode 1.691 + bool Opened; 1.692 + FILE* fs; 1.693 + int OpenFlags; 1.694 + // Error code for last request 1.695 + int ErrorCode; 1.696 + 1.697 + int LastOp; 1.698 + 1.699 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.700 + UByte* pFileTestBuffer; 1.701 + unsigned FileTestLength; 1.702 + unsigned TestPos; // File pointer position during tests. 1.703 +#endif 1.704 + 1.705 +public: 1.706 + 1.707 + FILEFile() 1.708 + { 1.709 + Opened = 0; FileName = ""; 1.710 + 1.711 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.712 + pFileTestBuffer =0; 1.713 + FileTestLength =0; 1.714 + TestPos =0; 1.715 +#endif 1.716 + } 1.717 + // Initialize file by opening it 1.718 + FILEFile(const String& fileName, int flags, int Mode); 1.719 + // The 'pfileName' should be encoded as UTF-8 to support international file names. 1.720 + FILEFile(const char* pfileName, int flags, int Mode); 1.721 + 1.722 + ~FILEFile() 1.723 + { 1.724 + if (Opened) 1.725 + Close(); 1.726 + } 1.727 + 1.728 + virtual const char* GetFilePath(); 1.729 + 1.730 + // ** File Information 1.731 + virtual bool IsValid(); 1.732 + virtual bool IsWritable(); 1.733 + 1.734 + // Return position / file size 1.735 + virtual int Tell(); 1.736 + virtual SInt64 LTell(); 1.737 + virtual int GetLength(); 1.738 + virtual SInt64 LGetLength(); 1.739 + 1.740 +// virtual bool Stat(FileStats *pfs); 1.741 + virtual int GetErrorCode(); 1.742 + 1.743 + // ** Stream implementation & I/O 1.744 + virtual int Write(const UByte *pbuffer, int numBytes); 1.745 + virtual int Read(UByte *pbuffer, int numBytes); 1.746 + virtual int SkipBytes(int numBytes); 1.747 + virtual int BytesAvailable(); 1.748 + virtual bool Flush(); 1.749 + virtual int Seek(int offset, int origin); 1.750 + virtual SInt64 LSeek(SInt64 offset, int origin); 1.751 + 1.752 + virtual int CopyFromStream(File *pStream, int byteSize); 1.753 + virtual bool Close(); 1.754 +private: 1.755 + void init(); 1.756 +}; 1.757 + 1.758 + 1.759 +// Initialize file by opening it 1.760 +FILEFile::FILEFile(const String& fileName, int flags, int mode) 1.761 + : FileName(fileName), OpenFlags(flags) 1.762 +{ 1.763 + OVR_UNUSED(mode); 1.764 + init(); 1.765 +} 1.766 + 1.767 +// The 'pfileName' should be encoded as UTF-8 to support international file names. 1.768 +FILEFile::FILEFile(const char* pfileName, int flags, int mode) 1.769 + : FileName(pfileName), OpenFlags(flags) 1.770 +{ 1.771 + OVR_UNUSED(mode); 1.772 + init(); 1.773 +} 1.774 + 1.775 +void FILEFile::init() 1.776 +{ 1.777 + // Open mode for file's open 1.778 + const char *omode = "rb"; 1.779 + 1.780 + if (OpenFlags & Open_Truncate) 1.781 + { 1.782 + if (OpenFlags & Open_Read) 1.783 + omode = "w+b"; 1.784 + else 1.785 + omode = "wb"; 1.786 + } 1.787 + else if (OpenFlags & Open_Create) 1.788 + { 1.789 + if (OpenFlags & Open_Read) 1.790 + omode = "a+b"; 1.791 + else 1.792 + omode = "ab"; 1.793 + } 1.794 + else if (OpenFlags & Open_Write) 1.795 + omode = "r+b"; 1.796 + 1.797 +#ifdef OVR_OS_WIN32 1.798 + SysErrorModeDisabler disabler(FileName.ToCStr()); 1.799 +#endif 1.800 + 1.801 +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) 1.802 + wchar_t womode[16]; 1.803 + wchar_t *pwFileName = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(FileName.ToCStr())+1) * sizeof(wchar_t)); 1.804 + UTF8Util::DecodeString(pwFileName, FileName.ToCStr()); 1.805 + OVR_ASSERT(strlen(omode) < sizeof(womode)/sizeof(womode[0])); 1.806 + UTF8Util::DecodeString(womode, omode); 1.807 + _wfopen_s(&fs, pwFileName, womode); 1.808 + OVR_FREE(pwFileName); 1.809 +#else 1.810 + fs = fopen(FileName.ToCStr(), omode); 1.811 +#endif 1.812 + if (fs) 1.813 + rewind (fs); 1.814 + Opened = (fs != NULL); 1.815 + // Set error code 1.816 + if (!Opened) 1.817 + ErrorCode = SFerror(); 1.818 + else 1.819 + { 1.820 + // If we are testing file seek correctness, pre-load the entire file so 1.821 + // that we can do comparison tests later. 1.822 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.823 + TestPos = 0; 1.824 + fseek(fs, 0, SEEK_END); 1.825 + FileTestLength = ftell(fs); 1.826 + fseek(fs, 0, SEEK_SET); 1.827 + pFileTestBuffer = (UByte*)OVR_ALLOC(FileTestLength); 1.828 + if (pFileTestBuffer) 1.829 + { 1.830 + OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength)); 1.831 + Seek(0, Seek_Set); 1.832 + } 1.833 +#endif 1.834 + 1.835 + ErrorCode = 0; 1.836 + } 1.837 + LastOp = 0; 1.838 +} 1.839 + 1.840 + 1.841 +const char* FILEFile::GetFilePath() 1.842 +{ 1.843 + return FileName.ToCStr(); 1.844 +} 1.845 + 1.846 + 1.847 +// ** File Information 1.848 +bool FILEFile::IsValid() 1.849 +{ 1.850 + return Opened; 1.851 +} 1.852 +bool FILEFile::IsWritable() 1.853 +{ 1.854 + return IsValid() && (OpenFlags&Open_Write); 1.855 +} 1.856 +/* 1.857 +bool FILEFile::IsRecoverable() 1.858 +{ 1.859 + return IsValid() && ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC); 1.860 +} 1.861 +*/ 1.862 + 1.863 +// Return position / file size 1.864 +int FILEFile::Tell() 1.865 +{ 1.866 + int pos = (int)ftell (fs); 1.867 + if (pos < 0) 1.868 + ErrorCode = SFerror(); 1.869 + return pos; 1.870 +} 1.871 + 1.872 +SInt64 FILEFile::LTell() 1.873 +{ 1.874 + SInt64 pos = ftell(fs); 1.875 + if (pos < 0) 1.876 + ErrorCode = SFerror(); 1.877 + return pos; 1.878 +} 1.879 + 1.880 +int FILEFile::GetLength() 1.881 +{ 1.882 + int pos = Tell(); 1.883 + if (pos >= 0) 1.884 + { 1.885 + Seek (0, Seek_End); 1.886 + int size = Tell(); 1.887 + Seek (pos, Seek_Set); 1.888 + return size; 1.889 + } 1.890 + return -1; 1.891 +} 1.892 +SInt64 FILEFile::LGetLength() 1.893 +{ 1.894 + SInt64 pos = LTell(); 1.895 + if (pos >= 0) 1.896 + { 1.897 + LSeek (0, Seek_End); 1.898 + SInt64 size = LTell(); 1.899 + LSeek (pos, Seek_Set); 1.900 + return size; 1.901 + } 1.902 + return -1; 1.903 +} 1.904 + 1.905 +int FILEFile::GetErrorCode() 1.906 +{ 1.907 + return ErrorCode; 1.908 +} 1.909 + 1.910 +// ** Stream implementation & I/O 1.911 +int FILEFile::Write(const UByte *pbuffer, int numBytes) 1.912 +{ 1.913 + if (LastOp && LastOp != Open_Write) 1.914 + fflush(fs); 1.915 + LastOp = Open_Write; 1.916 + int written = (int) fwrite(pbuffer, 1, numBytes, fs); 1.917 + if (written < numBytes) 1.918 + ErrorCode = SFerror(); 1.919 + 1.920 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.921 + if (written > 0) 1.922 + TestPos += written; 1.923 +#endif 1.924 + 1.925 + return written; 1.926 +} 1.927 + 1.928 +int FILEFile::Read(UByte *pbuffer, int numBytes) 1.929 +{ 1.930 + if (LastOp && LastOp != Open_Read) 1.931 + fflush(fs); 1.932 + LastOp = Open_Read; 1.933 + int read = (int) fread(pbuffer, 1, numBytes, fs); 1.934 + if (read < numBytes) 1.935 + ErrorCode = SFerror(); 1.936 + 1.937 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.938 + if (read > 0) 1.939 + { 1.940 + // Read-in data must match our pre-loaded buffer data! 1.941 + UByte* pcompareBuffer = pFileTestBuffer + TestPos; 1.942 + for (int i=0; i< read; i++) 1.943 + { 1.944 + OVR_ASSERT(pcompareBuffer[i] == pbuffer[i]); 1.945 + } 1.946 + 1.947 + //OVR_ASSERT(!memcmp(pFileTestBuffer + TestPos, pbuffer, read)); 1.948 + TestPos += read; 1.949 + OVR_ASSERT(ftell(fs) == (int)TestPos); 1.950 + } 1.951 +#endif 1.952 + 1.953 + return read; 1.954 +} 1.955 + 1.956 +// Seeks ahead to skip bytes 1.957 +int FILEFile::SkipBytes(int numBytes) 1.958 +{ 1.959 + SInt64 pos = LTell(); 1.960 + SInt64 newPos = LSeek(numBytes, Seek_Cur); 1.961 + 1.962 + // Return -1 for major error 1.963 + if ((pos==-1) || (newPos==-1)) 1.964 + { 1.965 + return -1; 1.966 + } 1.967 + //ErrorCode = ((NewPos-Pos)<numBytes) ? errno : 0; 1.968 + 1.969 + return int (newPos-(int)pos); 1.970 +} 1.971 + 1.972 +// Return # of bytes till EOF 1.973 +int FILEFile::BytesAvailable() 1.974 +{ 1.975 + SInt64 pos = LTell(); 1.976 + SInt64 endPos = LGetLength(); 1.977 + 1.978 + // Return -1 for major error 1.979 + if ((pos==-1) || (endPos==-1)) 1.980 + { 1.981 + ErrorCode = SFerror(); 1.982 + return 0; 1.983 + } 1.984 + else 1.985 + ErrorCode = 0; 1.986 + 1.987 + return int (endPos-(int)pos); 1.988 +} 1.989 + 1.990 +// Flush file contents 1.991 +bool FILEFile::Flush() 1.992 +{ 1.993 + return !fflush(fs); 1.994 +} 1.995 + 1.996 +int FILEFile::Seek(int offset, int origin) 1.997 +{ 1.998 + int newOrigin = 0; 1.999 + switch(origin) 1.1000 + { 1.1001 + case Seek_Set: newOrigin = SEEK_SET; break; 1.1002 + case Seek_Cur: newOrigin = SEEK_CUR; break; 1.1003 + case Seek_End: newOrigin = SEEK_END; break; 1.1004 + } 1.1005 + 1.1006 + if (newOrigin == SEEK_SET && offset == Tell()) 1.1007 + return Tell(); 1.1008 + 1.1009 + if (fseek (fs, offset, newOrigin)) 1.1010 + { 1.1011 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.1012 + OVR_ASSERT(0); 1.1013 +#endif 1.1014 + return -1; 1.1015 + } 1.1016 + 1.1017 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.1018 + // Track file position after seeks for read verification later. 1.1019 + switch(origin) 1.1020 + { 1.1021 + case Seek_Set: TestPos = offset; break; 1.1022 + case Seek_Cur: TestPos += offset; break; 1.1023 + case Seek_End: TestPos = FileTestLength + offset; break; 1.1024 + } 1.1025 + OVR_ASSERT((int)TestPos == Tell()); 1.1026 +#endif 1.1027 + 1.1028 + return (int)Tell(); 1.1029 +} 1.1030 + 1.1031 +SInt64 FILEFile::LSeek(SInt64 offset, int origin) 1.1032 +{ 1.1033 + return Seek((int)offset,origin); 1.1034 +} 1.1035 + 1.1036 +int FILEFile::CopyFromStream(File *pstream, int byteSize) 1.1037 +{ 1.1038 + UByte buff[0x4000]; 1.1039 + int count = 0; 1.1040 + int szRequest, szRead, szWritten; 1.1041 + 1.1042 + while (byteSize) 1.1043 + { 1.1044 + szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize; 1.1045 + 1.1046 + szRead = pstream->Read(buff, szRequest); 1.1047 + szWritten = 0; 1.1048 + if (szRead > 0) 1.1049 + szWritten = Write(buff, szRead); 1.1050 + 1.1051 + count += szWritten; 1.1052 + byteSize -= szWritten; 1.1053 + if (szWritten < szRequest) 1.1054 + break; 1.1055 + } 1.1056 + return count; 1.1057 +} 1.1058 + 1.1059 + 1.1060 +bool FILEFile::Close() 1.1061 +{ 1.1062 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS 1.1063 + if (pFileTestBuffer) 1.1064 + { 1.1065 + OVR_FREE(pFileTestBuffer); 1.1066 + pFileTestBuffer = 0; 1.1067 + FileTestLength = 0; 1.1068 + } 1.1069 +#endif 1.1070 + 1.1071 + bool closeRet = !fclose(fs); 1.1072 + 1.1073 + if (!closeRet) 1.1074 + { 1.1075 + ErrorCode = SFerror(); 1.1076 + return 0; 1.1077 + } 1.1078 + else 1.1079 + { 1.1080 + Opened = 0; 1.1081 + fs = 0; 1.1082 + ErrorCode = 0; 1.1083 + } 1.1084 + 1.1085 + // Handle safe truncate 1.1086 + /* 1.1087 + if ((OpenFlags & OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) 1.1088 + { 1.1089 + // Delete original file (if it existed) 1.1090 + DWORD oldAttributes = FileUtilWin32::GetFileAttributes(FileName); 1.1091 + if (oldAttributes!=0xFFFFFFFF) 1.1092 + if (!FileUtilWin32::DeleteFile(FileName)) 1.1093 + { 1.1094 + // Try to remove the readonly attribute 1.1095 + FileUtilWin32::SetFileAttributes(FileName, oldAttributes & (~FILE_ATTRIBUTE_READONLY) ); 1.1096 + // And delete the file again 1.1097 + if (!FileUtilWin32::DeleteFile(FileName)) 1.1098 + return 0; 1.1099 + } 1.1100 + 1.1101 + // Rename temp file to real filename 1.1102 + if (!FileUtilWin32::MoveFile(TempName, FileName)) 1.1103 + { 1.1104 + //ErrorCode = errno; 1.1105 + return 0; 1.1106 + } 1.1107 + } 1.1108 + */ 1.1109 + return 1; 1.1110 +} 1.1111 + 1.1112 +/* 1.1113 +bool FILEFile::CloseCancel() 1.1114 +{ 1.1115 + bool closeRet = (bool)::CloseHandle(fd); 1.1116 + 1.1117 + if (!closeRet) 1.1118 + { 1.1119 + //ErrorCode = errno; 1.1120 + return 0; 1.1121 + } 1.1122 + else 1.1123 + { 1.1124 + Opened = 0; 1.1125 + fd = INVALID_HANDLE_VALUE; 1.1126 + ErrorCode = 0; 1.1127 + } 1.1128 + 1.1129 + // Handle safe truncate (delete tmp file, leave original unchanged) 1.1130 + if ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) 1.1131 + if (!FileUtilWin32::DeleteFile(TempName)) 1.1132 + { 1.1133 + //ErrorCode = errno; 1.1134 + return 0; 1.1135 + } 1.1136 + return 1; 1.1137 +} 1.1138 +*/ 1.1139 + 1.1140 +File *FileFILEOpen(const String& path, int flags, int mode) 1.1141 +{ 1.1142 + return new FILEFile(path, flags, mode); 1.1143 +} 1.1144 + 1.1145 +// Helper function: obtain file information time. 1.1146 +bool SysFile::GetFileStat(FileStat* pfileStat, const String& path) 1.1147 +{ 1.1148 +#if defined(OVR_OS_WIN32) 1.1149 + // 64-bit implementation on Windows. 1.1150 + struct __stat64 fileStat; 1.1151 + // Stat returns 0 for success. 1.1152 + wchar_t *pwpath = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(path.ToCStr())+1)*sizeof(wchar_t)); 1.1153 + UTF8Util::DecodeString(pwpath, path.ToCStr()); 1.1154 + 1.1155 + int ret = _wstat64(pwpath, &fileStat); 1.1156 + OVR_FREE(pwpath); 1.1157 + if (ret) return false; 1.1158 +#else 1.1159 + struct stat fileStat; 1.1160 + // Stat returns 0 for success. 1.1161 + if (stat(path, &fileStat) != 0) 1.1162 + return false; 1.1163 +#endif 1.1164 + pfileStat->AccessTime = fileStat.st_atime; 1.1165 + pfileStat->ModifyTime = fileStat.st_mtime; 1.1166 + pfileStat->FileSize = fileStat.st_size; 1.1167 + return true; 1.1168 +} 1.1169 + 1.1170 +} // Scaleform