1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// XzHandler.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../C/Alloc.h"
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../C/XzCrc64.h"
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../C/XzEnc.h"
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/ComTry.h"
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/IntToString.h"
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../ICoder.h"
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/CWrappers.h"
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/ProgressUtils.h"
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/RegisterArc.h"
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/StreamUtils.h"
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Compress/CopyCoder.h"
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "IArchive.h"
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Common/HandlerOut.h"
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
25baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NWindows;
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
27baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NCompress {
28baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NLzma2 {
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
30baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props);
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}}
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
34baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void *SzAlloc(void *, size_t size) { return MyAlloc(size); }
35baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void SzFree(void *, void *address) { MyFree(address); }
36baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic ISzAlloc g_Alloc = { SzAlloc, SzFree };
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
38baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NArchive {
39baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NXz {
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
41baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit;
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
43baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CHandler:
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public IInArchive,
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public IArchiveOpenSeq,
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef EXTRACT_ONLY
47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public IOutArchive,
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public ISetProperties,
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public COutHandler,
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public CMyUnknownImp
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Int64 _startPosition;
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 _packSize;
55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 _unpackSize;
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 _numBlocks;
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  AString _methodsString;
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool _useSeq;
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 _unpackSizeDefined;
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 _packSizeDefined;
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<IInStream> _stream;
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialInStream> _seqStream;
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 _crcSize;
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void Init()
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _crcSize = 4;
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    COutHandler::Init();
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT Open2(IInStream *inStream, IArchiveOpenCallback *callback);
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
75baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_QUERYINTERFACE_BEGIN2(IInArchive)
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_QUERYINTERFACE_ENTRY(IArchiveOpenSeq)
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef EXTRACT_ONLY
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_QUERYINTERFACE_ENTRY(IOutArchive)
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_QUERYINTERFACE_ENTRY(ISetProperties)
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_QUERYINTERFACE_END
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ADDREF_RELEASE
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  INTERFACE_IInArchive(;)
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(OpenSeq)(ISequentialInStream *stream);
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef EXTRACT_ONLY
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  INTERFACE_IOutArchive(;)
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CHandler();
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
96baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCHandler::CHandler()
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Init();
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
101baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTATPROPSTG kProps[] =
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { NULL, kpidSize, VT_UI8},
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { NULL, kpidPackSize, VT_UI8},
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { NULL, kpidMethod, VT_BSTR}
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
108baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTATPROPSTG kArcProps[] =
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { NULL, kpidMethod, VT_BSTR},
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { NULL, kpidNumBlocks, VT_UI4}
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
114baa3858d3f5d128a5c8466b700098109edcad5f2repo syncIMP_IInArchive_Props
115baa3858d3f5d128a5c8466b700098109edcad5f2repo syncIMP_IInArchive_ArcProps
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
117baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic char GetHex(Byte value)
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
122baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline void AddHexToString(AString &res, Byte value)
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  res += GetHex((Byte)(value >> 4));
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  res += GetHex((Byte)(value & 0xF));
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
128baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic AString ConvertUInt32ToString(UInt32 value)
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  char temp[32];
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ::ConvertUInt32ToString(value, temp);
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return temp;
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
135baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic AString Lzma2PropToString(int prop)
136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if ((prop & 1) == 0)
138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return ConvertUInt32ToString(prop / 2 + 12);
139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  AString res;
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  char c;
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 size = (2 | ((prop) & 1)) << ((prop) / 2 + 1);
143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (prop > 17)
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    res = ConvertUInt32ToString(size >> 10);
147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    c = 'm';
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    res = ConvertUInt32ToString(size);
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    c = 'k';
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res + c;
155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
157baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CMethodNamePair
158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 Id;
160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const char *Name;
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
163baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic CMethodNamePair g_NamePairs[] =
164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { XZ_ID_Subblock, "SB" },
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { XZ_ID_Delta, "Delta" },
167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { XZ_ID_X86, "x86" },
168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { XZ_ID_PPC, "PPC" },
169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { XZ_ID_IA64, "IA64" },
170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { XZ_ID_ARM, "ARM" },
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { XZ_ID_ARMT, "ARMT" },
172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { XZ_ID_SPARC, "SPARC" },
173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { XZ_ID_LZMA2, "LZMA2" }
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
176baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic AString GetMethodString(const CXzFilter &f)
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  AString s;
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 0; i < sizeof(g_NamePairs) / sizeof(g_NamePairs[i]); i++)
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (g_NamePairs[i].Id == f.id)
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      s = g_NamePairs[i].Name;
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (s.IsEmpty())
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    char temp[32];
186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ::ConvertUInt64ToString(f.id, temp);
187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    s = temp;
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (f.propsSize > 0)
191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    s += ':';
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (f.id == XZ_ID_LZMA2 && f.propsSize == 1)
194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      s += Lzma2PropToString(f.props[0]);
195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else if (f.id == XZ_ID_Delta && f.propsSize == 1)
196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      s += ConvertUInt32ToString((UInt32)f.props[0] + 1);
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      s += '[';
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (UInt32 bi = 0; bi < f.propsSize; bi++)
201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        AddHexToString(s, f.props[bi]);
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      s += ']';
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return s;
206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
208baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void AddString(AString &dest, const AString &src)
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!dest.IsEmpty())
211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    dest += ' ';
212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  dest += src;
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
215baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kChecks[] =
216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  "NoCheck",
218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  "CRC32",
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL,
220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL,
221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  "CRC64",
222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL,
223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL,
224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL,
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL,
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL,
227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  "SHA256",
228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL,
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL,
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL,
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL,
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NULL
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
235baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic AString GetCheckString(const CXzs &xzs)
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t i;
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 mask = 0;
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < xzs.num; i++)
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    mask |= ((UInt32)1 << XzFlags_GetCheckType(xzs.streams[i].flags));
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  AString s;
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i <= XZ_CHECK_MASK; i++)
243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (((mask >> i) & 1) != 0)
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      AString s2;
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (kChecks[i])
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        s2 = kChecks[i];
248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else
249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        s2 = "Check-" + ConvertUInt32ToString((UInt32)i);
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      AddString(s, s2);
251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return s;
253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
255baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NWindows::NCOM::CPropVariant prop;
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  switch(propID)
260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case kpidNumBlocks: if (!_useSeq) prop = _numBlocks; break;
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  prop.Detach(value);
266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
270baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *numItems = 1;
273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
276baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID,  PROPVARIANT *value)
277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NWindows::NCOM::CPropVariant prop;
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  switch(propID)
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case kpidSize: if (_unpackSizeDefined) prop = _unpackSize; break;
283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;
285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  prop.Detach(value);
287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
292baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct COpenCallbackWrap
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ICompressProgress p;
295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IArchiveOpenCallback *OpenCallback;
296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT Res;
297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COpenCallbackWrap(IArchiveOpenCallback *progress);
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
300baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes OpenCallbackProgress(void *pp, UInt64 inSize, UInt64 /* outSize */)
301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COpenCallbackWrap *p = (COpenCallbackWrap *)pp;
303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->Res = p->OpenCallback->SetCompleted(NULL, &inSize);
304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (SRes)p->Res;
305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
307baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCOpenCallbackWrap::COpenCallbackWrap(IArchiveOpenCallback *callback)
308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p.Progress = OpenCallbackProgress;
310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  OpenCallback = callback;
311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Res = SZ_OK;
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
314baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CXzsCPP
315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CXzs p;
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CXzsCPP() { Xzs_Construct(&p); }
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ~CXzsCPP() { Xzs_Free(&p, &g_Alloc); }
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
321baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CHandler::Open2(IInStream *inStream, IArchiveOpenCallback *callback)
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSeekInStreamWrap inStreamImp(inStream);
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLookToRead lookStream;
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LookToRead_CreateVTable(&lookStream, True);
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  lookStream.realStream = &inStreamImp.p;
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LookToRead_Init(&lookStream);
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COpenCallbackWrap openWrap(callback);
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize));
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(callback->SetTotal(NULL, &_packSize));
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CXzsCPP xzs;
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.s, &_startPosition, &openWrap.p, &g_Alloc);
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res == SZ_ERROR_NO_ARCHIVE && xzs.p.num > 0)
337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    res = SZ_OK;
338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res == SZ_OK)
339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _packSize -= _startPosition;
341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _unpackSize = Xzs_GetUnpackSize(&xzs.p);
342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _unpackSizeDefined = _packSizeDefined = true;
343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _numBlocks = (UInt64)Xzs_GetNumBlocks(&xzs.p);
344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CXzStreamFlags st;
347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSeqInStreamWrap inStreamWrap(inStream);
348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SRes res2 = Xz_ReadHeader(&st, &inStreamWrap.p);
349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (res2 == SZ_OK)
351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CXzBlock block;
353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      Bool isIndex;
354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt32 headerSizeRes;
355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      res2 = XzBlock_ReadHeader(&block, &inStreamWrap.p, &isIndex, &headerSizeRes);
356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res2 == SZ_OK && !isIndex)
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        int numFilters = XzBlock_GetNumFilters(&block);
359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        for (int i = 0; i < numFilters; i++)
360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          AddString(_methodsString, GetMethodString(block.filters[i]));
361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    AddString(_methodsString, GetCheckString(xzs.p));
364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res != SZ_OK || _startPosition != 0)
367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CXzStreamFlags st;
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSeqInStreamWrap inStreamWrap(inStream);
371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SRes res2 = Xz_ReadHeader(&st, &inStreamWrap.p);
372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (res2 == SZ_OK)
373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      res = res2;
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _startPosition = 0;
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _useSeq = True;
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _unpackSizeDefined = _packSizeDefined = false;
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res == SZ_ERROR_NO_ARCHIVE)
381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_FALSE;
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SResToHRESULT(res));
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _stream = inStream;
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _seqStream = inStream;
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
388baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  try
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Close();
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return Open2(inStream, callback);
395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  catch(...) { return S_FALSE; }
397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
400baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Close();
403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _seqStream = stream;
404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
407baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::Close()
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _numBlocks = 0;
410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _useSeq = true;
411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _unpackSizeDefined = _packSizeDefined = false;
412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _methodsString.Empty();
413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _stream.Release();
414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _seqStream.Release();
415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
418baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CSeekToSeqStream:
419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public IInStream,
420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public CMyUnknownImp
421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
422baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialInStream> Stream;
424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_UNKNOWN_IMP1(IInStream)
425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
430baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CSeekToSeqStream::Read(void *data, UInt32 size, UInt32 *processedSize)
431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return Stream->Read(data, size, processedSize);
433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
435baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CSeekToSeqStream::Seek(Int64, UInt32, UInt64 *) { return E_NOTIMPL; }
436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
437baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CXzUnpackerCPP
438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *InBuf;
440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *OutBuf;
441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CXzUnpacker p;
442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CXzUnpackerCPP(): InBuf(0), OutBuf(0) {}
443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ~CXzUnpackerCPP()
444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    XzUnpacker_Free(&p);
446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MyFree(InBuf);
447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MyFree(OutBuf);
448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
451baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Int32 testMode, IArchiveExtractCallback *extractCallback)
453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numItems == 0)
456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_OK;
457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_INVALIDARG;
459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  extractCallback->SetTotal(_packSize);
461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 currentTotalPacked = 0;
462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(extractCallback->SetCompleted(&currentTotalPacked));
463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialOutStream> realOutStream;
464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Int32 askMode = testMode ?
465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NExtract::NAskMode::kTest :
466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NExtract::NAskMode::kExtract;
467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!testMode && !realOutStream)
471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_OK;
472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  extractCallback->PrepareOperation(askMode);
474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_stream)
476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_stream->Seek(_startPosition, STREAM_SEEK_SET, NULL));
478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLocalProgress *lps = new CLocalProgress;
481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ICompressProgressInfo> progress = lps;
482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  lps->Init(extractCallback, true);
483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CCompressProgressWrap progressWrap(progress);
485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SRes res;
487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
488baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const UInt32 kInBufSize = 1 << 15;
489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const UInt32 kOutBufSize = 1 << 21;
490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 inPos = 0;
492baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 inSize = 0;
493baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 outPos = 0;
494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CXzUnpackerCPP xzu;
495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  res = XzUnpacker_Create(&xzu.p, &g_Alloc);
496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res == SZ_OK)
497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    xzu.InBuf = (Byte *)MyAlloc(kInBufSize);
499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    xzu.OutBuf = (Byte *)MyAlloc(kOutBufSize);
500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (xzu.InBuf == 0 || xzu.OutBuf == 0)
501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      res = SZ_ERROR_MEM;
502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res == SZ_OK)
504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (inPos == inSize)
507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      inPos = inSize = 0;
509baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(_seqStream->Read(xzu.InBuf, kInBufSize, &inSize));
510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SizeT inLen = inSize - inPos;
513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SizeT outLen = kOutBufSize - outPos;
514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ECoderStatus status;
515baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    res = XzUnpacker_Code(&xzu.p,
516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        xzu.OutBuf + outPos, &outLen,
517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        xzu.InBuf + inPos, &inLen,
518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        (inSize == 0 ? CODER_FINISH_END : CODER_FINISH_ANY), &status);
519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
520baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // printf("\n_inPos = %6d  inLen = %5d, outLen = %5d", inPos, inLen, outLen);
521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    inPos += (UInt32)inLen;
523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    outPos += (UInt32)outLen;
524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    lps->InSize += inLen;
525baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    lps->OutSize += outLen;
526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool finished = (((inLen == 0) && (outLen == 0)) || res != SZ_OK);
528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (outPos == kOutBufSize || finished)
530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (realOutStream && outPos > 0)
532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(WriteStream(realOutStream, xzu.OutBuf, outPos));
534baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
535baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outPos = 0;
536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (finished)
538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _packSize = lps->InSize;
540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _unpackSize = lps->OutSize;
541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _packSizeDefined = _unpackSizeDefined = true;
542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res == SZ_OK)
543baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
544baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (status == CODER_STATUS_NEEDS_MORE_INPUT)
545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if (XzUnpacker_IsStreamWasFinished(&xzu.p))
547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            _packSize -= xzu.p.padSize;
548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          else
549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            res = SZ_ERROR_DATA;
550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else
552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          res = SZ_ERROR_DATA;
553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(lps->SetCur());
557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Int32 opRes;
560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  switch(res)
561baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case SZ_OK:
563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      opRes = NExtract::NOperationResult::kOK; break;
564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case SZ_ERROR_UNSUPPORTED:
565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      opRes = NExtract::NOperationResult::kUnSupportedMethod; break;
566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case SZ_ERROR_CRC:
567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      opRes = NExtract::NOperationResult::kCRCError; break;
568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case SZ_ERROR_DATA:
569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case SZ_ERROR_ARCHIVE:
570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case SZ_ERROR_NO_ARCHIVE:
571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      opRes = NExtract::NOperationResult::kDataError; break;
572baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    default:
573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SResToHRESULT(res);
574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  realOutStream.Release();
576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(extractCallback->SetOperationResult(opRes));
577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef EXTRACT_ONLY
582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
583baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *timeType = NFileTimeType::kUnix;
586baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
589baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    IArchiveUpdateCallback *updateCallback)
591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSeqOutStreamWrap seqOutStream(outStream);
593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numItems == 0)
595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SRes res = Xz_EncodeEmpty(&seqOutStream.p);
597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SResToHRESULT(res);
598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numItems != 1)
601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_INVALIDARG;
602baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Int32 newData, newProps;
604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 indexInArchive;
605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!updateCallback)
606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_FAIL;
607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive));
608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (IntToBool(newProps))
610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCOM::CPropVariant prop;
613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop));
614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (prop.vt != VT_EMPTY)
615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE)
616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return E_INVALIDARG;
617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (IntToBool(newData))
621baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt64 size;
624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCOM::CPropVariant prop;
625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (prop.vt != VT_UI8)
627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_INVALIDARG;
628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      size = prop.uhVal.QuadPart;
629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(updateCallback->SetTotal(size));
630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CLzma2EncProps lzma2Props;
633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Lzma2EncProps_Init(&lzma2Props);
634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    lzma2Props.lzmaProps.level = _level;
636baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
637baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ISequentialInStream> fileInStream;
638baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(updateCallback->GetStream(0, &fileInStream));
639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSeqInStreamWrap seqInStream(fileInStream);
641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (int i = 0; i < _methods.Size(); i++)
643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
644baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      COneMethodInfo &m = _methods[i];
645baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      SetCompressionMethod2(m
646baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #ifndef _7ZIP_ST
647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      , _numThreads
648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #endif
649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      );
650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (m.IsLzma())
651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        for (int j = 0; j < m.Props.Size(); j++)
653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          const CProp &prop = m.Props[j];
655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          RINOK(NCompress::NLzma2::SetLzma2Prop(prop.Id, prop.Value, lzma2Props));
656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
660baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifndef _7ZIP_ST
661baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    lzma2Props.numTotalThreads = _numThreads;
662baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CLocalProgress *lps = new CLocalProgress;
665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ICompressProgressInfo> progress = lps;
666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    lps->Init(updateCallback, true);
667baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
668baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CCompressProgressWrap progressWrap(progress);
669baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SRes res = Xz_Encode(&seqOutStream.p, &seqInStream.p, &lzma2Props, False, &progressWrap.p);
670baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (res == SZ_OK)
671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
672baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SResToHRESULT(res);
673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
674baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (indexInArchive != 0)
675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_INVALIDARG;
676baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_stream)
677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_stream->Seek(_startPosition, STREAM_SEEK_SET, NULL));
678baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return NCompress::CopyStream(_stream, outStream, 0);
679baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
680baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
681baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
682baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
683baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
684baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  BeforeSetProperty();
685baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 0; i < numProps; i++)
686baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
687baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SetProperty(names[i], values[i]));
688baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
689baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
690baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
691baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
692baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
694baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
695baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic IInArchive *CreateArc() { return new NArchive::NXz::CHandler; }
696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef EXTRACT_ONLY
697baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic IOutArchive *CreateArcOut() { return new NArchive::NXz::CHandler; }
698baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#else
699baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define CreateArcOut 0
700baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
701baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
702baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic CArcInfo g_ArcInfo =
703baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { L"xz", L"xz txz", L"* .tar", 0xC, {0xFD, '7' , 'z', 'X', 'Z', '\0'}, 6, true, CreateArc, CreateArcOut };
704baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
705baa3858d3f5d128a5c8466b700098109edcad5f2repo syncREGISTER_ARC(xz)
706baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
707baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}}
708