xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/LzmaHandler.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // LzmaHandler.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/CpuArch.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ComTry.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/IntToString.h"
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/PropVariant.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker #include "../Common/FilterCoder.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ProgressUtils.h"
14*f6dc9357SAndroid Build Coastguard Worker #include "../Common/RegisterArc.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/BcjCoder.h"
18*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/LzmaDecoder.h"
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker #include "Common/DummyOutStream.h"
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
23*f6dc9357SAndroid Build Coastguard Worker 
24*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
25*f6dc9357SAndroid Build Coastguard Worker namespace NLzma {
26*f6dc9357SAndroid Build Coastguard Worker 
CheckDicSize(const Byte * p)27*f6dc9357SAndroid Build Coastguard Worker static bool CheckDicSize(const Byte *p)
28*f6dc9357SAndroid Build Coastguard Worker {
29*f6dc9357SAndroid Build Coastguard Worker   UInt32 dicSize = GetUi32(p);
30*f6dc9357SAndroid Build Coastguard Worker   if (dicSize == 1)
31*f6dc9357SAndroid Build Coastguard Worker     return true;
32*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i <= 30; i++)
33*f6dc9357SAndroid Build Coastguard Worker     if (dicSize == ((UInt32)2 << i) || dicSize == ((UInt32)3 << i))
34*f6dc9357SAndroid Build Coastguard Worker       return true;
35*f6dc9357SAndroid Build Coastguard Worker   return (dicSize == 0xFFFFFFFF);
36*f6dc9357SAndroid Build Coastguard Worker }
37*f6dc9357SAndroid Build Coastguard Worker 
38*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
39*f6dc9357SAndroid Build Coastguard Worker {
40*f6dc9357SAndroid Build Coastguard Worker   kpidSize,
41*f6dc9357SAndroid Build Coastguard Worker   kpidPackSize,
42*f6dc9357SAndroid Build Coastguard Worker   kpidMethod
43*f6dc9357SAndroid Build Coastguard Worker };
44*f6dc9357SAndroid Build Coastguard Worker 
45*f6dc9357SAndroid Build Coastguard Worker static const Byte kArcProps[] =
46*f6dc9357SAndroid Build Coastguard Worker {
47*f6dc9357SAndroid Build Coastguard Worker   kpidNumStreams,
48*f6dc9357SAndroid Build Coastguard Worker   kpidMethod
49*f6dc9357SAndroid Build Coastguard Worker };
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker struct CHeader
52*f6dc9357SAndroid Build Coastguard Worker {
53*f6dc9357SAndroid Build Coastguard Worker   UInt64 Size;
54*f6dc9357SAndroid Build Coastguard Worker   Byte FilterID;
55*f6dc9357SAndroid Build Coastguard Worker   Byte LzmaProps[5];
56*f6dc9357SAndroid Build Coastguard Worker 
GetPropNArchive::NLzma::CHeader57*f6dc9357SAndroid Build Coastguard Worker   Byte GetProp() const { return LzmaProps[0]; }
GetDicSizeNArchive::NLzma::CHeader58*f6dc9357SAndroid Build Coastguard Worker   UInt32 GetDicSize() const { return GetUi32(LzmaProps + 1); }
HasSizeNArchive::NLzma::CHeader59*f6dc9357SAndroid Build Coastguard Worker   bool HasSize() const { return (Size != (UInt64)(Int64)-1); }
60*f6dc9357SAndroid Build Coastguard Worker   bool Parse(const Byte *buf, bool isThereFilter);
61*f6dc9357SAndroid Build Coastguard Worker };
62*f6dc9357SAndroid Build Coastguard Worker 
Parse(const Byte * buf,bool isThereFilter)63*f6dc9357SAndroid Build Coastguard Worker bool CHeader::Parse(const Byte *buf, bool isThereFilter)
64*f6dc9357SAndroid Build Coastguard Worker {
65*f6dc9357SAndroid Build Coastguard Worker   FilterID = 0;
66*f6dc9357SAndroid Build Coastguard Worker   if (isThereFilter)
67*f6dc9357SAndroid Build Coastguard Worker     FilterID = buf[0];
68*f6dc9357SAndroid Build Coastguard Worker   const Byte *sig = buf + (isThereFilter ? 1 : 0);
69*f6dc9357SAndroid Build Coastguard Worker   for (int i = 0; i < 5; i++)
70*f6dc9357SAndroid Build Coastguard Worker     LzmaProps[i] = sig[i];
71*f6dc9357SAndroid Build Coastguard Worker   Size = GetUi64(sig + 5);
72*f6dc9357SAndroid Build Coastguard Worker   return
73*f6dc9357SAndroid Build Coastguard Worker     LzmaProps[0] < 5 * 5 * 9 &&
74*f6dc9357SAndroid Build Coastguard Worker     FilterID < 2 &&
75*f6dc9357SAndroid Build Coastguard Worker     (!HasSize() || Size < ((UInt64)1 << 56))
76*f6dc9357SAndroid Build Coastguard Worker     && CheckDicSize(LzmaProps + 1);
77*f6dc9357SAndroid Build Coastguard Worker }
78*f6dc9357SAndroid Build Coastguard Worker 
79*f6dc9357SAndroid Build Coastguard Worker class CDecoder Z7_final
80*f6dc9357SAndroid Build Coastguard Worker {
81*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> _bcjStream;
82*f6dc9357SAndroid Build Coastguard Worker   CFilterCoder *_filterCoder;
83*f6dc9357SAndroid Build Coastguard Worker public:
84*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2<ICompressCoder, NCompress::NLzma::CDecoder> _lzmaDecoder;
85*f6dc9357SAndroid Build Coastguard Worker 
86*f6dc9357SAndroid Build Coastguard Worker   ~CDecoder();
87*f6dc9357SAndroid Build Coastguard Worker   HRESULT Create(bool filtered, ISequentialInStream *inStream);
88*f6dc9357SAndroid Build Coastguard Worker 
89*f6dc9357SAndroid Build Coastguard Worker   HRESULT Code(const CHeader &header, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
90*f6dc9357SAndroid Build Coastguard Worker 
GetInputProcessedSize() const91*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetInputProcessedSize() const { return _lzmaDecoder->GetInputProcessedSize(); }
92*f6dc9357SAndroid Build Coastguard Worker 
ReleaseInStream()93*f6dc9357SAndroid Build Coastguard Worker   void ReleaseInStream() { if (_lzmaDecoder) _lzmaDecoder->ReleaseInStream(); }
94*f6dc9357SAndroid Build Coastguard Worker 
ReadInput(Byte * data,UInt32 size,UInt32 * processedSize)95*f6dc9357SAndroid Build Coastguard Worker   HRESULT ReadInput(Byte *data, UInt32 size, UInt32 *processedSize)
96*f6dc9357SAndroid Build Coastguard Worker     { return _lzmaDecoder->ReadFromInputStream(data, size, processedSize); }
97*f6dc9357SAndroid Build Coastguard Worker };
98*f6dc9357SAndroid Build Coastguard Worker 
Create(bool filteredMode,ISequentialInStream * inStream)99*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::Create(bool filteredMode, ISequentialInStream *inStream)
100*f6dc9357SAndroid Build Coastguard Worker {
101*f6dc9357SAndroid Build Coastguard Worker   _lzmaDecoder.Create_if_Empty();
102*f6dc9357SAndroid Build Coastguard Worker   _lzmaDecoder->FinishStream = true;
103*f6dc9357SAndroid Build Coastguard Worker 
104*f6dc9357SAndroid Build Coastguard Worker   if (filteredMode)
105*f6dc9357SAndroid Build Coastguard Worker   {
106*f6dc9357SAndroid Build Coastguard Worker     if (!_bcjStream)
107*f6dc9357SAndroid Build Coastguard Worker     {
108*f6dc9357SAndroid Build Coastguard Worker       _filterCoder = new CFilterCoder(false);
109*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ICompressCoder> coder = _filterCoder;
110*f6dc9357SAndroid Build Coastguard Worker       _filterCoder->Filter = new NCompress::NBcj::CCoder2(z7_BranchConvSt_X86_Dec);
111*f6dc9357SAndroid Build Coastguard Worker       _bcjStream = _filterCoder;
112*f6dc9357SAndroid Build Coastguard Worker     }
113*f6dc9357SAndroid Build Coastguard Worker   }
114*f6dc9357SAndroid Build Coastguard Worker 
115*f6dc9357SAndroid Build Coastguard Worker   return _lzmaDecoder->SetInStream(inStream);
116*f6dc9357SAndroid Build Coastguard Worker }
117*f6dc9357SAndroid Build Coastguard Worker 
~CDecoder()118*f6dc9357SAndroid Build Coastguard Worker CDecoder::~CDecoder()
119*f6dc9357SAndroid Build Coastguard Worker {
120*f6dc9357SAndroid Build Coastguard Worker   ReleaseInStream();
121*f6dc9357SAndroid Build Coastguard Worker }
122*f6dc9357SAndroid Build Coastguard Worker 
Code(const CHeader & header,ISequentialOutStream * outStream,ICompressProgressInfo * progress)123*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
124*f6dc9357SAndroid Build Coastguard Worker     ICompressProgressInfo *progress)
125*f6dc9357SAndroid Build Coastguard Worker {
126*f6dc9357SAndroid Build Coastguard Worker   if (header.FilterID > 1)
127*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
128*f6dc9357SAndroid Build Coastguard Worker 
129*f6dc9357SAndroid Build Coastguard Worker   RINOK(_lzmaDecoder->SetDecoderProperties2(header.LzmaProps, 5))
130*f6dc9357SAndroid Build Coastguard Worker 
131*f6dc9357SAndroid Build Coastguard Worker   bool filteredMode = (header.FilterID == 1);
132*f6dc9357SAndroid Build Coastguard Worker 
133*f6dc9357SAndroid Build Coastguard Worker   if (filteredMode)
134*f6dc9357SAndroid Build Coastguard Worker   {
135*f6dc9357SAndroid Build Coastguard Worker     RINOK(_filterCoder->SetOutStream(outStream))
136*f6dc9357SAndroid Build Coastguard Worker     outStream = _bcjStream;
137*f6dc9357SAndroid Build Coastguard Worker     RINOK(_filterCoder->SetOutStreamSize(NULL))
138*f6dc9357SAndroid Build Coastguard Worker   }
139*f6dc9357SAndroid Build Coastguard Worker 
140*f6dc9357SAndroid Build Coastguard Worker   const UInt64 *Size = header.HasSize() ? &header.Size : NULL;
141*f6dc9357SAndroid Build Coastguard Worker   HRESULT res = _lzmaDecoder->CodeResume(outStream, Size, progress);
142*f6dc9357SAndroid Build Coastguard Worker 
143*f6dc9357SAndroid Build Coastguard Worker   if (filteredMode)
144*f6dc9357SAndroid Build Coastguard Worker   {
145*f6dc9357SAndroid Build Coastguard Worker     {
146*f6dc9357SAndroid Build Coastguard Worker       HRESULT res2 = _filterCoder->OutStreamFinish();
147*f6dc9357SAndroid Build Coastguard Worker       if (res == S_OK)
148*f6dc9357SAndroid Build Coastguard Worker         res = res2;
149*f6dc9357SAndroid Build Coastguard Worker     }
150*f6dc9357SAndroid Build Coastguard Worker     HRESULT res2 = _filterCoder->ReleaseOutStream();
151*f6dc9357SAndroid Build Coastguard Worker     if (res == S_OK)
152*f6dc9357SAndroid Build Coastguard Worker       res = res2;
153*f6dc9357SAndroid Build Coastguard Worker   }
154*f6dc9357SAndroid Build Coastguard Worker 
155*f6dc9357SAndroid Build Coastguard Worker   RINOK(res)
156*f6dc9357SAndroid Build Coastguard Worker 
157*f6dc9357SAndroid Build Coastguard Worker   if (header.HasSize())
158*f6dc9357SAndroid Build Coastguard Worker     if (_lzmaDecoder->GetOutputProcessedSize() != header.Size)
159*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
160*f6dc9357SAndroid Build Coastguard Worker 
161*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
162*f6dc9357SAndroid Build Coastguard Worker }
163*f6dc9357SAndroid Build Coastguard Worker 
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_CHandler_IInArchive_1(
166*f6dc9357SAndroid Build Coastguard Worker   IArchiveOpenSeq
167*f6dc9357SAndroid Build Coastguard Worker )
168*f6dc9357SAndroid Build Coastguard Worker   bool _lzma86;
169*f6dc9357SAndroid Build Coastguard Worker   bool _isArc;
170*f6dc9357SAndroid Build Coastguard Worker   bool _needSeekToStart;
171*f6dc9357SAndroid Build Coastguard Worker   bool _dataAfterEnd;
172*f6dc9357SAndroid Build Coastguard Worker   bool _needMoreInput;
173*f6dc9357SAndroid Build Coastguard Worker   bool _unsupported;
174*f6dc9357SAndroid Build Coastguard Worker   bool _dataError;
175*f6dc9357SAndroid Build Coastguard Worker 
176*f6dc9357SAndroid Build Coastguard Worker   bool _packSize_Defined;
177*f6dc9357SAndroid Build Coastguard Worker   bool _unpackSize_Defined;
178*f6dc9357SAndroid Build Coastguard Worker   bool _numStreams_Defined;
179*f6dc9357SAndroid Build Coastguard Worker 
180*f6dc9357SAndroid Build Coastguard Worker   CHeader _header;
181*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IInStream> _stream;
182*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialInStream> _seqStream;
183*f6dc9357SAndroid Build Coastguard Worker 
184*f6dc9357SAndroid Build Coastguard Worker   UInt64 _packSize;
185*f6dc9357SAndroid Build Coastguard Worker   UInt64 _unpackSize;
186*f6dc9357SAndroid Build Coastguard Worker   UInt64 _numStreams;
187*f6dc9357SAndroid Build Coastguard Worker 
188*f6dc9357SAndroid Build Coastguard Worker   void GetMethod(NCOM::CPropVariant &prop);
189*f6dc9357SAndroid Build Coastguard Worker 
GetHeaderSize() const190*f6dc9357SAndroid Build Coastguard Worker   unsigned GetHeaderSize() const { return 5 + 8 + (_lzma86 ? 1 : 0); }
191*f6dc9357SAndroid Build Coastguard Worker public:
192*f6dc9357SAndroid Build Coastguard Worker   CHandler(bool lzma86) { _lzma86 = lzma86; }
193*f6dc9357SAndroid Build Coastguard Worker };
194*f6dc9357SAndroid Build Coastguard Worker 
195*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props
196*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps
197*f6dc9357SAndroid Build Coastguard Worker 
198*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
199*f6dc9357SAndroid Build Coastguard Worker {
200*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
201*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
202*f6dc9357SAndroid Build Coastguard Worker   {
203*f6dc9357SAndroid Build Coastguard Worker     case kpidPhySize: if (_packSize_Defined) prop = _packSize; break;
204*f6dc9357SAndroid Build Coastguard Worker     case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break;
205*f6dc9357SAndroid Build Coastguard Worker     case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break;
206*f6dc9357SAndroid Build Coastguard Worker     case kpidMethod: GetMethod(prop); break;
207*f6dc9357SAndroid Build Coastguard Worker     case kpidErrorFlags:
208*f6dc9357SAndroid Build Coastguard Worker     {
209*f6dc9357SAndroid Build Coastguard Worker       UInt32 v = 0;
210*f6dc9357SAndroid Build Coastguard Worker       if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
211*f6dc9357SAndroid Build Coastguard Worker       if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd;
212*f6dc9357SAndroid Build Coastguard Worker       if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
213*f6dc9357SAndroid Build Coastguard Worker       if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
214*f6dc9357SAndroid Build Coastguard Worker       if (_dataError) v |= kpv_ErrorFlags_DataError;
215*f6dc9357SAndroid Build Coastguard Worker       prop = v;
216*f6dc9357SAndroid Build Coastguard Worker       break;
217*f6dc9357SAndroid Build Coastguard Worker     }
218*f6dc9357SAndroid Build Coastguard Worker     default: break;
219*f6dc9357SAndroid Build Coastguard Worker   }
220*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
221*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
222*f6dc9357SAndroid Build Coastguard Worker }
223*f6dc9357SAndroid Build Coastguard Worker 
224*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
225*f6dc9357SAndroid Build Coastguard Worker {
226*f6dc9357SAndroid Build Coastguard Worker   *numItems = 1;
227*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
228*f6dc9357SAndroid Build Coastguard Worker }
229*f6dc9357SAndroid Build Coastguard Worker 
230*f6dc9357SAndroid Build Coastguard Worker 
231*f6dc9357SAndroid Build Coastguard Worker static char * DictSizeToString(UInt32 val, char *s)
232*f6dc9357SAndroid Build Coastguard Worker {
233*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < 32; i++)
234*f6dc9357SAndroid Build Coastguard Worker     if (((UInt32)1 << i) == val)
235*f6dc9357SAndroid Build Coastguard Worker       return ::ConvertUInt32ToString(i, s);
236*f6dc9357SAndroid Build Coastguard Worker   char c = 'b';
237*f6dc9357SAndroid Build Coastguard Worker        if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
238*f6dc9357SAndroid Build Coastguard Worker   else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
239*f6dc9357SAndroid Build Coastguard Worker   s = ::ConvertUInt32ToString(val, s);
240*f6dc9357SAndroid Build Coastguard Worker   *s++ = c;
241*f6dc9357SAndroid Build Coastguard Worker   *s = 0;
242*f6dc9357SAndroid Build Coastguard Worker   return s;
243*f6dc9357SAndroid Build Coastguard Worker }
244*f6dc9357SAndroid Build Coastguard Worker 
245*f6dc9357SAndroid Build Coastguard Worker static char *AddProp32(char *s, const char *name, UInt32 v)
246*f6dc9357SAndroid Build Coastguard Worker {
247*f6dc9357SAndroid Build Coastguard Worker   *s++ = ':';
248*f6dc9357SAndroid Build Coastguard Worker   s = MyStpCpy(s, name);
249*f6dc9357SAndroid Build Coastguard Worker   return ::ConvertUInt32ToString(v, s);
250*f6dc9357SAndroid Build Coastguard Worker }
251*f6dc9357SAndroid Build Coastguard Worker 
252*f6dc9357SAndroid Build Coastguard Worker void CHandler::GetMethod(NCOM::CPropVariant &prop)
253*f6dc9357SAndroid Build Coastguard Worker {
254*f6dc9357SAndroid Build Coastguard Worker   if (!_stream)
255*f6dc9357SAndroid Build Coastguard Worker     return;
256*f6dc9357SAndroid Build Coastguard Worker 
257*f6dc9357SAndroid Build Coastguard Worker   char sz[64];
258*f6dc9357SAndroid Build Coastguard Worker   char *s = sz;
259*f6dc9357SAndroid Build Coastguard Worker   if (_header.FilterID != 0)
260*f6dc9357SAndroid Build Coastguard Worker     s = MyStpCpy(s, "BCJ ");
261*f6dc9357SAndroid Build Coastguard Worker   s = MyStpCpy(s, "LZMA:");
262*f6dc9357SAndroid Build Coastguard Worker   s = DictSizeToString(_header.GetDicSize(), s);
263*f6dc9357SAndroid Build Coastguard Worker 
264*f6dc9357SAndroid Build Coastguard Worker   UInt32 d = _header.GetProp();
265*f6dc9357SAndroid Build Coastguard Worker   // if (d != 0x5D)
266*f6dc9357SAndroid Build Coastguard Worker   {
267*f6dc9357SAndroid Build Coastguard Worker     UInt32 lc = d % 9;
268*f6dc9357SAndroid Build Coastguard Worker     d /= 9;
269*f6dc9357SAndroid Build Coastguard Worker     UInt32 pb = d / 5;
270*f6dc9357SAndroid Build Coastguard Worker     UInt32 lp = d % 5;
271*f6dc9357SAndroid Build Coastguard Worker     if (lc != 3) s = AddProp32(s, "lc", lc);
272*f6dc9357SAndroid Build Coastguard Worker     if (lp != 0) s = AddProp32(s, "lp", lp);
273*f6dc9357SAndroid Build Coastguard Worker     if (pb != 2) s = AddProp32(s, "pb", pb);
274*f6dc9357SAndroid Build Coastguard Worker   }
275*f6dc9357SAndroid Build Coastguard Worker   prop = sz;
276*f6dc9357SAndroid Build Coastguard Worker }
277*f6dc9357SAndroid Build Coastguard Worker 
278*f6dc9357SAndroid Build Coastguard Worker 
279*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value))
280*f6dc9357SAndroid Build Coastguard Worker {
281*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
282*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
283*f6dc9357SAndroid Build Coastguard Worker   {
284*f6dc9357SAndroid Build Coastguard Worker     case kpidSize: if (_stream && _header.HasSize()) prop = _header.Size; break;
285*f6dc9357SAndroid Build Coastguard Worker     case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
286*f6dc9357SAndroid Build Coastguard Worker     case kpidMethod: GetMethod(prop); break;
287*f6dc9357SAndroid Build Coastguard Worker     default: break;
288*f6dc9357SAndroid Build Coastguard Worker   }
289*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
290*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
291*f6dc9357SAndroid Build Coastguard Worker }
292*f6dc9357SAndroid Build Coastguard Worker 
293*f6dc9357SAndroid Build Coastguard Worker API_FUNC_static_IsArc IsArc_Lzma(const Byte *p, size_t size)
294*f6dc9357SAndroid Build Coastguard Worker {
295*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kHeaderSize = 1 + 4 + 8;
296*f6dc9357SAndroid Build Coastguard Worker   if (size < kHeaderSize)
297*f6dc9357SAndroid Build Coastguard Worker     return k_IsArc_Res_NEED_MORE;
298*f6dc9357SAndroid Build Coastguard Worker   if (p[0] >= 5 * 5 * 9)
299*f6dc9357SAndroid Build Coastguard Worker     return k_IsArc_Res_NO;
300*f6dc9357SAndroid Build Coastguard Worker   const UInt64 unpackSize = GetUi64(p + 1 + 4);
301*f6dc9357SAndroid Build Coastguard Worker   if (unpackSize != (UInt64)(Int64)-1)
302*f6dc9357SAndroid Build Coastguard Worker   {
303*f6dc9357SAndroid Build Coastguard Worker     if (unpackSize >= ((UInt64)1 << 56))
304*f6dc9357SAndroid Build Coastguard Worker       return k_IsArc_Res_NO;
305*f6dc9357SAndroid Build Coastguard Worker   }
306*f6dc9357SAndroid Build Coastguard Worker   if (unpackSize != 0)
307*f6dc9357SAndroid Build Coastguard Worker   {
308*f6dc9357SAndroid Build Coastguard Worker     if (size < kHeaderSize + 2)
309*f6dc9357SAndroid Build Coastguard Worker       return k_IsArc_Res_NEED_MORE;
310*f6dc9357SAndroid Build Coastguard Worker     if (p[kHeaderSize] != 0)
311*f6dc9357SAndroid Build Coastguard Worker       return k_IsArc_Res_NO;
312*f6dc9357SAndroid Build Coastguard Worker     if (unpackSize != (UInt64)(Int64)-1)
313*f6dc9357SAndroid Build Coastguard Worker     {
314*f6dc9357SAndroid Build Coastguard Worker       if ((p[kHeaderSize + 1] & 0x80) != 0)
315*f6dc9357SAndroid Build Coastguard Worker         return k_IsArc_Res_NO;
316*f6dc9357SAndroid Build Coastguard Worker     }
317*f6dc9357SAndroid Build Coastguard Worker   }
318*f6dc9357SAndroid Build Coastguard Worker   if (!CheckDicSize(p + 1))
319*f6dc9357SAndroid Build Coastguard Worker     // return k_IsArc_Res_YES_LOW_PROB;
320*f6dc9357SAndroid Build Coastguard Worker     return k_IsArc_Res_NO;
321*f6dc9357SAndroid Build Coastguard Worker   return k_IsArc_Res_YES;
322*f6dc9357SAndroid Build Coastguard Worker }
323*f6dc9357SAndroid Build Coastguard Worker }
324*f6dc9357SAndroid Build Coastguard Worker 
325*f6dc9357SAndroid Build Coastguard Worker API_FUNC_static_IsArc IsArc_Lzma86(const Byte *p, size_t size)
326*f6dc9357SAndroid Build Coastguard Worker {
327*f6dc9357SAndroid Build Coastguard Worker   if (size < 1)
328*f6dc9357SAndroid Build Coastguard Worker     return k_IsArc_Res_NEED_MORE;
329*f6dc9357SAndroid Build Coastguard Worker   Byte filterID = p[0];
330*f6dc9357SAndroid Build Coastguard Worker   if (filterID != 0 && filterID != 1)
331*f6dc9357SAndroid Build Coastguard Worker     return k_IsArc_Res_NO;
332*f6dc9357SAndroid Build Coastguard Worker   return IsArc_Lzma(p + 1, size - 1);
333*f6dc9357SAndroid Build Coastguard Worker }
334*f6dc9357SAndroid Build Coastguard Worker }
335*f6dc9357SAndroid Build Coastguard Worker 
336*f6dc9357SAndroid Build Coastguard Worker 
337*f6dc9357SAndroid Build Coastguard Worker 
338*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *))
339*f6dc9357SAndroid Build Coastguard Worker {
340*f6dc9357SAndroid Build Coastguard Worker   Close();
341*f6dc9357SAndroid Build Coastguard Worker 
342*f6dc9357SAndroid Build Coastguard Worker   const unsigned headerSize = GetHeaderSize();
343*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kBufSize = 1 << 7;
344*f6dc9357SAndroid Build Coastguard Worker   Byte buf[kBufSize];
345*f6dc9357SAndroid Build Coastguard Worker   size_t processedSize = kBufSize;
346*f6dc9357SAndroid Build Coastguard Worker   RINOK(ReadStream(inStream, buf, &processedSize))
347*f6dc9357SAndroid Build Coastguard Worker   if (processedSize < headerSize + 2)
348*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
349*f6dc9357SAndroid Build Coastguard Worker   if (!_header.Parse(buf, _lzma86))
350*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
351*f6dc9357SAndroid Build Coastguard Worker   const Byte *start = buf + headerSize;
352*f6dc9357SAndroid Build Coastguard Worker   if (start[0] != 0 /* || (start[1] & 0x80) != 0 */ ) // empty stream with EOS is not 0x80
353*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
354*f6dc9357SAndroid Build Coastguard Worker 
355*f6dc9357SAndroid Build Coastguard Worker   RINOK(InStream_GetSize_SeekToEnd(inStream, _packSize))
356*f6dc9357SAndroid Build Coastguard Worker 
357*f6dc9357SAndroid Build Coastguard Worker   SizeT srcLen = (SizeT)processedSize - headerSize;
358*f6dc9357SAndroid Build Coastguard Worker 
359*f6dc9357SAndroid Build Coastguard Worker   if (srcLen > 10
360*f6dc9357SAndroid Build Coastguard Worker       && _header.Size == 0
361*f6dc9357SAndroid Build Coastguard Worker       // && _header.FilterID == 0
362*f6dc9357SAndroid Build Coastguard Worker       && _header.LzmaProps[0] == 0
363*f6dc9357SAndroid Build Coastguard Worker       )
364*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
365*f6dc9357SAndroid Build Coastguard Worker 
366*f6dc9357SAndroid Build Coastguard Worker   const UInt32 outLimit = 1 << 11;
367*f6dc9357SAndroid Build Coastguard Worker   Byte outBuf[outLimit];
368*f6dc9357SAndroid Build Coastguard Worker 
369*f6dc9357SAndroid Build Coastguard Worker   SizeT outSize = outLimit;
370*f6dc9357SAndroid Build Coastguard Worker   if (outSize > _header.Size)
371*f6dc9357SAndroid Build Coastguard Worker     outSize = (SizeT)_header.Size;
372*f6dc9357SAndroid Build Coastguard Worker   SizeT destLen = outSize;
373*f6dc9357SAndroid Build Coastguard Worker   ELzmaStatus status;
374*f6dc9357SAndroid Build Coastguard Worker 
375*f6dc9357SAndroid Build Coastguard Worker   SRes res = LzmaDecode(outBuf, &destLen, start, &srcLen,
376*f6dc9357SAndroid Build Coastguard Worker       _header.LzmaProps, 5, LZMA_FINISH_ANY,
377*f6dc9357SAndroid Build Coastguard Worker       &status, &g_Alloc);
378*f6dc9357SAndroid Build Coastguard Worker 
379*f6dc9357SAndroid Build Coastguard Worker   if (res != SZ_OK)
380*f6dc9357SAndroid Build Coastguard Worker     if (res != SZ_ERROR_INPUT_EOF)
381*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
382*f6dc9357SAndroid Build Coastguard Worker 
383*f6dc9357SAndroid Build Coastguard Worker   _isArc = true;
384*f6dc9357SAndroid Build Coastguard Worker   _stream = inStream;
385*f6dc9357SAndroid Build Coastguard Worker   _seqStream = inStream;
386*f6dc9357SAndroid Build Coastguard Worker   _needSeekToStart = true;
387*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
388*f6dc9357SAndroid Build Coastguard Worker }
389*f6dc9357SAndroid Build Coastguard Worker 
390*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream))
391*f6dc9357SAndroid Build Coastguard Worker {
392*f6dc9357SAndroid Build Coastguard Worker   Close();
393*f6dc9357SAndroid Build Coastguard Worker   _isArc = true;
394*f6dc9357SAndroid Build Coastguard Worker   _seqStream = stream;
395*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
396*f6dc9357SAndroid Build Coastguard Worker }
397*f6dc9357SAndroid Build Coastguard Worker 
398*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
399*f6dc9357SAndroid Build Coastguard Worker {
400*f6dc9357SAndroid Build Coastguard Worker   _isArc = false;
401*f6dc9357SAndroid Build Coastguard Worker   _needSeekToStart = false;
402*f6dc9357SAndroid Build Coastguard Worker   _dataAfterEnd = false;
403*f6dc9357SAndroid Build Coastguard Worker   _needMoreInput = false;
404*f6dc9357SAndroid Build Coastguard Worker   _unsupported = false;
405*f6dc9357SAndroid Build Coastguard Worker   _dataError = false;
406*f6dc9357SAndroid Build Coastguard Worker 
407*f6dc9357SAndroid Build Coastguard Worker   _packSize_Defined = false;
408*f6dc9357SAndroid Build Coastguard Worker   _unpackSize_Defined = false;
409*f6dc9357SAndroid Build Coastguard Worker   _numStreams_Defined = false;
410*f6dc9357SAndroid Build Coastguard Worker 
411*f6dc9357SAndroid Build Coastguard Worker   _packSize = 0;
412*f6dc9357SAndroid Build Coastguard Worker 
413*f6dc9357SAndroid Build Coastguard Worker   _stream.Release();
414*f6dc9357SAndroid Build Coastguard Worker   _seqStream.Release();
415*f6dc9357SAndroid Build Coastguard Worker    return S_OK;
416*f6dc9357SAndroid Build Coastguard Worker }
417*f6dc9357SAndroid Build Coastguard Worker 
418*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1(
419*f6dc9357SAndroid Build Coastguard Worker   CCompressProgressInfoImp,
420*f6dc9357SAndroid Build Coastguard Worker   ICompressProgressInfo
421*f6dc9357SAndroid Build Coastguard Worker )
422*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IArchiveOpenCallback> Callback;
423*f6dc9357SAndroid Build Coastguard Worker public:
424*f6dc9357SAndroid Build Coastguard Worker   UInt64 Offset;
425*f6dc9357SAndroid Build Coastguard Worker 
426*f6dc9357SAndroid Build Coastguard Worker   void Init(IArchiveOpenCallback *callback) { Callback = callback; }
427*f6dc9357SAndroid Build Coastguard Worker };
428*f6dc9357SAndroid Build Coastguard Worker 
429*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */))
430*f6dc9357SAndroid Build Coastguard Worker {
431*f6dc9357SAndroid Build Coastguard Worker   if (Callback)
432*f6dc9357SAndroid Build Coastguard Worker   {
433*f6dc9357SAndroid Build Coastguard Worker     const UInt64 files = 0;
434*f6dc9357SAndroid Build Coastguard Worker     const UInt64 val = Offset + *inSize;
435*f6dc9357SAndroid Build Coastguard Worker     return Callback->SetCompleted(&files, &val);
436*f6dc9357SAndroid Build Coastguard Worker   }
437*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
438*f6dc9357SAndroid Build Coastguard Worker }
439*f6dc9357SAndroid Build Coastguard Worker 
440*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
441*f6dc9357SAndroid Build Coastguard Worker     Int32 testMode, IArchiveExtractCallback *extractCallback))
442*f6dc9357SAndroid Build Coastguard Worker {
443*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
444*f6dc9357SAndroid Build Coastguard Worker 
445*f6dc9357SAndroid Build Coastguard Worker   if (numItems == 0)
446*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
447*f6dc9357SAndroid Build Coastguard Worker   if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
448*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
449*f6dc9357SAndroid Build Coastguard Worker 
450*f6dc9357SAndroid Build Coastguard Worker   if (_packSize_Defined)
451*f6dc9357SAndroid Build Coastguard Worker     RINOK(extractCallback->SetTotal(_packSize))
452*f6dc9357SAndroid Build Coastguard Worker 
453*f6dc9357SAndroid Build Coastguard Worker   Int32 opResult;
454*f6dc9357SAndroid Build Coastguard Worker  {
455*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> realOutStream;
456*f6dc9357SAndroid Build Coastguard Worker   const Int32 askMode = testMode ?
457*f6dc9357SAndroid Build Coastguard Worker       NExtract::NAskMode::kTest :
458*f6dc9357SAndroid Build Coastguard Worker       NExtract::NAskMode::kExtract;
459*f6dc9357SAndroid Build Coastguard Worker   RINOK(extractCallback->GetStream(0, &realOutStream, askMode))
460*f6dc9357SAndroid Build Coastguard Worker   if (!testMode && !realOutStream)
461*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
462*f6dc9357SAndroid Build Coastguard Worker 
463*f6dc9357SAndroid Build Coastguard Worker   RINOK(extractCallback->PrepareOperation(askMode))
464*f6dc9357SAndroid Build Coastguard Worker 
465*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ISequentialOutStream, CDummyOutStream> outStream;
466*f6dc9357SAndroid Build Coastguard Worker   outStream->SetStream(realOutStream);
467*f6dc9357SAndroid Build Coastguard Worker   outStream->Init();
468*f6dc9357SAndroid Build Coastguard Worker   realOutStream.Release();
469*f6dc9357SAndroid Build Coastguard Worker 
470*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
471*f6dc9357SAndroid Build Coastguard Worker   lps->Init(extractCallback, true);
472*f6dc9357SAndroid Build Coastguard Worker 
473*f6dc9357SAndroid Build Coastguard Worker   if (_needSeekToStart)
474*f6dc9357SAndroid Build Coastguard Worker   {
475*f6dc9357SAndroid Build Coastguard Worker     if (!_stream)
476*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
477*f6dc9357SAndroid Build Coastguard Worker     RINOK(InStream_SeekToBegin(_stream))
478*f6dc9357SAndroid Build Coastguard Worker   }
479*f6dc9357SAndroid Build Coastguard Worker   else
480*f6dc9357SAndroid Build Coastguard Worker     _needSeekToStart = true;
481*f6dc9357SAndroid Build Coastguard Worker 
482*f6dc9357SAndroid Build Coastguard Worker   CDecoder decoder;
483*f6dc9357SAndroid Build Coastguard Worker   RINOK(decoder.Create(_lzma86, _seqStream))
484*f6dc9357SAndroid Build Coastguard Worker 
485*f6dc9357SAndroid Build Coastguard Worker   bool firstItem = true;
486*f6dc9357SAndroid Build Coastguard Worker 
487*f6dc9357SAndroid Build Coastguard Worker   UInt64 packSize = 0;
488*f6dc9357SAndroid Build Coastguard Worker   UInt64 unpackSize = 0;
489*f6dc9357SAndroid Build Coastguard Worker   UInt64 numStreams = 0;
490*f6dc9357SAndroid Build Coastguard Worker 
491*f6dc9357SAndroid Build Coastguard Worker   bool dataAfterEnd = false;
492*f6dc9357SAndroid Build Coastguard Worker 
493*f6dc9357SAndroid Build Coastguard Worker   HRESULT hres = S_OK;
494*f6dc9357SAndroid Build Coastguard Worker 
495*f6dc9357SAndroid Build Coastguard Worker   for (;;)
496*f6dc9357SAndroid Build Coastguard Worker   {
497*f6dc9357SAndroid Build Coastguard Worker     lps->InSize = packSize;
498*f6dc9357SAndroid Build Coastguard Worker     lps->OutSize = unpackSize;
499*f6dc9357SAndroid Build Coastguard Worker     RINOK(lps->SetCur())
500*f6dc9357SAndroid Build Coastguard Worker 
501*f6dc9357SAndroid Build Coastguard Worker     const UInt32 kBufSize = 1 + 5 + 8;
502*f6dc9357SAndroid Build Coastguard Worker     Byte buf[kBufSize];
503*f6dc9357SAndroid Build Coastguard Worker     const UInt32 headerSize = GetHeaderSize();
504*f6dc9357SAndroid Build Coastguard Worker     UInt32 processed;
505*f6dc9357SAndroid Build Coastguard Worker     RINOK(decoder.ReadInput(buf, headerSize, &processed))
506*f6dc9357SAndroid Build Coastguard Worker     if (processed != headerSize)
507*f6dc9357SAndroid Build Coastguard Worker     {
508*f6dc9357SAndroid Build Coastguard Worker       if (processed != 0)
509*f6dc9357SAndroid Build Coastguard Worker         dataAfterEnd = true;
510*f6dc9357SAndroid Build Coastguard Worker       break;
511*f6dc9357SAndroid Build Coastguard Worker     }
512*f6dc9357SAndroid Build Coastguard Worker 
513*f6dc9357SAndroid Build Coastguard Worker     CHeader st;
514*f6dc9357SAndroid Build Coastguard Worker     if (!st.Parse(buf, _lzma86))
515*f6dc9357SAndroid Build Coastguard Worker     {
516*f6dc9357SAndroid Build Coastguard Worker       dataAfterEnd = true;
517*f6dc9357SAndroid Build Coastguard Worker       break;
518*f6dc9357SAndroid Build Coastguard Worker     }
519*f6dc9357SAndroid Build Coastguard Worker     numStreams++;
520*f6dc9357SAndroid Build Coastguard Worker     firstItem = false;
521*f6dc9357SAndroid Build Coastguard Worker 
522*f6dc9357SAndroid Build Coastguard Worker     hres = decoder.Code(st, outStream, lps);
523*f6dc9357SAndroid Build Coastguard Worker 
524*f6dc9357SAndroid Build Coastguard Worker     packSize = decoder.GetInputProcessedSize();
525*f6dc9357SAndroid Build Coastguard Worker     unpackSize = outStream->GetSize();
526*f6dc9357SAndroid Build Coastguard Worker 
527*f6dc9357SAndroid Build Coastguard Worker     if (hres == E_NOTIMPL)
528*f6dc9357SAndroid Build Coastguard Worker     {
529*f6dc9357SAndroid Build Coastguard Worker       _unsupported = true;
530*f6dc9357SAndroid Build Coastguard Worker       hres = S_FALSE;
531*f6dc9357SAndroid Build Coastguard Worker       break;
532*f6dc9357SAndroid Build Coastguard Worker     }
533*f6dc9357SAndroid Build Coastguard Worker     if (hres == S_FALSE)
534*f6dc9357SAndroid Build Coastguard Worker       break;
535*f6dc9357SAndroid Build Coastguard Worker     RINOK(hres)
536*f6dc9357SAndroid Build Coastguard Worker   }
537*f6dc9357SAndroid Build Coastguard Worker 
538*f6dc9357SAndroid Build Coastguard Worker   if (firstItem)
539*f6dc9357SAndroid Build Coastguard Worker   {
540*f6dc9357SAndroid Build Coastguard Worker     _isArc = false;
541*f6dc9357SAndroid Build Coastguard Worker     hres = S_FALSE;
542*f6dc9357SAndroid Build Coastguard Worker   }
543*f6dc9357SAndroid Build Coastguard Worker   else if (hres == S_OK || hres == S_FALSE)
544*f6dc9357SAndroid Build Coastguard Worker   {
545*f6dc9357SAndroid Build Coastguard Worker     if (dataAfterEnd)
546*f6dc9357SAndroid Build Coastguard Worker       _dataAfterEnd = true;
547*f6dc9357SAndroid Build Coastguard Worker     else if (decoder._lzmaDecoder->NeedsMoreInput())
548*f6dc9357SAndroid Build Coastguard Worker       _needMoreInput = true;
549*f6dc9357SAndroid Build Coastguard Worker 
550*f6dc9357SAndroid Build Coastguard Worker     _packSize = packSize;
551*f6dc9357SAndroid Build Coastguard Worker     _unpackSize = unpackSize;
552*f6dc9357SAndroid Build Coastguard Worker     _numStreams = numStreams;
553*f6dc9357SAndroid Build Coastguard Worker 
554*f6dc9357SAndroid Build Coastguard Worker     _packSize_Defined = true;
555*f6dc9357SAndroid Build Coastguard Worker     _unpackSize_Defined = true;
556*f6dc9357SAndroid Build Coastguard Worker     _numStreams_Defined = true;
557*f6dc9357SAndroid Build Coastguard Worker   }
558*f6dc9357SAndroid Build Coastguard Worker 
559*f6dc9357SAndroid Build Coastguard Worker   opResult = NExtract::NOperationResult::kOK;
560*f6dc9357SAndroid Build Coastguard Worker 
561*f6dc9357SAndroid Build Coastguard Worker   if (!_isArc)
562*f6dc9357SAndroid Build Coastguard Worker     opResult = NExtract::NOperationResult::kIsNotArc;
563*f6dc9357SAndroid Build Coastguard Worker   else if (_needMoreInput)
564*f6dc9357SAndroid Build Coastguard Worker     opResult = NExtract::NOperationResult::kUnexpectedEnd;
565*f6dc9357SAndroid Build Coastguard Worker   else if (_unsupported)
566*f6dc9357SAndroid Build Coastguard Worker     opResult = NExtract::NOperationResult::kUnsupportedMethod;
567*f6dc9357SAndroid Build Coastguard Worker   else if (_dataAfterEnd)
568*f6dc9357SAndroid Build Coastguard Worker     opResult = NExtract::NOperationResult::kDataAfterEnd;
569*f6dc9357SAndroid Build Coastguard Worker   else if (hres == S_FALSE)
570*f6dc9357SAndroid Build Coastguard Worker     opResult = NExtract::NOperationResult::kDataError;
571*f6dc9357SAndroid Build Coastguard Worker   else if (hres == S_OK)
572*f6dc9357SAndroid Build Coastguard Worker     opResult = NExtract::NOperationResult::kOK;
573*f6dc9357SAndroid Build Coastguard Worker   else
574*f6dc9357SAndroid Build Coastguard Worker     return hres;
575*f6dc9357SAndroid Build Coastguard Worker 
576*f6dc9357SAndroid Build Coastguard Worker   // outStream.Release();
577*f6dc9357SAndroid Build Coastguard Worker  }
578*f6dc9357SAndroid Build Coastguard Worker   return extractCallback->SetOperationResult(opResult);
579*f6dc9357SAndroid Build Coastguard Worker 
580*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
581*f6dc9357SAndroid Build Coastguard Worker }
582*f6dc9357SAndroid Build Coastguard Worker 
583*f6dc9357SAndroid Build Coastguard Worker namespace NLzmaAr {
584*f6dc9357SAndroid Build Coastguard Worker 
585*f6dc9357SAndroid Build Coastguard Worker // 2, { 0x5D, 0x00 },
586*f6dc9357SAndroid Build Coastguard Worker 
587*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_I_CLS_NO_SIG(
588*f6dc9357SAndroid Build Coastguard Worker   CHandler(false),
589*f6dc9357SAndroid Build Coastguard Worker   "lzma", "lzma", NULL, 0xA,
590*f6dc9357SAndroid Build Coastguard Worker   0,
591*f6dc9357SAndroid Build Coastguard Worker   NArcInfoFlags::kStartOpen |
592*f6dc9357SAndroid Build Coastguard Worker   NArcInfoFlags::kKeepName,
593*f6dc9357SAndroid Build Coastguard Worker   IsArc_Lzma)
594*f6dc9357SAndroid Build Coastguard Worker 
595*f6dc9357SAndroid Build Coastguard Worker }
596*f6dc9357SAndroid Build Coastguard Worker 
597*f6dc9357SAndroid Build Coastguard Worker namespace NLzma86Ar {
598*f6dc9357SAndroid Build Coastguard Worker 
599*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_I_CLS_NO_SIG(
600*f6dc9357SAndroid Build Coastguard Worker   CHandler(true),
601*f6dc9357SAndroid Build Coastguard Worker   "lzma86", "lzma86", NULL, 0xB,
602*f6dc9357SAndroid Build Coastguard Worker   0,
603*f6dc9357SAndroid Build Coastguard Worker   NArcInfoFlags::kKeepName,
604*f6dc9357SAndroid Build Coastguard Worker   IsArc_Lzma86)
605*f6dc9357SAndroid Build Coastguard Worker 
606*f6dc9357SAndroid Build Coastguard Worker }
607*f6dc9357SAndroid Build Coastguard Worker 
608*f6dc9357SAndroid Build Coastguard Worker }}
609