| // OutBuffer.cpp |
| |
| #include "StdAfx.h" |
| |
| #include "../../../C/Alloc.h" |
| |
| #include "OutBuffer.h" |
| |
| bool COutBuffer::Create(UInt32 bufferSize) |
| { |
| const UInt32 kMinBlockSize = 1; |
| if (bufferSize < kMinBlockSize) |
| bufferSize = kMinBlockSize; |
| if (_buffer != 0 && _bufferSize == bufferSize) |
| return true; |
| Free(); |
| _bufferSize = bufferSize; |
| _buffer = (Byte *)::MidAlloc(bufferSize); |
| return (_buffer != 0); |
| } |
| |
| void COutBuffer::Free() |
| { |
| ::MidFree(_buffer); |
| _buffer = 0; |
| } |
| |
| void COutBuffer::SetStream(ISequentialOutStream *stream) |
| { |
| _stream = stream; |
| } |
| |
| void COutBuffer::Init() |
| { |
| _streamPos = 0; |
| _limitPos = _bufferSize; |
| _pos = 0; |
| _processedSize = 0; |
| _overDict = false; |
| #ifdef _NO_EXCEPTIONS |
| ErrorCode = S_OK; |
| #endif |
| } |
| |
| UInt64 COutBuffer::GetProcessedSize() const |
| { |
| UInt64 res = _processedSize + _pos - _streamPos; |
| if (_streamPos > _pos) |
| res += _bufferSize; |
| return res; |
| } |
| |
| |
| HRESULT COutBuffer::FlushPart() |
| { |
| // _streamPos < _bufferSize |
| UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos); |
| HRESULT result = S_OK; |
| #ifdef _NO_EXCEPTIONS |
| result = ErrorCode; |
| #endif |
| if (_buffer2 != 0) |
| { |
| memmove(_buffer2, _buffer + _streamPos, size); |
| _buffer2 += size; |
| } |
| |
| if (_stream != 0 |
| #ifdef _NO_EXCEPTIONS |
| && (ErrorCode == S_OK) |
| #endif |
| ) |
| { |
| UInt32 processedSize = 0; |
| result = _stream->Write(_buffer + _streamPos, size, &processedSize); |
| size = processedSize; |
| } |
| _streamPos += size; |
| if (_streamPos == _bufferSize) |
| _streamPos = 0; |
| if (_pos == _bufferSize) |
| { |
| _overDict = true; |
| _pos = 0; |
| } |
| _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize; |
| _processedSize += size; |
| return result; |
| } |
| |
| HRESULT COutBuffer::Flush() |
| { |
| #ifdef _NO_EXCEPTIONS |
| if (ErrorCode != S_OK) |
| return ErrorCode; |
| #endif |
| |
| while(_streamPos != _pos) |
| { |
| HRESULT result = FlushPart(); |
| if (result != S_OK) |
| return result; |
| } |
| return S_OK; |
| } |
| |
| void COutBuffer::FlushWithCheck() |
| { |
| HRESULT result = Flush(); |
| #ifdef _NO_EXCEPTIONS |
| ErrorCode = result; |
| #else |
| if (result != S_OK) |
| throw COutBufferException(result); |
| #endif |
| } |