OutBuffer.cpp revision baa3858d3f5d128a5c8466b700098109edcad5f2
1// OutBuffer.cpp 2 3#include "StdAfx.h" 4 5#include "../../../C/Alloc.h" 6 7#include "OutBuffer.h" 8 9bool COutBuffer::Create(UInt32 bufferSize) 10{ 11 const UInt32 kMinBlockSize = 1; 12 if (bufferSize < kMinBlockSize) 13 bufferSize = kMinBlockSize; 14 if (_buffer != 0 && _bufferSize == bufferSize) 15 return true; 16 Free(); 17 _bufferSize = bufferSize; 18 _buffer = (Byte *)::MidAlloc(bufferSize); 19 return (_buffer != 0); 20} 21 22void COutBuffer::Free() 23{ 24 ::MidFree(_buffer); 25 _buffer = 0; 26} 27 28void COutBuffer::SetStream(ISequentialOutStream *stream) 29{ 30 _stream = stream; 31} 32 33void COutBuffer::Init() 34{ 35 _streamPos = 0; 36 _limitPos = _bufferSize; 37 _pos = 0; 38 _processedSize = 0; 39 _overDict = false; 40 #ifdef _NO_EXCEPTIONS 41 ErrorCode = S_OK; 42 #endif 43} 44 45UInt64 COutBuffer::GetProcessedSize() const 46{ 47 UInt64 res = _processedSize + _pos - _streamPos; 48 if (_streamPos > _pos) 49 res += _bufferSize; 50 return res; 51} 52 53 54HRESULT COutBuffer::FlushPart() 55{ 56 // _streamPos < _bufferSize 57 UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos); 58 HRESULT result = S_OK; 59 #ifdef _NO_EXCEPTIONS 60 result = ErrorCode; 61 #endif 62 if (_buffer2 != 0) 63 { 64 memmove(_buffer2, _buffer + _streamPos, size); 65 _buffer2 += size; 66 } 67 68 if (_stream != 0 69 #ifdef _NO_EXCEPTIONS 70 && (ErrorCode == S_OK) 71 #endif 72 ) 73 { 74 UInt32 processedSize = 0; 75 result = _stream->Write(_buffer + _streamPos, size, &processedSize); 76 size = processedSize; 77 } 78 _streamPos += size; 79 if (_streamPos == _bufferSize) 80 _streamPos = 0; 81 if (_pos == _bufferSize) 82 { 83 _overDict = true; 84 _pos = 0; 85 } 86 _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize; 87 _processedSize += size; 88 return result; 89} 90 91HRESULT COutBuffer::Flush() 92{ 93 #ifdef _NO_EXCEPTIONS 94 if (ErrorCode != S_OK) 95 return ErrorCode; 96 #endif 97 98 while(_streamPos != _pos) 99 { 100 HRESULT result = FlushPart(); 101 if (result != S_OK) 102 return result; 103 } 104 return S_OK; 105} 106 107void COutBuffer::FlushWithCheck() 108{ 109 HRESULT result = Flush(); 110 #ifdef _NO_EXCEPTIONS 111 ErrorCode = result; 112 #else 113 if (result != S_OK) 114 throw COutBufferException(result); 115 #endif 116} 117