xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/ZstdHandler.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // ZstdHandler.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker // #define Z7_USE_ZSTD_ORIG_DECODER
6*f6dc9357SAndroid Build Coastguard Worker // #define Z7_USE_ZSTD_COMPRESSION
7*f6dc9357SAndroid Build Coastguard Worker 
8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ComTry.h"
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "../Common/MethodProps.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ProgressUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker #include "../Common/RegisterArc.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/CopyCoder.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/ZstdDecoder.h"
17*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_ORIG_DECODER
18*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/Zstd2Decoder.h"
19*f6dc9357SAndroid Build Coastguard Worker #endif
20*f6dc9357SAndroid Build Coastguard Worker 
21*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_COMPRESSION
22*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/ZstdEncoder.h"
23*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/ZstdEncoderProps.h"
24*f6dc9357SAndroid Build Coastguard Worker #include "Common/HandlerOut.h"
25*f6dc9357SAndroid Build Coastguard Worker #endif
26*f6dc9357SAndroid Build Coastguard Worker 
27*f6dc9357SAndroid Build Coastguard Worker #include "Common/DummyOutStream.h"
28*f6dc9357SAndroid Build Coastguard Worker 
29*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/CpuArch.h"
30*f6dc9357SAndroid Build Coastguard Worker 
31*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
32*f6dc9357SAndroid Build Coastguard Worker 
33*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
34*f6dc9357SAndroid Build Coastguard Worker namespace NZstd {
35*f6dc9357SAndroid Build Coastguard Worker 
36*f6dc9357SAndroid Build Coastguard Worker #define DESCRIPTOR_Get_DictionaryId_Flag(d)   ((d) & 3)
37*f6dc9357SAndroid Build Coastguard Worker #define DESCRIPTOR_FLAG_CHECKSUM              (1 << 2)
38*f6dc9357SAndroid Build Coastguard Worker #define DESCRIPTOR_FLAG_RESERVED              (1 << 3)
39*f6dc9357SAndroid Build Coastguard Worker #define DESCRIPTOR_FLAG_UNUSED                (1 << 4)
40*f6dc9357SAndroid Build Coastguard Worker #define DESCRIPTOR_FLAG_SINGLE                (1 << 5)
41*f6dc9357SAndroid Build Coastguard Worker #define DESCRIPTOR_Get_ContentSize_Flag3(d)   ((d) >> 5)
42*f6dc9357SAndroid Build Coastguard Worker #define DESCRIPTOR_Is_ContentSize_Defined(d)  (((d) & 0xe0) != 0)
43*f6dc9357SAndroid Build Coastguard Worker 
44*f6dc9357SAndroid Build Coastguard Worker struct CFrameHeader
45*f6dc9357SAndroid Build Coastguard Worker {
46*f6dc9357SAndroid Build Coastguard Worker   Byte Descriptor;
47*f6dc9357SAndroid Build Coastguard Worker   Byte WindowDescriptor;
48*f6dc9357SAndroid Build Coastguard Worker   UInt32 DictionaryId;
49*f6dc9357SAndroid Build Coastguard Worker   UInt64 ContentSize;
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker   /* by zstd specification:
52*f6dc9357SAndroid Build Coastguard Worker       the decoder must check that (Is_Reserved() == false)
53*f6dc9357SAndroid Build Coastguard Worker       the decoder must ignore Unused_bit */
Is_ReservedNArchive::NZstd::CFrameHeader54*f6dc9357SAndroid Build Coastguard Worker   bool Is_Reserved() const                { return (Descriptor & DESCRIPTOR_FLAG_RESERVED) != 0; }
Is_ChecksumNArchive::NZstd::CFrameHeader55*f6dc9357SAndroid Build Coastguard Worker   bool Is_Checksum() const                { return (Descriptor & DESCRIPTOR_FLAG_CHECKSUM) != 0; }
Is_SingleSegmentNArchive::NZstd::CFrameHeader56*f6dc9357SAndroid Build Coastguard Worker   bool Is_SingleSegment() const           { return (Descriptor & DESCRIPTOR_FLAG_SINGLE) != 0; }
Is_ContentSize_DefinedNArchive::NZstd::CFrameHeader57*f6dc9357SAndroid Build Coastguard Worker   bool Is_ContentSize_Defined() const     { return DESCRIPTOR_Is_ContentSize_Defined(Descriptor); }
Get_DictionaryId_FlagNArchive::NZstd::CFrameHeader58*f6dc9357SAndroid Build Coastguard Worker   unsigned Get_DictionaryId_Flag() const  { return DESCRIPTOR_Get_DictionaryId_Flag(Descriptor); }
Get_ContentSize_Flag3NArchive::NZstd::CFrameHeader59*f6dc9357SAndroid Build Coastguard Worker   unsigned Get_ContentSize_Flag3() const  { return DESCRIPTOR_Get_ContentSize_Flag3(Descriptor); }
60*f6dc9357SAndroid Build Coastguard Worker 
ParseNArchive::NZstd::CFrameHeader61*f6dc9357SAndroid Build Coastguard Worker   const Byte *Parse(const Byte *p, int size)
62*f6dc9357SAndroid Build Coastguard Worker   {
63*f6dc9357SAndroid Build Coastguard Worker     if ((unsigned)size < 2)
64*f6dc9357SAndroid Build Coastguard Worker       return NULL;
65*f6dc9357SAndroid Build Coastguard Worker     Descriptor = *p++;
66*f6dc9357SAndroid Build Coastguard Worker     size--;
67*f6dc9357SAndroid Build Coastguard Worker     {
68*f6dc9357SAndroid Build Coastguard Worker       Byte w = 0;
69*f6dc9357SAndroid Build Coastguard Worker       if (!Is_SingleSegment())
70*f6dc9357SAndroid Build Coastguard Worker       {
71*f6dc9357SAndroid Build Coastguard Worker         w = *p++;
72*f6dc9357SAndroid Build Coastguard Worker         size--;
73*f6dc9357SAndroid Build Coastguard Worker       }
74*f6dc9357SAndroid Build Coastguard Worker       WindowDescriptor = w;
75*f6dc9357SAndroid Build Coastguard Worker     }
76*f6dc9357SAndroid Build Coastguard Worker     {
77*f6dc9357SAndroid Build Coastguard Worker       unsigned n = Get_DictionaryId_Flag();
78*f6dc9357SAndroid Build Coastguard Worker       UInt32 d = 0;
79*f6dc9357SAndroid Build Coastguard Worker       if (n)
80*f6dc9357SAndroid Build Coastguard Worker       {
81*f6dc9357SAndroid Build Coastguard Worker         n = (unsigned)1 << (n - 1);
82*f6dc9357SAndroid Build Coastguard Worker         if ((size -= (int)n) < 0)
83*f6dc9357SAndroid Build Coastguard Worker           return NULL;
84*f6dc9357SAndroid Build Coastguard Worker         d = GetUi32(p) & ((UInt32)(Int32)-1 >> (32 - 8u * n));
85*f6dc9357SAndroid Build Coastguard Worker         p += n;
86*f6dc9357SAndroid Build Coastguard Worker       }
87*f6dc9357SAndroid Build Coastguard Worker       DictionaryId = d;
88*f6dc9357SAndroid Build Coastguard Worker     }
89*f6dc9357SAndroid Build Coastguard Worker     {
90*f6dc9357SAndroid Build Coastguard Worker       unsigned n = Get_ContentSize_Flag3();
91*f6dc9357SAndroid Build Coastguard Worker       UInt64 v = 0;
92*f6dc9357SAndroid Build Coastguard Worker       if (n)
93*f6dc9357SAndroid Build Coastguard Worker       {
94*f6dc9357SAndroid Build Coastguard Worker         n >>= 1;
95*f6dc9357SAndroid Build Coastguard Worker         if (n == 1)
96*f6dc9357SAndroid Build Coastguard Worker           v = 256;
97*f6dc9357SAndroid Build Coastguard Worker         n = (unsigned)1 << n;
98*f6dc9357SAndroid Build Coastguard Worker         if ((size -= (int)n) < 0)
99*f6dc9357SAndroid Build Coastguard Worker           return NULL;
100*f6dc9357SAndroid Build Coastguard Worker         v += GetUi64(p) & ((UInt64)(Int64)-1 >> (64 - 8u * n));
101*f6dc9357SAndroid Build Coastguard Worker         p += n;
102*f6dc9357SAndroid Build Coastguard Worker       }
103*f6dc9357SAndroid Build Coastguard Worker       ContentSize = v;
104*f6dc9357SAndroid Build Coastguard Worker     }
105*f6dc9357SAndroid Build Coastguard Worker     return p;
106*f6dc9357SAndroid Build Coastguard Worker   }
107*f6dc9357SAndroid Build Coastguard Worker };
108*f6dc9357SAndroid Build Coastguard Worker 
109*f6dc9357SAndroid Build Coastguard Worker 
110*f6dc9357SAndroid Build Coastguard Worker 
111*f6dc9357SAndroid Build Coastguard Worker class CHandler Z7_final:
112*f6dc9357SAndroid Build Coastguard Worker   public IInArchive,
113*f6dc9357SAndroid Build Coastguard Worker   public IArchiveOpenSeq,
114*f6dc9357SAndroid Build Coastguard Worker   public ISetProperties,
115*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_COMPRESSION
116*f6dc9357SAndroid Build Coastguard Worker   public IOutArchive,
117*f6dc9357SAndroid Build Coastguard Worker #endif
118*f6dc9357SAndroid Build Coastguard Worker   public CMyUnknownImp
119*f6dc9357SAndroid Build Coastguard Worker {
120*f6dc9357SAndroid Build Coastguard Worker   Z7_COM_QI_BEGIN2(IInArchive)
121*f6dc9357SAndroid Build Coastguard Worker   Z7_COM_QI_ENTRY(IArchiveOpenSeq)
122*f6dc9357SAndroid Build Coastguard Worker   Z7_COM_QI_ENTRY(ISetProperties)
123*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_COMPRESSION
124*f6dc9357SAndroid Build Coastguard Worker   Z7_COM_QI_ENTRY(IOutArchive)
125*f6dc9357SAndroid Build Coastguard Worker #endif
126*f6dc9357SAndroid Build Coastguard Worker   Z7_COM_QI_END
127*f6dc9357SAndroid Build Coastguard Worker   Z7_COM_ADDREF_RELEASE
128*f6dc9357SAndroid Build Coastguard Worker 
129*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(IInArchive)
130*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(IArchiveOpenSeq)
131*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(ISetProperties)
132*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_COMPRESSION
133*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(IOutArchive)
134*f6dc9357SAndroid Build Coastguard Worker #endif
135*f6dc9357SAndroid Build Coastguard Worker 
136*f6dc9357SAndroid Build Coastguard Worker   bool _isArc;
137*f6dc9357SAndroid Build Coastguard Worker   bool _needSeekToStart;
138*f6dc9357SAndroid Build Coastguard Worker   // bool _dataAfterEnd;
139*f6dc9357SAndroid Build Coastguard Worker   // bool _needMoreInput;
140*f6dc9357SAndroid Build Coastguard Worker   bool _unsupportedBlock;
141*f6dc9357SAndroid Build Coastguard Worker 
142*f6dc9357SAndroid Build Coastguard Worker   bool _wasParsed;
143*f6dc9357SAndroid Build Coastguard Worker   bool _phySize_Decoded_Defined;
144*f6dc9357SAndroid Build Coastguard Worker   bool _unpackSize_Defined; // decoded
145*f6dc9357SAndroid Build Coastguard Worker   bool _decoded_Info_Defined;
146*f6dc9357SAndroid Build Coastguard Worker 
147*f6dc9357SAndroid Build Coastguard Worker   bool _parseMode;
148*f6dc9357SAndroid Build Coastguard Worker   bool _disableHash;
149*f6dc9357SAndroid Build Coastguard Worker   // bool _smallMode;
150*f6dc9357SAndroid Build Coastguard Worker 
151*f6dc9357SAndroid Build Coastguard Worker   UInt64 _phySize;
152*f6dc9357SAndroid Build Coastguard Worker   UInt64 _phySize_Decoded;
153*f6dc9357SAndroid Build Coastguard Worker   UInt64 _unpackSize;
154*f6dc9357SAndroid Build Coastguard Worker 
155*f6dc9357SAndroid Build Coastguard Worker   CZstdDecInfo _parsed_Info;
156*f6dc9357SAndroid Build Coastguard Worker   CZstdDecInfo _decoded_Info;
157*f6dc9357SAndroid Build Coastguard Worker 
158*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IInStream> _stream;
159*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialInStream> _seqStream;
160*f6dc9357SAndroid Build Coastguard Worker 
161*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_COMPRESSION
162*f6dc9357SAndroid Build Coastguard Worker   CSingleMethodProps _props;
163*f6dc9357SAndroid Build Coastguard Worker #endif
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker public:
CHandler()166*f6dc9357SAndroid Build Coastguard Worker   CHandler():
167*f6dc9357SAndroid Build Coastguard Worker     _parseMode(false),
168*f6dc9357SAndroid Build Coastguard Worker     _disableHash(false)
169*f6dc9357SAndroid Build Coastguard Worker     // _smallMode(false)
170*f6dc9357SAndroid Build Coastguard Worker     {}
171*f6dc9357SAndroid Build Coastguard Worker };
172*f6dc9357SAndroid Build Coastguard Worker 
173*f6dc9357SAndroid Build Coastguard Worker 
174*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
175*f6dc9357SAndroid Build Coastguard Worker {
176*f6dc9357SAndroid Build Coastguard Worker   kpidSize,
177*f6dc9357SAndroid Build Coastguard Worker   kpidPackSize
178*f6dc9357SAndroid Build Coastguard Worker };
179*f6dc9357SAndroid Build Coastguard Worker 
180*f6dc9357SAndroid Build Coastguard Worker static const Byte kArcProps[] =
181*f6dc9357SAndroid Build Coastguard Worker {
182*f6dc9357SAndroid Build Coastguard Worker   kpidNumStreams,
183*f6dc9357SAndroid Build Coastguard Worker   kpidNumBlocks,
184*f6dc9357SAndroid Build Coastguard Worker   kpidMethod,
185*f6dc9357SAndroid Build Coastguard Worker   // kpidChecksum
186*f6dc9357SAndroid Build Coastguard Worker   kpidCRC
187*f6dc9357SAndroid Build Coastguard Worker };
188*f6dc9357SAndroid Build Coastguard Worker 
189*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props
190*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps
191*f6dc9357SAndroid Build Coastguard Worker 
192*f6dc9357SAndroid Build Coastguard Worker 
193*f6dc9357SAndroid Build Coastguard Worker // static const unsigned kBlockType_Raw = 0;
194*f6dc9357SAndroid Build Coastguard Worker static const unsigned kBlockType_RLE = 1;
195*f6dc9357SAndroid Build Coastguard Worker // static const unsigned kBlockType_Compressed = 2;
196*f6dc9357SAndroid Build Coastguard Worker static const unsigned kBlockType_Reserved = 3;
197*f6dc9357SAndroid Build Coastguard Worker /*
198*f6dc9357SAndroid Build Coastguard Worker static const char * const kNames[] =
199*f6dc9357SAndroid Build Coastguard Worker {
200*f6dc9357SAndroid Build Coastguard Worker     "RAW"
201*f6dc9357SAndroid Build Coastguard Worker   , "RLE"
202*f6dc9357SAndroid Build Coastguard Worker   , "Compressed"
203*f6dc9357SAndroid Build Coastguard Worker   , "Reserved"
204*f6dc9357SAndroid Build Coastguard Worker };
205*f6dc9357SAndroid Build Coastguard Worker */
206*f6dc9357SAndroid Build Coastguard Worker 
Add_UInt64(AString & s,const char * name,UInt64 v)207*f6dc9357SAndroid Build Coastguard Worker static void Add_UInt64(AString &s, const char *name, UInt64 v)
208*f6dc9357SAndroid Build Coastguard Worker {
209*f6dc9357SAndroid Build Coastguard Worker   s.Add_OptSpaced(name);
210*f6dc9357SAndroid Build Coastguard Worker   s.Add_Colon();
211*f6dc9357SAndroid Build Coastguard Worker   s.Add_UInt64(v);
212*f6dc9357SAndroid Build Coastguard Worker }
213*f6dc9357SAndroid Build Coastguard Worker 
214*f6dc9357SAndroid Build Coastguard Worker 
PrintSize(AString & s,UInt64 w)215*f6dc9357SAndroid Build Coastguard Worker static void PrintSize(AString &s, UInt64 w)
216*f6dc9357SAndroid Build Coastguard Worker {
217*f6dc9357SAndroid Build Coastguard Worker   char c = 0;
218*f6dc9357SAndroid Build Coastguard Worker        if ((w & ((1 << 30) - 1)) == 0)  { c = 'G'; w >>= 30; }
219*f6dc9357SAndroid Build Coastguard Worker   else if ((w & ((1 << 20) - 1)) == 0)  { c = 'M'; w >>= 20; }
220*f6dc9357SAndroid Build Coastguard Worker   else if ((w & ((1 << 10) - 1)) == 0)  { c = 'K'; w >>= 10; }
221*f6dc9357SAndroid Build Coastguard Worker   s.Add_UInt64(w);
222*f6dc9357SAndroid Build Coastguard Worker   if (c)
223*f6dc9357SAndroid Build Coastguard Worker   {
224*f6dc9357SAndroid Build Coastguard Worker     s.Add_Char(c);
225*f6dc9357SAndroid Build Coastguard Worker     s += "iB";
226*f6dc9357SAndroid Build Coastguard Worker   }
227*f6dc9357SAndroid Build Coastguard Worker }
228*f6dc9357SAndroid Build Coastguard Worker 
229*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetArchiveProperty (PROPID propID,PROPVARIANT * value))230*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
231*f6dc9357SAndroid Build Coastguard Worker {
232*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
233*f6dc9357SAndroid Build Coastguard Worker 
234*f6dc9357SAndroid Build Coastguard Worker   CZstdDecInfo *p = NULL;
235*f6dc9357SAndroid Build Coastguard Worker   if (_wasParsed || !_decoded_Info_Defined)
236*f6dc9357SAndroid Build Coastguard Worker     p = &_parsed_Info;
237*f6dc9357SAndroid Build Coastguard Worker   else if (_decoded_Info_Defined)
238*f6dc9357SAndroid Build Coastguard Worker     p = &_decoded_Info;
239*f6dc9357SAndroid Build Coastguard Worker 
240*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
241*f6dc9357SAndroid Build Coastguard Worker   {
242*f6dc9357SAndroid Build Coastguard Worker     case kpidPhySize:
243*f6dc9357SAndroid Build Coastguard Worker       if (_wasParsed)
244*f6dc9357SAndroid Build Coastguard Worker         prop = _phySize;
245*f6dc9357SAndroid Build Coastguard Worker       else if (_phySize_Decoded_Defined)
246*f6dc9357SAndroid Build Coastguard Worker         prop = _phySize_Decoded;
247*f6dc9357SAndroid Build Coastguard Worker       break;
248*f6dc9357SAndroid Build Coastguard Worker 
249*f6dc9357SAndroid Build Coastguard Worker     case kpidUnpackSize:
250*f6dc9357SAndroid Build Coastguard Worker       if (_unpackSize_Defined)
251*f6dc9357SAndroid Build Coastguard Worker         prop = _unpackSize;
252*f6dc9357SAndroid Build Coastguard Worker       break;
253*f6dc9357SAndroid Build Coastguard Worker 
254*f6dc9357SAndroid Build Coastguard Worker     case kpidNumStreams:
255*f6dc9357SAndroid Build Coastguard Worker       if (p)
256*f6dc9357SAndroid Build Coastguard Worker       if (_wasParsed || _decoded_Info_Defined)
257*f6dc9357SAndroid Build Coastguard Worker         prop = p->num_DataFrames;
258*f6dc9357SAndroid Build Coastguard Worker       break;
259*f6dc9357SAndroid Build Coastguard Worker 
260*f6dc9357SAndroid Build Coastguard Worker     case kpidNumBlocks:
261*f6dc9357SAndroid Build Coastguard Worker       if (p)
262*f6dc9357SAndroid Build Coastguard Worker       if (_wasParsed || _decoded_Info_Defined)
263*f6dc9357SAndroid Build Coastguard Worker         prop = p->num_Blocks;
264*f6dc9357SAndroid Build Coastguard Worker       break;
265*f6dc9357SAndroid Build Coastguard Worker 
266*f6dc9357SAndroid Build Coastguard Worker     // case kpidChecksum:
267*f6dc9357SAndroid Build Coastguard Worker     case kpidCRC:
268*f6dc9357SAndroid Build Coastguard Worker       if (p)
269*f6dc9357SAndroid Build Coastguard Worker         if (p->checksum_Defined && p->num_DataFrames == 1)
270*f6dc9357SAndroid Build Coastguard Worker           prop = p->checksum; // it's checksum from last frame
271*f6dc9357SAndroid Build Coastguard Worker       break;
272*f6dc9357SAndroid Build Coastguard Worker 
273*f6dc9357SAndroid Build Coastguard Worker     case kpidMethod:
274*f6dc9357SAndroid Build Coastguard Worker     {
275*f6dc9357SAndroid Build Coastguard Worker       AString s;
276*f6dc9357SAndroid Build Coastguard Worker       s.Add_OptSpaced(p == &_decoded_Info ?
277*f6dc9357SAndroid Build Coastguard Worker           "decoded:" : _wasParsed ?
278*f6dc9357SAndroid Build Coastguard Worker           "parsed:" :
279*f6dc9357SAndroid Build Coastguard Worker           "header-open-only:");
280*f6dc9357SAndroid Build Coastguard Worker 
281*f6dc9357SAndroid Build Coastguard Worker       if (p->dictionaryId != 0)
282*f6dc9357SAndroid Build Coastguard Worker       {
283*f6dc9357SAndroid Build Coastguard Worker         if (p->are_DictionaryId_Different)
284*f6dc9357SAndroid Build Coastguard Worker           s.Add_OptSpaced("different-dictionary-IDs");
285*f6dc9357SAndroid Build Coastguard Worker         s.Add_OptSpaced("dictionary-ID:");
286*f6dc9357SAndroid Build Coastguard Worker         s.Add_UInt32(p->dictionaryId);
287*f6dc9357SAndroid Build Coastguard Worker       }
288*f6dc9357SAndroid Build Coastguard Worker       /*
289*f6dc9357SAndroid Build Coastguard Worker       if (ContentSize_Defined)
290*f6dc9357SAndroid Build Coastguard Worker       {
291*f6dc9357SAndroid Build Coastguard Worker         s.Add_OptSpaced("ContentSize=");
292*f6dc9357SAndroid Build Coastguard Worker         s.Add_UInt64(ContentSize_Total);
293*f6dc9357SAndroid Build Coastguard Worker       }
294*f6dc9357SAndroid Build Coastguard Worker       */
295*f6dc9357SAndroid Build Coastguard Worker       // if (p->are_Checksums)
296*f6dc9357SAndroid Build Coastguard Worker       if (p->descriptor_OR & DESCRIPTOR_FLAG_CHECKSUM)
297*f6dc9357SAndroid Build Coastguard Worker         s.Add_OptSpaced("XXH64");
298*f6dc9357SAndroid Build Coastguard Worker       if (p->descriptor_NOT_OR & DESCRIPTOR_FLAG_CHECKSUM)
299*f6dc9357SAndroid Build Coastguard Worker         s.Add_OptSpaced("NO-XXH64");
300*f6dc9357SAndroid Build Coastguard Worker 
301*f6dc9357SAndroid Build Coastguard Worker       if (p->descriptor_OR & DESCRIPTOR_FLAG_UNUSED)
302*f6dc9357SAndroid Build Coastguard Worker         s.Add_OptSpaced("unused_bit");
303*f6dc9357SAndroid Build Coastguard Worker 
304*f6dc9357SAndroid Build Coastguard Worker       if (p->descriptor_OR & DESCRIPTOR_FLAG_SINGLE)
305*f6dc9357SAndroid Build Coastguard Worker         s.Add_OptSpaced("single-segments");
306*f6dc9357SAndroid Build Coastguard Worker 
307*f6dc9357SAndroid Build Coastguard Worker       if (p->descriptor_NOT_OR & DESCRIPTOR_FLAG_SINGLE)
308*f6dc9357SAndroid Build Coastguard Worker       {
309*f6dc9357SAndroid Build Coastguard Worker         // Add_UInt64(s, "wnd-descriptors", p->num_WindowDescriptors);
310*f6dc9357SAndroid Build Coastguard Worker         s.Add_OptSpaced("wnd-desc-log-MAX:");
311*f6dc9357SAndroid Build Coastguard Worker         // WindowDescriptor_MAX = 16 << 3; // for debug
312*f6dc9357SAndroid Build Coastguard Worker         const unsigned e = p->windowDescriptor_MAX >> 3;
313*f6dc9357SAndroid Build Coastguard Worker         s.Add_UInt32(e + 10);
314*f6dc9357SAndroid Build Coastguard Worker         const unsigned m = p->windowDescriptor_MAX & 7;
315*f6dc9357SAndroid Build Coastguard Worker         if (m != 0)
316*f6dc9357SAndroid Build Coastguard Worker         {
317*f6dc9357SAndroid Build Coastguard Worker           s.Add_Dot();
318*f6dc9357SAndroid Build Coastguard Worker           s.Add_UInt32(m);
319*f6dc9357SAndroid Build Coastguard Worker         }
320*f6dc9357SAndroid Build Coastguard Worker       }
321*f6dc9357SAndroid Build Coastguard Worker 
322*f6dc9357SAndroid Build Coastguard Worker       if (DESCRIPTOR_Is_ContentSize_Defined(p->descriptor_OR) ||
323*f6dc9357SAndroid Build Coastguard Worker           (p->descriptor_NOT_OR & DESCRIPTOR_FLAG_SINGLE))
324*f6dc9357SAndroid Build Coastguard Worker       /*
325*f6dc9357SAndroid Build Coastguard Worker       if (p->are_ContentSize_Known ||
326*f6dc9357SAndroid Build Coastguard Worker           p->are_WindowDescriptors)
327*f6dc9357SAndroid Build Coastguard Worker       */
328*f6dc9357SAndroid Build Coastguard Worker       {
329*f6dc9357SAndroid Build Coastguard Worker         s.Add_OptSpaced("wnd-MAX:");
330*f6dc9357SAndroid Build Coastguard Worker         PrintSize(s, p->windowSize_MAX);
331*f6dc9357SAndroid Build Coastguard Worker         if (p->windowSize_MAX != p->windowSize_Allocate_MAX)
332*f6dc9357SAndroid Build Coastguard Worker         {
333*f6dc9357SAndroid Build Coastguard Worker           s.Add_OptSpaced("wnd-use-MAX:");
334*f6dc9357SAndroid Build Coastguard Worker           PrintSize(s, p->windowSize_Allocate_MAX);
335*f6dc9357SAndroid Build Coastguard Worker         }
336*f6dc9357SAndroid Build Coastguard Worker       }
337*f6dc9357SAndroid Build Coastguard Worker 
338*f6dc9357SAndroid Build Coastguard Worker       if (p->num_DataFrames != 1)
339*f6dc9357SAndroid Build Coastguard Worker         Add_UInt64(s, "data-frames", p->num_DataFrames);
340*f6dc9357SAndroid Build Coastguard Worker       if (p->num_SkipFrames != 0)
341*f6dc9357SAndroid Build Coastguard Worker       {
342*f6dc9357SAndroid Build Coastguard Worker         Add_UInt64(s, "skip-frames", p->num_SkipFrames);
343*f6dc9357SAndroid Build Coastguard Worker         Add_UInt64(s, "skip-frames-size-total", p->skipFrames_Size);
344*f6dc9357SAndroid Build Coastguard Worker       }
345*f6dc9357SAndroid Build Coastguard Worker 
346*f6dc9357SAndroid Build Coastguard Worker       if (p->are_ContentSize_Unknown)
347*f6dc9357SAndroid Build Coastguard Worker         s.Add_OptSpaced("unknown-content-size");
348*f6dc9357SAndroid Build Coastguard Worker 
349*f6dc9357SAndroid Build Coastguard Worker       if (DESCRIPTOR_Is_ContentSize_Defined(p->descriptor_OR))
350*f6dc9357SAndroid Build Coastguard Worker       {
351*f6dc9357SAndroid Build Coastguard Worker         Add_UInt64(s, "content-size-frame-max", p->contentSize_MAX);
352*f6dc9357SAndroid Build Coastguard Worker         Add_UInt64(s, "content-size-total", p->contentSize_Total);
353*f6dc9357SAndroid Build Coastguard Worker       }
354*f6dc9357SAndroid Build Coastguard Worker 
355*f6dc9357SAndroid Build Coastguard Worker       /*
356*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0; i < 4; i++)
357*f6dc9357SAndroid Build Coastguard Worker       {
358*f6dc9357SAndroid Build Coastguard Worker         const UInt64 n = p->num_Blocks_forType[i];
359*f6dc9357SAndroid Build Coastguard Worker         if (n)
360*f6dc9357SAndroid Build Coastguard Worker         {
361*f6dc9357SAndroid Build Coastguard Worker           s.Add_OptSpaced(kNames[i]);
362*f6dc9357SAndroid Build Coastguard Worker           s += "-blocks:";
363*f6dc9357SAndroid Build Coastguard Worker           s.Add_UInt64(n);
364*f6dc9357SAndroid Build Coastguard Worker 
365*f6dc9357SAndroid Build Coastguard Worker           s.Add_OptSpaced(kNames[i]);
366*f6dc9357SAndroid Build Coastguard Worker           s += "-block-bytes:";
367*f6dc9357SAndroid Build Coastguard Worker           s.Add_UInt64(p->num_BlockBytes_forType[i]);
368*f6dc9357SAndroid Build Coastguard Worker         }
369*f6dc9357SAndroid Build Coastguard Worker       }
370*f6dc9357SAndroid Build Coastguard Worker       */
371*f6dc9357SAndroid Build Coastguard Worker       prop = s;
372*f6dc9357SAndroid Build Coastguard Worker       break;
373*f6dc9357SAndroid Build Coastguard Worker     }
374*f6dc9357SAndroid Build Coastguard Worker 
375*f6dc9357SAndroid Build Coastguard Worker     case kpidErrorFlags:
376*f6dc9357SAndroid Build Coastguard Worker     {
377*f6dc9357SAndroid Build Coastguard Worker       UInt32 v = 0;
378*f6dc9357SAndroid Build Coastguard Worker       if (!_isArc)            v |= kpv_ErrorFlags_IsNotArc;
379*f6dc9357SAndroid Build Coastguard Worker       // if (_needMoreInput)     v |= kpv_ErrorFlags_UnexpectedEnd;
380*f6dc9357SAndroid Build Coastguard Worker       // if (_dataAfterEnd)      v |= kpv_ErrorFlags_DataAfterEnd;
381*f6dc9357SAndroid Build Coastguard Worker       if (_unsupportedBlock)  v |= kpv_ErrorFlags_UnsupportedMethod;
382*f6dc9357SAndroid Build Coastguard Worker       /*
383*f6dc9357SAndroid Build Coastguard Worker       if (_parsed_Info.numBlocks_forType[kBlockType_Reserved])
384*f6dc9357SAndroid Build Coastguard Worker         v |= kpv_ErrorFlags_UnsupportedMethod;
385*f6dc9357SAndroid Build Coastguard Worker       */
386*f6dc9357SAndroid Build Coastguard Worker       prop = v;
387*f6dc9357SAndroid Build Coastguard Worker       break;
388*f6dc9357SAndroid Build Coastguard Worker     }
389*f6dc9357SAndroid Build Coastguard Worker 
390*f6dc9357SAndroid Build Coastguard Worker     default: break;
391*f6dc9357SAndroid Build Coastguard Worker   }
392*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
393*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
394*f6dc9357SAndroid Build Coastguard Worker }
395*f6dc9357SAndroid Build Coastguard Worker 
396*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetNumberOfItems (UInt32 * numItems))397*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
398*f6dc9357SAndroid Build Coastguard Worker {
399*f6dc9357SAndroid Build Coastguard Worker   *numItems = 1;
400*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
401*f6dc9357SAndroid Build Coastguard Worker }
402*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetProperty (UInt32,PROPID propID,PROPVARIANT * value))403*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value))
404*f6dc9357SAndroid Build Coastguard Worker {
405*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
406*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
407*f6dc9357SAndroid Build Coastguard Worker   {
408*f6dc9357SAndroid Build Coastguard Worker     case kpidPackSize:
409*f6dc9357SAndroid Build Coastguard Worker       if (_wasParsed)
410*f6dc9357SAndroid Build Coastguard Worker         prop = _phySize;
411*f6dc9357SAndroid Build Coastguard Worker       else if (_phySize_Decoded_Defined)
412*f6dc9357SAndroid Build Coastguard Worker         prop = _phySize_Decoded;
413*f6dc9357SAndroid Build Coastguard Worker       break;
414*f6dc9357SAndroid Build Coastguard Worker 
415*f6dc9357SAndroid Build Coastguard Worker     case kpidSize:
416*f6dc9357SAndroid Build Coastguard Worker       if (_wasParsed && !_parsed_Info.are_ContentSize_Unknown)
417*f6dc9357SAndroid Build Coastguard Worker         prop = _parsed_Info.contentSize_Total;
418*f6dc9357SAndroid Build Coastguard Worker       else if (_unpackSize_Defined)
419*f6dc9357SAndroid Build Coastguard Worker         prop = _unpackSize;
420*f6dc9357SAndroid Build Coastguard Worker       break;
421*f6dc9357SAndroid Build Coastguard Worker 
422*f6dc9357SAndroid Build Coastguard Worker     default: break;
423*f6dc9357SAndroid Build Coastguard Worker   }
424*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
425*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
426*f6dc9357SAndroid Build Coastguard Worker }
427*f6dc9357SAndroid Build Coastguard Worker 
428*f6dc9357SAndroid Build Coastguard Worker static const unsigned kSignatureSize = 4;
429*f6dc9357SAndroid Build Coastguard Worker static const Byte k_Signature[kSignatureSize] = { 0x28, 0xb5, 0x2f, 0xfd } ;
430*f6dc9357SAndroid Build Coastguard Worker 
431*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kDataFrameSignature32    = 0xfd2fb528;
432*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kSkipFrameSignature      = 0x184d2a50;
433*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kSkipFrameSignature_Mask = 0xfffffff0;
434*f6dc9357SAndroid Build Coastguard Worker 
435*f6dc9357SAndroid Build Coastguard Worker /*
436*f6dc9357SAndroid Build Coastguard Worker API_FUNC_static_IsArc IsArc_Zstd(const Byte *p, size_t size)
437*f6dc9357SAndroid Build Coastguard Worker {
438*f6dc9357SAndroid Build Coastguard Worker   if (size < kSignatureSize)
439*f6dc9357SAndroid Build Coastguard Worker     return k_IsArc_Res_NEED_MORE;
440*f6dc9357SAndroid Build Coastguard Worker   if (memcmp(p, k_Signature, kSignatureSize) != 0)
441*f6dc9357SAndroid Build Coastguard Worker   {
442*f6dc9357SAndroid Build Coastguard Worker     const UInt32 v = GetUi32(p);
443*f6dc9357SAndroid Build Coastguard Worker     if ((v & kSkipFrameSignature_Mask) != kSkipFrameSignature)
444*f6dc9357SAndroid Build Coastguard Worker       return k_IsArc_Res_NO;
445*f6dc9357SAndroid Build Coastguard Worker     return k_IsArc_Res_YES;
446*f6dc9357SAndroid Build Coastguard Worker   }
447*f6dc9357SAndroid Build Coastguard Worker   p += 4;
448*f6dc9357SAndroid Build Coastguard Worker   // return k_IsArc_Res_YES;
449*f6dc9357SAndroid Build Coastguard Worker }
450*f6dc9357SAndroid Build Coastguard Worker }
451*f6dc9357SAndroid Build Coastguard Worker */
452*f6dc9357SAndroid Build Coastguard Worker 
453*f6dc9357SAndroid Build Coastguard Worker // kBufSize must be >= (ZSTD_FRAMEHEADERSIZE_MAX = 18)
454*f6dc9357SAndroid Build Coastguard Worker // we use big buffer for fast parsing of worst case small blocks.
455*f6dc9357SAndroid Build Coastguard Worker static const unsigned kBufSize =
456*f6dc9357SAndroid Build Coastguard Worker      1 << 9;
457*f6dc9357SAndroid Build Coastguard Worker      // 1 << 14; // fastest in real file
458*f6dc9357SAndroid Build Coastguard Worker 
459*f6dc9357SAndroid Build Coastguard Worker struct CStreamBuffer
460*f6dc9357SAndroid Build Coastguard Worker {
461*f6dc9357SAndroid Build Coastguard Worker   unsigned pos;
462*f6dc9357SAndroid Build Coastguard Worker   unsigned lim;
463*f6dc9357SAndroid Build Coastguard Worker   IInStream *Stream;
464*f6dc9357SAndroid Build Coastguard Worker   UInt64 StreamOffset;
465*f6dc9357SAndroid Build Coastguard Worker   Byte buf[kBufSize];
466*f6dc9357SAndroid Build Coastguard Worker 
CStreamBufferNArchive::NZstd::CStreamBuffer467*f6dc9357SAndroid Build Coastguard Worker   CStreamBuffer():
468*f6dc9357SAndroid Build Coastguard Worker       pos(0),
469*f6dc9357SAndroid Build Coastguard Worker       lim(0),
470*f6dc9357SAndroid Build Coastguard Worker       StreamOffset(0)
471*f6dc9357SAndroid Build Coastguard Worker       {}
AvailNArchive::NZstd::CStreamBuffer472*f6dc9357SAndroid Build Coastguard Worker   unsigned Avail() const { return lim - pos; }
GetPtrNArchive::NZstd::CStreamBuffer473*f6dc9357SAndroid Build Coastguard Worker   const Byte *GetPtr() const { return &buf[pos]; }
GetCurOffsetNArchive::NZstd::CStreamBuffer474*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetCurOffset() const { return StreamOffset - Avail(); }
SkipInBufNArchive::NZstd::CStreamBuffer475*f6dc9357SAndroid Build Coastguard Worker   void SkipInBuf(UInt32 size) { pos += size; }
476*f6dc9357SAndroid Build Coastguard Worker   HRESULT Skip(UInt32 size);
477*f6dc9357SAndroid Build Coastguard Worker   HRESULT Read(unsigned num);
478*f6dc9357SAndroid Build Coastguard Worker };
479*f6dc9357SAndroid Build Coastguard Worker 
Skip(UInt32 size)480*f6dc9357SAndroid Build Coastguard Worker HRESULT CStreamBuffer::Skip(UInt32 size)
481*f6dc9357SAndroid Build Coastguard Worker {
482*f6dc9357SAndroid Build Coastguard Worker   unsigned rem = lim - pos;
483*f6dc9357SAndroid Build Coastguard Worker   if (rem != 0)
484*f6dc9357SAndroid Build Coastguard Worker   {
485*f6dc9357SAndroid Build Coastguard Worker     if (rem > size)
486*f6dc9357SAndroid Build Coastguard Worker       rem = size;
487*f6dc9357SAndroid Build Coastguard Worker     pos += rem;
488*f6dc9357SAndroid Build Coastguard Worker     size -= rem;
489*f6dc9357SAndroid Build Coastguard Worker     if (pos != lim)
490*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
491*f6dc9357SAndroid Build Coastguard Worker   }
492*f6dc9357SAndroid Build Coastguard Worker   if (size == 0)
493*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
494*f6dc9357SAndroid Build Coastguard Worker   return Stream->Seek(size, STREAM_SEEK_CUR, &StreamOffset);
495*f6dc9357SAndroid Build Coastguard Worker }
496*f6dc9357SAndroid Build Coastguard Worker 
Read(unsigned num)497*f6dc9357SAndroid Build Coastguard Worker HRESULT CStreamBuffer::Read(unsigned num)
498*f6dc9357SAndroid Build Coastguard Worker {
499*f6dc9357SAndroid Build Coastguard Worker   if (lim - pos >= num)
500*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
501*f6dc9357SAndroid Build Coastguard Worker   if (pos != 0)
502*f6dc9357SAndroid Build Coastguard Worker   {
503*f6dc9357SAndroid Build Coastguard Worker     lim -= pos;
504*f6dc9357SAndroid Build Coastguard Worker     memmove(buf, buf + pos, lim);
505*f6dc9357SAndroid Build Coastguard Worker     pos = 0;
506*f6dc9357SAndroid Build Coastguard Worker   }
507*f6dc9357SAndroid Build Coastguard Worker   size_t processed = kBufSize - ((unsigned)StreamOffset & (kBufSize - 1));
508*f6dc9357SAndroid Build Coastguard Worker   const unsigned avail = kBufSize - lim;
509*f6dc9357SAndroid Build Coastguard Worker   num -= lim;
510*f6dc9357SAndroid Build Coastguard Worker   if (avail < processed || processed < num)
511*f6dc9357SAndroid Build Coastguard Worker     processed = avail;
512*f6dc9357SAndroid Build Coastguard Worker   const HRESULT res = ReadStream(Stream, buf + lim, &processed);
513*f6dc9357SAndroid Build Coastguard Worker   StreamOffset += processed;
514*f6dc9357SAndroid Build Coastguard Worker   lim += (unsigned)processed;
515*f6dc9357SAndroid Build Coastguard Worker   return res;
516*f6dc9357SAndroid Build Coastguard Worker }
517*f6dc9357SAndroid Build Coastguard Worker 
518*f6dc9357SAndroid Build Coastguard Worker 
519*f6dc9357SAndroid Build Coastguard Worker static const unsigned k_ZSTD_FRAMEHEADERSIZE_MAX = 4 + 14;
520*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::Open (IInStream * stream,const UInt64 *,IArchiveOpenCallback * callback))521*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback))
522*f6dc9357SAndroid Build Coastguard Worker {
523*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
524*f6dc9357SAndroid Build Coastguard Worker   Close();
525*f6dc9357SAndroid Build Coastguard Worker 
526*f6dc9357SAndroid Build Coastguard Worker   CZstdDecInfo *p = &_parsed_Info;
527*f6dc9357SAndroid Build Coastguard Worker   // p->are_ContentSize_Unknown = False;
528*f6dc9357SAndroid Build Coastguard Worker   CStreamBuffer sb;
529*f6dc9357SAndroid Build Coastguard Worker   sb.Stream = stream;
530*f6dc9357SAndroid Build Coastguard Worker 
531*f6dc9357SAndroid Build Coastguard Worker   for (;;)
532*f6dc9357SAndroid Build Coastguard Worker   {
533*f6dc9357SAndroid Build Coastguard Worker     RINOK(sb.Read(k_ZSTD_FRAMEHEADERSIZE_MAX))
534*f6dc9357SAndroid Build Coastguard Worker     if (sb.Avail() < kSignatureSize)
535*f6dc9357SAndroid Build Coastguard Worker       break;
536*f6dc9357SAndroid Build Coastguard Worker 
537*f6dc9357SAndroid Build Coastguard Worker     if (callback && (ZstdDecInfo_GET_NUM_FRAMES(p) & 0xFFF) == 2)
538*f6dc9357SAndroid Build Coastguard Worker     {
539*f6dc9357SAndroid Build Coastguard Worker       const UInt64 numBytes = sb.GetCurOffset();
540*f6dc9357SAndroid Build Coastguard Worker       RINOK(callback->SetCompleted(NULL, &numBytes))
541*f6dc9357SAndroid Build Coastguard Worker     }
542*f6dc9357SAndroid Build Coastguard Worker 
543*f6dc9357SAndroid Build Coastguard Worker     const UInt32 v = GetUi32(sb.GetPtr());
544*f6dc9357SAndroid Build Coastguard Worker     if (v != kDataFrameSignature32)
545*f6dc9357SAndroid Build Coastguard Worker     {
546*f6dc9357SAndroid Build Coastguard Worker       if ((v & kSkipFrameSignature_Mask) != kSkipFrameSignature)
547*f6dc9357SAndroid Build Coastguard Worker         break;
548*f6dc9357SAndroid Build Coastguard Worker       _phySize = sb.GetCurOffset() + 8;
549*f6dc9357SAndroid Build Coastguard Worker       p->num_SkipFrames++;
550*f6dc9357SAndroid Build Coastguard Worker       sb.SkipInBuf(4);
551*f6dc9357SAndroid Build Coastguard Worker       if (sb.Avail() < 4)
552*f6dc9357SAndroid Build Coastguard Worker         break;
553*f6dc9357SAndroid Build Coastguard Worker       const UInt32 size = GetUi32(sb.GetPtr());
554*f6dc9357SAndroid Build Coastguard Worker       p->skipFrames_Size += size;
555*f6dc9357SAndroid Build Coastguard Worker       sb.SkipInBuf(4);
556*f6dc9357SAndroid Build Coastguard Worker       _phySize = sb.GetCurOffset() + size;
557*f6dc9357SAndroid Build Coastguard Worker       RINOK(sb.Skip(size))
558*f6dc9357SAndroid Build Coastguard Worker       continue;
559*f6dc9357SAndroid Build Coastguard Worker     }
560*f6dc9357SAndroid Build Coastguard Worker 
561*f6dc9357SAndroid Build Coastguard Worker     p->num_DataFrames++;
562*f6dc9357SAndroid Build Coastguard Worker     // _numStreams_Defined = true;
563*f6dc9357SAndroid Build Coastguard Worker     sb.SkipInBuf(4);
564*f6dc9357SAndroid Build Coastguard Worker     CFrameHeader fh;
565*f6dc9357SAndroid Build Coastguard Worker     {
566*f6dc9357SAndroid Build Coastguard Worker       const Byte *data = fh.Parse(sb.GetPtr(), (int)sb.Avail());
567*f6dc9357SAndroid Build Coastguard Worker       if (!data)
568*f6dc9357SAndroid Build Coastguard Worker       {
569*f6dc9357SAndroid Build Coastguard Worker         // _needMoreInput = true;
570*f6dc9357SAndroid Build Coastguard Worker         // we set size for one byte more to show that stream was truncated
571*f6dc9357SAndroid Build Coastguard Worker         _phySize = sb.StreamOffset + 1;
572*f6dc9357SAndroid Build Coastguard Worker         break;
573*f6dc9357SAndroid Build Coastguard Worker       }
574*f6dc9357SAndroid Build Coastguard Worker       if (fh.Is_Reserved())
575*f6dc9357SAndroid Build Coastguard Worker       {
576*f6dc9357SAndroid Build Coastguard Worker         // we don't want false detection
577*f6dc9357SAndroid Build Coastguard Worker         if (ZstdDecInfo_GET_NUM_FRAMES(p) == 1)
578*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
579*f6dc9357SAndroid Build Coastguard Worker         // _phySize = sb.GetCurOffset();
580*f6dc9357SAndroid Build Coastguard Worker         break;
581*f6dc9357SAndroid Build Coastguard Worker       }
582*f6dc9357SAndroid Build Coastguard Worker       sb.SkipInBuf((unsigned)(data - sb.GetPtr()));
583*f6dc9357SAndroid Build Coastguard Worker     }
584*f6dc9357SAndroid Build Coastguard Worker 
585*f6dc9357SAndroid Build Coastguard Worker     p->descriptor_OR     = (Byte)(p->descriptor_OR     |  fh.Descriptor);
586*f6dc9357SAndroid Build Coastguard Worker     p->descriptor_NOT_OR = (Byte)(p->descriptor_NOT_OR | ~fh.Descriptor);
587*f6dc9357SAndroid Build Coastguard Worker 
588*f6dc9357SAndroid Build Coastguard Worker     // _numBlocks_Defined = true;
589*f6dc9357SAndroid Build Coastguard Worker     // if (fh.Get_DictionaryId_Flag())
590*f6dc9357SAndroid Build Coastguard Worker     // p->dictionaryId_Cur = fh.DictionaryId;
591*f6dc9357SAndroid Build Coastguard Worker     if (fh.DictionaryId != 0)
592*f6dc9357SAndroid Build Coastguard Worker     {
593*f6dc9357SAndroid Build Coastguard Worker       if (p->dictionaryId == 0)
594*f6dc9357SAndroid Build Coastguard Worker         p->dictionaryId = fh.DictionaryId;
595*f6dc9357SAndroid Build Coastguard Worker       else if (p->dictionaryId != fh.DictionaryId)
596*f6dc9357SAndroid Build Coastguard Worker         p->are_DictionaryId_Different = True;
597*f6dc9357SAndroid Build Coastguard Worker     }
598*f6dc9357SAndroid Build Coastguard Worker 
599*f6dc9357SAndroid Build Coastguard Worker     UInt32 blockSizeAllowedMax = (UInt32)1 << 17;
600*f6dc9357SAndroid Build Coastguard Worker     {
601*f6dc9357SAndroid Build Coastguard Worker       UInt64 winSize = fh.ContentSize;
602*f6dc9357SAndroid Build Coastguard Worker       UInt64 winSize_forAllocate = fh.ContentSize;
603*f6dc9357SAndroid Build Coastguard Worker       if (!fh.Is_SingleSegment())
604*f6dc9357SAndroid Build Coastguard Worker       {
605*f6dc9357SAndroid Build Coastguard Worker         if (p->windowDescriptor_MAX < fh.WindowDescriptor)
606*f6dc9357SAndroid Build Coastguard Worker             p->windowDescriptor_MAX = fh.WindowDescriptor;
607*f6dc9357SAndroid Build Coastguard Worker         const unsigned e = (fh.WindowDescriptor >> 3);
608*f6dc9357SAndroid Build Coastguard Worker         const unsigned m = (fh.WindowDescriptor & 7);
609*f6dc9357SAndroid Build Coastguard Worker         winSize = (UInt64)(8 + m) << (e + 10 - 3);
610*f6dc9357SAndroid Build Coastguard Worker         if (!fh.Is_ContentSize_Defined()
611*f6dc9357SAndroid Build Coastguard Worker             || fh.DictionaryId != 0
612*f6dc9357SAndroid Build Coastguard Worker             || winSize_forAllocate > winSize)
613*f6dc9357SAndroid Build Coastguard Worker           winSize_forAllocate = winSize;
614*f6dc9357SAndroid Build Coastguard Worker         // p->are_WindowDescriptors = true;
615*f6dc9357SAndroid Build Coastguard Worker       }
616*f6dc9357SAndroid Build Coastguard Worker       else
617*f6dc9357SAndroid Build Coastguard Worker       {
618*f6dc9357SAndroid Build Coastguard Worker         // p->are_SingleSegments = True;
619*f6dc9357SAndroid Build Coastguard Worker       }
620*f6dc9357SAndroid Build Coastguard Worker       if (blockSizeAllowedMax > winSize)
621*f6dc9357SAndroid Build Coastguard Worker           blockSizeAllowedMax = (UInt32)winSize;
622*f6dc9357SAndroid Build Coastguard Worker       if (p->windowSize_MAX < winSize)
623*f6dc9357SAndroid Build Coastguard Worker           p->windowSize_MAX = winSize;
624*f6dc9357SAndroid Build Coastguard Worker       if (p->windowSize_Allocate_MAX < winSize_forAllocate)
625*f6dc9357SAndroid Build Coastguard Worker           p->windowSize_Allocate_MAX = winSize_forAllocate;
626*f6dc9357SAndroid Build Coastguard Worker     }
627*f6dc9357SAndroid Build Coastguard Worker 
628*f6dc9357SAndroid Build Coastguard Worker     if (fh.Is_ContentSize_Defined())
629*f6dc9357SAndroid Build Coastguard Worker     {
630*f6dc9357SAndroid Build Coastguard Worker       // p->are_ContentSize_Known = True;
631*f6dc9357SAndroid Build Coastguard Worker       p->contentSize_Total += fh.ContentSize;
632*f6dc9357SAndroid Build Coastguard Worker       if (p->contentSize_MAX < fh.ContentSize)
633*f6dc9357SAndroid Build Coastguard Worker           p->contentSize_MAX = fh.ContentSize;
634*f6dc9357SAndroid Build Coastguard Worker     }
635*f6dc9357SAndroid Build Coastguard Worker     else
636*f6dc9357SAndroid Build Coastguard Worker     {
637*f6dc9357SAndroid Build Coastguard Worker       p->are_ContentSize_Unknown = True;
638*f6dc9357SAndroid Build Coastguard Worker     }
639*f6dc9357SAndroid Build Coastguard Worker 
640*f6dc9357SAndroid Build Coastguard Worker     p->checksum_Defined = false;
641*f6dc9357SAndroid Build Coastguard Worker 
642*f6dc9357SAndroid Build Coastguard Worker     // p->numBlocks_forType[3] += 99; // for debug
643*f6dc9357SAndroid Build Coastguard Worker 
644*f6dc9357SAndroid Build Coastguard Worker     if (!_parseMode)
645*f6dc9357SAndroid Build Coastguard Worker     {
646*f6dc9357SAndroid Build Coastguard Worker       if (ZstdDecInfo_GET_NUM_FRAMES(p) == 1)
647*f6dc9357SAndroid Build Coastguard Worker         break;
648*f6dc9357SAndroid Build Coastguard Worker     }
649*f6dc9357SAndroid Build Coastguard Worker 
650*f6dc9357SAndroid Build Coastguard Worker     _wasParsed = true;
651*f6dc9357SAndroid Build Coastguard Worker 
652*f6dc9357SAndroid Build Coastguard Worker     bool blocksWereParsed = false;
653*f6dc9357SAndroid Build Coastguard Worker 
654*f6dc9357SAndroid Build Coastguard Worker     for (;;)
655*f6dc9357SAndroid Build Coastguard Worker     {
656*f6dc9357SAndroid Build Coastguard Worker       if (callback && (p->num_Blocks & 0xFFF) == 2)
657*f6dc9357SAndroid Build Coastguard Worker       {
658*f6dc9357SAndroid Build Coastguard Worker         // Sleep(10);
659*f6dc9357SAndroid Build Coastguard Worker         const UInt64 numBytes = sb.GetCurOffset();
660*f6dc9357SAndroid Build Coastguard Worker         RINOK(callback->SetCompleted(NULL, &numBytes))
661*f6dc9357SAndroid Build Coastguard Worker       }
662*f6dc9357SAndroid Build Coastguard Worker       _phySize = sb.GetCurOffset() + 3;
663*f6dc9357SAndroid Build Coastguard Worker       RINOK(sb.Read(3))
664*f6dc9357SAndroid Build Coastguard Worker       if (sb.Avail() < 3)
665*f6dc9357SAndroid Build Coastguard Worker       {
666*f6dc9357SAndroid Build Coastguard Worker         // _needMoreInput = true;
667*f6dc9357SAndroid Build Coastguard Worker         // return S_FALSE;
668*f6dc9357SAndroid Build Coastguard Worker         break; // change it
669*f6dc9357SAndroid Build Coastguard Worker       }
670*f6dc9357SAndroid Build Coastguard Worker       const unsigned pos = sb.pos;
671*f6dc9357SAndroid Build Coastguard Worker       sb.pos = pos + 3;
672*f6dc9357SAndroid Build Coastguard Worker       UInt32 b = 0;
673*f6dc9357SAndroid Build Coastguard Worker       b += (UInt32)sb.buf[pos];
674*f6dc9357SAndroid Build Coastguard Worker       b += (UInt32)sb.buf[pos + 1] << (8 * 1);
675*f6dc9357SAndroid Build Coastguard Worker       b += (UInt32)sb.buf[pos + 2] << (8 * 2);
676*f6dc9357SAndroid Build Coastguard Worker       p->num_Blocks++;
677*f6dc9357SAndroid Build Coastguard Worker       const unsigned blockType = (b >> 1) & 3;
678*f6dc9357SAndroid Build Coastguard Worker       UInt32 size = b >> 3;
679*f6dc9357SAndroid Build Coastguard Worker       // p->num_Blocks_forType[blockType]++;
680*f6dc9357SAndroid Build Coastguard Worker       // p->num_BlockBytes_forType[blockType] += size;
681*f6dc9357SAndroid Build Coastguard Worker       if (size > blockSizeAllowedMax
682*f6dc9357SAndroid Build Coastguard Worker           || blockType == kBlockType_Reserved)
683*f6dc9357SAndroid Build Coastguard Worker       {
684*f6dc9357SAndroid Build Coastguard Worker         _unsupportedBlock = true;
685*f6dc9357SAndroid Build Coastguard Worker         if (ZstdDecInfo_GET_NUM_FRAMES(p) == 1 && p->num_Blocks == 1)
686*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
687*f6dc9357SAndroid Build Coastguard Worker         break;
688*f6dc9357SAndroid Build Coastguard Worker       }
689*f6dc9357SAndroid Build Coastguard Worker       if (blockType == kBlockType_RLE)
690*f6dc9357SAndroid Build Coastguard Worker         size = 1;
691*f6dc9357SAndroid Build Coastguard Worker       _phySize = sb.GetCurOffset() + size;
692*f6dc9357SAndroid Build Coastguard Worker       RINOK(sb.Skip(size))
693*f6dc9357SAndroid Build Coastguard Worker       if (b & 1)
694*f6dc9357SAndroid Build Coastguard Worker       {
695*f6dc9357SAndroid Build Coastguard Worker         // it's last block
696*f6dc9357SAndroid Build Coastguard Worker         blocksWereParsed = true;
697*f6dc9357SAndroid Build Coastguard Worker         break;
698*f6dc9357SAndroid Build Coastguard Worker       }
699*f6dc9357SAndroid Build Coastguard Worker     }
700*f6dc9357SAndroid Build Coastguard Worker 
701*f6dc9357SAndroid Build Coastguard Worker     if (!blocksWereParsed)
702*f6dc9357SAndroid Build Coastguard Worker       break;
703*f6dc9357SAndroid Build Coastguard Worker 
704*f6dc9357SAndroid Build Coastguard Worker     if (fh.Is_Checksum())
705*f6dc9357SAndroid Build Coastguard Worker     {
706*f6dc9357SAndroid Build Coastguard Worker       _phySize = sb.GetCurOffset() + 4;
707*f6dc9357SAndroid Build Coastguard Worker       RINOK(sb.Read(4))
708*f6dc9357SAndroid Build Coastguard Worker       if (sb.Avail() < 4)
709*f6dc9357SAndroid Build Coastguard Worker         break;
710*f6dc9357SAndroid Build Coastguard Worker       p->checksum_Defined = true;
711*f6dc9357SAndroid Build Coastguard Worker       // if (p->num_DataFrames == 1)
712*f6dc9357SAndroid Build Coastguard Worker       p->checksum = GetUi32(sb.GetPtr());
713*f6dc9357SAndroid Build Coastguard Worker       sb.SkipInBuf(4);
714*f6dc9357SAndroid Build Coastguard Worker     }
715*f6dc9357SAndroid Build Coastguard Worker   }
716*f6dc9357SAndroid Build Coastguard Worker 
717*f6dc9357SAndroid Build Coastguard Worker   if (ZstdDecInfo_GET_NUM_FRAMES(p) == 0)
718*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
719*f6dc9357SAndroid Build Coastguard Worker 
720*f6dc9357SAndroid Build Coastguard Worker   _needSeekToStart = true;
721*f6dc9357SAndroid Build Coastguard Worker   // } // _parseMode
722*f6dc9357SAndroid Build Coastguard Worker   _isArc = true;
723*f6dc9357SAndroid Build Coastguard Worker   _stream = stream;
724*f6dc9357SAndroid Build Coastguard Worker   _seqStream = stream;
725*f6dc9357SAndroid Build Coastguard Worker 
726*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
727*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
728*f6dc9357SAndroid Build Coastguard Worker }
729*f6dc9357SAndroid Build Coastguard Worker 
730*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::OpenSeq (ISequentialInStream * stream))731*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream))
732*f6dc9357SAndroid Build Coastguard Worker {
733*f6dc9357SAndroid Build Coastguard Worker   Close();
734*f6dc9357SAndroid Build Coastguard Worker   _isArc = true;
735*f6dc9357SAndroid Build Coastguard Worker   _seqStream = stream;
736*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
737*f6dc9357SAndroid Build Coastguard Worker }
738*f6dc9357SAndroid Build Coastguard Worker 
739*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::Close ())740*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
741*f6dc9357SAndroid Build Coastguard Worker {
742*f6dc9357SAndroid Build Coastguard Worker   _isArc = false;
743*f6dc9357SAndroid Build Coastguard Worker   _needSeekToStart = false;
744*f6dc9357SAndroid Build Coastguard Worker   // _dataAfterEnd = false;
745*f6dc9357SAndroid Build Coastguard Worker   // _needMoreInput = false;
746*f6dc9357SAndroid Build Coastguard Worker   _unsupportedBlock = false;
747*f6dc9357SAndroid Build Coastguard Worker 
748*f6dc9357SAndroid Build Coastguard Worker   _wasParsed = false;
749*f6dc9357SAndroid Build Coastguard Worker   _phySize_Decoded_Defined = false;
750*f6dc9357SAndroid Build Coastguard Worker   _unpackSize_Defined = false;
751*f6dc9357SAndroid Build Coastguard Worker   _decoded_Info_Defined = false;
752*f6dc9357SAndroid Build Coastguard Worker 
753*f6dc9357SAndroid Build Coastguard Worker   ZstdDecInfo_CLEAR(&_parsed_Info)
754*f6dc9357SAndroid Build Coastguard Worker   ZstdDecInfo_CLEAR(&_decoded_Info)
755*f6dc9357SAndroid Build Coastguard Worker 
756*f6dc9357SAndroid Build Coastguard Worker   _phySize = 0;
757*f6dc9357SAndroid Build Coastguard Worker   _phySize_Decoded = 0;
758*f6dc9357SAndroid Build Coastguard Worker   _unpackSize = 0;
759*f6dc9357SAndroid Build Coastguard Worker 
760*f6dc9357SAndroid Build Coastguard Worker   _seqStream.Release();
761*f6dc9357SAndroid Build Coastguard Worker   _stream.Release();
762*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
763*f6dc9357SAndroid Build Coastguard Worker }
764*f6dc9357SAndroid Build Coastguard Worker 
765*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::Extract (const UInt32 * indices,UInt32 numItems,Int32 testMode,IArchiveExtractCallback * extractCallback))766*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
767*f6dc9357SAndroid Build Coastguard Worker   Int32 testMode, IArchiveExtractCallback *extractCallback))
768*f6dc9357SAndroid Build Coastguard Worker {
769*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
770*f6dc9357SAndroid Build Coastguard Worker   if (numItems == 0)
771*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
772*f6dc9357SAndroid Build Coastguard Worker   if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
773*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
774*f6dc9357SAndroid Build Coastguard Worker   if (_wasParsed)
775*f6dc9357SAndroid Build Coastguard Worker   {
776*f6dc9357SAndroid Build Coastguard Worker     RINOK(extractCallback->SetTotal(_phySize))
777*f6dc9357SAndroid Build Coastguard Worker   }
778*f6dc9357SAndroid Build Coastguard Worker 
779*f6dc9357SAndroid Build Coastguard Worker   Int32 opRes;
780*f6dc9357SAndroid Build Coastguard Worker   {
781*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ISequentialOutStream> realOutStream;
782*f6dc9357SAndroid Build Coastguard Worker     const Int32 askMode = testMode ?
783*f6dc9357SAndroid Build Coastguard Worker         NExtract::NAskMode::kTest :
784*f6dc9357SAndroid Build Coastguard Worker         NExtract::NAskMode::kExtract;
785*f6dc9357SAndroid Build Coastguard Worker     RINOK(extractCallback->GetStream(0, &realOutStream, askMode))
786*f6dc9357SAndroid Build Coastguard Worker     if (!testMode && !realOutStream)
787*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
788*f6dc9357SAndroid Build Coastguard Worker 
789*f6dc9357SAndroid Build Coastguard Worker     extractCallback->PrepareOperation(askMode);
790*f6dc9357SAndroid Build Coastguard Worker 
791*f6dc9357SAndroid Build Coastguard Worker     if (_needSeekToStart)
792*f6dc9357SAndroid Build Coastguard Worker     {
793*f6dc9357SAndroid Build Coastguard Worker       if (!_stream)
794*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
795*f6dc9357SAndroid Build Coastguard Worker       RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL))
796*f6dc9357SAndroid Build Coastguard Worker     }
797*f6dc9357SAndroid Build Coastguard Worker     else
798*f6dc9357SAndroid Build Coastguard Worker       _needSeekToStart = true;
799*f6dc9357SAndroid Build Coastguard Worker 
800*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
801*f6dc9357SAndroid Build Coastguard Worker     lps->Init(extractCallback, true);
802*f6dc9357SAndroid Build Coastguard Worker 
803*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_ORIG_DECODER
804*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr2_Create<ICompressCoder, NCompress::NZstd2::CDecoder> decoder;
805*f6dc9357SAndroid Build Coastguard Worker #else
806*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr2_Create<ICompressCoder, NCompress::NZstd::CDecoder> decoder;
807*f6dc9357SAndroid Build Coastguard Worker #endif
808*f6dc9357SAndroid Build Coastguard Worker 
809*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr2_Create<ISequentialOutStream, CDummyOutStream> outStreamSpec;
810*f6dc9357SAndroid Build Coastguard Worker     outStreamSpec->SetStream(realOutStream);
811*f6dc9357SAndroid Build Coastguard Worker     outStreamSpec->Init();
812*f6dc9357SAndroid Build Coastguard Worker     // realOutStream.Release();
813*f6dc9357SAndroid Build Coastguard Worker 
814*f6dc9357SAndroid Build Coastguard Worker     decoder->FinishMode = true;
815*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_USE_ZSTD_ORIG_DECODER
816*f6dc9357SAndroid Build Coastguard Worker     decoder->DisableHash = _disableHash;
817*f6dc9357SAndroid Build Coastguard Worker #endif
818*f6dc9357SAndroid Build Coastguard Worker 
819*f6dc9357SAndroid Build Coastguard Worker     // _dataAfterEnd = false;
820*f6dc9357SAndroid Build Coastguard Worker     // _needMoreInput = false;
821*f6dc9357SAndroid Build Coastguard Worker     const HRESULT hres = decoder.Interface()->Code(_seqStream, outStreamSpec, NULL, NULL, lps);
822*f6dc9357SAndroid Build Coastguard Worker     /*
823*f6dc9357SAndroid Build Coastguard Worker     {
824*f6dc9357SAndroid Build Coastguard Worker       UInt64 t1 = decoder->GetInputProcessedSize();
825*f6dc9357SAndroid Build Coastguard Worker       // for debug
826*f6dc9357SAndroid Build Coastguard Worker       const UInt32 kTempSize = 64;
827*f6dc9357SAndroid Build Coastguard Worker       Byte buf[kTempSize];
828*f6dc9357SAndroid Build Coastguard Worker       UInt32 processedSize = 0;
829*f6dc9357SAndroid Build Coastguard Worker       RINOK(decoder->ReadUnusedFromInBuf(buf, kTempSize, &processedSize))
830*f6dc9357SAndroid Build Coastguard Worker       processedSize -= processedSize;
831*f6dc9357SAndroid Build Coastguard Worker       UInt64 t2 = decoder->GetInputProcessedSize();
832*f6dc9357SAndroid Build Coastguard Worker       t2 = t2;
833*f6dc9357SAndroid Build Coastguard Worker       t1 = t1;
834*f6dc9357SAndroid Build Coastguard Worker     }
835*f6dc9357SAndroid Build Coastguard Worker     */
836*f6dc9357SAndroid Build Coastguard Worker     const UInt64 outSize = outStreamSpec->GetSize();
837*f6dc9357SAndroid Build Coastguard Worker   // }
838*f6dc9357SAndroid Build Coastguard Worker 
839*f6dc9357SAndroid Build Coastguard Worker     // if (hres == E_ABORT) return hres;
840*f6dc9357SAndroid Build Coastguard Worker     opRes = NExtract::NOperationResult::kDataError;
841*f6dc9357SAndroid Build Coastguard Worker 
842*f6dc9357SAndroid Build Coastguard Worker     if (hres == E_OUTOFMEMORY)
843*f6dc9357SAndroid Build Coastguard Worker     {
844*f6dc9357SAndroid Build Coastguard Worker       return hres;
845*f6dc9357SAndroid Build Coastguard Worker       // opRes = NExtract::NOperationResult::kMemError;
846*f6dc9357SAndroid Build Coastguard Worker     }
847*f6dc9357SAndroid Build Coastguard Worker     else if (hres == S_OK || hres == S_FALSE)
848*f6dc9357SAndroid Build Coastguard Worker     {
849*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_USE_ZSTD_ORIG_DECODER
850*f6dc9357SAndroid Build Coastguard Worker       _decoded_Info_Defined = true;
851*f6dc9357SAndroid Build Coastguard Worker       _decoded_Info = decoder->_state.info;
852*f6dc9357SAndroid Build Coastguard Worker       // NumDataFrames_Decoded = decoder->_state.info.num_DataFrames;
853*f6dc9357SAndroid Build Coastguard Worker       // NumSkipFrames_Decoded = decoder->_state.info.num_SkipFrames;
854*f6dc9357SAndroid Build Coastguard Worker       const UInt64 inSize = decoder->_inProcessed;
855*f6dc9357SAndroid Build Coastguard Worker #else
856*f6dc9357SAndroid Build Coastguard Worker       const UInt64 inSize = decoder->GetInputProcessedSize();
857*f6dc9357SAndroid Build Coastguard Worker #endif
858*f6dc9357SAndroid Build Coastguard Worker       _phySize_Decoded = inSize;
859*f6dc9357SAndroid Build Coastguard Worker       _phySize_Decoded_Defined = true;
860*f6dc9357SAndroid Build Coastguard Worker 
861*f6dc9357SAndroid Build Coastguard Worker       _unpackSize_Defined = true;
862*f6dc9357SAndroid Build Coastguard Worker       _unpackSize = outSize;
863*f6dc9357SAndroid Build Coastguard Worker 
864*f6dc9357SAndroid Build Coastguard Worker       // RINOK(
865*f6dc9357SAndroid Build Coastguard Worker       lps.Interface()->SetRatioInfo(&inSize, &outSize);
866*f6dc9357SAndroid Build Coastguard Worker 
867*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_ORIG_DECODER
868*f6dc9357SAndroid Build Coastguard Worker       if (hres == S_OK)
869*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kOK;
870*f6dc9357SAndroid Build Coastguard Worker #else
871*f6dc9357SAndroid Build Coastguard Worker       if (decoder->ResInfo.decode_SRes == SZ_ERROR_CRC)
872*f6dc9357SAndroid Build Coastguard Worker       {
873*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kCRCError;
874*f6dc9357SAndroid Build Coastguard Worker       }
875*f6dc9357SAndroid Build Coastguard Worker       else if (decoder->ResInfo.decode_SRes == SZ_ERROR_NO_ARCHIVE)
876*f6dc9357SAndroid Build Coastguard Worker       {
877*f6dc9357SAndroid Build Coastguard Worker         _isArc = false;
878*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kIsNotArc;
879*f6dc9357SAndroid Build Coastguard Worker       }
880*f6dc9357SAndroid Build Coastguard Worker       else if (decoder->ResInfo.decode_SRes == SZ_ERROR_INPUT_EOF)
881*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kUnexpectedEnd;
882*f6dc9357SAndroid Build Coastguard Worker       else
883*f6dc9357SAndroid Build Coastguard Worker       {
884*f6dc9357SAndroid Build Coastguard Worker         if (hres == S_OK && decoder->ResInfo.decode_SRes == SZ_OK)
885*f6dc9357SAndroid Build Coastguard Worker           opRes = NExtract::NOperationResult::kOK;
886*f6dc9357SAndroid Build Coastguard Worker         if (decoder->ResInfo.extraSize)
887*f6dc9357SAndroid Build Coastguard Worker         {
888*f6dc9357SAndroid Build Coastguard Worker           // if (inSize == 0) _isArc = false;
889*f6dc9357SAndroid Build Coastguard Worker           opRes = NExtract::NOperationResult::kDataAfterEnd;
890*f6dc9357SAndroid Build Coastguard Worker         }
891*f6dc9357SAndroid Build Coastguard Worker         /*
892*f6dc9357SAndroid Build Coastguard Worker         if (decoder->ResInfo.unexpededEnd)
893*f6dc9357SAndroid Build Coastguard Worker           opRes = NExtract::NOperationResult::kUnexpectedEnd;
894*f6dc9357SAndroid Build Coastguard Worker         */
895*f6dc9357SAndroid Build Coastguard Worker       }
896*f6dc9357SAndroid Build Coastguard Worker #endif
897*f6dc9357SAndroid Build Coastguard Worker     }
898*f6dc9357SAndroid Build Coastguard Worker     else if (hres == E_NOTIMPL)
899*f6dc9357SAndroid Build Coastguard Worker     {
900*f6dc9357SAndroid Build Coastguard Worker       opRes = NExtract::NOperationResult::kUnsupportedMethod;
901*f6dc9357SAndroid Build Coastguard Worker     }
902*f6dc9357SAndroid Build Coastguard Worker     else
903*f6dc9357SAndroid Build Coastguard Worker       return hres;
904*f6dc9357SAndroid Build Coastguard Worker   }
905*f6dc9357SAndroid Build Coastguard Worker 
906*f6dc9357SAndroid Build Coastguard Worker   return extractCallback->SetOperationResult(opRes);
907*f6dc9357SAndroid Build Coastguard Worker 
908*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
909*f6dc9357SAndroid Build Coastguard Worker }
910*f6dc9357SAndroid Build Coastguard Worker 
911*f6dc9357SAndroid Build Coastguard Worker 
912*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::SetProperties (const wchar_t * const * names,const PROPVARIANT * values,UInt32 numProps))913*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
914*f6dc9357SAndroid Build Coastguard Worker {
915*f6dc9357SAndroid Build Coastguard Worker   // return _props.SetProperties(names, values, numProps);
916*f6dc9357SAndroid Build Coastguard Worker   // _smallMode = false;
917*f6dc9357SAndroid Build Coastguard Worker   _disableHash = false;
918*f6dc9357SAndroid Build Coastguard Worker   _parseMode = false;
919*f6dc9357SAndroid Build Coastguard Worker   // _parseMode = true; // for debug
920*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_COMPRESSION
921*f6dc9357SAndroid Build Coastguard Worker   _props.Init();
922*f6dc9357SAndroid Build Coastguard Worker #endif
923*f6dc9357SAndroid Build Coastguard Worker 
924*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numProps; i++)
925*f6dc9357SAndroid Build Coastguard Worker   {
926*f6dc9357SAndroid Build Coastguard Worker     UString name = names[i];
927*f6dc9357SAndroid Build Coastguard Worker     const PROPVARIANT &value = values[i];
928*f6dc9357SAndroid Build Coastguard Worker 
929*f6dc9357SAndroid Build Coastguard Worker     if (name.IsEqualTo("parse"))
930*f6dc9357SAndroid Build Coastguard Worker     {
931*f6dc9357SAndroid Build Coastguard Worker       bool parseMode = true;
932*f6dc9357SAndroid Build Coastguard Worker       RINOK(PROPVARIANT_to_bool(value, parseMode))
933*f6dc9357SAndroid Build Coastguard Worker         _parseMode = parseMode;
934*f6dc9357SAndroid Build Coastguard Worker       continue;
935*f6dc9357SAndroid Build Coastguard Worker     }
936*f6dc9357SAndroid Build Coastguard Worker     if (name.IsPrefixedBy_Ascii_NoCase("crc"))
937*f6dc9357SAndroid Build Coastguard Worker     {
938*f6dc9357SAndroid Build Coastguard Worker       name.Delete(0, 3);
939*f6dc9357SAndroid Build Coastguard Worker       UInt32 crcSize = 4;
940*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParsePropToUInt32(name, value, crcSize))
941*f6dc9357SAndroid Build Coastguard Worker       if (crcSize == 0)
942*f6dc9357SAndroid Build Coastguard Worker         _disableHash = true;
943*f6dc9357SAndroid Build Coastguard Worker       else if (crcSize == 4)
944*f6dc9357SAndroid Build Coastguard Worker         _disableHash = false;
945*f6dc9357SAndroid Build Coastguard Worker       else
946*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
947*f6dc9357SAndroid Build Coastguard Worker       continue;
948*f6dc9357SAndroid Build Coastguard Worker     }
949*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_COMPRESSION
950*f6dc9357SAndroid Build Coastguard Worker     /*
951*f6dc9357SAndroid Build Coastguard Worker     if (name.IsEqualTo("small"))
952*f6dc9357SAndroid Build Coastguard Worker     {
953*f6dc9357SAndroid Build Coastguard Worker       bool smallMode = true;
954*f6dc9357SAndroid Build Coastguard Worker       RINOK(PROPVARIANT_to_bool(value, smallMode))
955*f6dc9357SAndroid Build Coastguard Worker       _smallMode = smallMode;
956*f6dc9357SAndroid Build Coastguard Worker       continue;
957*f6dc9357SAndroid Build Coastguard Worker     }
958*f6dc9357SAndroid Build Coastguard Worker     */
959*f6dc9357SAndroid Build Coastguard Worker     RINOK(_props.SetProperty(names[i], value))
960*f6dc9357SAndroid Build Coastguard Worker #endif
961*f6dc9357SAndroid Build Coastguard Worker   }
962*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
963*f6dc9357SAndroid Build Coastguard Worker }
964*f6dc9357SAndroid Build Coastguard Worker 
965*f6dc9357SAndroid Build Coastguard Worker 
966*f6dc9357SAndroid Build Coastguard Worker 
967*f6dc9357SAndroid Build Coastguard Worker 
968*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_COMPRESSION
969*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetFileTimeType (UInt32 * timeType))970*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType))
971*f6dc9357SAndroid Build Coastguard Worker {
972*f6dc9357SAndroid Build Coastguard Worker   *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType;
973*f6dc9357SAndroid Build Coastguard Worker   // *timeType = NFileTimeType::kUnix;
974*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
975*f6dc9357SAndroid Build Coastguard Worker }
976*f6dc9357SAndroid Build Coastguard Worker 
977*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::UpdateItems (ISequentialOutStream * outStream,UInt32 numItems,IArchiveUpdateCallback * updateCallback))978*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
979*f6dc9357SAndroid Build Coastguard Worker     IArchiveUpdateCallback *updateCallback))
980*f6dc9357SAndroid Build Coastguard Worker {
981*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
982*f6dc9357SAndroid Build Coastguard Worker 
983*f6dc9357SAndroid Build Coastguard Worker   if (numItems != 1)
984*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
985*f6dc9357SAndroid Build Coastguard Worker   {
986*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IStreamSetRestriction> setRestriction;
987*f6dc9357SAndroid Build Coastguard Worker     outStream->QueryInterface(IID_IStreamSetRestriction, (void **)&setRestriction);
988*f6dc9357SAndroid Build Coastguard Worker     if (setRestriction)
989*f6dc9357SAndroid Build Coastguard Worker       RINOK(setRestriction->SetRestriction(0, 0))
990*f6dc9357SAndroid Build Coastguard Worker   }
991*f6dc9357SAndroid Build Coastguard Worker   Int32 newData, newProps;
992*f6dc9357SAndroid Build Coastguard Worker   UInt32 indexInArchive;
993*f6dc9357SAndroid Build Coastguard Worker   if (!updateCallback)
994*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
995*f6dc9357SAndroid Build Coastguard Worker   RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive))
996*f6dc9357SAndroid Build Coastguard Worker 
997*f6dc9357SAndroid Build Coastguard Worker   if (IntToBool(newProps))
998*f6dc9357SAndroid Build Coastguard Worker   {
999*f6dc9357SAndroid Build Coastguard Worker     {
1000*f6dc9357SAndroid Build Coastguard Worker       NCOM::CPropVariant prop;
1001*f6dc9357SAndroid Build Coastguard Worker       RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop))
1002*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_EMPTY)
1003*f6dc9357SAndroid Build Coastguard Worker         if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE)
1004*f6dc9357SAndroid Build Coastguard Worker           return E_INVALIDARG;
1005*f6dc9357SAndroid Build Coastguard Worker     }
1006*f6dc9357SAndroid Build Coastguard Worker   }
1007*f6dc9357SAndroid Build Coastguard Worker 
1008*f6dc9357SAndroid Build Coastguard Worker   if (IntToBool(newData))
1009*f6dc9357SAndroid Build Coastguard Worker   {
1010*f6dc9357SAndroid Build Coastguard Worker     UInt64 size;
1011*f6dc9357SAndroid Build Coastguard Worker     {
1012*f6dc9357SAndroid Build Coastguard Worker       NCOM::CPropVariant prop;
1013*f6dc9357SAndroid Build Coastguard Worker       RINOK(updateCallback->GetProperty(0, kpidSize, &prop))
1014*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_UI8)
1015*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
1016*f6dc9357SAndroid Build Coastguard Worker       size = prop.uhVal.QuadPart;
1017*f6dc9357SAndroid Build Coastguard Worker     }
1018*f6dc9357SAndroid Build Coastguard Worker 
1019*f6dc9357SAndroid Build Coastguard Worker     if (!_props.MethodName.IsEmpty()
1020*f6dc9357SAndroid Build Coastguard Worker         && !_props.MethodName.IsEqualTo_Ascii_NoCase("zstd"))
1021*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
1022*f6dc9357SAndroid Build Coastguard Worker 
1023*f6dc9357SAndroid Build Coastguard Worker     {
1024*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ISequentialInStream> fileInStream;
1025*f6dc9357SAndroid Build Coastguard Worker       RINOK(updateCallback->GetStream(0, &fileInStream))
1026*f6dc9357SAndroid Build Coastguard Worker       if (!fileInStream)
1027*f6dc9357SAndroid Build Coastguard Worker         return S_FALSE;
1028*f6dc9357SAndroid Build Coastguard Worker       {
1029*f6dc9357SAndroid Build Coastguard Worker         CMyComPtr<IStreamGetSize> streamGetSize;
1030*f6dc9357SAndroid Build Coastguard Worker         fileInStream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
1031*f6dc9357SAndroid Build Coastguard Worker         if (streamGetSize)
1032*f6dc9357SAndroid Build Coastguard Worker         {
1033*f6dc9357SAndroid Build Coastguard Worker           UInt64 size2;
1034*f6dc9357SAndroid Build Coastguard Worker           if (streamGetSize->GetSize(&size2) == S_OK)
1035*f6dc9357SAndroid Build Coastguard Worker             size = size2;
1036*f6dc9357SAndroid Build Coastguard Worker         }
1037*f6dc9357SAndroid Build Coastguard Worker       }
1038*f6dc9357SAndroid Build Coastguard Worker       RINOK(updateCallback->SetTotal(size))
1039*f6dc9357SAndroid Build Coastguard Worker 
1040*f6dc9357SAndroid Build Coastguard Worker       CMethodProps props2 = _props;
1041*f6dc9357SAndroid Build Coastguard Worker 
1042*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1043*f6dc9357SAndroid Build Coastguard Worker       /*
1044*f6dc9357SAndroid Build Coastguard Worker       CSingleMethodProps (_props)
1045*f6dc9357SAndroid Build Coastguard Worker       derives from
1046*f6dc9357SAndroid Build Coastguard Worker       CMethodProps (props2)
1047*f6dc9357SAndroid Build Coastguard Worker       So we transfer additional variable (num Threads) to CMethodProps list of properties
1048*f6dc9357SAndroid Build Coastguard Worker       */
1049*f6dc9357SAndroid Build Coastguard Worker 
1050*f6dc9357SAndroid Build Coastguard Worker       UInt32 numThreads = _props._numThreads;
1051*f6dc9357SAndroid Build Coastguard Worker 
1052*f6dc9357SAndroid Build Coastguard Worker       if (numThreads > Z7_ZSTDMT_NBWORKERS_MAX)
1053*f6dc9357SAndroid Build Coastguard Worker           numThreads = Z7_ZSTDMT_NBWORKERS_MAX;
1054*f6dc9357SAndroid Build Coastguard Worker 
1055*f6dc9357SAndroid Build Coastguard Worker       if (_props.FindProp(NCoderPropID::kNumThreads) < 0)
1056*f6dc9357SAndroid Build Coastguard Worker       {
1057*f6dc9357SAndroid Build Coastguard Worker         if (!_props._numThreads_WasForced
1058*f6dc9357SAndroid Build Coastguard Worker             && numThreads >= 1
1059*f6dc9357SAndroid Build Coastguard Worker             && _props._memUsage_WasSet)
1060*f6dc9357SAndroid Build Coastguard Worker         {
1061*f6dc9357SAndroid Build Coastguard Worker           NCompress::NZstd::CEncoderProps zstdProps;
1062*f6dc9357SAndroid Build Coastguard Worker           RINOK(zstdProps.SetFromMethodProps(_props))
1063*f6dc9357SAndroid Build Coastguard Worker           ZstdEncProps_NormalizeFull(&zstdProps.EncProps);
1064*f6dc9357SAndroid Build Coastguard Worker           numThreads = ZstdEncProps_GetNumThreads_for_MemUsageLimit(
1065*f6dc9357SAndroid Build Coastguard Worker               &zstdProps.EncProps, _props._memUsage_Compress, numThreads);
1066*f6dc9357SAndroid Build Coastguard Worker         }
1067*f6dc9357SAndroid Build Coastguard Worker         props2.AddProp_NumThreads(numThreads);
1068*f6dc9357SAndroid Build Coastguard Worker       }
1069*f6dc9357SAndroid Build Coastguard Worker 
1070*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_ST
1071*f6dc9357SAndroid Build Coastguard Worker 
1072*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
1073*f6dc9357SAndroid Build Coastguard Worker       lps->Init(updateCallback, true);
1074*f6dc9357SAndroid Build Coastguard Worker       {
1075*f6dc9357SAndroid Build Coastguard Worker         CMyComPtr2_Create<ICompressCoder, NCompress::NZstd::CEncoder> encoder;
1076*f6dc9357SAndroid Build Coastguard Worker         // size = 1 << 24; // for debug
1077*f6dc9357SAndroid Build Coastguard Worker         RINOK(props2.SetCoderProps(encoder.ClsPtr(), size != (UInt64)(Int64)-1 ? &size : NULL))
1078*f6dc9357SAndroid Build Coastguard Worker         // encoderSpec->_props.SmallFileOpt = _smallMode;
1079*f6dc9357SAndroid Build Coastguard Worker         // we must set kExpectedDataSize just before Code().
1080*f6dc9357SAndroid Build Coastguard Worker         encoder->SrcSizeHint64 = size;
1081*f6dc9357SAndroid Build Coastguard Worker         /*
1082*f6dc9357SAndroid Build Coastguard Worker         CMyComPtr<ICompressSetCoderPropertiesOpt> optProps;
1083*f6dc9357SAndroid Build Coastguard Worker         _compressEncoder->QueryInterface(IID_ICompressSetCoderPropertiesOpt, (void**)&optProps);
1084*f6dc9357SAndroid Build Coastguard Worker         if (optProps)
1085*f6dc9357SAndroid Build Coastguard Worker         {
1086*f6dc9357SAndroid Build Coastguard Worker           PROPID propID = NCoderPropID::kExpectedDataSize;
1087*f6dc9357SAndroid Build Coastguard Worker           NWindows::NCOM::CPropVariant prop = (UInt64)size;
1088*f6dc9357SAndroid Build Coastguard Worker           // RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1))
1089*f6dc9357SAndroid Build Coastguard Worker           RINOK(encoderSpec->SetCoderPropertiesOpt(&propID, &prop, 1))
1090*f6dc9357SAndroid Build Coastguard Worker         }
1091*f6dc9357SAndroid Build Coastguard Worker         */
1092*f6dc9357SAndroid Build Coastguard Worker         RINOK(encoder.Interface()->Code(fileInStream, outStream, NULL, NULL, lps))
1093*f6dc9357SAndroid Build Coastguard Worker       }
1094*f6dc9357SAndroid Build Coastguard Worker     }
1095*f6dc9357SAndroid Build Coastguard Worker     return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
1096*f6dc9357SAndroid Build Coastguard Worker   }
1097*f6dc9357SAndroid Build Coastguard Worker 
1098*f6dc9357SAndroid Build Coastguard Worker   if (indexInArchive != 0)
1099*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
1100*f6dc9357SAndroid Build Coastguard Worker 
1101*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
1102*f6dc9357SAndroid Build Coastguard Worker   lps->Init(updateCallback, true);
1103*f6dc9357SAndroid Build Coastguard Worker 
1104*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
1105*f6dc9357SAndroid Build Coastguard Worker   updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
1106*f6dc9357SAndroid Build Coastguard Worker   if (opCallback)
1107*f6dc9357SAndroid Build Coastguard Worker   {
1108*f6dc9357SAndroid Build Coastguard Worker     RINOK(opCallback->ReportOperation(
1109*f6dc9357SAndroid Build Coastguard Worker         NEventIndexType::kInArcIndex, 0,
1110*f6dc9357SAndroid Build Coastguard Worker         NUpdateNotifyOp::kReplicate))
1111*f6dc9357SAndroid Build Coastguard Worker   }
1112*f6dc9357SAndroid Build Coastguard Worker 
1113*f6dc9357SAndroid Build Coastguard Worker   if (_stream)
1114*f6dc9357SAndroid Build Coastguard Worker     RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL))
1115*f6dc9357SAndroid Build Coastguard Worker 
1116*f6dc9357SAndroid Build Coastguard Worker   return NCompress::CopyStream(_stream, outStream, lps);
1117*f6dc9357SAndroid Build Coastguard Worker 
1118*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
1119*f6dc9357SAndroid Build Coastguard Worker }
1120*f6dc9357SAndroid Build Coastguard Worker #endif
1121*f6dc9357SAndroid Build Coastguard Worker 
1122*f6dc9357SAndroid Build Coastguard Worker 
1123*f6dc9357SAndroid Build Coastguard Worker 
1124*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_USE_ZSTD_COMPRESSION
1125*f6dc9357SAndroid Build Coastguard Worker #undef  IMP_CreateArcOut
1126*f6dc9357SAndroid Build Coastguard Worker #define IMP_CreateArcOut
1127*f6dc9357SAndroid Build Coastguard Worker #undef  CreateArcOut
1128*f6dc9357SAndroid Build Coastguard Worker #define CreateArcOut NULL
1129*f6dc9357SAndroid Build Coastguard Worker #endif
1130*f6dc9357SAndroid Build Coastguard Worker 
1131*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_ZSTD_COMPRESSION
1132*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_IO(
1133*f6dc9357SAndroid Build Coastguard Worker   "zstd2", "zst tzst", "* .tar", 0xe + 1,
1134*f6dc9357SAndroid Build Coastguard Worker   k_Signature, 0
1135*f6dc9357SAndroid Build Coastguard Worker   , NArcInfoFlags::kKeepName
1136*f6dc9357SAndroid Build Coastguard Worker   , 0
1137*f6dc9357SAndroid Build Coastguard Worker   , NULL)
1138*f6dc9357SAndroid Build Coastguard Worker #else
1139*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_IO(
1140*f6dc9357SAndroid Build Coastguard Worker   "zstd", "zst tzst", "* .tar", 0xe,
1141*f6dc9357SAndroid Build Coastguard Worker   k_Signature, 0
1142*f6dc9357SAndroid Build Coastguard Worker   , NArcInfoFlags::kKeepName
1143*f6dc9357SAndroid Build Coastguard Worker   , 0
1144*f6dc9357SAndroid Build Coastguard Worker   , NULL)
1145*f6dc9357SAndroid Build Coastguard Worker #endif
1146*f6dc9357SAndroid Build Coastguard Worker 
1147*f6dc9357SAndroid Build Coastguard Worker }}
1148