From 42f11e9e490971f6fea8044ed9c830bca4ccb897 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 20 Feb 2007 21:41:01 +0000 Subject: Added new ReadStream::readStream method which can be used to read a portion of an arbitrary ReadStream into a memory buffer wrapped by a MemoryReadStream svn-id: r25754 --- common/stream.cpp | 33 ++++++++++++++++++++++++++++++--- common/stream.h | 51 ++++++++++++++++++++++++--------------------------- 2 files changed, 54 insertions(+), 30 deletions(-) (limited to 'common') diff --git a/common/stream.cpp b/common/stream.cpp index 3926fc30f6..55ada03195 100644 --- a/common/stream.cpp +++ b/common/stream.cpp @@ -31,14 +31,41 @@ void WriteStream::writeString(const String &str) { write(str.c_str(), str.size()); } +MemoryReadStream *ReadStream::readStream(uint32 dataSize) { + void *buf = malloc(dataSize); + dataSize = read(buf, dataSize); + assert(dataSize > 0); + return new MemoryReadStream((byte *)buf, dataSize, true); +} + + +uint32 MemoryReadStream::read(void *dataPtr, uint32 dataSize) { + // Read at most as many bytes as are still available... + if (dataSize > _size - _pos) + dataSize = _size - _pos; + memcpy(dataPtr, _ptr, dataSize); + + if (_encbyte) { + byte *p = (byte *)dataPtr; + byte *end = p + dataSize; + while (p < end) + *p++ ^= _encbyte; + } + + _ptr += dataSize; + _pos += dataSize; + + return dataSize; +} + void MemoryReadStream::seek(int32 offs, int whence) { // Pre-Condition - assert(_pos <= _bufSize); + assert(_pos <= _size); switch (whence) { case SEEK_END: // SEEK_END works just like SEEK_SET, only 'reversed', // i.e. from the end. - offs = _bufSize - offs; + offs = _size - offs; // Fall through case SEEK_SET: _ptr = _ptrOrig + offs; @@ -51,7 +78,7 @@ void MemoryReadStream::seek(int32 offs, int whence) { break; } // Post-Condition - assert(_pos <= _bufSize); + assert(_pos <= _size); } #define LF 0x0A diff --git a/common/stream.h b/common/stream.h index 85b4315aed..3332b1beda 100644 --- a/common/stream.h +++ b/common/stream.h @@ -29,6 +29,7 @@ namespace Common { class String; +class MemoryReadStream; /** * Virtual base class for both ReadStream and WriteStream. @@ -201,6 +202,13 @@ public: int32 readSint32BE() { return (int32)readUint32BE(); } + + /** + * Read the specified amount of data into a malloc'ed buffer + * which then is wrapped into a MemoryReadStream. + */ + MemoryReadStream *readStream(uint32 dataSize); + }; @@ -284,51 +292,40 @@ public: */ class MemoryReadStream : public SeekableReadStream { private: - const byte *_ptr; const byte * const _ptrOrig; - const uint32 _bufSize; + const byte *_ptr; + const uint32 _size; uint32 _pos; byte _encbyte; bool _disposeMemory; public: - MemoryReadStream(const byte *buf, uint32 len, bool disposeMemory = false) : - _ptr(buf), - _ptrOrig(buf), - _bufSize(len), + + /** + * This constructor takes a pointer to a memory buffer and a length, and + * wraps it. If disposeMemory is true, the MemoryReadStream takes ownership + * of the buffer and hence free's it when destructed. + */ + MemoryReadStream(const byte *dataPtr, uint32 dataSize, bool disposeMemory = false) : + _ptrOrig(dataPtr), + _ptr(dataPtr), + _size(dataSize), _pos(0), _encbyte(0), _disposeMemory(disposeMemory) {} ~MemoryReadStream() { if (_disposeMemory) - free((void *)_ptrOrig); + free(const_cast(_ptrOrig)); } void setEnc(byte value) { _encbyte = value; } - uint32 read(void *dataPtr, uint32 dataSize) { - // Read at most as many bytes as are still available... - if (dataSize > _bufSize - _pos) - dataSize = _bufSize - _pos; - memcpy(dataPtr, _ptr, dataSize); - - if (_encbyte) { - byte *p = (byte *)dataPtr; - byte *end = p + dataSize; - while (p < end) - *p++ ^= _encbyte; - } - - _ptr += dataSize; - _pos += dataSize; - - return dataSize; - } + uint32 read(void *dataPtr, uint32 dataSize); - bool eos() const { return _pos == _bufSize; } + bool eos() const { return _pos == _size; } uint32 pos() const { return _pos; } - uint32 size() const { return _bufSize; } + uint32 size() const { return _size; } void seek(int32 offs, int whence = SEEK_SET); }; -- cgit v1.2.3