diff options
Diffstat (limited to '7zip/Common/OutBuffer.cpp')
-rwxr-xr-x | 7zip/Common/OutBuffer.cpp | 73 |
1 files changed, 58 insertions, 15 deletions
diff --git a/7zip/Common/OutBuffer.cpp b/7zip/Common/OutBuffer.cpp index ab4651b4..38827de1 100755 --- a/7zip/Common/OutBuffer.cpp +++ b/7zip/Common/OutBuffer.cpp @@ -32,35 +32,78 @@ void COutBuffer::SetStream(ISequentialOutStream *stream) void COutBuffer::Init() { - _processedSize = 0; + _streamPos = 0; + _limitPos = _bufferSize; _pos = 0; + _processedSize = 0; #ifdef _NO_EXCEPTIONS ErrorCode = S_OK; #endif } -HRESULT COutBuffer::Flush() +UInt64 COutBuffer::GetProcessedSize() const +{ + UInt64 res = _processedSize + _pos - _streamPos; + if (_streamPos > _pos) + res += _bufferSize; + return res; +} + +HRESULT COutBuffer::FlushPart() { - if (_pos == 0) - return S_OK; - UInt32 processedSize; - HRESULT result = _stream->Write(_buffer, _pos, &processedSize); - if (result != S_OK) + UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos); + HRESULT result = S_OK; + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + result = ErrorCode; + #endif + if (size == 0) return result; - if (_pos != processedSize) - return E_FAIL; - _processedSize += processedSize; - _pos = 0; - return S_OK; + 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; + _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize; + if (_streamPos == _bufferSize) + _streamPos = 0; + _processedSize += size; + return result; } -void COutBuffer::WriteBlock() +HRESULT COutBuffer::Flush() { #ifdef _NO_EXCEPTIONS if (ErrorCode != S_OK) - return; + return ErrorCode; #endif - HRESULT result = Flush(); + + while(_streamPos != _pos) + { + HRESULT result = FlushPart(); + if (result != S_OK) + return result; + } + return S_OK; +} + +void COutBuffer::FlushWithCheck() +{ + HRESULT result = FlushPart(); + if (_pos == _bufferSize) + _pos = 0; #ifdef _NO_EXCEPTIONS ErrorCode = result; #else |