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(¤tTotalPacked))
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