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