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