00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "CATStreamFile.h"
00014 #include "CATStreamSub.h"
00015
00016 CATStreamFile::CATStreamFile() : CATStream()
00017 {
00018 fFileHandle = 0;
00019 }
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 CATStreamFile::~CATStreamFile()
00030 {
00031 CATASSERT(fFileHandle == 0, "Close your streams....");
00032 if (fFileHandle != 0)
00033 {
00034 this->Close();
00035 }
00036 }
00037
00038
00039
00040
00041 CATResult CATStreamFile::Open(const CATWChar* pathname, OPEN_MODE mode)
00042 {
00043 CATASSERT(fFileHandle == 0, "Trying to open an already open stream!");
00044 if (fFileHandle != 0)
00045 {
00046
00047 (void)this->Close();
00048 }
00049
00050
00051
00052
00053
00054
00055 switch (mode)
00056 {
00057 case READ_ONLY:
00058 fFileHandle = _wfopen(pathname,L"rb");
00059 break;
00060
00061 case READ_WRITE_EXISTING_ONLY:
00062 fFileHandle = _wfopen(pathname,L"rb+");
00063 break;
00064
00065 case READ_WRITE_EXISTING_FIRST:
00066 fFileHandle = _wfopen(pathname,L"rb+");
00067 if (fFileHandle == 0)
00068 {
00069 fFileHandle = _wfopen(pathname,L"wb+");
00070 }
00071 break;
00072
00073 case READ_WRITE_CREATE_TRUNC:
00074 {
00075 DWORD attribs = ::GetFileAttributes(pathname);
00076 if (attribs != 0xFFFFFFFF)
00077 ::DeleteFile(pathname);
00078
00079 fFileHandle = _wfopen(pathname,L"wb+");
00080 }
00081 break;
00082
00083 case WRITE_CREATE_ONLY:
00084 fFileHandle = _wfopen(pathname,L"wb");
00085 break;
00086
00087 default:
00088 CATASSERT(false,"Unsupported open mode.");
00089 return CATRESULT(CAT_ERR_FILE_UNSUPPORTED_MODE);
00090 break;
00091 }
00092
00093 if (fFileHandle == 0)
00094 {
00095 return CATRESULTFILE(CAT_ERR_FILE_OPEN,pathname);
00096 }
00097
00098 fFilename = pathname;
00099
00100 return CATRESULT(CAT_SUCCESS);
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 CATResult CATStreamFile::Close()
00112 {
00113 CATASSERT(fFileHandle != 0, "Attempting to close an already closed file.");
00114
00115 CATASSERT(fSubCount == 0, "There are still substreams left open!");
00116 if (fSubCount != 0)
00117 {
00118 return CATRESULT(CAT_ERR_FILE_HAS_OPEN_SUBSTREAMS);
00119 }
00120
00121
00122
00123
00124 if (fFileHandle == 0)
00125 {
00126 return CATRESULT(CAT_ERR_FILE_NOT_OPEN);
00127 }
00128
00129 fFilename = L"";
00130
00131 fclose(fFileHandle);
00132 fFileHandle = 0;
00133
00134 return CATRESULT(CAT_SUCCESS);
00135 }
00136
00137
00138
00139
00140
00141
00142
00143 bool CATStreamFile::IsOpen()
00144 {
00145 return (fFileHandle != 0);
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 CATResult CATStreamFile::Read(void* buffer, CATUInt32& length)
00163 {
00164 CATASSERT(fFileHandle != 0, "Reading from closed file.");
00165 CATASSERT(buffer != 0, "Null buffer passed to read.");
00166
00167 if (!IsOpen())
00168 {
00169 return CATRESULT(CAT_ERR_FILE_NOT_OPEN);
00170 }
00171
00172 CATUInt32 amountRead = (CATUInt32)fread(buffer,1,length,fFileHandle);
00173 if (length != amountRead)
00174 {
00175 if (feof(fFileHandle))
00176 {
00177
00178
00179
00180 length = amountRead;
00181 return CATRESULT(CAT_STAT_FILE_AT_EOF);
00182 }
00183
00184 length = amountRead;
00185 return CATRESULTFILE(CAT_ERR_FILE_READ,fFilename);
00186 }
00187 else
00188 {
00189 return CATRESULT(CAT_SUCCESS);
00190 }
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 CATResult CATStreamFile::Write(const void* buffer, CATUInt32 length)
00204 {
00205 CATASSERT(fFileHandle != 0, "Reading from closed file.");
00206 CATASSERT(buffer != 0, "Null buffer passed to read.");
00207
00208 if (!IsOpen())
00209 {
00210 return CATRESULT(CAT_ERR_FILE_NOT_OPEN);
00211 }
00212
00213 CATUInt32 amountWritten = (CATUInt32)fwrite(buffer,1,length,fFileHandle);
00214
00215 if (length != amountWritten)
00216 {
00217 return CATRESULTFILE(CAT_ERR_FILE_WRITE,fFilename);
00218 }
00219 else
00220 {
00221
00222 fflush(fFileHandle);
00223 return CAT_SUCCESS;
00224 }
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 CATResult CATStreamFile::Size(CATInt64& filesize)
00237 {
00238 CATASSERT(fFileHandle != 0, "File must be opened first.");
00239 if (!IsOpen())
00240 {
00241 return CATRESULT(CAT_ERR_FILE_NOT_OPEN);
00242 }
00243
00244
00245 fpos_t curPos;
00246 if (0 != fgetpos(fFileHandle, &curPos))
00247 {
00248 return CATRESULTFILE(CAT_ERR_FILE_GET_POSITION,fFilename);
00249 }
00250
00251
00252 if (0 != fseek(fFileHandle,0,SEEK_END))
00253 {
00254 return CATRESULTFILE(CAT_ERR_FILE_SEEK,fFilename);
00255 }
00256
00257 fpos_t eofPos;
00258
00259 if (0 != fgetpos(fFileHandle, &eofPos))
00260 {
00261 return CATRESULTFILE(CAT_ERR_FILE_GET_POSITION,fFilename);
00262 }
00263
00264
00265 if (0 != fsetpos(fFileHandle,&curPos))
00266 {
00267 return CATRESULTFILE(CAT_ERR_FILE_SET_POSITION,fFilename);
00268 }
00269
00270 filesize = eofPos;
00271
00272 return CAT_SUCCESS;
00273 }
00274
00275
00276
00277
00278 bool CATStreamFile::IsSeekable()
00279 {
00280 return true;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 CATResult CATStreamFile::SeekRelative(CATInt32 offset)
00292 {
00293 CATASSERT(fFileHandle != 0, "File must be opened first.");
00294 if (!IsOpen())
00295 {
00296 return CATRESULT(CAT_ERR_FILE_NOT_OPEN);
00297 }
00298
00299 if ( 0 != fseek(fFileHandle,offset,SEEK_CUR))
00300 {
00301 return CATRESULTFILE(CAT_ERR_FILE_SEEK,fFilename);
00302 }
00303 return CAT_SUCCESS;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 CATResult CATStreamFile::SeekAbsolute(CATInt64 position)
00316 {
00317 CATASSERT(fFileHandle != 0, "File must be opened first.");
00318 if (!IsOpen())
00319 {
00320 return CATRESULT(CAT_ERR_FILE_NOT_OPEN);
00321 }
00322
00323 fpos_t filePos = position;
00324 if (0 != fsetpos(fFileHandle,&filePos))
00325 {
00326 return CATRESULTFILE(CAT_ERR_FILE_SET_POSITION,fFilename);
00327 }
00328
00329 return CAT_SUCCESS;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 CATResult CATStreamFile::SeekFromEnd(CATInt32 offset)
00340 {
00341 CATASSERT(fFileHandle != 0, "File must be opened first.");
00342 if (!IsOpen())
00343 {
00344 return CATRESULT(CAT_ERR_FILE_NOT_OPEN);
00345 }
00346
00347 if (0 != fseek(fFileHandle,-offset,SEEK_END))
00348 {
00349 return CATRESULTFILE(CAT_ERR_FILE_SEEK,fFilename);
00350 }
00351
00352 return CAT_SUCCESS;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 CATResult CATStreamFile::GetPosition(CATInt64& position)
00365 {
00366 CATASSERT(fFileHandle != 0, "File must be opened first.");
00367 if (!IsOpen())
00368 {
00369 return CATRESULT(CAT_ERR_FILE_NOT_OPEN);
00370 }
00371
00372 fpos_t curPos;
00373 if (0 != fgetpos(fFileHandle, &curPos))
00374 {
00375 return CATRESULTFILE(CAT_ERR_FILE_GET_POSITION,fFilename);
00376 }
00377
00378 position = curPos;
00379
00380 return CAT_SUCCESS;
00381 }
00382
00383
00384
00385
00386 CATString CATStreamFile::GetName() const
00387 {
00388 return fFilename;
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 CATResult CATStreamFile::ReadAbs(void *buffer, CATUInt32& length, CATInt64 position)
00406 {
00407 CATResult result = CAT_SUCCESS;
00408 CATInt64 orgPos = 0;
00409
00410 if (CATFAILED(result = this->GetPosition(orgPos)))
00411 {
00412 return result;
00413 }
00414
00415
00416 if (CATFAILED(result = this->SeekAbsolute(position)))
00417 {
00418 this->SeekAbsolute(orgPos);
00419 return result;
00420 }
00421
00422 if (CATFAILED(result = this->Read(buffer,length)))
00423 {
00424 this->SeekAbsolute(orgPos);
00425 return result;
00426 }
00427
00428 return this->SeekAbsolute(orgPos);
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 CATResult CATStreamFile::WriteAbs(const void *buffer, CATUInt32 length, CATInt64 position)
00445 {
00446 CATResult result = CAT_SUCCESS;
00447 CATInt64 orgPos = 0;
00448
00449 if (CATFAILED(result = this->GetPosition(orgPos)))
00450 {
00451 return result;
00452 }
00453
00454
00455 if (CATFAILED(result = this->SeekAbsolute(position)))
00456 {
00457 this->SeekAbsolute(orgPos);
00458 return result;
00459 }
00460
00461 if (CATFAILED(result = this->Write(buffer,length)))
00462 {
00463 this->SeekAbsolute(orgPos);
00464 return result;
00465 }
00466
00467 return this->SeekAbsolute(orgPos);
00468 }
00469