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:
parent
cc210d7512
commit
42f11e9e49
2 changed files with 54 additions and 30 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue