1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
// 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;
default: break;
}
return S_FALSE;
}
HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress)
{
MainDecodeSRes = SZ_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 Z7_ST
{
props.numThreads = 1;
const 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 Z7_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; // for debug check
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);
}
Z7_COM7F_IMF(CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress))
{
return Decode(inStream, outStream, outSize, _finishStream, progress);
}
Z7_COM7F_IMF(CComDecoder::SetFinishMode(UInt32 finishMode))
{
_finishStream = (finishMode != 0);
return S_OK;
}
Z7_COM7F_IMF(CComDecoder::GetInStreamProcessedSize(UInt64 *value))
{
*value = Stat.InSize;
return S_OK;
}
#ifndef Z7_ST
Z7_COM7F_IMF(CComDecoder::SetNumberOfThreads(UInt32 numThreads))
{
_numThreads = numThreads;
return S_OK;
}
Z7_COM7F_IMF(CComDecoder::SetMemLimit(UInt64 memUsage))
{
_memUsage = memUsage;
return S_OK;
}
#endif
}}
|