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