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
This commit is contained in:
Max Horn 2007-02-20 21:41:01 +00:00
parent cc210d7512
commit 42f11e9e49
2 changed files with 54 additions and 30 deletions

View file

@ -31,14 +31,41 @@ void WriteStream::writeString(const String &str) {
write(str.c_str(), str.size()); 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) { void MemoryReadStream::seek(int32 offs, int whence) {
// Pre-Condition // Pre-Condition
assert(_pos <= _bufSize); assert(_pos <= _size);
switch (whence) { switch (whence) {
case SEEK_END: case SEEK_END:
// SEEK_END works just like SEEK_SET, only 'reversed', // SEEK_END works just like SEEK_SET, only 'reversed',
// i.e. from the end. // i.e. from the end.
offs = _bufSize - offs; offs = _size - offs;
// Fall through // Fall through
case SEEK_SET: case SEEK_SET:
_ptr = _ptrOrig + offs; _ptr = _ptrOrig + offs;
@ -51,7 +78,7 @@ void MemoryReadStream::seek(int32 offs, int whence) {
break; break;
} }
// Post-Condition // Post-Condition
assert(_pos <= _bufSize); assert(_pos <= _size);
} }
#define LF 0x0A #define LF 0x0A

View file

@ -29,6 +29,7 @@
namespace Common { namespace Common {
class String; class String;
class MemoryReadStream;
/** /**
* Virtual base class for both ReadStream and WriteStream. * Virtual base class for both ReadStream and WriteStream.
@ -201,6 +202,13 @@ public:
int32 readSint32BE() { int32 readSint32BE() {
return (int32)readUint32BE(); 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 { class MemoryReadStream : public SeekableReadStream {
private: private:
const byte *_ptr;
const byte * const _ptrOrig; const byte * const _ptrOrig;
const uint32 _bufSize; const byte *_ptr;
const uint32 _size;
uint32 _pos; uint32 _pos;
byte _encbyte; byte _encbyte;
bool _disposeMemory; bool _disposeMemory;
public: public:
MemoryReadStream(const byte *buf, uint32 len, bool disposeMemory = false) :
_ptr(buf), /**
_ptrOrig(buf), * This constructor takes a pointer to a memory buffer and a length, and
_bufSize(len), * 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), _pos(0),
_encbyte(0), _encbyte(0),
_disposeMemory(disposeMemory) {} _disposeMemory(disposeMemory) {}
~MemoryReadStream() { ~MemoryReadStream() {
if (_disposeMemory) if (_disposeMemory)
free((void *)_ptrOrig); free(const_cast<byte *>(_ptrOrig));
} }
void setEnc(byte value) { _encbyte = value; } void setEnc(byte value) { _encbyte = value; }
uint32 read(void *dataPtr, uint32 dataSize) { 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) { bool eos() const { return _pos == _size; }
byte *p = (byte *)dataPtr;
byte *end = p + dataSize;
while (p < end)
*p++ ^= _encbyte;
}
_ptr += dataSize;
_pos += dataSize;
return dataSize;
}
bool eos() const { return _pos == _bufSize; }
uint32 pos() const { return _pos; } uint32 pos() const { return _pos; }
uint32 size() const { return _bufSize; } uint32 size() const { return _size; }
void seek(int32 offs, int whence = SEEK_SET); void seek(int32 offs, int whence = SEEK_SET);
}; };