00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "CATStreamSub.h"
00014 CATStreamSub::CATStreamSub( CATInt64 offset, CATInt64 length, CATStream* parent) :
00015 CATStream()
00016 {
00017 CATASSERT(parent != 0, "Sub streams with no parent aren't worth much....");
00018 CATASSERT(parent->IsOpen(), "The parent stream must be open, too...");
00019
00020 fParent = parent;
00021 fOffset = offset;
00022 fLength = length;
00023 fCurPos = 0;
00024 }
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 CATStreamSub::~CATStreamSub()
00035 {
00036 CATASSERT(fSubCount == 0, "You have substreams left open on a substream!");
00037 }
00038
00039
00040
00041
00042 CATResult CATStreamSub::Open(const CATWChar* name, OPEN_MODE mode)
00043 {
00044 CATASSERT(false, "Substreams are always open.");
00045 return CATRESULT(CAT_ERR_OPENING_SUBSTREAM);
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055 CATResult CATStreamSub::Close()
00056 {
00057 CATASSERT(false, "Close() should not be called on substreams.");
00058 return CATRESULT(CAT_ERR_CLOSING_SUBSTREAM);
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 bool CATStreamSub::IsOpen()
00070 {
00071 return (fParent != 0);
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 CATResult CATStreamSub::Read(void* buffer, CATUInt32& length)
00089 {
00090 CATASSERT(this->fParent != 0, "Can't read with a null parent.");
00091 if (this->fParent == 0)
00092 {
00093 return CATRESULT(CAT_ERR_SUBSTREAM_NO_PARENT);
00094 }
00095
00096 if (this->fLength != -1)
00097 {
00098 if (length + fCurPos > this->fLength)
00099 {
00100 length = (CATUInt32)(fLength - fCurPos);
00101 }
00102 }
00103
00104 CATResult result = fParent->ReadAbs(buffer,length,fCurPos + this->fOffset);
00105 fCurPos += length;
00106 return result;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 CATResult CATStreamSub::Write(const void* buffer, CATUInt32 length)
00120 {
00121 CATASSERT(this->fParent != 0, "Can't read with a null parent.");
00122 if (this->fParent == 0)
00123 {
00124 return CATRESULT(CAT_ERR_SUBSTREAM_NO_PARENT);
00125 }
00126
00127
00128 if (this->fLength != -1)
00129 {
00130 if (length + fCurPos > this->fLength)
00131 {
00132 CATTRACE("Warning! Attempt to write beyond specified end of substream! Write truncated...");
00133 if (fCurPos < fLength)
00134 {
00135 length = (CATUInt32)(fLength - fCurPos);
00136 }
00137 else
00138 {
00139 return CATRESULT(CAT_ERR_WRITE_PAST_SPECIFIED_END);
00140 }
00141 }
00142 }
00143
00144 CATResult result = fParent->WriteAbs(buffer,length,fCurPos + this->fOffset);
00145
00146
00147 if (CATSUCCEEDED(result))
00148 fCurPos += length;
00149
00150 return result;
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 CATResult CATStreamSub::Size(CATInt64& filesize)
00163 {
00164 CATResult result = CAT_SUCCESS;
00165 CATASSERT(this->fParent != 0, "Can't read with a null parent.");
00166 if (this->fParent == 0)
00167 {
00168 return CATRESULT(CAT_ERR_SUBSTREAM_NO_PARENT);
00169 }
00170
00171 if (this->fLength == -1)
00172 {
00173 this->fParent->Size(filesize);
00174 filesize -= this->fOffset;
00175 }
00176 else
00177 {
00178 filesize = this->fLength;
00179 }
00180
00181 return result;
00182 }
00183
00184
00185
00186
00187 bool CATStreamSub::IsSeekable()
00188 {
00189 return true;
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 CATResult CATStreamSub::SeekRelative(CATInt32 offset)
00201 {
00202 CATResult result = CAT_SUCCESS;
00203 CATASSERT(this->fParent != 0, "Can't read with a null parent.");
00204 if (this->fParent == 0)
00205 {
00206 return CATRESULT(CAT_ERR_SUBSTREAM_NO_PARENT);
00207 }
00208
00209 if (offset + fCurPos < 0)
00210 {
00211 fCurPos = 0;
00212 return CATRESULTFILE(CAT_ERR_FILE_SEEK,"SubStream");
00213 }
00214
00215 if (fLength != -1)
00216 {
00217 if (fCurPos + offset > fLength)
00218 {
00219 fCurPos = fLength;
00220 return CATRESULT(CAT_ERR_SEEK_PAST_SPECIFIED_END);
00221 }
00222 }
00223
00224 fCurPos += offset;
00225
00226 return CAT_SUCCESS;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 CATResult CATStreamSub::SeekAbsolute(CATInt64 position)
00239 {
00240 CATResult result = CAT_SUCCESS;
00241 CATASSERT(this->fParent != 0, "Can't read with a null parent.");
00242 if (this->fParent == 0)
00243 {
00244 return CATRESULT(CAT_ERR_SUBSTREAM_NO_PARENT);
00245 }
00246
00247 if (position < 0)
00248 {
00249 fCurPos = 0;
00250 return CATRESULTFILE(CAT_ERR_FILE_SEEK,"SubStream");
00251 }
00252
00253 if (fLength != -1)
00254 {
00255 if (position > fLength)
00256 {
00257 fCurPos = fLength;
00258 return CATRESULT(CAT_ERR_SEEK_PAST_SPECIFIED_END);
00259 }
00260 }
00261
00262 fCurPos = position;
00263
00264 return CAT_SUCCESS;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274 CATResult CATStreamSub::SeekFromEnd(CATInt32 offset)
00275 {
00276 CATResult result = CAT_SUCCESS;
00277 CATInt64 position = 0;
00278 if (CATFAILED(result = this->Size(position)))
00279 {
00280 return result;
00281 }
00282 return this->SeekAbsolute(position - offset);
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 CATResult CATStreamSub::GetPosition(CATInt64& position)
00295 {
00296 position = this->fCurPos;
00297 return CAT_SUCCESS;
00298 }
00299
00300
00301
00302
00303 CATString CATStreamSub::GetName() const
00304 {
00305 if (fParent == 0)
00306 {
00307 return L"NULLSTREAM";
00308 }
00309 return this->fParent->GetName();
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 CATResult CATStreamSub::ReadAbs(void *buffer, CATUInt32& length, CATInt64 position)
00329 {
00330 CATResult result = CAT_SUCCESS;
00331 CATInt64 orgPos = 0;
00332
00333 if (CATFAILED(result = this->GetPosition(orgPos)))
00334 {
00335 return result;
00336 }
00337
00338
00339 if (CATFAILED(result = this->SeekAbsolute(position)))
00340 {
00341 this->SeekAbsolute(orgPos);
00342 return result;
00343 }
00344
00345 if (CATFAILED(result = this->Read(buffer,length)))
00346 {
00347 this->SeekAbsolute(orgPos);
00348 return result;
00349 }
00350
00351 return this->SeekAbsolute(orgPos);
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 CATResult CATStreamSub::WriteAbs(const void *buffer, CATUInt32 length, CATInt64 position)
00368 {
00369 CATResult result = CAT_SUCCESS;
00370 CATInt64 orgPos = 0;
00371
00372 if (CATFAILED(result = this->GetPosition(orgPos)))
00373 {
00374 return result;
00375 }
00376
00377
00378 if (CATFAILED(result = this->SeekAbsolute(position)))
00379 {
00380 this->SeekAbsolute(orgPos);
00381 return result;
00382 }
00383
00384 if (CATFAILED(result = this->Write(buffer,length)))
00385 {
00386 this->SeekAbsolute(orgPos);
00387 return result;
00388 }
00389
00390 return this->SeekAbsolute(orgPos);
00391 }
00392