1*f6dc9357SAndroid Build Coastguard Worker // ZHandler.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 "../../Windows/PropVariant.h"
8*f6dc9357SAndroid Build Coastguard Worker
9*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ProgressUtils.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../Common/RegisterArc.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker
13*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/ZDecoder.h"
14*f6dc9357SAndroid Build Coastguard Worker
15*f6dc9357SAndroid Build Coastguard Worker #include "Common/DummyOutStream.h"
16*f6dc9357SAndroid Build Coastguard Worker
17*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
18*f6dc9357SAndroid Build Coastguard Worker namespace NZ {
19*f6dc9357SAndroid Build Coastguard Worker
20*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_CHandler_IInArchive_0
21*f6dc9357SAndroid Build Coastguard Worker
22*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IInStream> _stream;
23*f6dc9357SAndroid Build Coastguard Worker UInt64 _packSize;
24*f6dc9357SAndroid Build Coastguard Worker // UInt64 _unpackSize;
25*f6dc9357SAndroid Build Coastguard Worker // bool _unpackSize_Defined;
26*f6dc9357SAndroid Build Coastguard Worker };
27*f6dc9357SAndroid Build Coastguard Worker
28*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
29*f6dc9357SAndroid Build Coastguard Worker {
30*f6dc9357SAndroid Build Coastguard Worker kpidPackSize
31*f6dc9357SAndroid Build Coastguard Worker };
32*f6dc9357SAndroid Build Coastguard Worker
33*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props
34*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps_NO_Table
35*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetNumberOfItems (UInt32 * numItems))36*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
37*f6dc9357SAndroid Build Coastguard Worker {
38*f6dc9357SAndroid Build Coastguard Worker *numItems = 1;
39*f6dc9357SAndroid Build Coastguard Worker return S_OK;
40*f6dc9357SAndroid Build Coastguard Worker }
41*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetArchiveProperty (PROPID propID,PROPVARIANT * value))42*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
43*f6dc9357SAndroid Build Coastguard Worker {
44*f6dc9357SAndroid Build Coastguard Worker NWindows::NCOM::CPropVariant prop;
45*f6dc9357SAndroid Build Coastguard Worker switch (propID)
46*f6dc9357SAndroid Build Coastguard Worker {
47*f6dc9357SAndroid Build Coastguard Worker case kpidPhySizeCantBeDetected: prop = true; break;
48*f6dc9357SAndroid Build Coastguard Worker }
49*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
50*f6dc9357SAndroid Build Coastguard Worker return S_OK;
51*f6dc9357SAndroid Build Coastguard Worker }
52*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetProperty (UInt32,PROPID propID,PROPVARIANT * value))53*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value))
54*f6dc9357SAndroid Build Coastguard Worker {
55*f6dc9357SAndroid Build Coastguard Worker NWindows::NCOM::CPropVariant prop;
56*f6dc9357SAndroid Build Coastguard Worker switch (propID)
57*f6dc9357SAndroid Build Coastguard Worker {
58*f6dc9357SAndroid Build Coastguard Worker // case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break;
59*f6dc9357SAndroid Build Coastguard Worker case kpidPackSize: prop = _packSize; break;
60*f6dc9357SAndroid Build Coastguard Worker }
61*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
62*f6dc9357SAndroid Build Coastguard Worker return S_OK;
63*f6dc9357SAndroid Build Coastguard Worker }
64*f6dc9357SAndroid Build Coastguard Worker
65*f6dc9357SAndroid Build Coastguard Worker /*
66*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1(
67*f6dc9357SAndroid Build Coastguard Worker CCompressProgressInfoImp
68*f6dc9357SAndroid Build Coastguard Worker , ICompressProgressInfo
69*f6dc9357SAndroid Build Coastguard Worker )
70*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IArchiveOpenCallback> Callback;
71*f6dc9357SAndroid Build Coastguard Worker public:
72*f6dc9357SAndroid Build Coastguard Worker void Init(IArchiveOpenCallback *callback) { Callback = callback; }
73*f6dc9357SAndroid Build Coastguard Worker };
74*f6dc9357SAndroid Build Coastguard Worker
75*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
76*f6dc9357SAndroid Build Coastguard Worker {
77*f6dc9357SAndroid Build Coastguard Worker outSize = outSize;
78*f6dc9357SAndroid Build Coastguard Worker if (Callback)
79*f6dc9357SAndroid Build Coastguard Worker {
80*f6dc9357SAndroid Build Coastguard Worker const UInt64 files = 1;
81*f6dc9357SAndroid Build Coastguard Worker return Callback->SetCompleted(&files, inSize);
82*f6dc9357SAndroid Build Coastguard Worker }
83*f6dc9357SAndroid Build Coastguard Worker return S_OK;
84*f6dc9357SAndroid Build Coastguard Worker }
85*f6dc9357SAndroid Build Coastguard Worker */
86*f6dc9357SAndroid Build Coastguard Worker
IsArc_Z(const Byte * p,size_t size)87*f6dc9357SAndroid Build Coastguard Worker API_FUNC_static_IsArc IsArc_Z(const Byte *p, size_t size)
88*f6dc9357SAndroid Build Coastguard Worker {
89*f6dc9357SAndroid Build Coastguard Worker if (size < 3)
90*f6dc9357SAndroid Build Coastguard Worker return k_IsArc_Res_NEED_MORE;
91*f6dc9357SAndroid Build Coastguard Worker if (size > NCompress::NZ::kRecommendedCheckSize)
92*f6dc9357SAndroid Build Coastguard Worker size = NCompress::NZ::kRecommendedCheckSize;
93*f6dc9357SAndroid Build Coastguard Worker if (!NCompress::NZ::CheckStream(p, size))
94*f6dc9357SAndroid Build Coastguard Worker return k_IsArc_Res_NO;
95*f6dc9357SAndroid Build Coastguard Worker return k_IsArc_Res_YES;
96*f6dc9357SAndroid Build Coastguard Worker }
97*f6dc9357SAndroid Build Coastguard Worker }
98*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::Open (IInStream * stream,const UInt64 *,IArchiveOpenCallback *))99*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *stream,
100*f6dc9357SAndroid Build Coastguard Worker const UInt64 * /* maxCheckStartPosition */,
101*f6dc9357SAndroid Build Coastguard Worker IArchiveOpenCallback * /* openCallback */))
102*f6dc9357SAndroid Build Coastguard Worker {
103*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
104*f6dc9357SAndroid Build Coastguard Worker {
105*f6dc9357SAndroid Build Coastguard Worker // RINOK(InStream_GetPos(stream, _streamStartPosition));
106*f6dc9357SAndroid Build Coastguard Worker Byte buffer[NCompress::NZ::kRecommendedCheckSize];
107*f6dc9357SAndroid Build Coastguard Worker // Byte buffer[1500];
108*f6dc9357SAndroid Build Coastguard Worker size_t size = NCompress::NZ::kRecommendedCheckSize;
109*f6dc9357SAndroid Build Coastguard Worker // size = 700;
110*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream(stream, buffer, &size))
111*f6dc9357SAndroid Build Coastguard Worker if (!NCompress::NZ::CheckStream(buffer, size))
112*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
113*f6dc9357SAndroid Build Coastguard Worker
114*f6dc9357SAndroid Build Coastguard Worker UInt64 endPos;
115*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_GetSize_SeekToEnd(stream, endPos))
116*f6dc9357SAndroid Build Coastguard Worker _packSize = endPos;
117*f6dc9357SAndroid Build Coastguard Worker
118*f6dc9357SAndroid Build Coastguard Worker /*
119*f6dc9357SAndroid Build Coastguard Worker bool fullCheck = false;
120*f6dc9357SAndroid Build Coastguard Worker if (fullCheck)
121*f6dc9357SAndroid Build Coastguard Worker {
122*f6dc9357SAndroid Build Coastguard Worker CCompressProgressInfoImp *compressProgressSpec = new CCompressProgressInfoImp;
123*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ICompressProgressInfo> compressProgress = compressProgressSpec;
124*f6dc9357SAndroid Build Coastguard Worker compressProgressSpec->Init(openCallback);
125*f6dc9357SAndroid Build Coastguard Worker
126*f6dc9357SAndroid Build Coastguard Worker NCompress::NZ::CDecoder *decoderSpec = new NCompress::NZ::CDecoder;
127*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ICompressCoder> decoder = decoderSpec;
128*f6dc9357SAndroid Build Coastguard Worker
129*f6dc9357SAndroid Build Coastguard Worker CDummyOutStream *outStreamSpec = new CDummyOutStream;
130*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
131*f6dc9357SAndroid Build Coastguard Worker outStreamSpec->SetStream(NULL);
132*f6dc9357SAndroid Build Coastguard Worker outStreamSpec->Init();
133*f6dc9357SAndroid Build Coastguard Worker decoderSpec->SetProp(_prop);
134*f6dc9357SAndroid Build Coastguard Worker if (openCallback)
135*f6dc9357SAndroid Build Coastguard Worker {
136*f6dc9357SAndroid Build Coastguard Worker UInt64 files = 1;
137*f6dc9357SAndroid Build Coastguard Worker RINOK(openCallback->SetTotal(&files, &endPos));
138*f6dc9357SAndroid Build Coastguard Worker }
139*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(stream, _streamStartPosition + kSignatureSize))
140*f6dc9357SAndroid Build Coastguard Worker HRESULT res = decoder->Code(stream, outStream, NULL, NULL, openCallback ? compressProgress : NULL);
141*f6dc9357SAndroid Build Coastguard Worker if (res != S_OK)
142*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
143*f6dc9357SAndroid Build Coastguard Worker _packSize = decoderSpec->PackSize;
144*f6dc9357SAndroid Build Coastguard Worker }
145*f6dc9357SAndroid Build Coastguard Worker */
146*f6dc9357SAndroid Build Coastguard Worker _stream = stream;
147*f6dc9357SAndroid Build Coastguard Worker }
148*f6dc9357SAndroid Build Coastguard Worker return S_OK;
149*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
150*f6dc9357SAndroid Build Coastguard Worker }
151*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::Close ())152*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
153*f6dc9357SAndroid Build Coastguard Worker {
154*f6dc9357SAndroid Build Coastguard Worker _packSize = 0;
155*f6dc9357SAndroid Build Coastguard Worker // _unpackSize_Defined = false;
156*f6dc9357SAndroid Build Coastguard Worker _stream.Release();
157*f6dc9357SAndroid Build Coastguard Worker return S_OK;
158*f6dc9357SAndroid Build Coastguard Worker }
159*f6dc9357SAndroid Build Coastguard Worker
160*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::Extract (const UInt32 * indices,UInt32 numItems,Int32 testMode,IArchiveExtractCallback * extractCallback))161*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
162*f6dc9357SAndroid Build Coastguard Worker Int32 testMode, IArchiveExtractCallback *extractCallback))
163*f6dc9357SAndroid Build Coastguard Worker {
164*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
165*f6dc9357SAndroid Build Coastguard Worker if (numItems == 0)
166*f6dc9357SAndroid Build Coastguard Worker return S_OK;
167*f6dc9357SAndroid Build Coastguard Worker if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
168*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
169*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->SetTotal(_packSize))
170*f6dc9357SAndroid Build Coastguard Worker UInt64 currentTotalPacked = 0;
171*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->SetCompleted(¤tTotalPacked))
172*f6dc9357SAndroid Build Coastguard Worker
173*f6dc9357SAndroid Build Coastguard Worker int opRes;
174*f6dc9357SAndroid Build Coastguard Worker {
175*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> realOutStream;
176*f6dc9357SAndroid Build Coastguard Worker const Int32 askMode = testMode ?
177*f6dc9357SAndroid Build Coastguard Worker NExtract::NAskMode::kTest :
178*f6dc9357SAndroid Build Coastguard Worker NExtract::NAskMode::kExtract;
179*f6dc9357SAndroid Build Coastguard Worker
180*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->GetStream(0, &realOutStream, askMode))
181*f6dc9357SAndroid Build Coastguard Worker
182*f6dc9357SAndroid Build Coastguard Worker if (!testMode && !realOutStream)
183*f6dc9357SAndroid Build Coastguard Worker return S_OK;
184*f6dc9357SAndroid Build Coastguard Worker
185*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->PrepareOperation(askMode))
186*f6dc9357SAndroid Build Coastguard Worker
187*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ISequentialOutStream, CDummyOutStream> outStream;
188*f6dc9357SAndroid Build Coastguard Worker outStream->SetStream(realOutStream);
189*f6dc9357SAndroid Build Coastguard Worker outStream->Init();
190*f6dc9357SAndroid Build Coastguard Worker // realOutStream.Release();
191*f6dc9357SAndroid Build Coastguard Worker
192*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
193*f6dc9357SAndroid Build Coastguard Worker lps->Init(extractCallback, true);
194*f6dc9357SAndroid Build Coastguard Worker
195*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekToBegin(_stream))
196*f6dc9357SAndroid Build Coastguard Worker
197*f6dc9357SAndroid Build Coastguard Worker NCompress::NZ::CDecoder decoder;
198*f6dc9357SAndroid Build Coastguard Worker {
199*f6dc9357SAndroid Build Coastguard Worker const HRESULT hres = decoder.Code(_stream, outStream, lps);
200*f6dc9357SAndroid Build Coastguard Worker if (hres == S_FALSE)
201*f6dc9357SAndroid Build Coastguard Worker opRes = NExtract::NOperationResult::kDataError;
202*f6dc9357SAndroid Build Coastguard Worker else
203*f6dc9357SAndroid Build Coastguard Worker {
204*f6dc9357SAndroid Build Coastguard Worker RINOK(hres)
205*f6dc9357SAndroid Build Coastguard Worker opRes = NExtract::NOperationResult::kOK;
206*f6dc9357SAndroid Build Coastguard Worker }
207*f6dc9357SAndroid Build Coastguard Worker }
208*f6dc9357SAndroid Build Coastguard Worker // _unpackSize = outStreamSpec->GetSize();
209*f6dc9357SAndroid Build Coastguard Worker // _unpackSize_Defined = true;
210*f6dc9357SAndroid Build Coastguard Worker // outStream.Release();
211*f6dc9357SAndroid Build Coastguard Worker }
212*f6dc9357SAndroid Build Coastguard Worker return extractCallback->SetOperationResult(opRes);
213*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
214*f6dc9357SAndroid Build Coastguard Worker }
215*f6dc9357SAndroid Build Coastguard Worker
216*f6dc9357SAndroid Build Coastguard Worker static const Byte k_Signature[] = { 0x1F, 0x9D };
217*f6dc9357SAndroid Build Coastguard Worker
218*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_I(
219*f6dc9357SAndroid Build Coastguard Worker "Z", "z taz", "* .tar", 5,
220*f6dc9357SAndroid Build Coastguard Worker k_Signature,
221*f6dc9357SAndroid Build Coastguard Worker 0,
222*f6dc9357SAndroid Build Coastguard Worker 0,
223*f6dc9357SAndroid Build Coastguard Worker IsArc_Z)
224*f6dc9357SAndroid Build Coastguard Worker
225*f6dc9357SAndroid Build Coastguard Worker }}
226