1 // OutBuffer.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../C/Alloc.h"
6 
7 #include "OutBuffer.h"
8 
Create(UInt32 bufSize)9 bool 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 
Free()22 void COutBuffer::Free() throw()
23 {
24   ::MidFree(_buf);
25   _buf = 0;
26 }
27 
Init()28 void 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 
GetProcessedSize() const40 UInt64 COutBuffer::GetProcessedSize() const throw()
41 {
42   UInt64 res = _processedSize + _pos - _streamPos;
43   if (_streamPos > _pos)
44     res += _bufSize;
45   return res;
46 }
47 
48 
FlushPart()49 HRESULT 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 
Flush()86 HRESULT 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 
FlushWithCheck()102 void 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