Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2018-03-12 14:19:17 +0300
committerKornel <kornel@geekhood.net>2018-03-12 14:19:46 +0300
commitf19b649c73cd8b74c4e0b8a3a728a82c6bda47b4 (patch)
tree3725026df472886583a019239ed169e356ce1f63 /CPP/7zip/Compress/XzDecoder.cpp
parent866a06f5a0c0ede11979504a318e150030aa7a11 (diff)
18.0318.03
Diffstat (limited to 'CPP/7zip/Compress/XzDecoder.cpp')
-rw-r--r--CPP/7zip/Compress/XzDecoder.cpp289
1 files changed, 88 insertions, 201 deletions
diff --git a/CPP/7zip/Compress/XzDecoder.cpp b/CPP/7zip/Compress/XzDecoder.cpp
index c28ac900..7a974311 100644
--- a/CPP/7zip/Compress/XzDecoder.cpp
+++ b/CPP/7zip/Compress/XzDecoder.cpp
@@ -4,248 +4,119 @@
#include "../../../C/Alloc.h"
-#include "../Common/StreamUtils.h"
-
-#include "../Archive/IArchive.h"
+#include "../Common/CWrappers.h"
#include "XzDecoder.h"
-using namespace NArchive;
-
namespace NCompress {
namespace NXz {
+#define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes;
-CXzUnpackerCPP::CXzUnpackerCPP(): InBuf(NULL), OutBuf(NULL)
-{
- XzUnpacker_Construct(&p, &g_Alloc);
-}
-
-CXzUnpackerCPP::~CXzUnpackerCPP()
-{
- XzUnpacker_Free(&p);
- MidFree(InBuf);
- MidFree(OutBuf);
-}
-
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
-void CStatInfo::Clear()
+static HRESULT SResToHRESULT_Code(SRes res) throw()
{
- InSize = 0;
- OutSize = 0;
- PhySize = 0;
-
- NumStreams = 0;
- NumBlocks = 0;
-
- UnpackSize_Defined = false;
-
- NumStreams_Defined = false;
- NumBlocks_Defined = false;
-
- IsArc = false;
- UnexpectedEnd = false;
- DataAfterEnd = false;
- Unsupported = false;
- HeadersError = false;
- DataError = false;
- CrcError = false;
+ if (res < 0)
+ return res;
+ switch (res)
+ {
+ case SZ_OK: return S_OK;
+ case SZ_ERROR_MEM: return E_OUTOFMEMORY;
+ case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
+ }
+ return S_FALSE;
}
HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress)
{
- const size_t kInBufSize = (size_t)1 << 20;
- const size_t kOutBufSize = (size_t)1 << 21;
-
- Clear();
- DecodeRes = SZ_OK;
-
- XzUnpacker_Init(&xzu.p);
+ MainDecodeSRes = S_OK;
+ MainDecodeSRes_wasUsed = false;
+ XzStatInfo_Clear(&Stat);
- if (!xzu.InBuf)
+ if (!xz)
{
- xzu.InBuf = (Byte *)MidAlloc(kInBufSize);
- if (!xzu.InBuf)
+ xz = XzDecMt_Create(&g_Alloc, &g_MidAlloc);
+ if (!xz)
return E_OUTOFMEMORY;
}
- if (!xzu.OutBuf)
- {
- xzu.OutBuf = (Byte *)MidAlloc(kOutBufSize);
- if (!xzu.OutBuf)
- return E_OUTOFMEMORY;
- }
-
- UInt32 inSize = 0;
- UInt32 inPos = 0;
- SizeT outPos = 0;
- HRESULT readRes = S_OK;
+ CXzDecMtProps props;
+ XzDecMtProps_Init(&props);
- for (;;)
+ int isMT = False;
+
+ #ifndef _7ZIP_ST
{
- if (inPos == inSize && readRes == S_OK)
+ props.numThreads = 1;
+ UInt32 numThreads = _numThreads;
+
+ if (_tryMt && numThreads > 1)
{
- inPos = inSize = 0;
- readRes = seqInStream->Read(xzu.InBuf, kInBufSize, &inSize);
+ size_t memUsage = (size_t)_memUsage;
+ if (memUsage != _memUsage)
+ memUsage = (size_t)0 - 1;
+ props.memUseMax = memUsage;
+ isMT = (numThreads > 1);
}
- SizeT inLen = inSize - inPos;
- SizeT outLen = kOutBufSize - outPos;
- ECoderFinishMode finishMode = CODER_FINISH_ANY;
+ props.numThreads = numThreads;
+ }
+ #endif
- /*
- // 17.01 : the code was disabled:
- if (inSize == 0)
- finishMode = CODER_FINISH_END;
- */
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
- if (outSizeLimit)
- {
- const UInt64 rem = *outSizeLimit - OutSize;
- if (outLen >= rem)
- {
- outLen = (SizeT)rem;
- if (finishStream)
- finishMode = CODER_FINISH_END;
- }
- }
-
- ECoderStatus status;
+ inWrap.Init(seqInStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
- const SizeT outLenRequested = outLen;
+ SRes res = XzDecMt_Decode(xz,
+ &props,
+ outSizeLimit, finishStream,
+ &outWrap.vt,
+ &inWrap.vt,
+ &Stat,
+ &isMT,
+ progress ? &progressWrap.vt : NULL);
- SRes res = XzUnpacker_Code(&xzu.p,
- xzu.OutBuf + outPos, &outLen,
- xzu.InBuf + inPos, &inLen,
- finishMode, &status);
+ MainDecodeSRes = res;
- DecodeRes = res;
+ #ifndef _7ZIP_ST
+ // _tryMt = isMT;
+ #endif
- inPos += (UInt32)inLen;
- outPos += outLen;
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+ RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ)
- InSize += inLen;
- OutSize += outLen;
+ // return E_OUTOFMEMORY;
- bool finished = ((inLen == 0 && outLen == 0) || res != SZ_OK);
+ MainDecodeSRes_wasUsed = true;
- if (outLen >= outLenRequested || finished)
- {
- if (outStream && outPos != 0)
- {
- RINOK(WriteStream(outStream, xzu.OutBuf, outPos));
- }
- outPos = 0;
- }
-
- if (progress)
- {
- RINOK(progress->SetRatioInfo(&InSize, &OutSize));
- }
-
- if (!finished)
- continue;
-
- {
- PhySize = InSize;
- NumStreams = xzu.p.numStartedStreams;
- if (NumStreams > 0)
- IsArc = true;
- NumBlocks = xzu.p.numTotalBlocks;
-
- UnpackSize_Defined = true;
- NumStreams_Defined = true;
- NumBlocks_Defined = true;
-
- UInt64 extraSize = XzUnpacker_GetExtraSize(&xzu.p);
-
- if (res == SZ_OK)
- {
- if (status == CODER_STATUS_NEEDS_MORE_INPUT)
- {
- extraSize = 0;
- if (!XzUnpacker_IsStreamWasFinished(&xzu.p))
- {
- // finished at padding bytes, but padding is not aligned for 4
- UnexpectedEnd = true;
- res = SZ_ERROR_DATA;
- }
- }
- else // status == CODER_STATUS_NOT_FINISHED
- res = SZ_ERROR_DATA;
- }
- else if (res == SZ_ERROR_NO_ARCHIVE)
- {
- if (InSize == extraSize)
- IsArc = false;
- else
- {
- if (extraSize != 0 || inPos != inSize)
- {
- DataAfterEnd = true;
- res = SZ_OK;
- }
- }
- }
-
- DecodeRes = res;
- PhySize -= extraSize;
-
- switch (res)
- {
- case SZ_OK: break;
- case SZ_ERROR_NO_ARCHIVE: IsArc = false; break;
- case SZ_ERROR_ARCHIVE: HeadersError = true; break;
- case SZ_ERROR_UNSUPPORTED: Unsupported = true; break;
- case SZ_ERROR_CRC: CrcError = true; break;
- case SZ_ERROR_DATA: DataError = true; break;
- default: DataError = true; break;
- }
-
- return readRes;
- }
+ if (res == SZ_OK && finishStream)
+ {
+ /*
+ if (inSize && *inSize != Stat.PhySize)
+ res = SZ_ERROR_DATA;
+ */
+ if (outSizeLimit && *outSizeLimit != outWrap.Processed)
+ res = SZ_ERROR_DATA;
}
-}
-
-Int32 CDecoder::Get_Extract_OperationResult() const
-{
- Int32 opRes;
- if (!IsArc)
- opRes = NExtract::NOperationResult::kIsNotArc;
- else if (UnexpectedEnd)
- opRes = NExtract::NOperationResult::kUnexpectedEnd;
- else if (DataAfterEnd)
- opRes = NExtract::NOperationResult::kDataAfterEnd;
- else if (CrcError)
- opRes = NExtract::NOperationResult::kCRCError;
- else if (Unsupported)
- opRes = NExtract::NOperationResult::kUnsupportedMethod;
- else if (HeadersError)
- opRes = NExtract::NOperationResult::kDataError;
- else if (DataError)
- opRes = NExtract::NOperationResult::kDataError;
- else if (DecodeRes != SZ_OK)
- opRes = NExtract::NOperationResult::kDataError;
- else
- opRes = NExtract::NOperationResult::kOK;
- return opRes;
+ return SResToHRESULT_Code(res);
}
-
HRESULT CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
{
- RINOK(_decoder.Decode(inStream, outStream, outSize, _finishStream, progress));
- Int32 opRes = _decoder.Get_Extract_OperationResult();
- if (opRes == NArchive::NExtract::NOperationResult::kUnsupportedMethod)
- return E_NOTIMPL;
- if (opRes != NArchive::NExtract::NOperationResult::kOK)
- return S_FALSE;
- return S_OK;
+ return Decode(inStream, outStream, outSize, _finishStream, progress);
}
STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode)
@@ -256,8 +127,24 @@ STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode)
STDMETHODIMP CComDecoder::GetInStreamProcessedSize(UInt64 *value)
{
- *value = _decoder.InSize;
+ *value = Stat.InSize;
+ return S_OK;
+}
+
+#ifndef _7ZIP_ST
+
+STDMETHODIMP CComDecoder::SetNumberOfThreads(UInt32 numThreads)
+{
+ _numThreads = numThreads;
return S_OK;
}
+STDMETHODIMP CComDecoder::SetMemLimit(UInt64 memUsage)
+{
+ _memUsage = memUsage;
+ return S_OK;
+}
+
+#endif
+
}}