Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Compress/LzmaDecoder.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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Compress/LzmaDecoder.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,190 @@ 1.4 +// LzmaDecoder.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +extern "C" 1.9 +{ 1.10 +#include "../../../C/Alloc.h" 1.11 +} 1.12 + 1.13 +#include "../Common/StreamUtils.h" 1.14 + 1.15 +#include "LzmaDecoder.h" 1.16 + 1.17 +static HRESULT SResToHRESULT(SRes res) 1.18 +{ 1.19 + switch(res) 1.20 + { 1.21 + case SZ_OK: return S_OK; 1.22 + case SZ_ERROR_MEM: return E_OUTOFMEMORY; 1.23 + case SZ_ERROR_PARAM: return E_INVALIDARG; 1.24 + case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; 1.25 + // case SZ_ERROR_PROGRESS: return E_ABORT; 1.26 + case SZ_ERROR_DATA: return S_FALSE; 1.27 + } 1.28 + return E_FAIL; 1.29 +} 1.30 + 1.31 +namespace NCompress { 1.32 +namespace NLzma { 1.33 + 1.34 +static const UInt32 kInBufSize = 1 << 20; 1.35 + 1.36 +CDecoder::CDecoder(): _inBuf(0), _outSizeDefined(false), FinishStream(false) 1.37 +{ 1.38 + LzmaDec_Construct(&_state); 1.39 +} 1.40 + 1.41 +static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } 1.42 +static void SzFree(void *p, void *address) { p = p; MyFree(address); } 1.43 +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; 1.44 + 1.45 +CDecoder::~CDecoder() 1.46 +{ 1.47 + LzmaDec_Free(&_state, &g_Alloc); 1.48 + MyFree(_inBuf); 1.49 +} 1.50 + 1.51 +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) 1.52 +{ 1.53 + RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_Alloc))); 1.54 + 1.55 + if (_inBuf == 0) 1.56 + { 1.57 + _inBuf = (Byte *)MyAlloc(kInBufSize); 1.58 + if (_inBuf == 0) 1.59 + return E_OUTOFMEMORY; 1.60 + } 1.61 + 1.62 + return S_OK; 1.63 +} 1.64 + 1.65 +STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) { *value = _inSizeProcessed; return S_OK; } 1.66 +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; } 1.67 +STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; } 1.68 + 1.69 +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) 1.70 +{ 1.71 + _outSizeDefined = (outSize != NULL); 1.72 + if (_outSizeDefined) 1.73 + _outSize = *outSize; 1.74 + 1.75 + LzmaDec_Init(&_state); 1.76 + 1.77 + _inPos = _inSize = 0; 1.78 + _inSizeProcessed = _outSizeProcessed = 0; 1.79 + return S_OK; 1.80 +} 1.81 + 1.82 +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, 1.83 + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) 1.84 +{ 1.85 + if (_inBuf == 0) 1.86 + return S_FALSE; 1.87 + SetOutStreamSize(outSize); 1.88 + 1.89 + for (;;) 1.90 + { 1.91 + if (_inPos == _inSize) 1.92 + { 1.93 + _inPos = _inSize = 0; 1.94 + RINOK(inStream->Read(_inBuf, kInBufSize, &_inSize)); 1.95 + } 1.96 + 1.97 + SizeT dicPos = _state.dicPos; 1.98 + SizeT curSize = _state.dicBufSize - dicPos; 1.99 + const UInt32 kStepSize = ((UInt32)1 << 22); 1.100 + if (curSize > kStepSize) 1.101 + curSize = (SizeT)kStepSize; 1.102 + 1.103 + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; 1.104 + if (_outSizeDefined) 1.105 + { 1.106 + const UInt64 rem = _outSize - _outSizeProcessed; 1.107 + if (rem < curSize) 1.108 + { 1.109 + curSize = (SizeT)rem; 1.110 + if (FinishStream) 1.111 + finishMode = LZMA_FINISH_END; 1.112 + } 1.113 + } 1.114 + 1.115 + SizeT inSizeProcessed = _inSize - _inPos; 1.116 + ELzmaStatus status; 1.117 + SRes res = LzmaDec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status); 1.118 + 1.119 + _inPos += (UInt32)inSizeProcessed; 1.120 + _inSizeProcessed += inSizeProcessed; 1.121 + SizeT outSizeProcessed = _state.dicPos - dicPos; 1.122 + _outSizeProcessed += outSizeProcessed; 1.123 + 1.124 + bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0); 1.125 + bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize); 1.126 + 1.127 + if (res != 0 || _state.dicPos == _state.dicBufSize || finished || stopDecoding) 1.128 + { 1.129 + HRESULT res2 = WriteStream(outStream, _state.dic, _state.dicPos); 1.130 + if (res != 0) 1.131 + return S_FALSE; 1.132 + RINOK(res2); 1.133 + if (stopDecoding) 1.134 + return S_OK; 1.135 + if (finished) 1.136 + return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE); 1.137 + } 1.138 + if (_state.dicPos == _state.dicBufSize) 1.139 + _state.dicPos = 0; 1.140 + 1.141 + if (progress != NULL) 1.142 + { 1.143 + RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed)); 1.144 + } 1.145 + } 1.146 +} 1.147 + 1.148 +#ifndef NO_READ_FROM_CODER 1.149 + 1.150 +STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) 1.151 +{ 1.152 + if (processedSize) 1.153 + *processedSize = 0; 1.154 + do 1.155 + { 1.156 + if (_inPos == _inSize) 1.157 + { 1.158 + _inPos = _inSize = 0; 1.159 + RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize)); 1.160 + } 1.161 + { 1.162 + SizeT inProcessed = _inSize - _inPos; 1.163 + 1.164 + if (_outSizeDefined) 1.165 + { 1.166 + const UInt64 rem = _outSize - _outSizeProcessed; 1.167 + if (rem < size) 1.168 + size = (UInt32)rem; 1.169 + } 1.170 + 1.171 + SizeT outProcessed = size; 1.172 + ELzmaStatus status; 1.173 + SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, 1.174 + _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status); 1.175 + _inPos += (UInt32)inProcessed; 1.176 + _inSizeProcessed += inProcessed; 1.177 + _outSizeProcessed += outProcessed; 1.178 + size -= (UInt32)outProcessed; 1.179 + data = (Byte *)data + outProcessed; 1.180 + if (processedSize) 1.181 + *processedSize += (UInt32)outProcessed; 1.182 + RINOK(SResToHRESULT(res)); 1.183 + if (inProcessed == 0 && outProcessed == 0) 1.184 + return S_OK; 1.185 + } 1.186 + } 1.187 + while (size != 0); 1.188 + return S_OK; 1.189 +} 1.190 + 1.191 +#endif 1.192 + 1.193 +}}