Mercurial > vba-linux
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.cpp3 #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 ReadPart54 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_MODE86 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 else202 {203 _convertedPosEnd = _bufferPos; // check it204 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_MODE221 #ifndef _NO_CRYPTO222 STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)223 {224 return _setPassword->CryptoSetPassword(data, size);225 }226 #endif228 #ifndef EXTRACT_ONLY229 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 #endif253 STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)254 {255 return _setDecoderProperties->SetDecoderProperties2(data, size);256 }260 void foo()261 {262 }