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