diff options
-rw-r--r-- | backends/fs/psp/psp-fs.cpp | 4 | ||||
-rw-r--r-- | common/stream.cpp | 154 | ||||
-rw-r--r-- | common/stream.h | 89 | ||||
-rw-r--r-- | common/unarj.cpp | 4 | ||||
-rw-r--r-- | test/common/bufferedreadstream.h | 8 | ||||
-rw-r--r-- | test/common/bufferedseekablereadstream.h | 10 |
6 files changed, 176 insertions, 93 deletions
diff --git a/backends/fs/psp/psp-fs.cpp b/backends/fs/psp/psp-fs.cpp index 5b3d298001..b512f528c9 100644 --- a/backends/fs/psp/psp-fs.cpp +++ b/backends/fs/psp/psp-fs.cpp @@ -251,7 +251,7 @@ Common::SeekableReadStream *PSPFilesystemNode::createReadStream() { Common::SeekableReadStream *stream = PspIoStream::makeFromPath(getPath(), false); - return new Common::BufferedSeekableReadStream(stream, READ_BUFFER_SIZE, DisposeAfterUse::YES); + return Common::wrapBufferedSeekableReadStream(stream, READ_BUFFER_SIZE, DisposeAfterUse::YES); } Common::WriteStream *PSPFilesystemNode::createWriteStream() { @@ -259,7 +259,7 @@ Common::WriteStream *PSPFilesystemNode::createWriteStream() { Common::WriteStream *stream = PspIoStream::makeFromPath(getPath(), true); - return new Common::BufferedWriteStream(stream, WRITE_BUFFER_SIZE, DisposeAfterUse::YES); + return Common::wrapBufferedWriteStream(stream, WRITE_BUFFER_SIZE, DisposeAfterUse::YES); } #endif //#ifdef __PSP__ diff --git a/common/stream.cpp b/common/stream.cpp index 0e8e578e86..7a2eb2e23e 100644 --- a/common/stream.cpp +++ b/common/stream.cpp @@ -89,6 +89,33 @@ bool MemoryReadStream::seek(int32 offs, int whence) { return true; // FIXME: STREAM REWRITE } +bool MemoryWriteStreamDynamic::seek(int32 offs, int whence) { + // Pre-Condition + assert(_pos <= _size); + switch (whence) { + case SEEK_END: + // SEEK_END works just like SEEK_SET, only 'reversed', + // i.e. from the end. + offs = _size + offs; + // Fall through + case SEEK_SET: + _ptr = _data + offs; + _pos = offs; + break; + + case SEEK_CUR: + _ptr += offs; + _pos += offs; + break; + } + // Post-Condition + assert(_pos <= _size); + + return true; // FIXME: STREAM REWRITE +} + +#pragma mark - + enum { LF = 0x0A, CR = 0x0D @@ -222,6 +249,37 @@ bool SeekableSubReadStream::seek(int32 offset, int whence) { return ret; } + +#pragma mark - + +namespace { + +/** + * Wrapper class which adds buffering to any given ReadStream. + * Users can specify how big the buffer should be, and whether the + * wrapped stream should be disposed when the wrapper is disposed. + */ +class BufferedReadStream : virtual public ReadStream { +protected: + ReadStream *_parentStream; + DisposeAfterUse::Flag _disposeParentStream; + byte *_buf; + uint32 _pos; + bool _eos; // end of stream + uint32 _bufSize; + uint32 _realBufSize; + +public: + BufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream); + virtual ~BufferedReadStream(); + + virtual bool eos() const { return _eos; } + virtual bool err() const { return _parentStream->err(); } + virtual void clearErr() { _eos = false; _parentStream->clearErr(); } + + virtual uint32 read(void *dataPtr, uint32 dataSize); +}; + BufferedReadStream::BufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) : _parentStream(parentStream), _disposeParentStream(disposeParentStream), @@ -290,6 +348,35 @@ uint32 BufferedReadStream::read(void *dataPtr, uint32 dataSize) { return alreadyRead + dataSize; } +} // End of nameless namespace + + +ReadStream *wrapBufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) { + if (parentStream) + return new BufferedReadStream(parentStream, bufSize, disposeParentStream); + return 0; +} + +#pragma mark - + +namespace { + +/** + * Wrapper class which adds buffering to any given SeekableReadStream. + * @see BufferedReadStream + */ +class BufferedSeekableReadStream : public BufferedReadStream, public SeekableReadStream { +protected: + SeekableReadStream *_parentStream; +public: + BufferedSeekableReadStream(SeekableReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); + + virtual int32 pos() const { return _parentStream->pos() - (_bufSize - _pos); } + virtual int32 size() const { return _parentStream->size(); } + + virtual bool seek(int32 offset, int whence = SEEK_SET); +}; + BufferedSeekableReadStream::BufferedSeekableReadStream(SeekableReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) : BufferedReadStream(parentStream, bufSize, disposeParentStream), _parentStream(parentStream) { @@ -319,6 +406,46 @@ bool BufferedSeekableReadStream::seek(int32 offset, int whence) { return true; } +} // End of nameless namespace + +SeekableReadStream *wrapBufferedSeekableReadStream(SeekableReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) { + if (parentStream) + return new BufferedSeekableReadStream(parentStream, bufSize, disposeParentStream); + return 0; +} + +#pragma mark - + +namespace { + +/** + * Wrapper class which adds buffering to any WriteStream. + */ +class BufferedWriteStream : public WriteStream { +protected: + WriteStream *_parentStream; + DisposeAfterUse::Flag _disposeParentStream; + byte *_buf; + uint32 _pos; + const uint32 _bufSize; + + /** + * Write out the data in the buffer. + * + * @note This method is identical to flush() (which actually is + * implemented by calling this method), except that it is not + * virtual, hence there is less overhead calling it. + */ + bool flushBuffer(); + +public: + BufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); + virtual ~BufferedWriteStream(); + + virtual uint32 write(const void *dataPtr, uint32 dataSize); + virtual bool flush() { return flushBuffer(); } +}; + BufferedWriteStream::BufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) : _parentStream(parentStream), _disposeParentStream(disposeParentStream), @@ -369,29 +496,12 @@ bool BufferedWriteStream::flushBuffer() { return true; } -bool MemoryWriteStreamDynamic::seek(int32 offs, int whence) { - // Pre-Condition - assert(_pos <= _size); - switch (whence) { - case SEEK_END: - // SEEK_END works just like SEEK_SET, only 'reversed', - // i.e. from the end. - offs = _size + offs; - // Fall through - case SEEK_SET: - _ptr = _data + offs; - _pos = offs; - break; - - case SEEK_CUR: - _ptr += offs; - _pos += offs; - break; - } - // Post-Condition - assert(_pos <= _size); +} // End of nameless namespace - return true; // FIXME: STREAM REWRITE +WriteStream *wrapBufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) { + if (parentStream) + return new BufferedWriteStream(parentStream, bufSize, disposeParentStream); + return 0; } } // End of namespace Common diff --git a/common/stream.h b/common/stream.h index d497cabe2b..14b1243ca0 100644 --- a/common/stream.h +++ b/common/stream.h @@ -484,74 +484,37 @@ public: }; /** - * Wrapper class which adds buffering to any given ReadStream. - * Users can specify how big the buffer should be, and whether the - * wrapped stream should be disposed when the wrapper is disposed. + * Take an arbitrary ReadStream and wrap it in a custom stream which + * transparently provides buffering. + * Users can specify how big the buffer should be, and whether the wrapped + * stream should be disposed when the wrapper is disposed. + * + * It is safe to call this with a NULL parameter (in this case, NULL is + * returned). */ -class BufferedReadStream : virtual public ReadStream { -protected: - ReadStream *_parentStream; - DisposeAfterUse::Flag _disposeParentStream; - byte *_buf; - uint32 _pos; - bool _eos; // end of stream - uint32 _bufSize; - uint32 _realBufSize; - -public: - BufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); - virtual ~BufferedReadStream(); - - virtual bool eos() const { return _eos; } - virtual bool err() const { return _parentStream->err(); } - virtual void clearErr() { _eos = false; _parentStream->clearErr(); } - - virtual uint32 read(void *dataPtr, uint32 dataSize); -}; +ReadStream *wrapBufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream); /** - * Wrapper class which adds buffering to any given SeekableReadStream. - * @see BufferedReadStream + * Take an arbitrary SeekableReadStream and wrap it in a custom stream which + * transparently provides buffering. + * Users can specify how big the buffer should be, and whether the wrapped + * stream should be disposed when the wrapper is disposed. + * + * It is safe to call this with a NULL parameter (in this case, NULL is + * returned). */ -class BufferedSeekableReadStream : public BufferedReadStream, public SeekableReadStream { -protected: - SeekableReadStream *_parentStream; -public: - BufferedSeekableReadStream(SeekableReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); - - virtual int32 pos() const { return _parentStream->pos() - (_bufSize - _pos); } - virtual int32 size() const { return _parentStream->size(); } - - virtual bool seek(int32 offset, int whence = SEEK_SET); -}; +SeekableReadStream *wrapBufferedSeekableReadStream(SeekableReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream); /** - * Wrapper class which adds buffering to any WriteStream. + * Take an arbitrary WriteStream and wrap it in a custom stream which + * transparently provides buffering. + * Users can specify how big the buffer should be, and whether the wrapped + * stream should be disposed when the wrapper is disposed. + * + * It is safe to call this with a NULL parameter (in this case, NULL is + * returned). */ -class BufferedWriteStream : public WriteStream { -protected: - WriteStream *_parentStream; - DisposeAfterUse::Flag _disposeParentStream; - byte *_buf; - uint32 _pos; - const uint32 _bufSize; - - /** - * Write out the data in the buffer. - * - * @note This method is identical to flush() (which actually is - * implemented by calling this method), except that it is not - * virtual, hence there is less overhead calling it. - */ - bool flushBuffer(); - -public: - BufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); - virtual ~BufferedWriteStream(); - - virtual uint32 write(const void *dataPtr, uint32 dataSize); - virtual bool flush() { return flushBuffer(); } -}; +WriteStream *wrapBufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream); /** * Simple memory based 'stream', which implements the ReadStream interface for @@ -606,7 +569,7 @@ public: * This is a wrapper around MemoryReadStream, but it adds non-endian * read methods whose endianness is set on the stream creation. */ -class MemoryReadStreamEndian : public Common::MemoryReadStream { +class MemoryReadStreamEndian : public MemoryReadStream { private: const bool _bigEndian; @@ -664,7 +627,7 @@ public: * A sort of hybrid between MemoryWriteStream and Array classes. A stream * that grows as it's written to. */ -class MemoryWriteStreamDynamic : public Common::WriteStream { +class MemoryWriteStreamDynamic : public WriteStream { private: uint32 _capacity; uint32 _size; diff --git a/common/unarj.cpp b/common/unarj.cpp index 2b2af3c54f..050c7e65a2 100644 --- a/common/unarj.cpp +++ b/common/unarj.cpp @@ -108,7 +108,7 @@ public: void decode(int32 origsize); void decode_f(int32 origsize); - BufferedReadStream *_compressed; + ReadStream *_compressed; MemoryWriteStream *_outstream; //protected: @@ -817,7 +817,7 @@ SeekableReadStream *ArjArchive::createReadStreamForMember(const String &name) co // If reading from archiveFile directly is too slow to be usable, // maybe the filesystem code should instead wrap its files // in a BufferedReadStream. - decoder->_compressed = new Common::BufferedReadStream(&archiveFile, 4096, DisposeAfterUse::NO); + decoder->_compressed = Common::wrapBufferedReadStream(&archiveFile, 4096, DisposeAfterUse::NO); decoder->_outstream = new Common::MemoryWriteStream(uncompressedData, hdr->origSize); if (hdr->method == 1 || hdr->method == 2 || hdr->method == 3) diff --git a/test/common/bufferedreadstream.h b/test/common/bufferedreadstream.h index 0b2cda696c..4238c1b42e 100644 --- a/test/common/bufferedreadstream.h +++ b/test/common/bufferedreadstream.h @@ -11,7 +11,7 @@ class BufferedReadStreamTestSuite : public CxxTest::TestSuite { // Use a buffer size of 4 -- note that 10 % 4 != 0, // so we test what happens if the cache can't be completely // refilled. - Common::BufferedReadStream srs(&ms, 4); + Common::ReadStream &srs = *Common::wrapBufferedReadStream(&ms, 4, DisposeAfterUse::NO); byte i, b; for (i = 0; i < 10; ++i) { @@ -26,13 +26,15 @@ class BufferedReadStreamTestSuite : public CxxTest::TestSuite { b = srs.readByte(); TS_ASSERT(srs.eos()); + + delete &srs; } void test_traverse2() { byte contents[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; Common::MemoryReadStream ms(contents, 9); - Common::BufferedReadStream brs(&ms, 4); + Common::ReadStream &brs = *Common::wrapBufferedReadStream(&ms, 4, DisposeAfterUse::NO); // Traverse the stream with reads of 2 bytes. The size is not // a multiple of 2, so we can test the final partial read. @@ -51,5 +53,7 @@ class BufferedReadStreamTestSuite : public CxxTest::TestSuite { TS_ASSERT_EQUALS(n, 1); TS_ASSERT(brs.eos()); + + delete &brs; } }; diff --git a/test/common/bufferedseekablereadstream.h b/test/common/bufferedseekablereadstream.h index 74401ad202..d9b8e2f6a0 100644 --- a/test/common/bufferedseekablereadstream.h +++ b/test/common/bufferedseekablereadstream.h @@ -8,7 +8,8 @@ class BufferedSeekableReadStreamTestSuite : public CxxTest::TestSuite { byte contents[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Common::MemoryReadStream ms(contents, 10); - Common::BufferedSeekableReadStream ssrs(&ms, 4); + Common::SeekableReadStream &ssrs + = *Common::wrapBufferedSeekableReadStream(&ms, 4, DisposeAfterUse::NO); byte i, b; for (i = 0; i < 10; ++i) { @@ -24,13 +25,16 @@ class BufferedSeekableReadStreamTestSuite : public CxxTest::TestSuite { TS_ASSERT_EQUALS((uint)0, ssrs.read(&b, 1)); TS_ASSERT(ssrs.eos()); + + delete &ssrs; } void test_seek() { byte contents[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Common::MemoryReadStream ms(contents, 10); - Common::BufferedSeekableReadStream ssrs(&ms, 4); + Common::SeekableReadStream &ssrs + = *Common::wrapBufferedSeekableReadStream(&ms, 4, DisposeAfterUse::NO); byte b; TS_ASSERT_EQUALS(ssrs.pos(), 0); @@ -66,5 +70,7 @@ class BufferedSeekableReadStreamTestSuite : public CxxTest::TestSuite { TS_ASSERT_EQUALS(ssrs.pos(), 2); b = ssrs.readByte(); TS_ASSERT_EQUALS(b, 2); + + delete &ssrs; } }; |