1 // OutBuffer.cpp 2 3 #include "StdAfx.h" 4 5 #include "../../../C/Alloc.h" 6 7 #include "OutBuffer.h" 8 9 bool 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 22 void COutBuffer::Free() 23 { 24 ::MidFree(_buffer); 25 _buffer = 0; 26 } 27 28 void COutBuffer::SetStream(ISequentialOutStream *stream) 29 { 30 _stream = stream; 31 } 32 33 void 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 45 UInt64 COutBuffer::GetProcessedSize() const 46 { 47 UInt64 res = _processedSize + _pos - _streamPos; 48 if (_streamPos > _pos) 49 res += _bufferSize; 50 return res; 51 } 52 53 54 HRESULT 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 91 HRESULT 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 107 void 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