ovr_sdk

annotate LibOVR/Src/Kernel/OVR_File.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_File.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 // Standard C library (Captain Obvious guarantees!)
nuclear@0 31 #include <stdio.h>
nuclear@0 32
nuclear@0 33 #include "OVR_File.h"
nuclear@0 34
nuclear@0 35 namespace OVR {
nuclear@0 36
nuclear@0 37 // Buffered file adds buffering to an existing file
nuclear@0 38 // FILEBUFFER_SIZE defines the size of internal buffer, while
nuclear@0 39 // FILEBUFFER_TOLERANCE controls the amount of data we'll effectively try to buffer
nuclear@0 40 #define FILEBUFFER_SIZE (8192-8)
nuclear@0 41 #define FILEBUFFER_TOLERANCE 4096
nuclear@0 42
nuclear@0 43 // ** Constructor/Destructor
nuclear@0 44
nuclear@0 45 // Hidden constructor
nuclear@0 46 // Not supposed to be used
nuclear@0 47 BufferedFile::BufferedFile() : DelegatedFile(0)
nuclear@0 48 {
nuclear@0 49 pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE);
nuclear@0 50 BufferMode = NoBuffer;
nuclear@0 51 FilePos = 0;
nuclear@0 52 Pos = 0;
nuclear@0 53 DataSize = 0;
nuclear@0 54 }
nuclear@0 55
nuclear@0 56 // Takes another file as source
nuclear@0 57 BufferedFile::BufferedFile(File *pfile) : DelegatedFile(pfile)
nuclear@0 58 {
nuclear@0 59 pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE);
nuclear@0 60 BufferMode = NoBuffer;
nuclear@0 61 FilePos = pfile->LTell();
nuclear@0 62 Pos = 0;
nuclear@0 63 DataSize = 0;
nuclear@0 64 }
nuclear@0 65
nuclear@0 66
nuclear@0 67 // Destructor
nuclear@0 68 BufferedFile::~BufferedFile()
nuclear@0 69 {
nuclear@0 70 // Flush in case there's data
nuclear@0 71 if (pFile)
nuclear@0 72 FlushBuffer();
nuclear@0 73 // Get rid of buffer
nuclear@0 74 if (pBuffer)
nuclear@0 75 OVR_FREE(pBuffer);
nuclear@0 76 }
nuclear@0 77
nuclear@0 78 /*
nuclear@0 79 bool BufferedFile::VCopy(const Object &source)
nuclear@0 80 {
nuclear@0 81 if (!DelegatedFile::VCopy(source))
nuclear@0 82 return 0;
nuclear@0 83
nuclear@0 84 // Data members
nuclear@0 85 BufferedFile *psource = (BufferedFile*)&source;
nuclear@0 86
nuclear@0 87 // Buffer & the mode it's in
nuclear@0 88 pBuffer = psource->pBuffer;
nuclear@0 89 BufferMode = psource->BufferMode;
nuclear@0 90 Pos = psource->Pos;
nuclear@0 91 DataSize = psource->DataSize;
nuclear@0 92 return 1;
nuclear@0 93 }
nuclear@0 94 */
nuclear@0 95
nuclear@0 96 // Initializes buffering to a certain mode
nuclear@0 97 bool BufferedFile::SetBufferMode(BufferModeType mode)
nuclear@0 98 {
nuclear@0 99 if (!pBuffer)
nuclear@0 100 return false;
nuclear@0 101 if (mode == BufferMode)
nuclear@0 102 return true;
nuclear@0 103
nuclear@0 104 FlushBuffer();
nuclear@0 105
nuclear@0 106 // Can't set write mode if we can't write
nuclear@0 107 if ((mode==WriteBuffer) && (!pFile || !pFile->IsWritable()) )
nuclear@0 108 return 0;
nuclear@0 109
nuclear@0 110 // And SetMode
nuclear@0 111 BufferMode = mode;
nuclear@0 112 Pos = 0;
nuclear@0 113 DataSize = 0;
nuclear@0 114 return 1;
nuclear@0 115 }
nuclear@0 116
nuclear@0 117 // Flushes buffer
nuclear@0 118 void BufferedFile::FlushBuffer()
nuclear@0 119 {
nuclear@0 120 switch(BufferMode)
nuclear@0 121 {
nuclear@0 122 case WriteBuffer:
nuclear@0 123 // Write data in buffer
nuclear@0 124 FilePos += pFile->Write(pBuffer,Pos);
nuclear@0 125 Pos = 0;
nuclear@0 126 break;
nuclear@0 127
nuclear@0 128 case ReadBuffer:
nuclear@0 129 // Seek back & reset buffer data
nuclear@0 130 if ((DataSize-Pos)>0)
nuclear@0 131 FilePos = pFile->LSeek(-(int)(DataSize-Pos), Seek_Cur);
nuclear@0 132 DataSize = 0;
nuclear@0 133 Pos = 0;
nuclear@0 134 break;
nuclear@0 135 default:
nuclear@0 136 // not handled!
nuclear@0 137 break;
nuclear@0 138 }
nuclear@0 139 }
nuclear@0 140
nuclear@0 141 // Reloads data for ReadBuffer
nuclear@0 142 void BufferedFile::LoadBuffer()
nuclear@0 143 {
nuclear@0 144 if (BufferMode == ReadBuffer)
nuclear@0 145 {
nuclear@0 146 // We should only reload once all of pre-loaded buffer is consumed.
nuclear@0 147 OVR_ASSERT(Pos == DataSize);
nuclear@0 148
nuclear@0 149 // WARNING: Right now LoadBuffer() assumes the buffer's empty
nuclear@0 150 int sz = pFile->Read(pBuffer,FILEBUFFER_SIZE);
nuclear@0 151 DataSize = sz<0 ? 0 : (unsigned)sz;
nuclear@0 152 Pos = 0;
nuclear@0 153 FilePos += DataSize;
nuclear@0 154 }
nuclear@0 155 }
nuclear@0 156
nuclear@0 157
nuclear@0 158 // ** Overridden functions
nuclear@0 159
nuclear@0 160 // We override all the functions that can possibly
nuclear@0 161 // require buffer mode switch, flush, or extra calculations
nuclear@0 162
nuclear@0 163 // Tell() requires buffer adjustment
nuclear@0 164 int BufferedFile::Tell()
nuclear@0 165 {
nuclear@0 166 if (BufferMode == ReadBuffer)
nuclear@0 167 return int (FilePos - DataSize + Pos);
nuclear@0 168
nuclear@0 169 int pos = pFile->Tell();
nuclear@0 170 // Adjust position based on buffer mode & data
nuclear@0 171 if (pos!=-1)
nuclear@0 172 {
nuclear@0 173 OVR_ASSERT(BufferMode != ReadBuffer);
nuclear@0 174 if (BufferMode == WriteBuffer)
nuclear@0 175 pos += Pos;
nuclear@0 176 }
nuclear@0 177 return pos;
nuclear@0 178 }
nuclear@0 179
nuclear@0 180 int64_t BufferedFile::LTell()
nuclear@0 181 {
nuclear@0 182 if (BufferMode == ReadBuffer)
nuclear@0 183 return FilePos - DataSize + Pos;
nuclear@0 184
nuclear@0 185 int64_t pos = pFile->LTell();
nuclear@0 186 if (pos!=-1)
nuclear@0 187 {
nuclear@0 188 OVR_ASSERT(BufferMode != ReadBuffer);
nuclear@0 189 if (BufferMode == WriteBuffer)
nuclear@0 190 pos += Pos;
nuclear@0 191 }
nuclear@0 192 return pos;
nuclear@0 193 }
nuclear@0 194
nuclear@0 195 int BufferedFile::GetLength()
nuclear@0 196 {
nuclear@0 197 int len = pFile->GetLength();
nuclear@0 198 // If writing through buffer, file length may actually be bigger
nuclear@0 199 if ((len!=-1) && (BufferMode==WriteBuffer))
nuclear@0 200 {
nuclear@0 201 int currPos = pFile->Tell() + Pos;
nuclear@0 202 if (currPos>len)
nuclear@0 203 len = currPos;
nuclear@0 204 }
nuclear@0 205 return len;
nuclear@0 206 }
nuclear@0 207 int64_t BufferedFile::LGetLength()
nuclear@0 208 {
nuclear@0 209 int64_t len = pFile->LGetLength();
nuclear@0 210 // If writing through buffer, file length may actually be bigger
nuclear@0 211 if ((len!=-1) && (BufferMode==WriteBuffer))
nuclear@0 212 {
nuclear@0 213 int64_t currPos = pFile->LTell() + Pos;
nuclear@0 214 if (currPos>len)
nuclear@0 215 len = currPos;
nuclear@0 216 }
nuclear@0 217 return len;
nuclear@0 218 }
nuclear@0 219
nuclear@0 220 /*
nuclear@0 221 bool BufferedFile::Stat(FileStats *pfs)
nuclear@0 222 {
nuclear@0 223 // Have to fix up length is stat
nuclear@0 224 if (pFile->Stat(pfs))
nuclear@0 225 {
nuclear@0 226 if (BufferMode==WriteBuffer)
nuclear@0 227 {
nuclear@0 228 int64_t currPos = pFile->LTell() + Pos;
nuclear@0 229 if (currPos > pfs->Size)
nuclear@0 230 {
nuclear@0 231 pfs->Size = currPos;
nuclear@0 232 // ??
nuclear@0 233 pfs->Blocks = (pfs->Size+511) >> 9;
nuclear@0 234 }
nuclear@0 235 }
nuclear@0 236 return 1;
nuclear@0 237 }
nuclear@0 238 return 0;
nuclear@0 239 }
nuclear@0 240 */
nuclear@0 241
nuclear@0 242 int BufferedFile::Write(const uint8_t *psourceBuffer, int numBytes)
nuclear@0 243 {
nuclear@0 244 if ( (BufferMode==WriteBuffer) || SetBufferMode(WriteBuffer))
nuclear@0 245 {
nuclear@0 246 // If not data space in buffer, flush
nuclear@0 247 if ((FILEBUFFER_SIZE-(int)Pos)<numBytes)
nuclear@0 248 {
nuclear@0 249 FlushBuffer();
nuclear@0 250 // If bigger then tolerance, just write directly
nuclear@0 251 if (numBytes>FILEBUFFER_TOLERANCE)
nuclear@0 252 {
nuclear@0 253 int sz = pFile->Write(psourceBuffer,numBytes);
nuclear@0 254 if (sz > 0)
nuclear@0 255 FilePos += sz;
nuclear@0 256 return sz;
nuclear@0 257 }
nuclear@0 258 }
nuclear@0 259
nuclear@0 260 // Enough space in buffer.. so copy to it
nuclear@0 261 memcpy(pBuffer+Pos, psourceBuffer, numBytes);
nuclear@0 262 Pos += numBytes;
nuclear@0 263 return numBytes;
nuclear@0 264 }
nuclear@0 265 int sz = pFile->Write(psourceBuffer,numBytes);
nuclear@0 266 if (sz > 0)
nuclear@0 267 FilePos += sz;
nuclear@0 268 return sz;
nuclear@0 269 }
nuclear@0 270
nuclear@0 271 int BufferedFile::Read(uint8_t *pdestBuffer, int numBytes)
nuclear@0 272 {
nuclear@0 273 if ( (BufferMode==ReadBuffer) || SetBufferMode(ReadBuffer))
nuclear@0 274 {
nuclear@0 275 // Data in buffer... copy it
nuclear@0 276 if ((int)(DataSize-Pos) >= numBytes)
nuclear@0 277 {
nuclear@0 278 memcpy(pdestBuffer, pBuffer+Pos, numBytes);
nuclear@0 279 Pos += numBytes;
nuclear@0 280 return numBytes;
nuclear@0 281 }
nuclear@0 282
nuclear@0 283 // Not enough data in buffer, copy buffer
nuclear@0 284 int readBytes = DataSize-Pos;
nuclear@0 285 memcpy(pdestBuffer, pBuffer+Pos, readBytes);
nuclear@0 286 numBytes -= readBytes;
nuclear@0 287 pdestBuffer += readBytes;
nuclear@0 288 Pos = DataSize;
nuclear@0 289
nuclear@0 290 // Don't reload buffer if more then tolerance
nuclear@0 291 // (No major advantage, and we don't want to write a loop)
nuclear@0 292 if (numBytes>FILEBUFFER_TOLERANCE)
nuclear@0 293 {
nuclear@0 294 numBytes = pFile->Read(pdestBuffer,numBytes);
nuclear@0 295 if (numBytes > 0)
nuclear@0 296 {
nuclear@0 297 FilePos += numBytes;
nuclear@0 298 Pos = DataSize = 0;
nuclear@0 299 }
nuclear@0 300 return readBytes + ((numBytes==-1) ? 0 : numBytes);
nuclear@0 301 }
nuclear@0 302
nuclear@0 303 // Reload the buffer
nuclear@0 304 // WARNING: Right now LoadBuffer() assumes the buffer's empty
nuclear@0 305 LoadBuffer();
nuclear@0 306 if ((int)(DataSize-Pos) < numBytes)
nuclear@0 307 numBytes = (int)DataSize-Pos;
nuclear@0 308
nuclear@0 309 memcpy(pdestBuffer, pBuffer+Pos, numBytes);
nuclear@0 310 Pos += numBytes;
nuclear@0 311 return numBytes + readBytes;
nuclear@0 312
nuclear@0 313 /*
nuclear@0 314 // Alternative Read implementation. The one above is probably better
nuclear@0 315 // due to FILEBUFFER_TOLERANCE.
nuclear@0 316 int total = 0;
nuclear@0 317
nuclear@0 318 do {
nuclear@0 319 int bufferBytes = (int)(DataSize-Pos);
nuclear@0 320 int copyBytes = (bufferBytes > numBytes) ? numBytes : bufferBytes;
nuclear@0 321
nuclear@0 322 memcpy(pdestBuffer, pBuffer+Pos, copyBytes);
nuclear@0 323 numBytes -= copyBytes;
nuclear@0 324 pdestBuffer += copyBytes;
nuclear@0 325 Pos += copyBytes;
nuclear@0 326 total += copyBytes;
nuclear@0 327
nuclear@0 328 if (numBytes == 0)
nuclear@0 329 break;
nuclear@0 330 LoadBuffer();
nuclear@0 331
nuclear@0 332 } while (DataSize > 0);
nuclear@0 333
nuclear@0 334 return total;
nuclear@0 335 */
nuclear@0 336 }
nuclear@0 337 int sz = pFile->Read(pdestBuffer,numBytes);
nuclear@0 338 if (sz > 0)
nuclear@0 339 FilePos += sz;
nuclear@0 340 return sz;
nuclear@0 341 }
nuclear@0 342
nuclear@0 343
nuclear@0 344 int BufferedFile::SkipBytes(int numBytes)
nuclear@0 345 {
nuclear@0 346 int skippedBytes = 0;
nuclear@0 347
nuclear@0 348 // Special case for skipping a little data in read buffer
nuclear@0 349 if (BufferMode==ReadBuffer)
nuclear@0 350 {
nuclear@0 351 skippedBytes = (((int)DataSize-(int)Pos) >= numBytes) ? numBytes : (DataSize-Pos);
nuclear@0 352 Pos += skippedBytes;
nuclear@0 353 numBytes -= skippedBytes;
nuclear@0 354 }
nuclear@0 355
nuclear@0 356 if (numBytes)
nuclear@0 357 {
nuclear@0 358 numBytes = pFile->SkipBytes(numBytes);
nuclear@0 359 // Make sure we return the actual number skipped, or error
nuclear@0 360 if (numBytes!=-1)
nuclear@0 361 {
nuclear@0 362 skippedBytes += numBytes;
nuclear@0 363 FilePos += numBytes;
nuclear@0 364 Pos = DataSize = 0;
nuclear@0 365 }
nuclear@0 366 else if (skippedBytes <= 0)
nuclear@0 367 skippedBytes = -1;
nuclear@0 368 }
nuclear@0 369 return skippedBytes;
nuclear@0 370 }
nuclear@0 371
nuclear@0 372 int BufferedFile::BytesAvailable()
nuclear@0 373 {
nuclear@0 374 int available = pFile->BytesAvailable();
nuclear@0 375 // Adjust available size based on buffers
nuclear@0 376 switch(BufferMode)
nuclear@0 377 {
nuclear@0 378 case ReadBuffer:
nuclear@0 379 available += DataSize-Pos;
nuclear@0 380 break;
nuclear@0 381 case WriteBuffer:
nuclear@0 382 available -= Pos;
nuclear@0 383 if (available<0)
nuclear@0 384 available= 0;
nuclear@0 385 break;
nuclear@0 386 default:
nuclear@0 387 break;
nuclear@0 388 }
nuclear@0 389 return available;
nuclear@0 390 }
nuclear@0 391
nuclear@0 392 bool BufferedFile::Flush()
nuclear@0 393 {
nuclear@0 394 FlushBuffer();
nuclear@0 395 return pFile->Flush();
nuclear@0 396 }
nuclear@0 397
nuclear@0 398 // Seeking could be optimized better..
nuclear@0 399 int BufferedFile::Seek(int offset, int origin)
nuclear@0 400 {
nuclear@0 401 if (BufferMode == ReadBuffer)
nuclear@0 402 {
nuclear@0 403 if (origin == Seek_Cur)
nuclear@0 404 {
nuclear@0 405 // Seek can fall either before or after Pos in the buffer,
nuclear@0 406 // but it must be within bounds.
nuclear@0 407 if (((unsigned(offset) + Pos)) <= DataSize)
nuclear@0 408 {
nuclear@0 409 Pos += offset;
nuclear@0 410 return int (FilePos - DataSize + Pos);
nuclear@0 411 }
nuclear@0 412
nuclear@0 413 // Lightweight buffer "Flush". We do this to avoid an extra seek
nuclear@0 414 // back operation which would take place if we called FlushBuffer directly.
nuclear@0 415 origin = Seek_Set;
nuclear@0 416 OVR_ASSERT(((FilePos - DataSize + Pos) + (uint64_t)offset) < ~(uint64_t)0);
nuclear@0 417 offset = (int)(FilePos - DataSize + Pos) + offset;
nuclear@0 418 Pos = DataSize = 0;
nuclear@0 419 }
nuclear@0 420 else if (origin == Seek_Set)
nuclear@0 421 {
nuclear@0 422 if (((unsigned)offset - (FilePos-DataSize)) <= DataSize)
nuclear@0 423 {
nuclear@0 424 OVR_ASSERT((FilePos-DataSize) < ~(uint64_t)0);
nuclear@0 425 Pos = (unsigned)offset - (unsigned)(FilePos-DataSize);
nuclear@0 426 return offset;
nuclear@0 427 }
nuclear@0 428 Pos = DataSize = 0;
nuclear@0 429 }
nuclear@0 430 else
nuclear@0 431 {
nuclear@0 432 FlushBuffer();
nuclear@0 433 }
nuclear@0 434 }
nuclear@0 435 else
nuclear@0 436 {
nuclear@0 437 FlushBuffer();
nuclear@0 438 }
nuclear@0 439
nuclear@0 440 /*
nuclear@0 441 // Old Seek Logic
nuclear@0 442 if (origin == Seek_Cur && offset + Pos < DataSize)
nuclear@0 443 {
nuclear@0 444 //OVR_ASSERT((FilePos - DataSize) >= (FilePos - DataSize + Pos + offset));
nuclear@0 445 Pos += offset;
nuclear@0 446 OVR_ASSERT(int (Pos) >= 0);
nuclear@0 447 return int (FilePos - DataSize + Pos);
nuclear@0 448 }
nuclear@0 449 else if (origin == Seek_Set && unsigned(offset) >= FilePos - DataSize && unsigned(offset) < FilePos)
nuclear@0 450 {
nuclear@0 451 Pos = unsigned(offset - FilePos + DataSize);
nuclear@0 452 OVR_ASSERT(int (Pos) >= 0);
nuclear@0 453 return int (FilePos - DataSize + Pos);
nuclear@0 454 }
nuclear@0 455
nuclear@0 456 FlushBuffer();
nuclear@0 457 */
nuclear@0 458
nuclear@0 459
nuclear@0 460 FilePos = pFile->Seek(offset,origin);
nuclear@0 461 return int (FilePos);
nuclear@0 462 }
nuclear@0 463
nuclear@0 464 int64_t BufferedFile::LSeek(int64_t offset, int origin)
nuclear@0 465 {
nuclear@0 466 if (BufferMode == ReadBuffer)
nuclear@0 467 {
nuclear@0 468 if (origin == Seek_Cur)
nuclear@0 469 {
nuclear@0 470 // Seek can fall either before or after Pos in the buffer,
nuclear@0 471 // but it must be within bounds.
nuclear@0 472 if (((unsigned(offset) + Pos)) <= DataSize)
nuclear@0 473 {
nuclear@0 474 Pos += (unsigned)offset;
nuclear@0 475 return int64_t(FilePos - DataSize + Pos);
nuclear@0 476 }
nuclear@0 477
nuclear@0 478 // Lightweight buffer "Flush". We do this to avoid an extra seek
nuclear@0 479 // back operation which would take place if we called FlushBuffer directly.
nuclear@0 480 origin = Seek_Set;
nuclear@0 481 offset = (int64_t)(FilePos - DataSize + Pos) + offset;
nuclear@0 482 Pos = DataSize = 0;
nuclear@0 483 }
nuclear@0 484 else if (origin == Seek_Set)
nuclear@0 485 {
nuclear@0 486 if (((uint64_t)offset - (FilePos-DataSize)) <= DataSize)
nuclear@0 487 {
nuclear@0 488 Pos = (unsigned)((uint64_t)offset - (FilePos-DataSize));
nuclear@0 489 return offset;
nuclear@0 490 }
nuclear@0 491 Pos = DataSize = 0;
nuclear@0 492 }
nuclear@0 493 else
nuclear@0 494 {
nuclear@0 495 FlushBuffer();
nuclear@0 496 }
nuclear@0 497 }
nuclear@0 498 else
nuclear@0 499 {
nuclear@0 500 FlushBuffer();
nuclear@0 501 }
nuclear@0 502
nuclear@0 503 /*
nuclear@0 504 OVR_ASSERT(BufferMode != NoBuffer);
nuclear@0 505
nuclear@0 506 if (origin == Seek_Cur && offset + Pos < DataSize)
nuclear@0 507 {
nuclear@0 508 Pos += int (offset);
nuclear@0 509 return FilePos - DataSize + Pos;
nuclear@0 510 }
nuclear@0 511 else if (origin == Seek_Set && offset >= int64_t(FilePos - DataSize) && offset < int64_t(FilePos))
nuclear@0 512 {
nuclear@0 513 Pos = unsigned(offset - FilePos + DataSize);
nuclear@0 514 return FilePos - DataSize + Pos;
nuclear@0 515 }
nuclear@0 516
nuclear@0 517 FlushBuffer();
nuclear@0 518 */
nuclear@0 519
nuclear@0 520 FilePos = pFile->LSeek(offset,origin);
nuclear@0 521 return FilePos;
nuclear@0 522 }
nuclear@0 523
nuclear@0 524 int BufferedFile::CopyFromStream(File *pstream, int byteSize)
nuclear@0 525 {
nuclear@0 526 // We can't rely on overridden Write()
nuclear@0 527 // because delegation doesn't override virtual pointers
nuclear@0 528 // So, just re-implement
nuclear@0 529 uint8_t* buff = new uint8_t[0x4000];
nuclear@0 530 int count = 0;
nuclear@0 531 int szRequest, szRead, szWritten;
nuclear@0 532
nuclear@0 533 while(byteSize)
nuclear@0 534 {
nuclear@0 535 szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize;
nuclear@0 536
nuclear@0 537 szRead = pstream->Read(buff,szRequest);
nuclear@0 538 szWritten = 0;
nuclear@0 539 if (szRead > 0)
nuclear@0 540 szWritten = Write(buff,szRead);
nuclear@0 541
nuclear@0 542 count +=szWritten;
nuclear@0 543 byteSize-=szWritten;
nuclear@0 544 if (szWritten < szRequest)
nuclear@0 545 break;
nuclear@0 546 }
nuclear@0 547
nuclear@0 548 delete[] buff;
nuclear@0 549
nuclear@0 550 return count;
nuclear@0 551 }
nuclear@0 552
nuclear@0 553 // Closing files
nuclear@0 554 bool BufferedFile::Close()
nuclear@0 555 {
nuclear@0 556 switch(BufferMode)
nuclear@0 557 {
nuclear@0 558 case WriteBuffer:
nuclear@0 559 FlushBuffer();
nuclear@0 560 break;
nuclear@0 561 case ReadBuffer:
nuclear@0 562 // No need to seek back on close
nuclear@0 563 BufferMode = NoBuffer;
nuclear@0 564 break;
nuclear@0 565 default:
nuclear@0 566 break;
nuclear@0 567 }
nuclear@0 568 return pFile->Close();
nuclear@0 569 }
nuclear@0 570
nuclear@0 571
nuclear@0 572 // ***** Global path helpers
nuclear@0 573
nuclear@0 574 // Find trailing short filename in a path.
nuclear@0 575 const char* OVR_CDECL GetShortFilename(const char* purl)
nuclear@0 576 {
nuclear@0 577 size_t len = OVR_strlen(purl);
nuclear@0 578 for (size_t i=len; i>0; i--)
nuclear@0 579 if (purl[i]=='\\' || purl[i]=='/')
nuclear@0 580 return purl+i+1;
nuclear@0 581 return purl;
nuclear@0 582 }
nuclear@0 583
nuclear@0 584 } // OVR
nuclear@0 585