xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/Bz2Handler.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Bz2Handler.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 "../../Common/ComTry.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ProgressUtils.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../Common/RegisterArc.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/BZip2Decoder.h"
12*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/BZip2Encoder.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/CopyCoder.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #include "Common/DummyOutStream.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "Common/HandlerOut.h"
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
21*f6dc9357SAndroid Build Coastguard Worker namespace NBz2 {
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_CHandler_IInArchive_3(
24*f6dc9357SAndroid Build Coastguard Worker   IArchiveOpenSeq,
25*f6dc9357SAndroid Build Coastguard Worker   IOutArchive,
26*f6dc9357SAndroid Build Coastguard Worker   ISetProperties
27*f6dc9357SAndroid Build Coastguard Worker )
28*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IInStream> _stream;
29*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialInStream> _seqStream;
30*f6dc9357SAndroid Build Coastguard Worker 
31*f6dc9357SAndroid Build Coastguard Worker   bool _isArc;
32*f6dc9357SAndroid Build Coastguard Worker   bool _needSeekToStart;
33*f6dc9357SAndroid Build Coastguard Worker   bool _dataAfterEnd;
34*f6dc9357SAndroid Build Coastguard Worker   bool _needMoreInput;
35*f6dc9357SAndroid Build Coastguard Worker 
36*f6dc9357SAndroid Build Coastguard Worker   bool _packSize_Defined;
37*f6dc9357SAndroid Build Coastguard Worker   bool _unpackSize_Defined;
38*f6dc9357SAndroid Build Coastguard Worker   bool _numStreams_Defined;
39*f6dc9357SAndroid Build Coastguard Worker   bool _numBlocks_Defined;
40*f6dc9357SAndroid Build Coastguard Worker 
41*f6dc9357SAndroid Build Coastguard Worker   UInt64 _packSize;
42*f6dc9357SAndroid Build Coastguard Worker   UInt64 _unpackSize;
43*f6dc9357SAndroid Build Coastguard Worker   UInt64 _numStreams;
44*f6dc9357SAndroid Build Coastguard Worker   UInt64 _numBlocks;
45*f6dc9357SAndroid Build Coastguard Worker 
46*f6dc9357SAndroid Build Coastguard Worker   CSingleMethodProps _props;
47*f6dc9357SAndroid Build Coastguard Worker };
48*f6dc9357SAndroid Build Coastguard Worker 
49*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
50*f6dc9357SAndroid Build Coastguard Worker {
51*f6dc9357SAndroid Build Coastguard Worker   kpidSize,
52*f6dc9357SAndroid Build Coastguard Worker   kpidPackSize
53*f6dc9357SAndroid Build Coastguard Worker };
54*f6dc9357SAndroid Build Coastguard Worker 
55*f6dc9357SAndroid Build Coastguard Worker static const Byte kArcProps[] =
56*f6dc9357SAndroid Build Coastguard Worker {
57*f6dc9357SAndroid Build Coastguard Worker   kpidNumStreams,
58*f6dc9357SAndroid Build Coastguard Worker   kpidNumBlocks
59*f6dc9357SAndroid Build Coastguard Worker };
60*f6dc9357SAndroid Build Coastguard Worker 
61*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props
62*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps
63*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetArchiveProperty (PROPID propID,PROPVARIANT * value))64*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
65*f6dc9357SAndroid Build Coastguard Worker {
66*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
67*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
68*f6dc9357SAndroid Build Coastguard Worker   {
69*f6dc9357SAndroid Build Coastguard Worker     case kpidPhySize: if (_packSize_Defined) prop = _packSize; break;
70*f6dc9357SAndroid Build Coastguard Worker     case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break;
71*f6dc9357SAndroid Build Coastguard Worker     case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break;
72*f6dc9357SAndroid Build Coastguard Worker     case kpidNumBlocks: if (_numBlocks_Defined) prop = _numBlocks; break;
73*f6dc9357SAndroid Build Coastguard Worker     case kpidErrorFlags:
74*f6dc9357SAndroid Build Coastguard Worker     {
75*f6dc9357SAndroid Build Coastguard Worker       UInt32 v = 0;
76*f6dc9357SAndroid Build Coastguard Worker       if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
77*f6dc9357SAndroid Build Coastguard Worker       if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd;
78*f6dc9357SAndroid Build Coastguard Worker       if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
79*f6dc9357SAndroid Build Coastguard Worker       prop = v;
80*f6dc9357SAndroid Build Coastguard Worker       break;
81*f6dc9357SAndroid Build Coastguard Worker     }
82*f6dc9357SAndroid Build Coastguard Worker     default: break;
83*f6dc9357SAndroid Build Coastguard Worker   }
84*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
85*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
86*f6dc9357SAndroid Build Coastguard Worker }
87*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetNumberOfItems (UInt32 * numItems))88*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
89*f6dc9357SAndroid Build Coastguard Worker {
90*f6dc9357SAndroid Build Coastguard Worker   *numItems = 1;
91*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
92*f6dc9357SAndroid Build Coastguard Worker }
93*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetProperty (UInt32,PROPID propID,PROPVARIANT * value))94*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value))
95*f6dc9357SAndroid Build Coastguard Worker {
96*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
97*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
98*f6dc9357SAndroid Build Coastguard Worker   {
99*f6dc9357SAndroid Build Coastguard Worker     case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
100*f6dc9357SAndroid Build Coastguard Worker     case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break;
101*f6dc9357SAndroid Build Coastguard Worker     default: break;
102*f6dc9357SAndroid Build Coastguard Worker   }
103*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
104*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
105*f6dc9357SAndroid Build Coastguard Worker }
106*f6dc9357SAndroid Build Coastguard Worker 
107*f6dc9357SAndroid Build Coastguard Worker static const unsigned kSignatureCheckSize = 10;
108*f6dc9357SAndroid Build Coastguard Worker 
IsArc_BZip2(const Byte * p,size_t size)109*f6dc9357SAndroid Build Coastguard Worker API_FUNC_static_IsArc IsArc_BZip2(const Byte *p, size_t size)
110*f6dc9357SAndroid Build Coastguard Worker {
111*f6dc9357SAndroid Build Coastguard Worker   if (size < kSignatureCheckSize)
112*f6dc9357SAndroid Build Coastguard Worker     return k_IsArc_Res_NEED_MORE;
113*f6dc9357SAndroid Build Coastguard Worker   if (p[0] != 'B' || p[1] != 'Z' || p[2] != 'h' || p[3] < '1' || p[3] > '9')
114*f6dc9357SAndroid Build Coastguard Worker     return k_IsArc_Res_NO;
115*f6dc9357SAndroid Build Coastguard Worker   p += 4;
116*f6dc9357SAndroid Build Coastguard Worker   if (NCompress::NBZip2::IsBlockSig(p))
117*f6dc9357SAndroid Build Coastguard Worker     return k_IsArc_Res_YES;
118*f6dc9357SAndroid Build Coastguard Worker   if (NCompress::NBZip2::IsEndSig(p))
119*f6dc9357SAndroid Build Coastguard Worker     return k_IsArc_Res_YES;
120*f6dc9357SAndroid Build Coastguard Worker   return k_IsArc_Res_NO;
121*f6dc9357SAndroid Build Coastguard Worker }
122*f6dc9357SAndroid Build Coastguard Worker }
123*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::Open (IInStream * stream,const UInt64 *,IArchiveOpenCallback *))124*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *))
125*f6dc9357SAndroid Build Coastguard Worker {
126*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
127*f6dc9357SAndroid Build Coastguard Worker   Close();
128*f6dc9357SAndroid Build Coastguard Worker   {
129*f6dc9357SAndroid Build Coastguard Worker     Byte buf[kSignatureCheckSize];
130*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadStream_FALSE(stream, buf, kSignatureCheckSize))
131*f6dc9357SAndroid Build Coastguard Worker     if (IsArc_BZip2(buf, kSignatureCheckSize) == k_IsArc_Res_NO)
132*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
133*f6dc9357SAndroid Build Coastguard Worker     _isArc = true;
134*f6dc9357SAndroid Build Coastguard Worker     _stream = stream;
135*f6dc9357SAndroid Build Coastguard Worker     _seqStream = stream;
136*f6dc9357SAndroid Build Coastguard Worker     _needSeekToStart = true;
137*f6dc9357SAndroid Build Coastguard Worker   }
138*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
139*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
140*f6dc9357SAndroid Build Coastguard Worker }
141*f6dc9357SAndroid Build Coastguard Worker 
142*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::OpenSeq (ISequentialInStream * stream))143*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream))
144*f6dc9357SAndroid Build Coastguard Worker {
145*f6dc9357SAndroid Build Coastguard Worker   Close();
146*f6dc9357SAndroid Build Coastguard Worker   _isArc = true;
147*f6dc9357SAndroid Build Coastguard Worker   _seqStream = stream;
148*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
149*f6dc9357SAndroid Build Coastguard Worker }
150*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::Close ())151*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
152*f6dc9357SAndroid Build Coastguard Worker {
153*f6dc9357SAndroid Build Coastguard Worker   _isArc = false;
154*f6dc9357SAndroid Build Coastguard Worker   _needSeekToStart = false;
155*f6dc9357SAndroid Build Coastguard Worker   _dataAfterEnd = false;
156*f6dc9357SAndroid Build Coastguard Worker   _needMoreInput = false;
157*f6dc9357SAndroid Build Coastguard Worker 
158*f6dc9357SAndroid Build Coastguard Worker   _packSize_Defined = false;
159*f6dc9357SAndroid Build Coastguard Worker   _unpackSize_Defined = false;
160*f6dc9357SAndroid Build Coastguard Worker   _numStreams_Defined = false;
161*f6dc9357SAndroid Build Coastguard Worker   _numBlocks_Defined = false;
162*f6dc9357SAndroid Build Coastguard Worker 
163*f6dc9357SAndroid Build Coastguard Worker   _packSize = 0;
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker   _seqStream.Release();
166*f6dc9357SAndroid Build Coastguard Worker   _stream.Release();
167*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
168*f6dc9357SAndroid Build Coastguard Worker }
169*f6dc9357SAndroid Build Coastguard Worker 
170*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::Extract (const UInt32 * indices,UInt32 numItems,Int32 testMode,IArchiveExtractCallback * extractCallback))171*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
172*f6dc9357SAndroid Build Coastguard Worker     Int32 testMode, IArchiveExtractCallback *extractCallback))
173*f6dc9357SAndroid Build Coastguard Worker {
174*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
175*f6dc9357SAndroid Build Coastguard Worker   if (numItems == 0)
176*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
177*f6dc9357SAndroid Build Coastguard Worker   if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
178*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
179*f6dc9357SAndroid Build Coastguard Worker 
180*f6dc9357SAndroid Build Coastguard Worker   if (_packSize_Defined)
181*f6dc9357SAndroid Build Coastguard Worker   {
182*f6dc9357SAndroid Build Coastguard Worker     RINOK(extractCallback->SetTotal(_packSize))
183*f6dc9357SAndroid Build Coastguard Worker   }
184*f6dc9357SAndroid Build Coastguard Worker 
185*f6dc9357SAndroid Build Coastguard Worker   Int32 opRes;
186*f6dc9357SAndroid Build Coastguard Worker  {
187*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> realOutStream;
188*f6dc9357SAndroid Build Coastguard Worker   const Int32 askMode = testMode ?
189*f6dc9357SAndroid Build Coastguard Worker       NExtract::NAskMode::kTest :
190*f6dc9357SAndroid Build Coastguard Worker       NExtract::NAskMode::kExtract;
191*f6dc9357SAndroid Build Coastguard Worker   RINOK(extractCallback->GetStream(0, &realOutStream, askMode))
192*f6dc9357SAndroid Build Coastguard Worker   if (!testMode && !realOutStream)
193*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
194*f6dc9357SAndroid Build Coastguard Worker 
195*f6dc9357SAndroid Build Coastguard Worker   RINOK(extractCallback->PrepareOperation(askMode))
196*f6dc9357SAndroid Build Coastguard Worker 
197*f6dc9357SAndroid Build Coastguard Worker   if (_needSeekToStart)
198*f6dc9357SAndroid Build Coastguard Worker   {
199*f6dc9357SAndroid Build Coastguard Worker     if (!_stream)
200*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
201*f6dc9357SAndroid Build Coastguard Worker     RINOK(InStream_SeekToBegin(_stream))
202*f6dc9357SAndroid Build Coastguard Worker   }
203*f6dc9357SAndroid Build Coastguard Worker   else
204*f6dc9357SAndroid Build Coastguard Worker     _needSeekToStart = true;
205*f6dc9357SAndroid Build Coastguard Worker 
206*f6dc9357SAndroid Build Coastguard Worker   // try {
207*f6dc9357SAndroid Build Coastguard Worker 
208*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ICompressCoder, NCompress::NBZip2::CDecoder> decoder;
209*f6dc9357SAndroid Build Coastguard Worker 
210*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
211*f6dc9357SAndroid Build Coastguard Worker   RINOK(decoder->SetNumberOfThreads(_props._numThreads))
212*f6dc9357SAndroid Build Coastguard Worker   #endif
213*f6dc9357SAndroid Build Coastguard Worker 
214*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ISequentialOutStream, CDummyOutStream> outStream;
215*f6dc9357SAndroid Build Coastguard Worker   outStream->SetStream(realOutStream);
216*f6dc9357SAndroid Build Coastguard Worker   outStream->Init();
217*f6dc9357SAndroid Build Coastguard Worker   // realOutStream.Release();
218*f6dc9357SAndroid Build Coastguard Worker 
219*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
220*f6dc9357SAndroid Build Coastguard Worker   lps->Init(extractCallback, true);
221*f6dc9357SAndroid Build Coastguard Worker 
222*f6dc9357SAndroid Build Coastguard Worker   decoder->FinishMode = true;
223*f6dc9357SAndroid Build Coastguard Worker   decoder->Base.DecodeAllStreams = true;
224*f6dc9357SAndroid Build Coastguard Worker 
225*f6dc9357SAndroid Build Coastguard Worker   _dataAfterEnd = false;
226*f6dc9357SAndroid Build Coastguard Worker   _needMoreInput = false;
227*f6dc9357SAndroid Build Coastguard Worker 
228*f6dc9357SAndroid Build Coastguard Worker   HRESULT result = decoder.Interface()->Code(_seqStream, outStream, NULL, NULL, lps);
229*f6dc9357SAndroid Build Coastguard Worker 
230*f6dc9357SAndroid Build Coastguard Worker   if (result != S_FALSE && result != S_OK)
231*f6dc9357SAndroid Build Coastguard Worker     return result;
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker   if (decoder->Base.NumStreams == 0)
234*f6dc9357SAndroid Build Coastguard Worker   {
235*f6dc9357SAndroid Build Coastguard Worker     _isArc = false;
236*f6dc9357SAndroid Build Coastguard Worker     result = S_FALSE;
237*f6dc9357SAndroid Build Coastguard Worker   }
238*f6dc9357SAndroid Build Coastguard Worker   else
239*f6dc9357SAndroid Build Coastguard Worker   {
240*f6dc9357SAndroid Build Coastguard Worker     const UInt64 inProcessedSize = decoder->GetInputProcessedSize();
241*f6dc9357SAndroid Build Coastguard Worker     UInt64 packSize = inProcessedSize;
242*f6dc9357SAndroid Build Coastguard Worker 
243*f6dc9357SAndroid Build Coastguard Worker     if (decoder->Base.NeedMoreInput)
244*f6dc9357SAndroid Build Coastguard Worker       _needMoreInput = true;
245*f6dc9357SAndroid Build Coastguard Worker 
246*f6dc9357SAndroid Build Coastguard Worker     if (!decoder->Base.IsBz)
247*f6dc9357SAndroid Build Coastguard Worker     {
248*f6dc9357SAndroid Build Coastguard Worker       packSize = decoder->Base.FinishedPackSize;
249*f6dc9357SAndroid Build Coastguard Worker       if (packSize != inProcessedSize)
250*f6dc9357SAndroid Build Coastguard Worker         _dataAfterEnd = true;
251*f6dc9357SAndroid Build Coastguard Worker     }
252*f6dc9357SAndroid Build Coastguard Worker 
253*f6dc9357SAndroid Build Coastguard Worker     _packSize = packSize;
254*f6dc9357SAndroid Build Coastguard Worker     _unpackSize = decoder->GetOutProcessedSize();
255*f6dc9357SAndroid Build Coastguard Worker     _numStreams = decoder->Base.NumStreams;
256*f6dc9357SAndroid Build Coastguard Worker     _numBlocks = decoder->GetNumBlocks();
257*f6dc9357SAndroid Build Coastguard Worker 
258*f6dc9357SAndroid Build Coastguard Worker     _packSize_Defined = true;
259*f6dc9357SAndroid Build Coastguard Worker     _unpackSize_Defined = true;
260*f6dc9357SAndroid Build Coastguard Worker     _numStreams_Defined = true;
261*f6dc9357SAndroid Build Coastguard Worker     _numBlocks_Defined = true;
262*f6dc9357SAndroid Build Coastguard Worker 
263*f6dc9357SAndroid Build Coastguard Worker     // RINOK(
264*f6dc9357SAndroid Build Coastguard Worker     lps.Interface()->SetRatioInfo(&packSize, &_unpackSize);
265*f6dc9357SAndroid Build Coastguard Worker   }
266*f6dc9357SAndroid Build Coastguard Worker 
267*f6dc9357SAndroid Build Coastguard Worker   // outStream.Release();
268*f6dc9357SAndroid Build Coastguard Worker 
269*f6dc9357SAndroid Build Coastguard Worker   if (!_isArc)
270*f6dc9357SAndroid Build Coastguard Worker     opRes = NExtract::NOperationResult::kIsNotArc;
271*f6dc9357SAndroid Build Coastguard Worker   else if (_needMoreInput)
272*f6dc9357SAndroid Build Coastguard Worker     opRes = NExtract::NOperationResult::kUnexpectedEnd;
273*f6dc9357SAndroid Build Coastguard Worker   else if (decoder->GetCrcError())
274*f6dc9357SAndroid Build Coastguard Worker     opRes = NExtract::NOperationResult::kCRCError;
275*f6dc9357SAndroid Build Coastguard Worker   else if (_dataAfterEnd)
276*f6dc9357SAndroid Build Coastguard Worker     opRes = NExtract::NOperationResult::kDataAfterEnd;
277*f6dc9357SAndroid Build Coastguard Worker   else if (result == S_FALSE)
278*f6dc9357SAndroid Build Coastguard Worker     opRes = NExtract::NOperationResult::kDataError;
279*f6dc9357SAndroid Build Coastguard Worker   else if (decoder->Base.MinorError)
280*f6dc9357SAndroid Build Coastguard Worker     opRes = NExtract::NOperationResult::kDataError;
281*f6dc9357SAndroid Build Coastguard Worker   else if (result == S_OK)
282*f6dc9357SAndroid Build Coastguard Worker     opRes = NExtract::NOperationResult::kOK;
283*f6dc9357SAndroid Build Coastguard Worker   else
284*f6dc9357SAndroid Build Coastguard Worker     return result;
285*f6dc9357SAndroid Build Coastguard Worker 
286*f6dc9357SAndroid Build Coastguard Worker  }
287*f6dc9357SAndroid Build Coastguard Worker   return extractCallback->SetOperationResult(opRes);
288*f6dc9357SAndroid Build Coastguard Worker 
289*f6dc9357SAndroid Build Coastguard Worker   // } catch(...)  { return E_FAIL; }
290*f6dc9357SAndroid Build Coastguard Worker 
291*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
292*f6dc9357SAndroid Build Coastguard Worker }
293*f6dc9357SAndroid Build Coastguard Worker 
294*f6dc9357SAndroid Build Coastguard Worker 
295*f6dc9357SAndroid Build Coastguard Worker /*
296*f6dc9357SAndroid Build Coastguard Worker static HRESULT ReportItemProp(IArchiveUpdateCallbackArcProp *reportArcProp, PROPID propID, const PROPVARIANT *value)
297*f6dc9357SAndroid Build Coastguard Worker {
298*f6dc9357SAndroid Build Coastguard Worker   return reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, 0, propID, value);
299*f6dc9357SAndroid Build Coastguard Worker }
300*f6dc9357SAndroid Build Coastguard Worker 
301*f6dc9357SAndroid Build Coastguard Worker static HRESULT ReportArcProp(IArchiveUpdateCallbackArcProp *reportArcProp, PROPID propID, const PROPVARIANT *value)
302*f6dc9357SAndroid Build Coastguard Worker {
303*f6dc9357SAndroid Build Coastguard Worker   return reportArcProp->ReportProp(NEventIndexType::kArcProp, 0, propID, value);
304*f6dc9357SAndroid Build Coastguard Worker }
305*f6dc9357SAndroid Build Coastguard Worker 
306*f6dc9357SAndroid Build Coastguard Worker static HRESULT ReportArcProps(IArchiveUpdateCallbackArcProp *reportArcProp,
307*f6dc9357SAndroid Build Coastguard Worker     const UInt64 *unpackSize,
308*f6dc9357SAndroid Build Coastguard Worker     const UInt64 *numBlocks)
309*f6dc9357SAndroid Build Coastguard Worker {
310*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant sizeProp;
311*f6dc9357SAndroid Build Coastguard Worker   if (unpackSize)
312*f6dc9357SAndroid Build Coastguard Worker   {
313*f6dc9357SAndroid Build Coastguard Worker     sizeProp = *unpackSize;
314*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReportItemProp(reportArcProp, kpidSize, &sizeProp));
315*f6dc9357SAndroid Build Coastguard Worker     RINOK(reportArcProp->ReportFinished(NEventIndexType::kOutArcIndex, 0, NArchive::NUpdate::NOperationResult::kOK));
316*f6dc9357SAndroid Build Coastguard Worker   }
317*f6dc9357SAndroid Build Coastguard Worker 
318*f6dc9357SAndroid Build Coastguard Worker   if (unpackSize)
319*f6dc9357SAndroid Build Coastguard Worker   {
320*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReportArcProp(reportArcProp, kpidSize, &sizeProp));
321*f6dc9357SAndroid Build Coastguard Worker   }
322*f6dc9357SAndroid Build Coastguard Worker   if (numBlocks)
323*f6dc9357SAndroid Build Coastguard Worker   {
324*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant prop;
325*f6dc9357SAndroid Build Coastguard Worker     prop = *numBlocks;
326*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReportArcProp(reportArcProp, kpidNumBlocks, &prop));
327*f6dc9357SAndroid Build Coastguard Worker   }
328*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
329*f6dc9357SAndroid Build Coastguard Worker }
330*f6dc9357SAndroid Build Coastguard Worker */
331*f6dc9357SAndroid Build Coastguard Worker 
UpdateArchive(UInt64 unpackSize,ISequentialOutStream * outStream,const CProps & props,IArchiveUpdateCallback * updateCallback)332*f6dc9357SAndroid Build Coastguard Worker static HRESULT UpdateArchive(
333*f6dc9357SAndroid Build Coastguard Worker     UInt64 unpackSize,
334*f6dc9357SAndroid Build Coastguard Worker     ISequentialOutStream *outStream,
335*f6dc9357SAndroid Build Coastguard Worker     const CProps &props,
336*f6dc9357SAndroid Build Coastguard Worker     IArchiveUpdateCallback *updateCallback
337*f6dc9357SAndroid Build Coastguard Worker     // , ArchiveUpdateCallbackArcProp *reportArcProp
338*f6dc9357SAndroid Build Coastguard Worker     )
339*f6dc9357SAndroid Build Coastguard Worker {
340*f6dc9357SAndroid Build Coastguard Worker   {
341*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ISequentialInStream> fileInStream;
342*f6dc9357SAndroid Build Coastguard Worker     RINOK(updateCallback->GetStream(0, &fileInStream))
343*f6dc9357SAndroid Build Coastguard Worker     if (!fileInStream)
344*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
345*f6dc9357SAndroid Build Coastguard Worker     {
346*f6dc9357SAndroid Build Coastguard Worker       Z7_DECL_CMyComPtr_QI_FROM(
347*f6dc9357SAndroid Build Coastguard Worker           IStreamGetSize,
348*f6dc9357SAndroid Build Coastguard Worker           streamGetSize, fileInStream)
349*f6dc9357SAndroid Build Coastguard Worker       if (streamGetSize)
350*f6dc9357SAndroid Build Coastguard Worker       {
351*f6dc9357SAndroid Build Coastguard Worker         UInt64 size;
352*f6dc9357SAndroid Build Coastguard Worker         if (streamGetSize->GetSize(&size) == S_OK)
353*f6dc9357SAndroid Build Coastguard Worker           unpackSize = size;
354*f6dc9357SAndroid Build Coastguard Worker       }
355*f6dc9357SAndroid Build Coastguard Worker     }
356*f6dc9357SAndroid Build Coastguard Worker     RINOK(updateCallback->SetTotal(unpackSize))
357*f6dc9357SAndroid Build Coastguard Worker 
358*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
359*f6dc9357SAndroid Build Coastguard Worker     lps->Init(updateCallback, true);
360*f6dc9357SAndroid Build Coastguard Worker     {
361*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr2_Create<ICompressCoder, NCompress::NBZip2::CEncoder> encoder;
362*f6dc9357SAndroid Build Coastguard Worker       RINOK(props.SetCoderProps(encoder.ClsPtr(), NULL))
363*f6dc9357SAndroid Build Coastguard Worker       RINOK(encoder.Interface()->Code(fileInStream, outStream, NULL, NULL, lps))
364*f6dc9357SAndroid Build Coastguard Worker       /*
365*f6dc9357SAndroid Build Coastguard Worker       if (reportArcProp)
366*f6dc9357SAndroid Build Coastguard Worker       {
367*f6dc9357SAndroid Build Coastguard Worker         unpackSize = encoderSpec->GetInProcessedSize();
368*f6dc9357SAndroid Build Coastguard Worker         RINOK(ReportArcProps(reportArcProp, &unpackSize, &encoderSpec->NumBlocks));
369*f6dc9357SAndroid Build Coastguard Worker       }
370*f6dc9357SAndroid Build Coastguard Worker       */
371*f6dc9357SAndroid Build Coastguard Worker     }
372*f6dc9357SAndroid Build Coastguard Worker   }
373*f6dc9357SAndroid Build Coastguard Worker   return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
374*f6dc9357SAndroid Build Coastguard Worker }
375*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetFileTimeType (UInt32 * timeType))376*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType))
377*f6dc9357SAndroid Build Coastguard Worker {
378*f6dc9357SAndroid Build Coastguard Worker   *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType;
379*f6dc9357SAndroid Build Coastguard Worker   // *timeType = NFileTimeType::kUnix;
380*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
381*f6dc9357SAndroid Build Coastguard Worker }
382*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::UpdateItems (ISequentialOutStream * outStream,UInt32 numItems,IArchiveUpdateCallback * updateCallback))383*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
384*f6dc9357SAndroid Build Coastguard Worker     IArchiveUpdateCallback *updateCallback))
385*f6dc9357SAndroid Build Coastguard Worker {
386*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
387*f6dc9357SAndroid Build Coastguard Worker 
388*f6dc9357SAndroid Build Coastguard Worker   if (numItems != 1)
389*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
390*f6dc9357SAndroid Build Coastguard Worker 
391*f6dc9357SAndroid Build Coastguard Worker   {
392*f6dc9357SAndroid Build Coastguard Worker     Z7_DECL_CMyComPtr_QI_FROM(
393*f6dc9357SAndroid Build Coastguard Worker         IStreamSetRestriction,
394*f6dc9357SAndroid Build Coastguard Worker         setRestriction, outStream)
395*f6dc9357SAndroid Build Coastguard Worker     if (setRestriction)
396*f6dc9357SAndroid Build Coastguard Worker       RINOK(setRestriction->SetRestriction(0, 0))
397*f6dc9357SAndroid Build Coastguard Worker   }
398*f6dc9357SAndroid Build Coastguard Worker 
399*f6dc9357SAndroid Build Coastguard Worker   Int32 newData, newProps;
400*f6dc9357SAndroid Build Coastguard Worker   UInt32 indexInArchive;
401*f6dc9357SAndroid Build Coastguard Worker   if (!updateCallback)
402*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
403*f6dc9357SAndroid Build Coastguard Worker   RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive))
404*f6dc9357SAndroid Build Coastguard Worker 
405*f6dc9357SAndroid Build Coastguard Worker   // Z7_DECL_CMyComPtr_QI_FROM(IArchiveUpdateCallbackArcProp, reportArcProp, updateCallback)
406*f6dc9357SAndroid Build Coastguard Worker 
407*f6dc9357SAndroid Build Coastguard Worker   if (IntToBool(newProps))
408*f6dc9357SAndroid Build Coastguard Worker   {
409*f6dc9357SAndroid Build Coastguard Worker     {
410*f6dc9357SAndroid Build Coastguard Worker       NCOM::CPropVariant prop;
411*f6dc9357SAndroid Build Coastguard Worker       RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop))
412*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_EMPTY)
413*f6dc9357SAndroid Build Coastguard Worker         if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE)
414*f6dc9357SAndroid Build Coastguard Worker           return E_INVALIDARG;
415*f6dc9357SAndroid Build Coastguard Worker     }
416*f6dc9357SAndroid Build Coastguard Worker   }
417*f6dc9357SAndroid Build Coastguard Worker 
418*f6dc9357SAndroid Build Coastguard Worker   if (IntToBool(newData))
419*f6dc9357SAndroid Build Coastguard Worker   {
420*f6dc9357SAndroid Build Coastguard Worker     UInt64 size;
421*f6dc9357SAndroid Build Coastguard Worker     {
422*f6dc9357SAndroid Build Coastguard Worker       NCOM::CPropVariant prop;
423*f6dc9357SAndroid Build Coastguard Worker       RINOK(updateCallback->GetProperty(0, kpidSize, &prop))
424*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_UI8)
425*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
426*f6dc9357SAndroid Build Coastguard Worker       size = prop.uhVal.QuadPart;
427*f6dc9357SAndroid Build Coastguard Worker     }
428*f6dc9357SAndroid Build Coastguard Worker 
429*f6dc9357SAndroid Build Coastguard Worker     CMethodProps props2 = _props;
430*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
431*f6dc9357SAndroid Build Coastguard Worker     props2.AddProp_NumThreads(_props._numThreads);
432*f6dc9357SAndroid Build Coastguard Worker     #endif
433*f6dc9357SAndroid Build Coastguard Worker 
434*f6dc9357SAndroid Build Coastguard Worker     return UpdateArchive(size, outStream, props2, updateCallback);
435*f6dc9357SAndroid Build Coastguard Worker   }
436*f6dc9357SAndroid Build Coastguard Worker 
437*f6dc9357SAndroid Build Coastguard Worker   if (indexInArchive != 0)
438*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
439*f6dc9357SAndroid Build Coastguard Worker 
440*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
441*f6dc9357SAndroid Build Coastguard Worker   lps->Init(updateCallback, true);
442*f6dc9357SAndroid Build Coastguard Worker 
443*f6dc9357SAndroid Build Coastguard Worker   Z7_DECL_CMyComPtr_QI_FROM(
444*f6dc9357SAndroid Build Coastguard Worker       IArchiveUpdateCallbackFile,
445*f6dc9357SAndroid Build Coastguard Worker       opCallback, updateCallback)
446*f6dc9357SAndroid Build Coastguard Worker   if (opCallback)
447*f6dc9357SAndroid Build Coastguard Worker   {
448*f6dc9357SAndroid Build Coastguard Worker     RINOK(opCallback->ReportOperation(
449*f6dc9357SAndroid Build Coastguard Worker         NEventIndexType::kInArcIndex, 0,
450*f6dc9357SAndroid Build Coastguard Worker         NUpdateNotifyOp::kReplicate))
451*f6dc9357SAndroid Build Coastguard Worker   }
452*f6dc9357SAndroid Build Coastguard Worker 
453*f6dc9357SAndroid Build Coastguard Worker   if (_stream)
454*f6dc9357SAndroid Build Coastguard Worker     RINOK(InStream_SeekToBegin(_stream))
455*f6dc9357SAndroid Build Coastguard Worker 
456*f6dc9357SAndroid Build Coastguard Worker   return NCompress::CopyStream(_stream, outStream, lps);
457*f6dc9357SAndroid Build Coastguard Worker 
458*f6dc9357SAndroid Build Coastguard Worker   // return ReportArcProps(reportArcProp, NULL, NULL);
459*f6dc9357SAndroid Build Coastguard Worker 
460*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
461*f6dc9357SAndroid Build Coastguard Worker }
462*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::SetProperties (const wchar_t * const * names,const PROPVARIANT * values,UInt32 numProps))463*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
464*f6dc9357SAndroid Build Coastguard Worker {
465*f6dc9357SAndroid Build Coastguard Worker   return _props.SetProperties(names, values, numProps);
466*f6dc9357SAndroid Build Coastguard Worker }
467*f6dc9357SAndroid Build Coastguard Worker 
468*f6dc9357SAndroid Build Coastguard Worker static const Byte k_Signature[] = { 'B', 'Z', 'h' };
469*f6dc9357SAndroid Build Coastguard Worker 
470*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_IO(
471*f6dc9357SAndroid Build Coastguard Worker   "bzip2", "bz2 bzip2 tbz2 tbz", "* * .tar .tar", 2,
472*f6dc9357SAndroid Build Coastguard Worker   k_Signature,
473*f6dc9357SAndroid Build Coastguard Worker   0,
474*f6dc9357SAndroid Build Coastguard Worker   NArcInfoFlags::kKeepName
475*f6dc9357SAndroid Build Coastguard Worker   , 0
476*f6dc9357SAndroid Build Coastguard Worker   , IsArc_BZip2)
477*f6dc9357SAndroid Build Coastguard Worker 
478*f6dc9357SAndroid Build Coastguard Worker }}
479