xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/XzDecoder.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // XzDecoder.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../C/Alloc.h"
6 
7 #include "../Common/CWrappers.h"
8 
9 #include "XzDecoder.h"
10 
11 namespace NCompress {
12 namespace NXz {
13 
14 #define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \
15   if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes;
16 
17 #define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
18   if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
19 
SResToHRESULT_Code(SRes res)20 static HRESULT SResToHRESULT_Code(SRes res) throw()
21 {
22   if (res < 0)
23     return res;
24   switch (res)
25   {
26     case SZ_OK: return S_OK;
27     case SZ_ERROR_MEM: return E_OUTOFMEMORY;
28     case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
29     default: break;
30   }
31   return S_FALSE;
32 }
33 
34 
Decode(ISequentialInStream * seqInStream,ISequentialOutStream * outStream,const UInt64 * outSizeLimit,bool finishStream,ICompressProgressInfo * progress)35 HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
36     const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress)
37 {
38   MainDecodeSRes = SZ_OK;
39   MainDecodeSRes_wasUsed = false;
40   XzStatInfo_Clear(&Stat);
41 
42   if (!xz)
43   {
44     xz = XzDecMt_Create(&g_Alloc, &g_MidAlloc);
45     if (!xz)
46       return E_OUTOFMEMORY;
47   }
48 
49   CXzDecMtProps props;
50   XzDecMtProps_Init(&props);
51 
52   int isMT = False;
53 
54   #ifndef Z7_ST
55   {
56     props.numThreads = 1;
57     const UInt32 numThreads = _numThreads;
58 
59     if (_tryMt && numThreads > 1)
60     {
61       size_t memUsage = (size_t)_memUsage;
62       if (memUsage != _memUsage)
63         memUsage = (size_t)0 - 1;
64       props.memUseMax = memUsage;
65       isMT = (numThreads > 1);
66     }
67 
68     props.numThreads = numThreads;
69   }
70   #endif
71 
72   CSeqInStreamWrap inWrap;
73   CSeqOutStreamWrap outWrap;
74   CCompressProgressWrap progressWrap;
75 
76   inWrap.Init(seqInStream);
77   outWrap.Init(outStream);
78   progressWrap.Init(progress);
79 
80   SRes res = XzDecMt_Decode(xz,
81       &props,
82       outSizeLimit, finishStream,
83       &outWrap.vt,
84       &inWrap.vt,
85       &Stat,
86       &isMT,
87       progress ? &progressWrap.vt : NULL);
88 
89   MainDecodeSRes = res;
90 
91   #ifndef Z7_ST
92   // _tryMt = isMT;
93   #endif
94 
95   RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
96   RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
97   RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ)
98 
99   // return E_OUTOFMEMORY; // for debug check
100 
101   MainDecodeSRes_wasUsed = true;
102 
103   if (res == SZ_OK && finishStream)
104   {
105     /*
106     if (inSize && *inSize != Stat.PhySize)
107       res = SZ_ERROR_DATA;
108     */
109     if (outSizeLimit && *outSizeLimit != outWrap.Processed)
110       res = SZ_ERROR_DATA;
111   }
112 
113   return SResToHRESULT_Code(res);
114 }
115 
116 
Z7_COM7F_IMF(CComDecoder::Code (ISequentialInStream * inStream,ISequentialOutStream * outStream,const UInt64 *,const UInt64 * outSize,ICompressProgressInfo * progress))117 Z7_COM7F_IMF(CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
118     const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress))
119 {
120   return Decode(inStream, outStream, outSize, _finishStream, progress);
121 }
122 
Z7_COM7F_IMF(CComDecoder::SetFinishMode (UInt32 finishMode))123 Z7_COM7F_IMF(CComDecoder::SetFinishMode(UInt32 finishMode))
124 {
125   _finishStream = (finishMode != 0);
126   return S_OK;
127 }
128 
Z7_COM7F_IMF(CComDecoder::GetInStreamProcessedSize (UInt64 * value))129 Z7_COM7F_IMF(CComDecoder::GetInStreamProcessedSize(UInt64 *value))
130 {
131   *value = Stat.InSize;
132   return S_OK;
133 }
134 
135 #ifndef Z7_ST
136 
Z7_COM7F_IMF(CComDecoder::SetNumberOfThreads (UInt32 numThreads))137 Z7_COM7F_IMF(CComDecoder::SetNumberOfThreads(UInt32 numThreads))
138 {
139   _numThreads = numThreads;
140   return S_OK;
141 }
142 
Z7_COM7F_IMF(CComDecoder::SetMemLimit (UInt64 memUsage))143 Z7_COM7F_IMF(CComDecoder::SetMemLimit(UInt64 memUsage))
144 {
145   _memUsage = memUsage;
146   return S_OK;
147 }
148 
149 #endif
150 
151 }}
152