COMMON: Turn BufferedWriteStream into a template class, with disposeParentStream as param

svn-id: r54336
This commit is contained in:
Max Horn 2010-11-18 17:56:21 +00:00
parent c02a233084
commit a9dcb11c54

View file

@ -421,10 +421,10 @@ namespace {
/** /**
* Wrapper class which adds buffering to any WriteStream. * Wrapper class which adds buffering to any WriteStream.
*/ */
template <DisposeAfterUse::Flag _disposeParentStream>
class BufferedWriteStream : public WriteStream { class BufferedWriteStream : public WriteStream {
protected: protected:
WriteStream *_parentStream; WriteStream *_parentStream;
DisposeAfterUse::Flag _disposeParentStream;
byte *_buf; byte *_buf;
uint32 _pos; uint32 _pos;
const uint32 _bufSize; const uint32 _bufSize;
@ -436,71 +436,71 @@ protected:
* implemented by calling this method), except that it is not * implemented by calling this method), except that it is not
* virtual, hence there is less overhead calling it. * virtual, hence there is less overhead calling it.
*/ */
bool flushBuffer(); bool flushBuffer() {
const uint32 bytesToWrite = _pos;
if (bytesToWrite) {
_pos = 0;
if (_parentStream->write(_buf, bytesToWrite) != bytesToWrite)
return false;
}
return true;
}
public: public:
BufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); BufferedWriteStream(WriteStream *parentStream, uint32 bufSize)
virtual ~BufferedWriteStream(); : _parentStream(parentStream),
_pos(0),
_bufSize(bufSize) {
assert(parentStream);
_buf = new byte[bufSize];
assert(_buf);
}
virtual ~BufferedWriteStream() {
const bool flushResult = flushBuffer();
assert(flushResult);
if (_disposeParentStream)
delete _parentStream;
delete[] _buf;
}
virtual uint32 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
const bool flushResult = flushBuffer();
assert(flushResult);
memcpy(_buf, dataPtr, dataSize);
_pos += dataSize;
} else { // too big for our buffer
const bool flushResult = flushBuffer();
assert(flushResult);
return _parentStream->write(dataPtr, dataSize);
}
return dataSize;
}
virtual uint32 write(const void *dataPtr, uint32 dataSize);
virtual bool flush() { return flushBuffer(); } virtual bool flush() { return flushBuffer(); }
}; };
BufferedWriteStream::BufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream)
: _parentStream(parentStream),
_disposeParentStream(disposeParentStream),
_pos(0),
_bufSize(bufSize) {
assert(parentStream);
_buf = new byte[bufSize];
assert(_buf);
}
BufferedWriteStream::~BufferedWriteStream() {
const bool flushResult = flushBuffer();
assert(flushResult);
if (_disposeParentStream)
delete _parentStream;
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
const bool flushResult = flushBuffer();
assert(flushResult);
memcpy(_buf, dataPtr, dataSize);
_pos += dataSize;
} else { // too big for our buffer
const bool flushResult = flushBuffer();
assert(flushResult);
return _parentStream->write(dataPtr, dataSize);
}
return dataSize;
}
bool BufferedWriteStream::flushBuffer() {
const uint32 bytesToWrite = _pos;
if (bytesToWrite) {
_pos = 0;
if (_parentStream->write(_buf, bytesToWrite) != bytesToWrite)
return false;
}
return true;
}
} // End of nameless namespace } // End of nameless namespace
WriteStream *wrapBufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) { WriteStream *wrapBufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) {
if (parentStream) if (parentStream) {
return new BufferedWriteStream(parentStream, bufSize, disposeParentStream); switch (disposeParentStream) {
case DisposeAfterUse::YES:
return new BufferedWriteStream<DisposeAfterUse::YES>(parentStream, bufSize);
case DisposeAfterUse::NO:
return new BufferedWriteStream<DisposeAfterUse::NO>(parentStream, bufSize);
}
}
return 0; return 0;
} }