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