xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/ZHandler.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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(&currentTotalPacked))
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