diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2016-09-29 03:00:00 +0300 |
---|---|---|
committer | Kornel LesinĚski <kornel@geekhood.net> | 2016-12-08 15:12:54 +0300 |
commit | 232ce7957441b06193c4cbdc1bc9e71436fadfdb (patch) | |
tree | cbfba61cb993434ebb38be4e058a977d91a8676a /CPP/7zip/Archive/Nsis/NsisDecode.cpp | |
parent | 1eddf527cacc149016ec987d554d3dfb52b69131 (diff) |
16.0316.03
Diffstat (limited to 'CPP/7zip/Archive/Nsis/NsisDecode.cpp')
-rw-r--r-- | CPP/7zip/Archive/Nsis/NsisDecode.cpp | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.cpp b/CPP/7zip/Archive/Nsis/NsisDecode.cpp index 0bbf6094..daf3df6e 100644 --- a/CPP/7zip/Archive/Nsis/NsisDecode.cpp +++ b/CPP/7zip/Archive/Nsis/NsisDecode.cpp @@ -12,7 +12,6 @@ #include "../../Compress/BcjCoder.h" #include "../../Compress/BZip2Decoder.h" -#include "../../Compress/DeflateDecoder.h" #define Get32(p) GetUi32(p) @@ -27,12 +26,16 @@ HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter) if (Method != _curMethod) Release(); _curMethod = Method; + if (!_codecInStream) { switch (Method) { // case NMethodType::kCopy: return E_NOTIMPL; - case NMethodType::kDeflate: _codecInStream = new NCompress::NDeflate::NDecoder::CNsisCOMCoder(); break; + case NMethodType::kDeflate: + _deflateDecoder = new NCompress::NDeflate::NDecoder::CCOMCoder(); + _codecInStream = _deflateDecoder; + break; case NMethodType::kBZip2: _codecInStream = new NCompress::NBZip2::CNsisDecoder(); break; case NMethodType::kLZMA: _lzmaDecoder = new NCompress::NLzma::CDecoder(); @@ -42,6 +45,9 @@ HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter) } } + if (Method == NMethodType::kDeflate) + _deflateDecoder->SetNsisMode(IsNsisDeflate); + if (FilterFlag) { Byte flag; @@ -199,9 +205,8 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp if (outBuf) { - if (!unpackSizeDefined) - return S_FALSE; - outBuf->Alloc(unpackSize); + if (unpackSizeDefined) + outBuf->Alloc(unpackSize); } UInt64 inSizeStart = 0; @@ -213,6 +218,8 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp unpackSize = 0xFFFFFFFF; UInt32 offset = 0; + HRESULT res = S_OK; + for (;;) { size_t rem = unpackSize - offset; @@ -225,11 +232,25 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp if (size == 0) { if (unpackSizeDefined) - return S_FALSE; + res = S_FALSE; break; } + if (outBuf) + { + size_t nextSize = offset + size; + if (outBuf->Size() < nextSize) + { + { + const size_t nextSize2 = outBuf->Size() * 2; + if (nextSize < nextSize2) + nextSize = nextSize2; + } + outBuf->ChangeSize_KeepData(nextSize, offset); + } memcpy((Byte *)*outBuf + (size_t)offset, Buffer, size); + } + StreamPos += size; offset += (UInt32)size; @@ -243,9 +264,17 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp UInt64 outSize = offset; RINOK(progress->SetRatioInfo(&inSize, &outSize)); if (realOutStream) - RINOK(WriteStream(realOutStream, Buffer, size)); + { + res = WriteStream(realOutStream, Buffer, size); + if (res != S_OK) + break; + } } - return S_OK; + + if (outBuf && offset != outBuf->Size()) + outBuf->ChangeSize_KeepData(offset, offset); + + return res; } }} |