oculus1

annotate libovr/Src/Kernel/OVR_FileFILE.cpp @ 1:e2f9e4603129

added LibOVR and started a simple vr wrapper.
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 14 Sep 2013 16:14:59 +0300
parents
children b069a5c27388
rev   line source
nuclear@1 1 /**************************************************************************
nuclear@1 2
nuclear@1 3 Filename : OVR_FileFILE.cpp
nuclear@1 4 Content : File wrapper class implementation (Win32)
nuclear@1 5
nuclear@1 6 Created : April 5, 1999
nuclear@1 7 Authors : Michael Antonov
nuclear@1 8
nuclear@1 9 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
nuclear@1 10
nuclear@1 11 Use of this software is subject to the terms of the Oculus license
nuclear@1 12 agreement provided at the time of installation or download, or which
nuclear@1 13 otherwise accompanies this software in either electronic or hard copy form.
nuclear@1 14
nuclear@1 15 **************************************************************************/
nuclear@1 16
nuclear@1 17 #define GFILE_CXX
nuclear@1 18
nuclear@1 19 #include "OVR_Types.h"
nuclear@1 20 #include "OVR_Log.h"
nuclear@1 21
nuclear@1 22 // Standard C library (Captain Obvious guarantees!)
nuclear@1 23 #include <stdio.h>
nuclear@1 24 #ifndef OVR_OS_WINCE
nuclear@1 25 #include <sys/stat.h>
nuclear@1 26 #endif
nuclear@1 27
nuclear@1 28 #include "OVR_SysFile.h"
nuclear@1 29
nuclear@1 30 #ifndef OVR_OS_WINCE
nuclear@1 31 #include <errno.h>
nuclear@1 32 #endif
nuclear@1 33
nuclear@1 34 namespace OVR {
nuclear@1 35
nuclear@1 36 // ***** File interface
nuclear@1 37
nuclear@1 38 // ***** FILEFile - C streams file
nuclear@1 39
nuclear@1 40 static int SFerror ()
nuclear@1 41 {
nuclear@1 42 if (errno == ENOENT)
nuclear@1 43 return FileConstants::Error_FileNotFound;
nuclear@1 44 else if (errno == EACCES || errno == EPERM)
nuclear@1 45 return FileConstants::Error_Access;
nuclear@1 46 else if (errno == ENOSPC)
nuclear@1 47 return FileConstants::Error_DiskFull;
nuclear@1 48 else
nuclear@1 49 return FileConstants::Error_IOError;
nuclear@1 50 };
nuclear@1 51
nuclear@1 52 #ifdef OVR_OS_WIN32
nuclear@1 53 #include "windows.h"
nuclear@1 54 // A simple helper class to disable/enable system error mode, if necessary
nuclear@1 55 // Disabling happens conditionally only if a drive name is involved
nuclear@1 56 class SysErrorModeDisabler
nuclear@1 57 {
nuclear@1 58 BOOL Disabled;
nuclear@1 59 UINT OldMode;
nuclear@1 60 public:
nuclear@1 61 SysErrorModeDisabler(const char* pfileName)
nuclear@1 62 {
nuclear@1 63 if (pfileName && (pfileName[0]!=0) && pfileName[1]==':')
nuclear@1 64 {
nuclear@1 65 Disabled = 1;
nuclear@1 66 OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS);
nuclear@1 67 }
nuclear@1 68 else
nuclear@1 69 Disabled = 0;
nuclear@1 70 }
nuclear@1 71
nuclear@1 72 ~SysErrorModeDisabler()
nuclear@1 73 {
nuclear@1 74 if (Disabled) ::SetErrorMode(OldMode);
nuclear@1 75 }
nuclear@1 76 };
nuclear@1 77 #else
nuclear@1 78 class SysErrorModeDisabler
nuclear@1 79 {
nuclear@1 80 public:
nuclear@1 81 SysErrorModeDisabler(const char* pfileName) { }
nuclear@1 82 };
nuclear@1 83 #endif // OVR_OS_WIN32
nuclear@1 84
nuclear@1 85
nuclear@1 86 // This macro enables verification of I/O results after seeks against a pre-loaded
nuclear@1 87 // full file buffer copy. This is generally not necessary, but can been used to debug
nuclear@1 88 // memory corruptions; we've seen this fail due to EAX2/DirectSound corrupting memory
nuclear@1 89 // under FMOD with XP64 (32-bit) and Realtek HA Audio driver.
nuclear@1 90 //#define GFILE_VERIFY_SEEK_ERRORS
nuclear@1 91
nuclear@1 92
nuclear@1 93 // This is the simplest possible file implementation, it wraps around the descriptor
nuclear@1 94 // This file is delegated to by SysFile.
nuclear@1 95
nuclear@1 96 class FILEFile : public File
nuclear@1 97 {
nuclear@1 98 protected:
nuclear@1 99
nuclear@1 100 // Allocated filename
nuclear@1 101 String FileName;
nuclear@1 102
nuclear@1 103 // File handle & open mode
nuclear@1 104 bool Opened;
nuclear@1 105 FILE* fs;
nuclear@1 106 int OpenFlags;
nuclear@1 107 // Error code for last request
nuclear@1 108 int ErrorCode;
nuclear@1 109
nuclear@1 110 int LastOp;
nuclear@1 111
nuclear@1 112 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
nuclear@1 113 UByte* pFileTestBuffer;
nuclear@1 114 unsigned FileTestLength;
nuclear@1 115 unsigned TestPos; // File pointer position during tests.
nuclear@1 116 #endif
nuclear@1 117
nuclear@1 118 public:
nuclear@1 119
nuclear@1 120 FILEFile()
nuclear@1 121 {
nuclear@1 122 Opened = 0; FileName = "";
nuclear@1 123
nuclear@1 124 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
nuclear@1 125 pFileTestBuffer =0;
nuclear@1 126 FileTestLength =0;
nuclear@1 127 TestPos =0;
nuclear@1 128 #endif
nuclear@1 129 }
nuclear@1 130 // Initialize file by opening it
nuclear@1 131 FILEFile(const String& fileName, int flags, int Mode);
nuclear@1 132 // The 'pfileName' should be encoded as UTF-8 to support international file names.
nuclear@1 133 FILEFile(const char* pfileName, int flags, int Mode);
nuclear@1 134
nuclear@1 135 ~FILEFile()
nuclear@1 136 {
nuclear@1 137 if (Opened)
nuclear@1 138 Close();
nuclear@1 139 }
nuclear@1 140
nuclear@1 141 virtual const char* GetFilePath();
nuclear@1 142
nuclear@1 143 // ** File Information
nuclear@1 144 virtual bool IsValid();
nuclear@1 145 virtual bool IsWritable();
nuclear@1 146
nuclear@1 147 // Return position / file size
nuclear@1 148 virtual int Tell();
nuclear@1 149 virtual SInt64 LTell();
nuclear@1 150 virtual int GetLength();
nuclear@1 151 virtual SInt64 LGetLength();
nuclear@1 152
nuclear@1 153 // virtual bool Stat(FileStats *pfs);
nuclear@1 154 virtual int GetErrorCode();
nuclear@1 155
nuclear@1 156 // ** Stream implementation & I/O
nuclear@1 157 virtual int Write(const UByte *pbuffer, int numBytes);
nuclear@1 158 virtual int Read(UByte *pbuffer, int numBytes);
nuclear@1 159 virtual int SkipBytes(int numBytes);
nuclear@1 160 virtual int BytesAvailable();
nuclear@1 161 virtual bool Flush();
nuclear@1 162 virtual int Seek(int offset, int origin);
nuclear@1 163 virtual SInt64 LSeek(SInt64 offset, int origin);
nuclear@1 164
nuclear@1 165 virtual int CopyFromStream(File *pStream, int byteSize);
nuclear@1 166 virtual bool Close();
nuclear@1 167 private:
nuclear@1 168 void init();
nuclear@1 169 };
nuclear@1 170
nuclear@1 171
nuclear@1 172 // Initialize file by opening it
nuclear@1 173 FILEFile::FILEFile(const String& fileName, int flags, int mode)
nuclear@1 174 : FileName(fileName), OpenFlags(flags)
nuclear@1 175 {
nuclear@1 176 OVR_UNUSED(mode);
nuclear@1 177 init();
nuclear@1 178 }
nuclear@1 179
nuclear@1 180 // The 'pfileName' should be encoded as UTF-8 to support international file names.
nuclear@1 181 FILEFile::FILEFile(const char* pfileName, int flags, int mode)
nuclear@1 182 : FileName(pfileName), OpenFlags(flags)
nuclear@1 183 {
nuclear@1 184 OVR_UNUSED(mode);
nuclear@1 185 init();
nuclear@1 186 }
nuclear@1 187
nuclear@1 188 void FILEFile::init()
nuclear@1 189 {
nuclear@1 190 // Open mode for file's open
nuclear@1 191 const char *omode = "rb";
nuclear@1 192
nuclear@1 193 if (OpenFlags & Open_Truncate)
nuclear@1 194 {
nuclear@1 195 if (OpenFlags & Open_Read)
nuclear@1 196 omode = "w+b";
nuclear@1 197 else
nuclear@1 198 omode = "wb";
nuclear@1 199 }
nuclear@1 200 else if (OpenFlags & Open_Create)
nuclear@1 201 {
nuclear@1 202 if (OpenFlags & Open_Read)
nuclear@1 203 omode = "a+b";
nuclear@1 204 else
nuclear@1 205 omode = "ab";
nuclear@1 206 }
nuclear@1 207 else if (OpenFlags & Open_Write)
nuclear@1 208 omode = "r+b";
nuclear@1 209
nuclear@1 210 #ifdef OVR_OS_WIN32
nuclear@1 211 SysErrorModeDisabler disabler(FileName.ToCStr());
nuclear@1 212 #endif
nuclear@1 213
nuclear@1 214 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
nuclear@1 215 wchar_t womode[16];
nuclear@1 216 wchar_t *pwFileName = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(FileName.ToCStr())+1) * sizeof(wchar_t));
nuclear@1 217 UTF8Util::DecodeString(pwFileName, FileName.ToCStr());
nuclear@1 218 OVR_ASSERT(strlen(omode) < sizeof(womode)/sizeof(womode[0]));
nuclear@1 219 UTF8Util::DecodeString(womode, omode);
nuclear@1 220 _wfopen_s(&fs, pwFileName, womode);
nuclear@1 221 OVR_FREE(pwFileName);
nuclear@1 222 #else
nuclear@1 223 fs = fopen(FileName.ToCStr(), omode);
nuclear@1 224 #endif
nuclear@1 225 if (fs)
nuclear@1 226 rewind (fs);
nuclear@1 227 Opened = (fs != NULL);
nuclear@1 228 // Set error code
nuclear@1 229 if (!Opened)
nuclear@1 230 ErrorCode = SFerror();
nuclear@1 231 else
nuclear@1 232 {
nuclear@1 233 // If we are testing file seek correctness, pre-load the entire file so
nuclear@1 234 // that we can do comparison tests later.
nuclear@1 235 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
nuclear@1 236 TestPos = 0;
nuclear@1 237 fseek(fs, 0, SEEK_END);
nuclear@1 238 FileTestLength = ftell(fs);
nuclear@1 239 fseek(fs, 0, SEEK_SET);
nuclear@1 240 pFileTestBuffer = (UByte*)OVR_ALLOC(FileTestLength);
nuclear@1 241 if (pFileTestBuffer)
nuclear@1 242 {
nuclear@1 243 OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength));
nuclear@1 244 Seek(0, Seek_Set);
nuclear@1 245 }
nuclear@1 246 #endif
nuclear@1 247
nuclear@1 248 ErrorCode = 0;
nuclear@1 249 }
nuclear@1 250 LastOp = 0;
nuclear@1 251 }
nuclear@1 252
nuclear@1 253
nuclear@1 254 const char* FILEFile::GetFilePath()
nuclear@1 255 {
nuclear@1 256 return FileName.ToCStr();
nuclear@1 257 }
nuclear@1 258
nuclear@1 259
nuclear@1 260 // ** File Information
nuclear@1 261 bool FILEFile::IsValid()
nuclear@1 262 {
nuclear@1 263 return Opened;
nuclear@1 264 }
nuclear@1 265 bool FILEFile::IsWritable()
nuclear@1 266 {
nuclear@1 267 return IsValid() && (OpenFlags&Open_Write);
nuclear@1 268 }
nuclear@1 269 /*
nuclear@1 270 bool FILEFile::IsRecoverable()
nuclear@1 271 {
nuclear@1 272 return IsValid() && ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC);
nuclear@1 273 }
nuclear@1 274 */
nuclear@1 275
nuclear@1 276 // Return position / file size
nuclear@1 277 int FILEFile::Tell()
nuclear@1 278 {
nuclear@1 279 int pos = (int)ftell (fs);
nuclear@1 280 if (pos < 0)
nuclear@1 281 ErrorCode = SFerror();
nuclear@1 282 return pos;
nuclear@1 283 }
nuclear@1 284
nuclear@1 285 SInt64 FILEFile::LTell()
nuclear@1 286 {
nuclear@1 287 SInt64 pos = ftell(fs);
nuclear@1 288 if (pos < 0)
nuclear@1 289 ErrorCode = SFerror();
nuclear@1 290 return pos;
nuclear@1 291 }
nuclear@1 292
nuclear@1 293 int FILEFile::GetLength()
nuclear@1 294 {
nuclear@1 295 int pos = Tell();
nuclear@1 296 if (pos >= 0)
nuclear@1 297 {
nuclear@1 298 Seek (0, Seek_End);
nuclear@1 299 int size = Tell();
nuclear@1 300 Seek (pos, Seek_Set);
nuclear@1 301 return size;
nuclear@1 302 }
nuclear@1 303 return -1;
nuclear@1 304 }
nuclear@1 305 SInt64 FILEFile::LGetLength()
nuclear@1 306 {
nuclear@1 307 SInt64 pos = LTell();
nuclear@1 308 if (pos >= 0)
nuclear@1 309 {
nuclear@1 310 LSeek (0, Seek_End);
nuclear@1 311 SInt64 size = LTell();
nuclear@1 312 LSeek (pos, Seek_Set);
nuclear@1 313 return size;
nuclear@1 314 }
nuclear@1 315 return -1;
nuclear@1 316 }
nuclear@1 317
nuclear@1 318 int FILEFile::GetErrorCode()
nuclear@1 319 {
nuclear@1 320 return ErrorCode;
nuclear@1 321 }
nuclear@1 322
nuclear@1 323 // ** Stream implementation & I/O
nuclear@1 324 int FILEFile::Write(const UByte *pbuffer, int numBytes)
nuclear@1 325 {
nuclear@1 326 if (LastOp && LastOp != Open_Write)
nuclear@1 327 fflush(fs);
nuclear@1 328 LastOp = Open_Write;
nuclear@1 329 int written = (int) fwrite(pbuffer, 1, numBytes, fs);
nuclear@1 330 if (written < numBytes)
nuclear@1 331 ErrorCode = SFerror();
nuclear@1 332
nuclear@1 333 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
nuclear@1 334 if (written > 0)
nuclear@1 335 TestPos += written;
nuclear@1 336 #endif
nuclear@1 337
nuclear@1 338 return written;
nuclear@1 339 }
nuclear@1 340
nuclear@1 341 int FILEFile::Read(UByte *pbuffer, int numBytes)
nuclear@1 342 {
nuclear@1 343 if (LastOp && LastOp != Open_Read)
nuclear@1 344 fflush(fs);
nuclear@1 345 LastOp = Open_Read;
nuclear@1 346 int read = (int) fread(pbuffer, 1, numBytes, fs);
nuclear@1 347 if (read < numBytes)
nuclear@1 348 ErrorCode = SFerror();
nuclear@1 349
nuclear@1 350 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
nuclear@1 351 if (read > 0)
nuclear@1 352 {
nuclear@1 353 // Read-in data must match our pre-loaded buffer data!
nuclear@1 354 UByte* pcompareBuffer = pFileTestBuffer + TestPos;
nuclear@1 355 for (int i=0; i< read; i++)
nuclear@1 356 {
nuclear@1 357 OVR_ASSERT(pcompareBuffer[i] == pbuffer[i]);
nuclear@1 358 }
nuclear@1 359
nuclear@1 360 //OVR_ASSERT(!memcmp(pFileTestBuffer + TestPos, pbuffer, read));
nuclear@1 361 TestPos += read;
nuclear@1 362 OVR_ASSERT(ftell(fs) == (int)TestPos);
nuclear@1 363 }
nuclear@1 364 #endif
nuclear@1 365
nuclear@1 366 return read;
nuclear@1 367 }
nuclear@1 368
nuclear@1 369 // Seeks ahead to skip bytes
nuclear@1 370 int FILEFile::SkipBytes(int numBytes)
nuclear@1 371 {
nuclear@1 372 SInt64 pos = LTell();
nuclear@1 373 SInt64 newPos = LSeek(numBytes, Seek_Cur);
nuclear@1 374
nuclear@1 375 // Return -1 for major error
nuclear@1 376 if ((pos==-1) || (newPos==-1))
nuclear@1 377 {
nuclear@1 378 return -1;
nuclear@1 379 }
nuclear@1 380 //ErrorCode = ((NewPos-Pos)<numBytes) ? errno : 0;
nuclear@1 381
nuclear@1 382 return int (newPos-(int)pos);
nuclear@1 383 }
nuclear@1 384
nuclear@1 385 // Return # of bytes till EOF
nuclear@1 386 int FILEFile::BytesAvailable()
nuclear@1 387 {
nuclear@1 388 SInt64 pos = LTell();
nuclear@1 389 SInt64 endPos = LGetLength();
nuclear@1 390
nuclear@1 391 // Return -1 for major error
nuclear@1 392 if ((pos==-1) || (endPos==-1))
nuclear@1 393 {
nuclear@1 394 ErrorCode = SFerror();
nuclear@1 395 return 0;
nuclear@1 396 }
nuclear@1 397 else
nuclear@1 398 ErrorCode = 0;
nuclear@1 399
nuclear@1 400 return int (endPos-(int)pos);
nuclear@1 401 }
nuclear@1 402
nuclear@1 403 // Flush file contents
nuclear@1 404 bool FILEFile::Flush()
nuclear@1 405 {
nuclear@1 406 return !fflush(fs);
nuclear@1 407 }
nuclear@1 408
nuclear@1 409 int FILEFile::Seek(int offset, int origin)
nuclear@1 410 {
nuclear@1 411 int newOrigin = 0;
nuclear@1 412 switch(origin)
nuclear@1 413 {
nuclear@1 414 case Seek_Set: newOrigin = SEEK_SET; break;
nuclear@1 415 case Seek_Cur: newOrigin = SEEK_CUR; break;
nuclear@1 416 case Seek_End: newOrigin = SEEK_END; break;
nuclear@1 417 }
nuclear@1 418
nuclear@1 419 if (newOrigin == SEEK_SET && offset == Tell())
nuclear@1 420 return Tell();
nuclear@1 421
nuclear@1 422 if (fseek (fs, offset, newOrigin))
nuclear@1 423 {
nuclear@1 424 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
nuclear@1 425 OVR_ASSERT(0);
nuclear@1 426 #endif
nuclear@1 427 return -1;
nuclear@1 428 }
nuclear@1 429
nuclear@1 430 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
nuclear@1 431 // Track file position after seeks for read verification later.
nuclear@1 432 switch(origin)
nuclear@1 433 {
nuclear@1 434 case Seek_Set: TestPos = offset; break;
nuclear@1 435 case Seek_Cur: TestPos += offset; break;
nuclear@1 436 case Seek_End: TestPos = FileTestLength + offset; break;
nuclear@1 437 }
nuclear@1 438 OVR_ASSERT((int)TestPos == Tell());
nuclear@1 439 #endif
nuclear@1 440
nuclear@1 441 return (int)Tell();
nuclear@1 442 }
nuclear@1 443
nuclear@1 444 SInt64 FILEFile::LSeek(SInt64 offset, int origin)
nuclear@1 445 {
nuclear@1 446 return Seek((int)offset,origin);
nuclear@1 447 }
nuclear@1 448
nuclear@1 449 int FILEFile::CopyFromStream(File *pstream, int byteSize)
nuclear@1 450 {
nuclear@1 451 UByte buff[0x4000];
nuclear@1 452 int count = 0;
nuclear@1 453 int szRequest, szRead, szWritten;
nuclear@1 454
nuclear@1 455 while (byteSize)
nuclear@1 456 {
nuclear@1 457 szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize;
nuclear@1 458
nuclear@1 459 szRead = pstream->Read(buff, szRequest);
nuclear@1 460 szWritten = 0;
nuclear@1 461 if (szRead > 0)
nuclear@1 462 szWritten = Write(buff, szRead);
nuclear@1 463
nuclear@1 464 count += szWritten;
nuclear@1 465 byteSize -= szWritten;
nuclear@1 466 if (szWritten < szRequest)
nuclear@1 467 break;
nuclear@1 468 }
nuclear@1 469 return count;
nuclear@1 470 }
nuclear@1 471
nuclear@1 472
nuclear@1 473 bool FILEFile::Close()
nuclear@1 474 {
nuclear@1 475 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
nuclear@1 476 if (pFileTestBuffer)
nuclear@1 477 {
nuclear@1 478 OVR_FREE(pFileTestBuffer);
nuclear@1 479 pFileTestBuffer = 0;
nuclear@1 480 FileTestLength = 0;
nuclear@1 481 }
nuclear@1 482 #endif
nuclear@1 483
nuclear@1 484 bool closeRet = !fclose(fs);
nuclear@1 485
nuclear@1 486 if (!closeRet)
nuclear@1 487 {
nuclear@1 488 ErrorCode = SFerror();
nuclear@1 489 return 0;
nuclear@1 490 }
nuclear@1 491 else
nuclear@1 492 {
nuclear@1 493 Opened = 0;
nuclear@1 494 fs = 0;
nuclear@1 495 ErrorCode = 0;
nuclear@1 496 }
nuclear@1 497
nuclear@1 498 // Handle safe truncate
nuclear@1 499 /*
nuclear@1 500 if ((OpenFlags & OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC)
nuclear@1 501 {
nuclear@1 502 // Delete original file (if it existed)
nuclear@1 503 DWORD oldAttributes = FileUtilWin32::GetFileAttributes(FileName);
nuclear@1 504 if (oldAttributes!=0xFFFFFFFF)
nuclear@1 505 if (!FileUtilWin32::DeleteFile(FileName))
nuclear@1 506 {
nuclear@1 507 // Try to remove the readonly attribute
nuclear@1 508 FileUtilWin32::SetFileAttributes(FileName, oldAttributes & (~FILE_ATTRIBUTE_READONLY) );
nuclear@1 509 // And delete the file again
nuclear@1 510 if (!FileUtilWin32::DeleteFile(FileName))
nuclear@1 511 return 0;
nuclear@1 512 }
nuclear@1 513
nuclear@1 514 // Rename temp file to real filename
nuclear@1 515 if (!FileUtilWin32::MoveFile(TempName, FileName))
nuclear@1 516 {
nuclear@1 517 //ErrorCode = errno;
nuclear@1 518 return 0;
nuclear@1 519 }
nuclear@1 520 }
nuclear@1 521 */
nuclear@1 522 return 1;
nuclear@1 523 }
nuclear@1 524
nuclear@1 525 /*
nuclear@1 526 bool FILEFile::CloseCancel()
nuclear@1 527 {
nuclear@1 528 bool closeRet = (bool)::CloseHandle(fd);
nuclear@1 529
nuclear@1 530 if (!closeRet)
nuclear@1 531 {
nuclear@1 532 //ErrorCode = errno;
nuclear@1 533 return 0;
nuclear@1 534 }
nuclear@1 535 else
nuclear@1 536 {
nuclear@1 537 Opened = 0;
nuclear@1 538 fd = INVALID_HANDLE_VALUE;
nuclear@1 539 ErrorCode = 0;
nuclear@1 540 }
nuclear@1 541
nuclear@1 542 // Handle safe truncate (delete tmp file, leave original unchanged)
nuclear@1 543 if ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC)
nuclear@1 544 if (!FileUtilWin32::DeleteFile(TempName))
nuclear@1 545 {
nuclear@1 546 //ErrorCode = errno;
nuclear@1 547 return 0;
nuclear@1 548 }
nuclear@1 549 return 1;
nuclear@1 550 }
nuclear@1 551 */
nuclear@1 552
nuclear@1 553 File *FileFILEOpen(const String& path, int flags, int mode)
nuclear@1 554 {
nuclear@1 555 return new FILEFile(path, flags, mode);
nuclear@1 556 }
nuclear@1 557
nuclear@1 558 // Helper function: obtain file information time.
nuclear@1 559 bool SysFile::GetFileStat(FileStat* pfileStat, const String& path)
nuclear@1 560 {
nuclear@1 561 #if defined(OVR_OS_WIN32)
nuclear@1 562 // 64-bit implementation on Windows.
nuclear@1 563 struct __stat64 fileStat;
nuclear@1 564 // Stat returns 0 for success.
nuclear@1 565 wchar_t *pwpath = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(path.ToCStr())+1)*sizeof(wchar_t));
nuclear@1 566 UTF8Util::DecodeString(pwpath, path.ToCStr());
nuclear@1 567
nuclear@1 568 int ret = _wstat64(pwpath, &fileStat);
nuclear@1 569 OVR_FREE(pwpath);
nuclear@1 570 if (ret) return false;
nuclear@1 571 #else
nuclear@1 572 struct stat fileStat;
nuclear@1 573 // Stat returns 0 for success.
nuclear@1 574 if (stat(path, &fileStat) != 0)
nuclear@1 575 return false;
nuclear@1 576 #endif
nuclear@1 577 pfileStat->AccessTime = fileStat.st_atime;
nuclear@1 578 pfileStat->ModifyTime = fileStat.st_mtime;
nuclear@1 579 pfileStat->FileSize = fileStat.st_size;
nuclear@1 580 return true;
nuclear@1 581 }
nuclear@1 582
nuclear@1 583 } // Scaleform