view src/win32/7zip/7z/CPP/7zip/Common/FilterCoder.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line source
1 // FilterCoder.cpp
3 #include "StdAfx.h"
5 #include "FilterCoder.h"
6 extern "C"
7 {
8 #include "../../../C/Alloc.h"
9 }
10 #include "../../Common/Defs.h"
11 #include "StreamUtils.h"
13 static const UInt32 kBufferSize = 1 << 17;
15 CFilterCoder::CFilterCoder()
16 {
17 _buffer = (Byte *)::MidAlloc(kBufferSize);
18 }
20 CFilterCoder::~CFilterCoder()
21 {
22 ::MidFree(_buffer);
23 }
25 HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size)
26 {
27 if (_outSizeIsDefined)
28 {
29 UInt64 remSize = _outSize - _nowPos64;
30 if (size > remSize)
31 size = (UInt32)remSize;
32 }
33 RINOK(WriteStream(outStream, _buffer, size));
34 _nowPos64 += size;
35 return S_OK;
36 }
39 STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream,
40 ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
41 ICompressProgressInfo *progress)
42 {
43 RINOK(Init());
44 UInt32 bufferPos = 0;
45 _outSizeIsDefined = (outSize != 0);
46 if (_outSizeIsDefined)
47 _outSize = *outSize;
49 while(NeedMore())
50 {
51 size_t processedSize = kBufferSize - bufferPos;
53 // Change it: It can be optimized using ReadPart
54 RINOK(ReadStream(inStream, _buffer + bufferPos, &processedSize));
56 UInt32 endPos = bufferPos + (UInt32)processedSize;
58 bufferPos = Filter->Filter(_buffer, endPos);
59 if (bufferPos > endPos)
60 {
61 for (; endPos< bufferPos; endPos++)
62 _buffer[endPos] = 0;
63 bufferPos = Filter->Filter(_buffer, endPos);
64 }
66 if (bufferPos == 0)
67 {
68 if (endPos > 0)
69 return WriteWithLimit(outStream, endPos);
70 return S_OK;
71 }
72 RINOK(WriteWithLimit(outStream, bufferPos));
73 if (progress != NULL)
74 {
75 RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64));
76 }
77 UInt32 i = 0;
78 while(bufferPos < endPos)
79 _buffer[i++] = _buffer[bufferPos++];
80 bufferPos = i;
81 }
82 return S_OK;
83 }
85 // #ifdef _ST_MODE
86 STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream)
87 {
88 _bufferPos = 0;
89 _outStream = outStream;
90 return Init();
91 }
93 STDMETHODIMP CFilterCoder::ReleaseOutStream()
94 {
95 _outStream.Release();
96 return S_OK;
97 };
100 STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)
101 {
102 UInt32 processedSizeTotal = 0;
103 while(size > 0)
104 {
105 UInt32 sizeMax = kBufferSize - _bufferPos;
106 UInt32 sizeTemp = size;
107 if (sizeTemp > sizeMax)
108 sizeTemp = sizeMax;
109 memmove(_buffer + _bufferPos, data, sizeTemp);
110 size -= sizeTemp;
111 processedSizeTotal += sizeTemp;
112 data = (const Byte *)data + sizeTemp;
113 UInt32 endPos = _bufferPos + sizeTemp;
114 _bufferPos = Filter->Filter(_buffer, endPos);
115 if (_bufferPos == 0)
116 {
117 _bufferPos = endPos;
118 break;
119 }
120 if (_bufferPos > endPos)
121 {
122 if (size != 0)
123 return E_FAIL;
124 break;
125 }
126 RINOK(WriteWithLimit(_outStream, _bufferPos));
127 UInt32 i = 0;
128 while(_bufferPos < endPos)
129 _buffer[i++] = _buffer[_bufferPos++];
130 _bufferPos = i;
131 }
132 if (processedSize != NULL)
133 *processedSize = processedSizeTotal;
134 return S_OK;
135 }
137 STDMETHODIMP CFilterCoder::Flush()
138 {
139 if (_bufferPos != 0)
140 {
141 UInt32 endPos = Filter->Filter(_buffer, _bufferPos);
142 if (endPos > _bufferPos)
143 {
144 for (; _bufferPos < endPos; _bufferPos++)
145 _buffer[_bufferPos] = 0;
146 if (Filter->Filter(_buffer, endPos) != endPos)
147 return E_FAIL;
148 }
149 RINOK(WriteStream(_outStream, _buffer, _bufferPos));
150 _bufferPos = 0;
151 }
152 CMyComPtr<IOutStreamFlush> flush;
153 _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
154 if (flush)
155 return flush->Flush();
156 return S_OK;
157 }
160 STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
161 {
162 _convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
163 _inStream = inStream;
164 return Init();
165 }
167 STDMETHODIMP CFilterCoder::ReleaseInStream()
168 {
169 _inStream.Release();
170 return S_OK;
171 };
173 STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
174 {
175 UInt32 processedSizeTotal = 0;
176 while(size > 0)
177 {
178 if (_convertedPosBegin != _convertedPosEnd)
179 {
180 UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin);
181 memmove(data, _buffer + _convertedPosBegin, sizeTemp);
182 _convertedPosBegin += sizeTemp;
183 data = (void *)((Byte *)data + sizeTemp);
184 size -= sizeTemp;
185 processedSizeTotal += sizeTemp;
186 break;
187 }
188 int i;
189 for (i = 0; _convertedPosEnd + i < _bufferPos; i++)
190 _buffer[i] = _buffer[i + _convertedPosEnd];
191 _bufferPos = i;
192 _convertedPosBegin = _convertedPosEnd = 0;
193 size_t processedSizeTemp = kBufferSize - _bufferPos;
194 RINOK(ReadStream(_inStream, _buffer + _bufferPos, &processedSizeTemp));
195 _bufferPos = _bufferPos + (UInt32)processedSizeTemp;
196 _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
197 if (_convertedPosEnd == 0)
198 {
199 if (_bufferPos == 0)
200 break;
201 else
202 {
203 _convertedPosEnd = _bufferPos; // check it
204 continue;
205 }
206 }
207 if (_convertedPosEnd > _bufferPos)
208 {
209 for (; _bufferPos < _convertedPosEnd; _bufferPos++)
210 _buffer[_bufferPos] = 0;
211 _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
212 }
213 }
214 if (processedSize != NULL)
215 *processedSize = processedSizeTotal;
216 return S_OK;
217 }
219 // #endif // _ST_MODE
221 #ifndef _NO_CRYPTO
222 STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)
223 {
224 return _setPassword->CryptoSetPassword(data, size);
225 }
226 #endif
228 #ifndef EXTRACT_ONLY
229 STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs,
230 const PROPVARIANT *properties, UInt32 numProperties)
231 {
232 return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties);
233 }
235 STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)
236 {
237 return _writeCoderProperties->WriteCoderProperties(outStream);
238 }
240 /*
241 STDMETHODIMP CFilterCoder::ResetSalt()
242 {
243 return _CryptoResetSalt->ResetSalt();
244 }
245 */
247 STDMETHODIMP CFilterCoder::ResetInitVector()
248 {
249 return _CryptoResetInitVector->ResetInitVector();
250 }
251 #endif
253 STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
254 {
255 return _setDecoderProperties->SetDecoderProperties2(data, size);
256 }
260 void foo()
261 {
262 }