From 4368d3c5749faadb89262dfa869d9a9d3b60a4c8 Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Wed, 25 Aug 2010 09:14:41 +0000 Subject: COMMON: fixed EOS handling in BufferedReadStream and BufferedSeekableReadStream EOS problem was causing Discworld to crash and zip files not to load on the PSP. svn-id: r52377 --- common/stream.cpp | 17 +++++++++++++---- common/stream.h | 3 ++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/common/stream.cpp b/common/stream.cpp index e4b6aab818..651cfaa3eb 100644 --- a/common/stream.cpp +++ b/common/stream.cpp @@ -226,6 +226,7 @@ BufferedReadStream::BufferedReadStream(ReadStream *parentStream, uint32 bufSize, : _parentStream(parentStream), _disposeParentStream(disposeParentStream), _pos(0), + _eos(false), _bufSize(0), _realBufSize(bufSize) { @@ -255,6 +256,7 @@ uint32 BufferedReadStream::read(void *dataPtr, uint32 dataSize) { // Check whether the data left in the buffer suffices.... if (dataSize > bufBytesLeft) { // Nope, we need to read more data + _eos = true; // we tried to read past the buffer // First, flush the buffer, if it is non-empty if (0 < bufBytesLeft) { @@ -277,13 +279,17 @@ uint32 BufferedReadStream::read(void *dataPtr, uint32 dataSize) { // return to the caller. _bufSize = _parentStream->read(_buf, _realBufSize); _pos = 0; + if (_bufSize) + _eos = false; // we've managed to replenish our buffer if (dataSize > _bufSize) dataSize = _bufSize; } - // Satisfy the request from the buffer - memcpy(dataPtr, _buf + _pos, dataSize); - _pos += dataSize; + if (dataSize) { + // Satisfy the request from the buffer + memcpy(dataPtr, _buf + _pos, dataSize); + _pos += dataSize; + } return alreadyRead + dataSize; } @@ -297,8 +303,11 @@ bool BufferedSeekableReadStream::seek(int32 offset, int whence) { // in the buffer only. // Note: We could try to handle SEEK_END and SEEK_SET, too, but // since they are rarely used, it seems not worth the effort. + _eos = false; // seeking always cancels EOS + if (whence == SEEK_CUR && (int)_pos + offset >= 0 && _pos + offset <= _bufSize) { _pos += offset; + } else { // Seek was not local enough, so we reset the buffer and // just seeks normally in the parent stream. @@ -308,7 +317,7 @@ bool BufferedSeekableReadStream::seek(int32 offset, int whence) { _parentStream->seek(offset, whence); } - return true; // FIXME: STREAM REWRITE + return true; } BufferedWriteStream::BufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) diff --git a/common/stream.h b/common/stream.h index ce02f90ca9..be52ca69cd 100644 --- a/common/stream.h +++ b/common/stream.h @@ -494,6 +494,7 @@ protected: DisposeAfterUse::Flag _disposeParentStream; byte *_buf; uint32 _pos; + bool _eos; // in this context it means: have we tried to read beyond the end of the buffer uint32 _bufSize; uint32 _realBufSize; virtual void allocBuf(uint32 bufSize); // virtual functions to allocate/deallocate the buffer @@ -503,7 +504,7 @@ public: BufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); virtual ~BufferedReadStream(); - virtual bool eos() const { return (_pos == _bufSize) && _parentStream->eos(); } + virtual bool eos() const { return _eos && _parentStream->eos(); } virtual bool err() const { return _parentStream->err(); } virtual void clearErr() { _parentStream->clearErr(); } -- cgit v1.2.3