oculus1

annotate libovr/Src/Kernel/OVR_FileFILE.cpp @ 29:9a973ef0e2a3

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