Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #define GFILE_CXX
00018
00019
00020 #include <stdio.h>
00021
00022 #include "OVR_File.h"
00023
00024 namespace OVR {
00025
00026
00027
00028
00029 #define FILEBUFFER_SIZE (8192-8)
00030 #define FILEBUFFER_TOLERANCE 4096
00031
00032
00033
00034
00035
00036 BufferedFile::BufferedFile() : DelegatedFile(0)
00037 {
00038 pBuffer = (UByte*)OVR_ALLOC(FILEBUFFER_SIZE);
00039 BufferMode = NoBuffer;
00040 FilePos = 0;
00041 Pos = 0;
00042 DataSize = 0;
00043 }
00044
00045
00046 BufferedFile::BufferedFile(File *pfile) : DelegatedFile(pfile)
00047 {
00048 pBuffer = (UByte*)OVR_ALLOC(FILEBUFFER_SIZE);
00049 BufferMode = NoBuffer;
00050 FilePos = pfile->LTell();
00051 Pos = 0;
00052 DataSize = 0;
00053 }
00054
00055
00056
00057 BufferedFile::~BufferedFile()
00058 {
00059
00060 if (pFile)
00061 FlushBuffer();
00062
00063 if (pBuffer)
00064 OVR_FREE(pBuffer);
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 bool BufferedFile::SetBufferMode(BufferModeType mode)
00087 {
00088 if (!pBuffer)
00089 return false;
00090 if (mode == BufferMode)
00091 return true;
00092
00093 FlushBuffer();
00094
00095
00096 if ((mode==WriteBuffer) && (!pFile || !pFile->IsWritable()) )
00097 return 0;
00098
00099
00100 BufferMode = mode;
00101 Pos = 0;
00102 DataSize = 0;
00103 return 1;
00104 }
00105
00106
00107 void BufferedFile::FlushBuffer()
00108 {
00109 switch(BufferMode)
00110 {
00111 case WriteBuffer:
00112
00113 FilePos += pFile->Write(pBuffer,Pos);
00114 Pos = 0;
00115 break;
00116
00117 case ReadBuffer:
00118
00119 if ((DataSize-Pos)>0)
00120 FilePos = pFile->LSeek(-(int)(DataSize-Pos), Seek_Cur);
00121 DataSize = 0;
00122 Pos = 0;
00123 break;
00124 default:
00125
00126 break;
00127 }
00128 }
00129
00130
00131 void BufferedFile::LoadBuffer()
00132 {
00133 if (BufferMode == ReadBuffer)
00134 {
00135
00136 OVR_ASSERT(Pos == DataSize);
00137
00138
00139 int sz = pFile->Read(pBuffer,FILEBUFFER_SIZE);
00140 DataSize = sz<0 ? 0 : (unsigned)sz;
00141 Pos = 0;
00142 FilePos += DataSize;
00143 }
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153 int BufferedFile::Tell()
00154 {
00155 if (BufferMode == ReadBuffer)
00156 return int (FilePos - DataSize + Pos);
00157
00158 int pos = pFile->Tell();
00159
00160 if (pos!=-1)
00161 {
00162 OVR_ASSERT(BufferMode != ReadBuffer);
00163 if (BufferMode == WriteBuffer)
00164 pos += Pos;
00165 }
00166 return pos;
00167 }
00168
00169 SInt64 BufferedFile::LTell()
00170 {
00171 if (BufferMode == ReadBuffer)
00172 return FilePos - DataSize + Pos;
00173
00174 SInt64 pos = pFile->LTell();
00175 if (pos!=-1)
00176 {
00177 OVR_ASSERT(BufferMode != ReadBuffer);
00178 if (BufferMode == WriteBuffer)
00179 pos += Pos;
00180 }
00181 return pos;
00182 }
00183
00184 int BufferedFile::GetLength()
00185 {
00186 int len = pFile->GetLength();
00187
00188 if ((len!=-1) && (BufferMode==WriteBuffer))
00189 {
00190 int currPos = pFile->Tell() + Pos;
00191 if (currPos>len)
00192 len = currPos;
00193 }
00194 return len;
00195 }
00196 SInt64 BufferedFile::LGetLength()
00197 {
00198 SInt64 len = pFile->LGetLength();
00199
00200 if ((len!=-1) && (BufferMode==WriteBuffer))
00201 {
00202 SInt64 currPos = pFile->LTell() + Pos;
00203 if (currPos>len)
00204 len = currPos;
00205 }
00206 return len;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 int BufferedFile::Write(const UByte *psourceBuffer, int numBytes)
00232 {
00233 if ( (BufferMode==WriteBuffer) || SetBufferMode(WriteBuffer))
00234 {
00235
00236 if ((FILEBUFFER_SIZE-(int)Pos)<numBytes)
00237 {
00238 FlushBuffer();
00239
00240 if (numBytes>FILEBUFFER_TOLERANCE)
00241 {
00242 int sz = pFile->Write(psourceBuffer,numBytes);
00243 if (sz > 0)
00244 FilePos += sz;
00245 return sz;
00246 }
00247 }
00248
00249
00250 memcpy(pBuffer+Pos, psourceBuffer, numBytes);
00251 Pos += numBytes;
00252 return numBytes;
00253 }
00254 int sz = pFile->Write(psourceBuffer,numBytes);
00255 if (sz > 0)
00256 FilePos += sz;
00257 return sz;
00258 }
00259
00260 int BufferedFile::Read(UByte *pdestBuffer, int numBytes)
00261 {
00262 if ( (BufferMode==ReadBuffer) || SetBufferMode(ReadBuffer))
00263 {
00264
00265 if ((int)(DataSize-Pos) >= numBytes)
00266 {
00267 memcpy(pdestBuffer, pBuffer+Pos, numBytes);
00268 Pos += numBytes;
00269 return numBytes;
00270 }
00271
00272
00273 int readBytes = DataSize-Pos;
00274 memcpy(pdestBuffer, pBuffer+Pos, readBytes);
00275 numBytes -= readBytes;
00276 pdestBuffer += readBytes;
00277 Pos = DataSize;
00278
00279
00280
00281 if (numBytes>FILEBUFFER_TOLERANCE)
00282 {
00283 numBytes = pFile->Read(pdestBuffer,numBytes);
00284 if (numBytes > 0)
00285 {
00286 FilePos += numBytes;
00287 Pos = DataSize = 0;
00288 }
00289 return readBytes + ((numBytes==-1) ? 0 : numBytes);
00290 }
00291
00292
00293
00294 LoadBuffer();
00295 if ((int)(DataSize-Pos) < numBytes)
00296 numBytes = (int)DataSize-Pos;
00297
00298 memcpy(pdestBuffer, pBuffer+Pos, numBytes);
00299 Pos += numBytes;
00300 return numBytes + readBytes;
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 }
00326 int sz = pFile->Read(pdestBuffer,numBytes);
00327 if (sz > 0)
00328 FilePos += sz;
00329 return sz;
00330 }
00331
00332
00333 int BufferedFile::SkipBytes(int numBytes)
00334 {
00335 int skippedBytes = 0;
00336
00337
00338 if (BufferMode==ReadBuffer)
00339 {
00340 skippedBytes = (((int)DataSize-(int)Pos) >= numBytes) ? numBytes : (DataSize-Pos);
00341 Pos += skippedBytes;
00342 numBytes -= skippedBytes;
00343 }
00344
00345 if (numBytes)
00346 {
00347 numBytes = pFile->SkipBytes(numBytes);
00348
00349 if (numBytes!=-1)
00350 {
00351 skippedBytes += numBytes;
00352 FilePos += numBytes;
00353 Pos = DataSize = 0;
00354 }
00355 else if (skippedBytes <= 0)
00356 skippedBytes = -1;
00357 }
00358 return skippedBytes;
00359 }
00360
00361 int BufferedFile::BytesAvailable()
00362 {
00363 int available = pFile->BytesAvailable();
00364
00365 switch(BufferMode)
00366 {
00367 case ReadBuffer:
00368 available += DataSize-Pos;
00369 break;
00370 case WriteBuffer:
00371 available -= Pos;
00372 if (available<0)
00373 available= 0;
00374 break;
00375 default:
00376 break;
00377 }
00378 return available;
00379 }
00380
00381 bool BufferedFile::Flush()
00382 {
00383 FlushBuffer();
00384 return pFile->Flush();
00385 }
00386
00387
00388 int BufferedFile::Seek(int offset, int origin)
00389 {
00390 if (BufferMode == ReadBuffer)
00391 {
00392 if (origin == Seek_Cur)
00393 {
00394
00395
00396 if (((unsigned(offset) + Pos)) <= DataSize)
00397 {
00398 Pos += offset;
00399 return int (FilePos - DataSize + Pos);
00400 }
00401
00402
00403
00404 origin = Seek_Set;
00405 OVR_ASSERT(((FilePos - DataSize + Pos) + (UInt64)offset) < ~(UInt64)0);
00406 offset = (int)(FilePos - DataSize + Pos) + offset;
00407 Pos = DataSize = 0;
00408 }
00409 else if (origin == Seek_Set)
00410 {
00411 if (((unsigned)offset - (FilePos-DataSize)) <= DataSize)
00412 {
00413 OVR_ASSERT((FilePos-DataSize) < ~(UInt64)0);
00414 Pos = (unsigned)offset - (unsigned)(FilePos-DataSize);
00415 return offset;
00416 }
00417 Pos = DataSize = 0;
00418 }
00419 else
00420 {
00421 FlushBuffer();
00422 }
00423 }
00424 else
00425 {
00426 FlushBuffer();
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 FilePos = pFile->Seek(offset,origin);
00450 return int (FilePos);
00451 }
00452
00453 SInt64 BufferedFile::LSeek(SInt64 offset, int origin)
00454 {
00455 if (BufferMode == ReadBuffer)
00456 {
00457 if (origin == Seek_Cur)
00458 {
00459
00460
00461 if (((unsigned(offset) + Pos)) <= DataSize)
00462 {
00463 Pos += (unsigned)offset;
00464 return SInt64(FilePos - DataSize + Pos);
00465 }
00466
00467
00468
00469 origin = Seek_Set;
00470 offset = (SInt64)(FilePos - DataSize + Pos) + offset;
00471 Pos = DataSize = 0;
00472 }
00473 else if (origin == Seek_Set)
00474 {
00475 if (((UInt64)offset - (FilePos-DataSize)) <= DataSize)
00476 {
00477 Pos = (unsigned)((UInt64)offset - (FilePos-DataSize));
00478 return offset;
00479 }
00480 Pos = DataSize = 0;
00481 }
00482 else
00483 {
00484 FlushBuffer();
00485 }
00486 }
00487 else
00488 {
00489 FlushBuffer();
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 FilePos = pFile->LSeek(offset,origin);
00510 return FilePos;
00511 }
00512
00513 int BufferedFile::CopyFromStream(File *pstream, int byteSize)
00514 {
00515
00516
00517
00518 UByte buff[0x4000];
00519 int count = 0;
00520 int szRequest, szRead, szWritten;
00521
00522 while(byteSize)
00523 {
00524 szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize;
00525
00526 szRead = pstream->Read(buff,szRequest);
00527 szWritten = 0;
00528 if (szRead > 0)
00529 szWritten = Write(buff,szRead);
00530
00531 count +=szWritten;
00532 byteSize-=szWritten;
00533 if (szWritten < szRequest)
00534 break;
00535 }
00536 return count;
00537 }
00538
00539
00540 bool BufferedFile::Close()
00541 {
00542 switch(BufferMode)
00543 {
00544 case WriteBuffer:
00545 FlushBuffer();
00546 break;
00547 case ReadBuffer:
00548
00549 BufferMode = NoBuffer;
00550 break;
00551 default:
00552 break;
00553 }
00554 return pFile->Close();
00555 }
00556
00557
00558
00559
00560
00561 const char* OVR_CDECL GetShortFilename(const char* purl)
00562 {
00563 UPInt len = OVR_strlen(purl);
00564 for (UPInt i=len; i>0; i--)
00565 if (purl[i]=='\\' || purl[i]=='/')
00566 return purl+i+1;
00567 return purl;
00568 }
00569
00570 }
00571