// XzDecoder.cpp #include "StdAfx.h" #include "../../../C/Alloc.h" #include "../Common/CWrappers.h" #include "XzDecoder.h" namespace NCompress { namespace NXz { #define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \ if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes; #define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; static HRESULT SResToHRESULT_Code(SRes res) throw() { 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) { MainDecodeSRes = S_OK; MainDecodeSRes_wasUsed = false; XzStatInfo_Clear(&Stat); if (!xz) { xz = XzDecMt_Create(&g_Alloc, &g_MidAlloc); if (!xz) return E_OUTOFMEMORY; } CXzDecMtProps props; XzDecMtProps_Init(&props); int isMT = False; #ifndef _7ZIP_ST { props.numThreads = 1; UInt32 numThreads = _numThreads; if (_tryMt && numThreads > 1) { size_t memUsage = (size_t)_memUsage; if (memUsage != _memUsage) memUsage = (size_t)0 - 1; props.memUseMax = memUsage; isMT = (numThreads > 1); } props.numThreads = numThreads; } #endif CSeqInStreamWrap inWrap; CSeqOutStreamWrap outWrap; CCompressProgressWrap progressWrap; inWrap.Init(seqInStream); outWrap.Init(outStream); progressWrap.Init(progress); SRes res = XzDecMt_Decode(xz, &props, outSizeLimit, finishStream, &outWrap.vt, &inWrap.vt, &Stat, &isMT, progress ? &progressWrap.vt : NULL); MainDecodeSRes = res; #ifndef _7ZIP_ST // _tryMt = isMT; #endif 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) // return E_OUTOFMEMORY; MainDecodeSRes_wasUsed = true; if (res == SZ_OK && finishStream) { /* if (inSize && *inSize != Stat.PhySize) res = SZ_ERROR_DATA; */ if (outSizeLimit && *outSizeLimit != outWrap.Processed) res = SZ_ERROR_DATA; } return SResToHRESULT_Code(res); } HRESULT CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) { return Decode(inStream, outStream, outSize, _finishStream, progress); } STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode) { _finishStream = (finishMode != 0); return S_OK; } STDMETHODIMP CComDecoder::GetInStreamProcessedSize(UInt64 *value) { *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 }}