1370b324cSopenharmony_ci// OutBuffer.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "../../../C/Alloc.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include "OutBuffer.h"
8370b324cSopenharmony_ci
9370b324cSopenharmony_cibool COutBuffer::Create(UInt32 bufSize) throw()
10370b324cSopenharmony_ci{
11370b324cSopenharmony_ci  const UInt32 kMinBlockSize = 1;
12370b324cSopenharmony_ci  if (bufSize < kMinBlockSize)
13370b324cSopenharmony_ci    bufSize = kMinBlockSize;
14370b324cSopenharmony_ci  if (_buf && _bufSize == bufSize)
15370b324cSopenharmony_ci    return true;
16370b324cSopenharmony_ci  Free();
17370b324cSopenharmony_ci  _bufSize = bufSize;
18370b324cSopenharmony_ci  _buf = (Byte *)::MidAlloc(bufSize);
19370b324cSopenharmony_ci  return (_buf != NULL);
20370b324cSopenharmony_ci}
21370b324cSopenharmony_ci
22370b324cSopenharmony_civoid COutBuffer::Free() throw()
23370b324cSopenharmony_ci{
24370b324cSopenharmony_ci  ::MidFree(_buf);
25370b324cSopenharmony_ci  _buf = NULL;
26370b324cSopenharmony_ci}
27370b324cSopenharmony_ci
28370b324cSopenharmony_civoid COutBuffer::Init() throw()
29370b324cSopenharmony_ci{
30370b324cSopenharmony_ci  _streamPos = 0;
31370b324cSopenharmony_ci  _limitPos = _bufSize;
32370b324cSopenharmony_ci  _pos = 0;
33370b324cSopenharmony_ci  _processedSize = 0;
34370b324cSopenharmony_ci  _overDict = false;
35370b324cSopenharmony_ci  #ifdef Z7_NO_EXCEPTIONS
36370b324cSopenharmony_ci  ErrorCode = S_OK;
37370b324cSopenharmony_ci  #endif
38370b324cSopenharmony_ci}
39370b324cSopenharmony_ci
40370b324cSopenharmony_ciUInt64 COutBuffer::GetProcessedSize() const throw()
41370b324cSopenharmony_ci{
42370b324cSopenharmony_ci  UInt64 res = _processedSize + _pos - _streamPos;
43370b324cSopenharmony_ci  if (_streamPos > _pos)
44370b324cSopenharmony_ci    res += _bufSize;
45370b324cSopenharmony_ci  return res;
46370b324cSopenharmony_ci}
47370b324cSopenharmony_ci
48370b324cSopenharmony_ci
49370b324cSopenharmony_ciHRESULT COutBuffer::FlushPart() throw()
50370b324cSopenharmony_ci{
51370b324cSopenharmony_ci  // _streamPos < _bufSize
52370b324cSopenharmony_ci  UInt32 size = (_streamPos >= _pos) ? (_bufSize - _streamPos) : (_pos - _streamPos);
53370b324cSopenharmony_ci  HRESULT result = S_OK;
54370b324cSopenharmony_ci  #ifdef Z7_NO_EXCEPTIONS
55370b324cSopenharmony_ci  result = ErrorCode;
56370b324cSopenharmony_ci  #endif
57370b324cSopenharmony_ci  if (_buf2)
58370b324cSopenharmony_ci  {
59370b324cSopenharmony_ci    memcpy(_buf2, _buf + _streamPos, size);
60370b324cSopenharmony_ci    _buf2 += size;
61370b324cSopenharmony_ci  }
62370b324cSopenharmony_ci
63370b324cSopenharmony_ci  if (_stream
64370b324cSopenharmony_ci      #ifdef Z7_NO_EXCEPTIONS
65370b324cSopenharmony_ci      && (ErrorCode == S_OK)
66370b324cSopenharmony_ci      #endif
67370b324cSopenharmony_ci     )
68370b324cSopenharmony_ci  {
69370b324cSopenharmony_ci    UInt32 processedSize = 0;
70370b324cSopenharmony_ci    result = _stream->Write(_buf + _streamPos, size, &processedSize);
71370b324cSopenharmony_ci    size = processedSize;
72370b324cSopenharmony_ci  }
73370b324cSopenharmony_ci  _streamPos += size;
74370b324cSopenharmony_ci  if (_streamPos == _bufSize)
75370b324cSopenharmony_ci    _streamPos = 0;
76370b324cSopenharmony_ci  if (_pos == _bufSize)
77370b324cSopenharmony_ci  {
78370b324cSopenharmony_ci    _overDict = true;
79370b324cSopenharmony_ci    _pos = 0;
80370b324cSopenharmony_ci  }
81370b324cSopenharmony_ci  _limitPos = (_streamPos > _pos) ? _streamPos : _bufSize;
82370b324cSopenharmony_ci  _processedSize += size;
83370b324cSopenharmony_ci  return result;
84370b324cSopenharmony_ci}
85370b324cSopenharmony_ci
86370b324cSopenharmony_ciHRESULT COutBuffer::Flush() throw()
87370b324cSopenharmony_ci{
88370b324cSopenharmony_ci  #ifdef Z7_NO_EXCEPTIONS
89370b324cSopenharmony_ci  if (ErrorCode != S_OK)
90370b324cSopenharmony_ci    return ErrorCode;
91370b324cSopenharmony_ci  #endif
92370b324cSopenharmony_ci
93370b324cSopenharmony_ci  while (_streamPos != _pos)
94370b324cSopenharmony_ci  {
95370b324cSopenharmony_ci    const HRESULT result = FlushPart();
96370b324cSopenharmony_ci    if (result != S_OK)
97370b324cSopenharmony_ci      return result;
98370b324cSopenharmony_ci  }
99370b324cSopenharmony_ci  return S_OK;
100370b324cSopenharmony_ci}
101370b324cSopenharmony_ci
102370b324cSopenharmony_civoid COutBuffer::FlushWithCheck()
103370b324cSopenharmony_ci{
104370b324cSopenharmony_ci  const HRESULT result = Flush();
105370b324cSopenharmony_ci  #ifdef Z7_NO_EXCEPTIONS
106370b324cSopenharmony_ci  ErrorCode = result;
107370b324cSopenharmony_ci  #else
108370b324cSopenharmony_ci  if (result != S_OK)
109370b324cSopenharmony_ci    throw COutBufferException(result);
110370b324cSopenharmony_ci  #endif
111370b324cSopenharmony_ci}
112