ovr_sdk

annotate LibOVR/Src/Kernel/OVR_FileFILE.cpp @ 0:1b39a1b46319

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