COMMON: implemented BufferedWriteStream and fixed bug in BufferedReadStream
I need the write buffering for the new version of the PSP streams and thought the simplest way to implement it would be along the lines of BufferedReadStream. Sadly, I found a nasty little bug in BRS but that's taken care of. Also, I adapted these streams for target-specific memory allocation by using virtual functions for allocation/deallocation. svn-id: r52325
This commit is contained in:
parent
cb93679ea2
commit
efdbb076a2
2 changed files with 94 additions and 4 deletions
|
@ -230,13 +230,21 @@ BufferedReadStream::BufferedReadStream(ReadStream *parentStream, uint32 bufSize,
|
||||||
_realBufSize(bufSize) {
|
_realBufSize(bufSize) {
|
||||||
|
|
||||||
assert(parentStream);
|
assert(parentStream);
|
||||||
_buf = new byte[bufSize];
|
allocBuf(bufSize);
|
||||||
assert(_buf);
|
assert(_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BufferedReadStream::allocBuf(uint32 bufSize) {
|
||||||
|
_buf = new byte[bufSize];
|
||||||
|
}
|
||||||
|
|
||||||
BufferedReadStream::~BufferedReadStream() {
|
BufferedReadStream::~BufferedReadStream() {
|
||||||
if (_disposeParentStream)
|
if (_disposeParentStream)
|
||||||
delete _parentStream;
|
delete _parentStream;
|
||||||
|
deallocBuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferedReadStream::deallocBuf() {
|
||||||
delete[] _buf;
|
delete[] _buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +267,7 @@ uint32 BufferedReadStream::read(void *dataPtr, uint32 dataSize) {
|
||||||
|
|
||||||
// At this point the buffer is empty. Now if the read request
|
// At this point the buffer is empty. Now if the read request
|
||||||
// exceeds the buffer size, just satisfy it directly.
|
// exceeds the buffer size, just satisfy it directly.
|
||||||
if (dataSize > _bufSize)
|
if (dataSize > _realBufSize)
|
||||||
return alreadyRead + _parentStream->read(dataPtr, dataSize);
|
return alreadyRead + _parentStream->read(dataPtr, dataSize);
|
||||||
|
|
||||||
// Refill the buffer.
|
// Refill the buffer.
|
||||||
|
@ -303,6 +311,67 @@ bool BufferedSeekableReadStream::seek(int32 offset, int whence) {
|
||||||
return true; // FIXME: STREAM REWRITE
|
return true; // FIXME: STREAM REWRITE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BufferedWriteStream::BufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream)
|
||||||
|
: _parentStream(parentStream),
|
||||||
|
_disposeParentStream(disposeParentStream),
|
||||||
|
_pos(0),
|
||||||
|
_bufSize(bufSize) {
|
||||||
|
|
||||||
|
assert(parentStream);
|
||||||
|
allocBuf(bufSize);
|
||||||
|
assert(_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedWriteStream::~BufferedWriteStream() {
|
||||||
|
assert(flush());
|
||||||
|
|
||||||
|
if (_disposeParentStream)
|
||||||
|
delete _parentStream;
|
||||||
|
|
||||||
|
deallocBuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferedWriteStream::allocBuf(uint32 bufSize) {
|
||||||
|
_buf = new byte[bufSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferedWriteStream::deallocBuf() {
|
||||||
|
delete[] _buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 BufferedWriteStream::write(const void *dataPtr, uint32 dataSize) {
|
||||||
|
// check if we have enough space for writing to the buffer
|
||||||
|
if (_bufSize - _pos >= dataSize) {
|
||||||
|
memcpy(_buf + _pos, dataPtr, dataSize);
|
||||||
|
_pos += dataSize;
|
||||||
|
} else if (_bufSize >= dataSize) { // check if we can flush the buffer and load the data
|
||||||
|
// flush the buffer
|
||||||
|
assert(flushBuffer());
|
||||||
|
memcpy(_buf, dataPtr, dataSize);
|
||||||
|
_pos += dataSize;
|
||||||
|
} else { // too big for our buffer
|
||||||
|
// flush the buffer
|
||||||
|
assert(flushBuffer());
|
||||||
|
return _parentStream->write(dataPtr, dataSize);
|
||||||
|
}
|
||||||
|
return dataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BufferedWriteStream::flushBuffer() {
|
||||||
|
uint32 bytesToWrite = _pos;
|
||||||
|
|
||||||
|
if (bytesToWrite) {
|
||||||
|
_pos = 0;
|
||||||
|
if (_parentStream->write(_buf, bytesToWrite) != bytesToWrite)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BufferedWriteStream::flush() {
|
||||||
|
return flushBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
bool MemoryWriteStreamDynamic::seek(int32 offs, int whence) {
|
bool MemoryWriteStreamDynamic::seek(int32 offs, int whence) {
|
||||||
// Pre-Condition
|
// Pre-Condition
|
||||||
assert(_pos <= _size);
|
assert(_pos <= _size);
|
||||||
|
|
|
@ -149,7 +149,6 @@ public:
|
||||||
void writeString(const String &str);
|
void writeString(const String &str);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic interface for a readable data stream.
|
* Generic interface for a readable data stream.
|
||||||
*/
|
*/
|
||||||
|
@ -497,10 +496,12 @@ protected:
|
||||||
uint32 _pos;
|
uint32 _pos;
|
||||||
uint32 _bufSize;
|
uint32 _bufSize;
|
||||||
uint32 _realBufSize;
|
uint32 _realBufSize;
|
||||||
|
virtual void allocBuf(uint32 bufSize); // virtual functions to allocate/deallocate the buffer
|
||||||
|
virtual void deallocBuf();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO);
|
BufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO);
|
||||||
~BufferedReadStream();
|
virtual ~BufferedReadStream();
|
||||||
|
|
||||||
virtual bool eos() const { return (_pos == _bufSize) && _parentStream->eos(); }
|
virtual bool eos() const { return (_pos == _bufSize) && _parentStream->eos(); }
|
||||||
virtual bool err() const { return _parentStream->err(); }
|
virtual bool err() const { return _parentStream->err(); }
|
||||||
|
@ -525,7 +526,27 @@ public:
|
||||||
virtual bool seek(int32 offset, int whence = SEEK_SET);
|
virtual bool seek(int32 offset, int whence = SEEK_SET);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper class which adds buffering to any WriteStream.
|
||||||
|
*/
|
||||||
|
class BufferedWriteStream : public WriteStream {
|
||||||
|
protected:
|
||||||
|
WriteStream *_parentStream;
|
||||||
|
DisposeAfterUse::Flag _disposeParentStream;
|
||||||
|
byte *_buf;
|
||||||
|
uint32 _pos;
|
||||||
|
uint32 _bufSize;
|
||||||
|
bool flushBuffer(); // write out the data in the buffer
|
||||||
|
virtual void allocBuf(uint32 bufSize); // virtual functions to allocate/deallocate the buffer
|
||||||
|
virtual void deallocBuf();
|
||||||
|
|
||||||
|
public:
|
||||||
|
BufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO);
|
||||||
|
virtual ~BufferedWriteStream();
|
||||||
|
|
||||||
|
virtual uint32 write(const void *dataPtr, uint32 dataSize);
|
||||||
|
virtual bool flush();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple memory based 'stream', which implements the ReadStream interface for
|
* Simple memory based 'stream', which implements the ReadStream interface for
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue