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