diff options
author | Max Horn | 2006-11-13 20:58:21 +0000 |
---|---|---|
committer | Max Horn | 2006-11-13 20:58:21 +0000 |
commit | cce7cba3b4d9efd123192aebdbbdb8dad7531509 (patch) | |
tree | a6f8c06e752a338dcb01b839d44ddba395890c35 /common | |
parent | 86d988132c8e422d34fd5732e18277253865791b (diff) | |
download | scummvm-rg350-cce7cba3b4d9efd123192aebdbbdb8dad7531509.tar.gz scummvm-rg350-cce7cba3b4d9efd123192aebdbbdb8dad7531509.tar.bz2 scummvm-rg350-cce7cba3b4d9efd123192aebdbbdb8dad7531509.zip |
Patch #1583931: (Seekable)SubReadStream
svn-id: r24713
Diffstat (limited to 'common')
-rw-r--r-- | common/stream.cpp | 40 | ||||
-rw-r--r-- | common/stream.h | 41 |
2 files changed, 78 insertions, 3 deletions
diff --git a/common/stream.cpp b/common/stream.cpp index 1e9c3134d1..94ca514ad1 100644 --- a/common/stream.cpp +++ b/common/stream.cpp @@ -105,7 +105,7 @@ char *SeekableReadStream::readLine(char *buf, size_t bufSize) { c = readByte(); } - + // This should fix a bug while using readLine with Common::File // it seems that it sets the eos flag after an invalid read // and at the same time the ioFailed flag @@ -118,5 +118,43 @@ char *SeekableReadStream::readLine(char *buf, size_t bufSize) { return buf; } +uint32 SubReadStream::read(void *dataPtr, uint32 dataSize) { + dataSize = MIN(dataSize, _end - _pos); + + dataSize = _parentStream->read(dataPtr, dataSize); + _pos += dataSize; + + return dataSize; +} + +SeekableSubReadStream::SeekableSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end) + : SubReadStream(parentStream, end), + _parentStream(parentStream), + _begin(begin) { + assert(_begin <= _end); + _pos = _begin; + _parentStream->seek(_pos); +} + +void SeekableSubReadStream::seek(int32 offset, int whence) { + assert(_pos >= _begin); + assert(_pos <= _end); + + switch(whence) { + case SEEK_END: + offset = size() - offset; + // fallthrough + case SEEK_SET: + _pos = _begin + offset; + break; + case SEEK_CUR: + _pos += offset; + } + + assert(_pos >= _begin); + assert(_pos <= _end); + + _parentStream->seek(_pos); +} } // End of namespace Common diff --git a/common/stream.h b/common/stream.h index 16b129d9c4..84eac2ac44 100644 --- a/common/stream.h +++ b/common/stream.h @@ -210,14 +210,14 @@ public: * @todo We really need better error handling here! * Like seek should somehow indicate whether it failed. */ -class SeekableReadStream : public ReadStream { +class SeekableReadStream : virtual public ReadStream { public: virtual uint32 pos() const = 0; virtual uint32 size() const = 0; virtual void seek(int32 offset, int whence = SEEK_SET) = 0; - + void skip(uint32 offset) { seek(offset, SEEK_CUR); } /** @@ -233,6 +233,43 @@ public: virtual char *readLine(char *buf, size_t bufSize); }; +/** + * SubReadStream provides access to a ReadStream restricted to the range + * [currentPosition, currentPosition+end). + * Manipulating the parent stream directly /will/ mess up a substream. + * Likewise, manipulating two substreams of a parent stream will cause them to + * step on each others toes. + */ +class SubReadStream : virtual public ReadStream { +protected: + ReadStream *_parentStream; + uint32 _pos; + uint32 _end; +public: + SubReadStream(ReadStream *parentStream, uint32 end) + : _parentStream(parentStream), _pos(0), _end(end) {} + + virtual bool eos() const { return _pos == _end; } + virtual uint32 read(void *dataPtr, uint32 dataSize); +}; + +/* + * SeekableSubReadStream provides access to a SeekableReadStream restricted to + * the range [begin, end). + * The same caveats apply to SeekableSubReadStream as do to SeekableReadStream. + */ +class SeekableSubReadStream : public SubReadStream, public SeekableReadStream { +protected: + SeekableReadStream *_parentStream; + uint32 _begin; +public: + SeekableSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end); + + virtual uint32 pos() const { return _pos - _begin; } + virtual uint32 size() const { return _end - _begin; } + + virtual void seek(int32 offset, int whence = SEEK_SET); +}; /** * XORReadStream is a wrapper around an arbitrary other ReadStream, |