1*f6dc9357SAndroid Build Coastguard Worker // 7zHandlerOut.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/ComTry.h"
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringToInt.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Wildcard.h"
8*f6dc9357SAndroid Build Coastguard Worker
9*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ItemNameUtils.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ParseProperties.h"
11*f6dc9357SAndroid Build Coastguard Worker
12*f6dc9357SAndroid Build Coastguard Worker #include "7zHandler.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "7zOut.h"
14*f6dc9357SAndroid Build Coastguard Worker #include "7zUpdate.h"
15*f6dc9357SAndroid Build Coastguard Worker
16*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_EXTRACT_ONLY
17*f6dc9357SAndroid Build Coastguard Worker
18*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
19*f6dc9357SAndroid Build Coastguard Worker
20*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
21*f6dc9357SAndroid Build Coastguard Worker namespace N7z {
22*f6dc9357SAndroid Build Coastguard Worker
23*f6dc9357SAndroid Build Coastguard Worker static const UInt32 k_decoderCompatibilityVersion = 2301;
24*f6dc9357SAndroid Build Coastguard Worker // 7-Zip version 2301 supports ARM64 filter
25*f6dc9357SAndroid Build Coastguard Worker
26*f6dc9357SAndroid Build Coastguard Worker #define k_LZMA_Name "LZMA"
27*f6dc9357SAndroid Build Coastguard Worker #define kDefaultMethodName "LZMA2"
28*f6dc9357SAndroid Build Coastguard Worker #define k_Copy_Name "Copy"
29*f6dc9357SAndroid Build Coastguard Worker
30*f6dc9357SAndroid Build Coastguard Worker #define k_MatchFinder_ForHeaders "BT2"
31*f6dc9357SAndroid Build Coastguard Worker
32*f6dc9357SAndroid Build Coastguard Worker static const UInt32 k_NumFastBytes_ForHeaders = 273;
33*f6dc9357SAndroid Build Coastguard Worker static const UInt32 k_Level_ForHeaders = 5;
34*f6dc9357SAndroid Build Coastguard Worker static const UInt32 k_Dictionary_ForHeaders =
35*f6dc9357SAndroid Build Coastguard Worker #ifdef UNDER_CE
36*f6dc9357SAndroid Build Coastguard Worker 1 << 18;
37*f6dc9357SAndroid Build Coastguard Worker #else
38*f6dc9357SAndroid Build Coastguard Worker 1 << 20;
39*f6dc9357SAndroid Build Coastguard Worker #endif
40*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetFileTimeType (UInt32 * type))41*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type))
42*f6dc9357SAndroid Build Coastguard Worker {
43*f6dc9357SAndroid Build Coastguard Worker *type = NFileTimeType::kWindows;
44*f6dc9357SAndroid Build Coastguard Worker return S_OK;
45*f6dc9357SAndroid Build Coastguard Worker }
46*f6dc9357SAndroid Build Coastguard Worker
PropsMethod_To_FullMethod(CMethodFull & dest,const COneMethodInfo & m)47*f6dc9357SAndroid Build Coastguard Worker HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
48*f6dc9357SAndroid Build Coastguard Worker {
49*f6dc9357SAndroid Build Coastguard Worker bool isFilter;
50*f6dc9357SAndroid Build Coastguard Worker dest.CodecIndex = FindMethod_Index(
51*f6dc9357SAndroid Build Coastguard Worker EXTERNAL_CODECS_VARS
52*f6dc9357SAndroid Build Coastguard Worker m.MethodName, true,
53*f6dc9357SAndroid Build Coastguard Worker dest.Id, dest.NumStreams, isFilter);
54*f6dc9357SAndroid Build Coastguard Worker if (dest.CodecIndex < 0)
55*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
56*f6dc9357SAndroid Build Coastguard Worker (CProps &)dest = (CProps &)m;
57*f6dc9357SAndroid Build Coastguard Worker return S_OK;
58*f6dc9357SAndroid Build Coastguard Worker }
59*f6dc9357SAndroid Build Coastguard Worker
SetHeaderMethod(CCompressionMethodMode & headerMethod)60*f6dc9357SAndroid Build Coastguard Worker HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
61*f6dc9357SAndroid Build Coastguard Worker {
62*f6dc9357SAndroid Build Coastguard Worker if (!_compressHeaders)
63*f6dc9357SAndroid Build Coastguard Worker return S_OK;
64*f6dc9357SAndroid Build Coastguard Worker COneMethodInfo m;
65*f6dc9357SAndroid Build Coastguard Worker m.MethodName = k_LZMA_Name;
66*f6dc9357SAndroid Build Coastguard Worker m.AddProp_Ascii(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
67*f6dc9357SAndroid Build Coastguard Worker m.AddProp_Level(k_Level_ForHeaders);
68*f6dc9357SAndroid Build Coastguard Worker m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders);
69*f6dc9357SAndroid Build Coastguard Worker m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders);
70*f6dc9357SAndroid Build Coastguard Worker m.AddProp_NumThreads(1);
71*f6dc9357SAndroid Build Coastguard Worker
72*f6dc9357SAndroid Build Coastguard Worker CMethodFull &methodFull = headerMethod.Methods.AddNew();
73*f6dc9357SAndroid Build Coastguard Worker return PropsMethod_To_FullMethod(methodFull, m);
74*f6dc9357SAndroid Build Coastguard Worker }
75*f6dc9357SAndroid Build Coastguard Worker
76*f6dc9357SAndroid Build Coastguard Worker
SetMainMethod(CCompressionMethodMode & methodMode)77*f6dc9357SAndroid Build Coastguard Worker HRESULT CHandler::SetMainMethod(CCompressionMethodMode &methodMode)
78*f6dc9357SAndroid Build Coastguard Worker {
79*f6dc9357SAndroid Build Coastguard Worker methodMode.Bonds = _bonds;
80*f6dc9357SAndroid Build Coastguard Worker
81*f6dc9357SAndroid Build Coastguard Worker // we create local copy of _methods. So we can modify it.
82*f6dc9357SAndroid Build Coastguard Worker CObjectVector<COneMethodInfo> methods = _methods;
83*f6dc9357SAndroid Build Coastguard Worker
84*f6dc9357SAndroid Build Coastguard Worker {
85*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, methods)
86*f6dc9357SAndroid Build Coastguard Worker {
87*f6dc9357SAndroid Build Coastguard Worker AString &methodName = methods[i].MethodName;
88*f6dc9357SAndroid Build Coastguard Worker if (methodName.IsEmpty())
89*f6dc9357SAndroid Build Coastguard Worker methodName = kDefaultMethodName;
90*f6dc9357SAndroid Build Coastguard Worker }
91*f6dc9357SAndroid Build Coastguard Worker if (methods.IsEmpty())
92*f6dc9357SAndroid Build Coastguard Worker {
93*f6dc9357SAndroid Build Coastguard Worker COneMethodInfo &m = methods.AddNew();
94*f6dc9357SAndroid Build Coastguard Worker m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName);
95*f6dc9357SAndroid Build Coastguard Worker methodMode.DefaultMethod_was_Inserted = true;
96*f6dc9357SAndroid Build Coastguard Worker }
97*f6dc9357SAndroid Build Coastguard Worker }
98*f6dc9357SAndroid Build Coastguard Worker
99*f6dc9357SAndroid Build Coastguard Worker if (!_filterMethod.MethodName.IsEmpty())
100*f6dc9357SAndroid Build Coastguard Worker {
101*f6dc9357SAndroid Build Coastguard Worker // if (methodMode.Bonds.IsEmpty())
102*f6dc9357SAndroid Build Coastguard Worker {
103*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (k, methodMode.Bonds)
104*f6dc9357SAndroid Build Coastguard Worker {
105*f6dc9357SAndroid Build Coastguard Worker CBond2 &bond = methodMode.Bonds[k];
106*f6dc9357SAndroid Build Coastguard Worker bond.InCoder++;
107*f6dc9357SAndroid Build Coastguard Worker bond.OutCoder++;
108*f6dc9357SAndroid Build Coastguard Worker }
109*f6dc9357SAndroid Build Coastguard Worker methods.Insert(0, _filterMethod);
110*f6dc9357SAndroid Build Coastguard Worker methodMode.Filter_was_Inserted = true;
111*f6dc9357SAndroid Build Coastguard Worker }
112*f6dc9357SAndroid Build Coastguard Worker }
113*f6dc9357SAndroid Build Coastguard Worker
114*f6dc9357SAndroid Build Coastguard Worker const UInt64 kSolidBytes_Min = (1 << 24);
115*f6dc9357SAndroid Build Coastguard Worker const UInt64 kSolidBytes_Max = ((UInt64)1 << 32);
116*f6dc9357SAndroid Build Coastguard Worker
117*f6dc9357SAndroid Build Coastguard Worker bool needSolid = false;
118*f6dc9357SAndroid Build Coastguard Worker
119*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, methods)
120*f6dc9357SAndroid Build Coastguard Worker {
121*f6dc9357SAndroid Build Coastguard Worker COneMethodInfo &oneMethodInfo = methods[i];
122*f6dc9357SAndroid Build Coastguard Worker
123*f6dc9357SAndroid Build Coastguard Worker SetGlobalLevelTo(oneMethodInfo);
124*f6dc9357SAndroid Build Coastguard Worker
125*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
126*f6dc9357SAndroid Build Coastguard Worker const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0);
127*f6dc9357SAndroid Build Coastguard Worker if (!numThreads_WasSpecifiedInMethod)
128*f6dc9357SAndroid Build Coastguard Worker {
129*f6dc9357SAndroid Build Coastguard Worker // here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already
130*f6dc9357SAndroid Build Coastguard Worker CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, methodMode.NumThreads);
131*f6dc9357SAndroid Build Coastguard Worker }
132*f6dc9357SAndroid Build Coastguard Worker #endif
133*f6dc9357SAndroid Build Coastguard Worker
134*f6dc9357SAndroid Build Coastguard Worker CMethodFull &methodFull = methodMode.Methods.AddNew();
135*f6dc9357SAndroid Build Coastguard Worker RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo))
136*f6dc9357SAndroid Build Coastguard Worker
137*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
138*f6dc9357SAndroid Build Coastguard Worker methodFull.Set_NumThreads = true;
139*f6dc9357SAndroid Build Coastguard Worker methodFull.NumThreads = methodMode.NumThreads;
140*f6dc9357SAndroid Build Coastguard Worker #endif
141*f6dc9357SAndroid Build Coastguard Worker
142*f6dc9357SAndroid Build Coastguard Worker if (methodFull.Id != k_Copy)
143*f6dc9357SAndroid Build Coastguard Worker needSolid = true;
144*f6dc9357SAndroid Build Coastguard Worker
145*f6dc9357SAndroid Build Coastguard Worker UInt64 dicSize;
146*f6dc9357SAndroid Build Coastguard Worker switch (methodFull.Id)
147*f6dc9357SAndroid Build Coastguard Worker {
148*f6dc9357SAndroid Build Coastguard Worker case k_LZMA:
149*f6dc9357SAndroid Build Coastguard Worker case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break;
150*f6dc9357SAndroid Build Coastguard Worker case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break;
151*f6dc9357SAndroid Build Coastguard Worker case k_Deflate: dicSize = (UInt32)1 << 15; break;
152*f6dc9357SAndroid Build Coastguard Worker case k_Deflate64: dicSize = (UInt32)1 << 16; break;
153*f6dc9357SAndroid Build Coastguard Worker case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
154*f6dc9357SAndroid Build Coastguard Worker // case k_ZSTD: dicSize = 1 << 23; break;
155*f6dc9357SAndroid Build Coastguard Worker default: continue;
156*f6dc9357SAndroid Build Coastguard Worker }
157*f6dc9357SAndroid Build Coastguard Worker
158*f6dc9357SAndroid Build Coastguard Worker UInt64 numSolidBytes;
159*f6dc9357SAndroid Build Coastguard Worker
160*f6dc9357SAndroid Build Coastguard Worker /*
161*f6dc9357SAndroid Build Coastguard Worker if (methodFull.Id == k_ZSTD)
162*f6dc9357SAndroid Build Coastguard Worker {
163*f6dc9357SAndroid Build Coastguard Worker // continue;
164*f6dc9357SAndroid Build Coastguard Worker NCompress::NZstd::CEncoderProps encoderProps;
165*f6dc9357SAndroid Build Coastguard Worker RINOK(oneMethodInfo.Set_PropsTo_zstd(encoderProps));
166*f6dc9357SAndroid Build Coastguard Worker CZstdEncProps &zstdProps = encoderProps.EncProps;
167*f6dc9357SAndroid Build Coastguard Worker ZstdEncProps_NormalizeFull(&zstdProps);
168*f6dc9357SAndroid Build Coastguard Worker UInt64 cs = (UInt64)(zstdProps.jobSize);
169*f6dc9357SAndroid Build Coastguard Worker UInt32 winSize = (UInt32)(1 << zstdProps.windowLog);
170*f6dc9357SAndroid Build Coastguard Worker if (cs < winSize)
171*f6dc9357SAndroid Build Coastguard Worker cs = winSize;
172*f6dc9357SAndroid Build Coastguard Worker numSolidBytes = cs << 6;
173*f6dc9357SAndroid Build Coastguard Worker const UInt64 kSolidBytes_Zstd_Max = ((UInt64)1 << 34);
174*f6dc9357SAndroid Build Coastguard Worker if (numSolidBytes > kSolidBytes_Zstd_Max)
175*f6dc9357SAndroid Build Coastguard Worker numSolidBytes = kSolidBytes_Zstd_Max;
176*f6dc9357SAndroid Build Coastguard Worker
177*f6dc9357SAndroid Build Coastguard Worker methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder
178*f6dc9357SAndroid Build Coastguard Worker
179*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
180*f6dc9357SAndroid Build Coastguard Worker if (!numThreads_WasSpecifiedInMethod
181*f6dc9357SAndroid Build Coastguard Worker && !methodMode.NumThreads_WasForced
182*f6dc9357SAndroid Build Coastguard Worker && methodMode.MemoryUsageLimit_WasSet
183*f6dc9357SAndroid Build Coastguard Worker )
184*f6dc9357SAndroid Build Coastguard Worker {
185*f6dc9357SAndroid Build Coastguard Worker const UInt32 numThreads_Original = methodMode.NumThreads;
186*f6dc9357SAndroid Build Coastguard Worker const UInt32 numThreads_New = ZstdEncProps_GetNumThreads_for_MemUsageLimit(
187*f6dc9357SAndroid Build Coastguard Worker &zstdProps,
188*f6dc9357SAndroid Build Coastguard Worker methodMode.MemoryUsageLimit,
189*f6dc9357SAndroid Build Coastguard Worker numThreads_Original);
190*f6dc9357SAndroid Build Coastguard Worker if (numThreads_Original != numThreads_New)
191*f6dc9357SAndroid Build Coastguard Worker {
192*f6dc9357SAndroid Build Coastguard Worker CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New);
193*f6dc9357SAndroid Build Coastguard Worker }
194*f6dc9357SAndroid Build Coastguard Worker }
195*f6dc9357SAndroid Build Coastguard Worker #endif
196*f6dc9357SAndroid Build Coastguard Worker }
197*f6dc9357SAndroid Build Coastguard Worker else
198*f6dc9357SAndroid Build Coastguard Worker */
199*f6dc9357SAndroid Build Coastguard Worker if (methodFull.Id == k_LZMA2)
200*f6dc9357SAndroid Build Coastguard Worker {
201*f6dc9357SAndroid Build Coastguard Worker // he we calculate default chunk Size for LZMA2 as defined in LZMA2 encoder code
202*f6dc9357SAndroid Build Coastguard Worker /* lzma2 code use dictionary up to fake 4 GiB to calculate ChunkSize.
203*f6dc9357SAndroid Build Coastguard Worker So we do same */
204*f6dc9357SAndroid Build Coastguard Worker UInt64 cs = (UInt64)dicSize << 2;
205*f6dc9357SAndroid Build Coastguard Worker const UInt32 kMinSize = (UInt32)1 << 20;
206*f6dc9357SAndroid Build Coastguard Worker const UInt32 kMaxSize = (UInt32)1 << 28;
207*f6dc9357SAndroid Build Coastguard Worker if (cs < kMinSize) cs = kMinSize;
208*f6dc9357SAndroid Build Coastguard Worker if (cs > kMaxSize) cs = kMaxSize;
209*f6dc9357SAndroid Build Coastguard Worker if (cs < dicSize) cs = dicSize;
210*f6dc9357SAndroid Build Coastguard Worker cs += (kMinSize - 1);
211*f6dc9357SAndroid Build Coastguard Worker cs &= ~(UInt64)(kMinSize - 1);
212*f6dc9357SAndroid Build Coastguard Worker // we want to use at least 64 chunks (threads) per one solid block.
213*f6dc9357SAndroid Build Coastguard Worker
214*f6dc9357SAndroid Build Coastguard Worker // here we don't use chunkSize property
215*f6dc9357SAndroid Build Coastguard Worker numSolidBytes = cs << 6;
216*f6dc9357SAndroid Build Coastguard Worker
217*f6dc9357SAndroid Build Coastguard Worker // here we get real chunkSize
218*f6dc9357SAndroid Build Coastguard Worker cs = oneMethodInfo.Get_Xz_BlockSize();
219*f6dc9357SAndroid Build Coastguard Worker if (dicSize > cs)
220*f6dc9357SAndroid Build Coastguard Worker dicSize = cs;
221*f6dc9357SAndroid Build Coastguard Worker
222*f6dc9357SAndroid Build Coastguard Worker const UInt64 kSolidBytes_Lzma2_Max = ((UInt64)1 << 34);
223*f6dc9357SAndroid Build Coastguard Worker if (numSolidBytes > kSolidBytes_Lzma2_Max)
224*f6dc9357SAndroid Build Coastguard Worker numSolidBytes = kSolidBytes_Lzma2_Max;
225*f6dc9357SAndroid Build Coastguard Worker
226*f6dc9357SAndroid Build Coastguard Worker methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder
227*f6dc9357SAndroid Build Coastguard Worker
228*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
229*f6dc9357SAndroid Build Coastguard Worker if (!numThreads_WasSpecifiedInMethod
230*f6dc9357SAndroid Build Coastguard Worker && !methodMode.NumThreads_WasForced
231*f6dc9357SAndroid Build Coastguard Worker && methodMode.MemoryUsageLimit_WasSet
232*f6dc9357SAndroid Build Coastguard Worker )
233*f6dc9357SAndroid Build Coastguard Worker {
234*f6dc9357SAndroid Build Coastguard Worker const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads();
235*f6dc9357SAndroid Build Coastguard Worker const UInt32 numBlockThreads_Original = methodMode.NumThreads / lzmaThreads;
236*f6dc9357SAndroid Build Coastguard Worker
237*f6dc9357SAndroid Build Coastguard Worker if (numBlockThreads_Original > 1)
238*f6dc9357SAndroid Build Coastguard Worker {
239*f6dc9357SAndroid Build Coastguard Worker /*
240*f6dc9357SAndroid Build Coastguard Worker const UInt32 kNumThreads_Max = 1024;
241*f6dc9357SAndroid Build Coastguard Worker if (numBlockThreads > kNumMaxThreads)
242*f6dc9357SAndroid Build Coastguard Worker numBlockThreads = kNumMaxThreads;
243*f6dc9357SAndroid Build Coastguard Worker */
244*f6dc9357SAndroid Build Coastguard Worker
245*f6dc9357SAndroid Build Coastguard Worker UInt32 numBlockThreads = numBlockThreads_Original;
246*f6dc9357SAndroid Build Coastguard Worker const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false); // solid
247*f6dc9357SAndroid Build Coastguard Worker
248*f6dc9357SAndroid Build Coastguard Worker for (; numBlockThreads > 1; numBlockThreads--)
249*f6dc9357SAndroid Build Coastguard Worker {
250*f6dc9357SAndroid Build Coastguard Worker UInt64 size = numBlockThreads * (lzmaMemUsage + cs);
251*f6dc9357SAndroid Build Coastguard Worker UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1;
252*f6dc9357SAndroid Build Coastguard Worker if (cs < ((UInt32)1 << 26)) numPackChunks++;
253*f6dc9357SAndroid Build Coastguard Worker if (cs < ((UInt32)1 << 24)) numPackChunks++;
254*f6dc9357SAndroid Build Coastguard Worker if (cs < ((UInt32)1 << 22)) numPackChunks++;
255*f6dc9357SAndroid Build Coastguard Worker size += numPackChunks * cs;
256*f6dc9357SAndroid Build Coastguard Worker // printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20));
257*f6dc9357SAndroid Build Coastguard Worker if (size <= methodMode.MemoryUsageLimit)
258*f6dc9357SAndroid Build Coastguard Worker break;
259*f6dc9357SAndroid Build Coastguard Worker }
260*f6dc9357SAndroid Build Coastguard Worker
261*f6dc9357SAndroid Build Coastguard Worker if (numBlockThreads == 0)
262*f6dc9357SAndroid Build Coastguard Worker numBlockThreads = 1;
263*f6dc9357SAndroid Build Coastguard Worker if (numBlockThreads != numBlockThreads_Original)
264*f6dc9357SAndroid Build Coastguard Worker {
265*f6dc9357SAndroid Build Coastguard Worker const UInt32 numThreads_New = numBlockThreads * lzmaThreads;
266*f6dc9357SAndroid Build Coastguard Worker CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New);
267*f6dc9357SAndroid Build Coastguard Worker }
268*f6dc9357SAndroid Build Coastguard Worker }
269*f6dc9357SAndroid Build Coastguard Worker }
270*f6dc9357SAndroid Build Coastguard Worker #endif
271*f6dc9357SAndroid Build Coastguard Worker }
272*f6dc9357SAndroid Build Coastguard Worker else
273*f6dc9357SAndroid Build Coastguard Worker {
274*f6dc9357SAndroid Build Coastguard Worker numSolidBytes = (UInt64)dicSize << 7;
275*f6dc9357SAndroid Build Coastguard Worker if (numSolidBytes > kSolidBytes_Max)
276*f6dc9357SAndroid Build Coastguard Worker numSolidBytes = kSolidBytes_Max;
277*f6dc9357SAndroid Build Coastguard Worker }
278*f6dc9357SAndroid Build Coastguard Worker
279*f6dc9357SAndroid Build Coastguard Worker if (_numSolidBytesDefined)
280*f6dc9357SAndroid Build Coastguard Worker continue;
281*f6dc9357SAndroid Build Coastguard Worker
282*f6dc9357SAndroid Build Coastguard Worker if (numSolidBytes < kSolidBytes_Min)
283*f6dc9357SAndroid Build Coastguard Worker numSolidBytes = kSolidBytes_Min;
284*f6dc9357SAndroid Build Coastguard Worker _numSolidBytes = numSolidBytes;
285*f6dc9357SAndroid Build Coastguard Worker _numSolidBytesDefined = true;
286*f6dc9357SAndroid Build Coastguard Worker }
287*f6dc9357SAndroid Build Coastguard Worker
288*f6dc9357SAndroid Build Coastguard Worker if (!_numSolidBytesDefined)
289*f6dc9357SAndroid Build Coastguard Worker {
290*f6dc9357SAndroid Build Coastguard Worker if (needSolid)
291*f6dc9357SAndroid Build Coastguard Worker _numSolidBytes = kSolidBytes_Max;
292*f6dc9357SAndroid Build Coastguard Worker else
293*f6dc9357SAndroid Build Coastguard Worker _numSolidBytes = 0;
294*f6dc9357SAndroid Build Coastguard Worker }
295*f6dc9357SAndroid Build Coastguard Worker _numSolidBytesDefined = true;
296*f6dc9357SAndroid Build Coastguard Worker
297*f6dc9357SAndroid Build Coastguard Worker
298*f6dc9357SAndroid Build Coastguard Worker return S_OK;
299*f6dc9357SAndroid Build Coastguard Worker }
300*f6dc9357SAndroid Build Coastguard Worker
301*f6dc9357SAndroid Build Coastguard Worker
302*f6dc9357SAndroid Build Coastguard Worker
GetTime(IArchiveUpdateCallback * updateCallback,unsigned index,PROPID propID,UInt64 & ft,bool & ftDefined)303*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, unsigned index, PROPID propID, UInt64 &ft, bool &ftDefined)
304*f6dc9357SAndroid Build Coastguard Worker {
305*f6dc9357SAndroid Build Coastguard Worker // ft = 0;
306*f6dc9357SAndroid Build Coastguard Worker // ftDefined = false;
307*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
308*f6dc9357SAndroid Build Coastguard Worker RINOK(updateCallback->GetProperty(index, propID, &prop))
309*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_FILETIME)
310*f6dc9357SAndroid Build Coastguard Worker {
311*f6dc9357SAndroid Build Coastguard Worker ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32);
312*f6dc9357SAndroid Build Coastguard Worker ftDefined = true;
313*f6dc9357SAndroid Build Coastguard Worker }
314*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
315*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
316*f6dc9357SAndroid Build Coastguard Worker else
317*f6dc9357SAndroid Build Coastguard Worker {
318*f6dc9357SAndroid Build Coastguard Worker ft = 0;
319*f6dc9357SAndroid Build Coastguard Worker ftDefined = false;
320*f6dc9357SAndroid Build Coastguard Worker }
321*f6dc9357SAndroid Build Coastguard Worker return S_OK;
322*f6dc9357SAndroid Build Coastguard Worker }
323*f6dc9357SAndroid Build Coastguard Worker
324*f6dc9357SAndroid Build Coastguard Worker /*
325*f6dc9357SAndroid Build Coastguard Worker
326*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
327*f6dc9357SAndroid Build Coastguard Worker static const wchar_t kDirDelimiter1 = L'\\';
328*f6dc9357SAndroid Build Coastguard Worker #endif
329*f6dc9357SAndroid Build Coastguard Worker static const wchar_t kDirDelimiter2 = L'/';
330*f6dc9357SAndroid Build Coastguard Worker
331*f6dc9357SAndroid Build Coastguard Worker static inline bool IsCharDirLimiter(wchar_t c)
332*f6dc9357SAndroid Build Coastguard Worker {
333*f6dc9357SAndroid Build Coastguard Worker return (
334*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
335*f6dc9357SAndroid Build Coastguard Worker c == kDirDelimiter1 ||
336*f6dc9357SAndroid Build Coastguard Worker #endif
337*f6dc9357SAndroid Build Coastguard Worker c == kDirDelimiter2);
338*f6dc9357SAndroid Build Coastguard Worker }
339*f6dc9357SAndroid Build Coastguard Worker
340*f6dc9357SAndroid Build Coastguard Worker static int FillSortIndex(CObjectVector<CTreeFolder> &treeFolders, int cur, int curSortIndex)
341*f6dc9357SAndroid Build Coastguard Worker {
342*f6dc9357SAndroid Build Coastguard Worker CTreeFolder &tf = treeFolders[cur];
343*f6dc9357SAndroid Build Coastguard Worker tf.SortIndex = curSortIndex++;
344*f6dc9357SAndroid Build Coastguard Worker for (int i = 0; i < tf.SubFolders.Size(); i++)
345*f6dc9357SAndroid Build Coastguard Worker curSortIndex = FillSortIndex(treeFolders, tf.SubFolders[i], curSortIndex);
346*f6dc9357SAndroid Build Coastguard Worker tf.SortIndexEnd = curSortIndex;
347*f6dc9357SAndroid Build Coastguard Worker return curSortIndex;
348*f6dc9357SAndroid Build Coastguard Worker }
349*f6dc9357SAndroid Build Coastguard Worker
350*f6dc9357SAndroid Build Coastguard Worker static int FindSubFolder(const CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name, int &insertPos)
351*f6dc9357SAndroid Build Coastguard Worker {
352*f6dc9357SAndroid Build Coastguard Worker const CIntVector &subFolders = treeFolders[cur].SubFolders;
353*f6dc9357SAndroid Build Coastguard Worker int left = 0, right = subFolders.Size();
354*f6dc9357SAndroid Build Coastguard Worker insertPos = -1;
355*f6dc9357SAndroid Build Coastguard Worker for (;;)
356*f6dc9357SAndroid Build Coastguard Worker {
357*f6dc9357SAndroid Build Coastguard Worker if (left == right)
358*f6dc9357SAndroid Build Coastguard Worker {
359*f6dc9357SAndroid Build Coastguard Worker insertPos = left;
360*f6dc9357SAndroid Build Coastguard Worker return -1;
361*f6dc9357SAndroid Build Coastguard Worker }
362*f6dc9357SAndroid Build Coastguard Worker int mid = (left + right) / 2;
363*f6dc9357SAndroid Build Coastguard Worker int midFolder = subFolders[mid];
364*f6dc9357SAndroid Build Coastguard Worker int compare = CompareFileNames(name, treeFolders[midFolder].Name);
365*f6dc9357SAndroid Build Coastguard Worker if (compare == 0)
366*f6dc9357SAndroid Build Coastguard Worker return midFolder;
367*f6dc9357SAndroid Build Coastguard Worker if (compare < 0)
368*f6dc9357SAndroid Build Coastguard Worker right = mid;
369*f6dc9357SAndroid Build Coastguard Worker else
370*f6dc9357SAndroid Build Coastguard Worker left = mid + 1;
371*f6dc9357SAndroid Build Coastguard Worker }
372*f6dc9357SAndroid Build Coastguard Worker }
373*f6dc9357SAndroid Build Coastguard Worker
374*f6dc9357SAndroid Build Coastguard Worker static int AddFolder(CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name)
375*f6dc9357SAndroid Build Coastguard Worker {
376*f6dc9357SAndroid Build Coastguard Worker int insertPos;
377*f6dc9357SAndroid Build Coastguard Worker int folderIndex = FindSubFolder(treeFolders, cur, name, insertPos);
378*f6dc9357SAndroid Build Coastguard Worker if (folderIndex < 0)
379*f6dc9357SAndroid Build Coastguard Worker {
380*f6dc9357SAndroid Build Coastguard Worker folderIndex = treeFolders.Size();
381*f6dc9357SAndroid Build Coastguard Worker CTreeFolder &newFolder = treeFolders.AddNew();
382*f6dc9357SAndroid Build Coastguard Worker newFolder.Parent = cur;
383*f6dc9357SAndroid Build Coastguard Worker newFolder.Name = name;
384*f6dc9357SAndroid Build Coastguard Worker treeFolders[cur].SubFolders.Insert(insertPos, folderIndex);
385*f6dc9357SAndroid Build Coastguard Worker }
386*f6dc9357SAndroid Build Coastguard Worker // else if (treeFolders[folderIndex].IsAltStreamFolder != isAltStreamFolder) throw 1123234234;
387*f6dc9357SAndroid Build Coastguard Worker return folderIndex;
388*f6dc9357SAndroid Build Coastguard Worker }
389*f6dc9357SAndroid Build Coastguard Worker */
390*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::UpdateItems (ISequentialOutStream * outStream,UInt32 numItems,IArchiveUpdateCallback * updateCallback))391*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
392*f6dc9357SAndroid Build Coastguard Worker IArchiveUpdateCallback *updateCallback))
393*f6dc9357SAndroid Build Coastguard Worker {
394*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
395*f6dc9357SAndroid Build Coastguard Worker
396*f6dc9357SAndroid Build Coastguard Worker const CDbEx *db = NULL;
397*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_7Z_VOL
398*f6dc9357SAndroid Build Coastguard Worker if (_volumes.Size() > 1)
399*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
400*f6dc9357SAndroid Build Coastguard Worker const CVolume *volume = 0;
401*f6dc9357SAndroid Build Coastguard Worker if (_volumes.Size() == 1)
402*f6dc9357SAndroid Build Coastguard Worker {
403*f6dc9357SAndroid Build Coastguard Worker volume = &_volumes.Front();
404*f6dc9357SAndroid Build Coastguard Worker db = &volume->Database;
405*f6dc9357SAndroid Build Coastguard Worker }
406*f6dc9357SAndroid Build Coastguard Worker #else
407*f6dc9357SAndroid Build Coastguard Worker if (_inStream)
408*f6dc9357SAndroid Build Coastguard Worker db = &_db;
409*f6dc9357SAndroid Build Coastguard Worker #endif
410*f6dc9357SAndroid Build Coastguard Worker
411*f6dc9357SAndroid Build Coastguard Worker if (db && !db->CanUpdate())
412*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
413*f6dc9357SAndroid Build Coastguard Worker
414*f6dc9357SAndroid Build Coastguard Worker /*
415*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
416*f6dc9357SAndroid Build Coastguard Worker IArchiveGetRawProps,
417*f6dc9357SAndroid Build Coastguard Worker getRawProps, updateCallback)
418*f6dc9357SAndroid Build Coastguard Worker
419*f6dc9357SAndroid Build Coastguard Worker CUniqBlocks secureBlocks;
420*f6dc9357SAndroid Build Coastguard Worker secureBlocks.AddUniq(NULL, 0);
421*f6dc9357SAndroid Build Coastguard Worker
422*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CTreeFolder> treeFolders;
423*f6dc9357SAndroid Build Coastguard Worker {
424*f6dc9357SAndroid Build Coastguard Worker CTreeFolder folder;
425*f6dc9357SAndroid Build Coastguard Worker folder.Parent = -1;
426*f6dc9357SAndroid Build Coastguard Worker treeFolders.Add(folder);
427*f6dc9357SAndroid Build Coastguard Worker }
428*f6dc9357SAndroid Build Coastguard Worker */
429*f6dc9357SAndroid Build Coastguard Worker
430*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CUpdateItem> updateItems;
431*f6dc9357SAndroid Build Coastguard Worker
432*f6dc9357SAndroid Build Coastguard Worker bool need_CTime = (TimeOptions.Write_CTime.Def && TimeOptions.Write_CTime.Val);
433*f6dc9357SAndroid Build Coastguard Worker bool need_ATime = (TimeOptions.Write_ATime.Def && TimeOptions.Write_ATime.Val);
434*f6dc9357SAndroid Build Coastguard Worker bool need_MTime = (TimeOptions.Write_MTime.Def ? TimeOptions.Write_MTime.Val : true);
435*f6dc9357SAndroid Build Coastguard Worker bool need_Attrib = (Write_Attrib.Def ? Write_Attrib.Val : true);
436*f6dc9357SAndroid Build Coastguard Worker
437*f6dc9357SAndroid Build Coastguard Worker if (db && !db->Files.IsEmpty())
438*f6dc9357SAndroid Build Coastguard Worker {
439*f6dc9357SAndroid Build Coastguard Worker if (!TimeOptions.Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
440*f6dc9357SAndroid Build Coastguard Worker if (!TimeOptions.Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
441*f6dc9357SAndroid Build Coastguard Worker if (!TimeOptions.Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
442*f6dc9357SAndroid Build Coastguard Worker if (!Write_Attrib.Def) need_Attrib = !db->Attrib.Defs.IsEmpty();
443*f6dc9357SAndroid Build Coastguard Worker }
444*f6dc9357SAndroid Build Coastguard Worker
445*f6dc9357SAndroid Build Coastguard Worker // UString s;
446*f6dc9357SAndroid Build Coastguard Worker UString name;
447*f6dc9357SAndroid Build Coastguard Worker
448*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numItems; i++)
449*f6dc9357SAndroid Build Coastguard Worker {
450*f6dc9357SAndroid Build Coastguard Worker Int32 newData, newProps;
451*f6dc9357SAndroid Build Coastguard Worker UInt32 indexInArchive;
452*f6dc9357SAndroid Build Coastguard Worker if (!updateCallback)
453*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
454*f6dc9357SAndroid Build Coastguard Worker RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive))
455*f6dc9357SAndroid Build Coastguard Worker CUpdateItem ui;
456*f6dc9357SAndroid Build Coastguard Worker ui.NewProps = IntToBool(newProps);
457*f6dc9357SAndroid Build Coastguard Worker ui.NewData = IntToBool(newData);
458*f6dc9357SAndroid Build Coastguard Worker ui.IndexInArchive = (int)indexInArchive;
459*f6dc9357SAndroid Build Coastguard Worker ui.IndexInClient = i;
460*f6dc9357SAndroid Build Coastguard Worker ui.IsAnti = false;
461*f6dc9357SAndroid Build Coastguard Worker ui.Size = 0;
462*f6dc9357SAndroid Build Coastguard Worker
463*f6dc9357SAndroid Build Coastguard Worker name.Empty();
464*f6dc9357SAndroid Build Coastguard Worker // bool isAltStream = false;
465*f6dc9357SAndroid Build Coastguard Worker if (ui.IndexInArchive != -1)
466*f6dc9357SAndroid Build Coastguard Worker {
467*f6dc9357SAndroid Build Coastguard Worker if (!db || (unsigned)ui.IndexInArchive >= db->Files.Size())
468*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
469*f6dc9357SAndroid Build Coastguard Worker const CFileItem &fi = db->Files[(unsigned)ui.IndexInArchive];
470*f6dc9357SAndroid Build Coastguard Worker if (!ui.NewProps)
471*f6dc9357SAndroid Build Coastguard Worker {
472*f6dc9357SAndroid Build Coastguard Worker _db.GetPath((unsigned)ui.IndexInArchive, name);
473*f6dc9357SAndroid Build Coastguard Worker }
474*f6dc9357SAndroid Build Coastguard Worker ui.IsDir = fi.IsDir;
475*f6dc9357SAndroid Build Coastguard Worker ui.Size = fi.Size;
476*f6dc9357SAndroid Build Coastguard Worker // isAltStream = fi.IsAltStream;
477*f6dc9357SAndroid Build Coastguard Worker ui.IsAnti = db->IsItemAnti((unsigned)ui.IndexInArchive);
478*f6dc9357SAndroid Build Coastguard Worker
479*f6dc9357SAndroid Build Coastguard Worker if (!ui.NewProps)
480*f6dc9357SAndroid Build Coastguard Worker {
481*f6dc9357SAndroid Build Coastguard Worker ui.CTimeDefined = db->CTime.GetItem((unsigned)ui.IndexInArchive, ui.CTime);
482*f6dc9357SAndroid Build Coastguard Worker ui.ATimeDefined = db->ATime.GetItem((unsigned)ui.IndexInArchive, ui.ATime);
483*f6dc9357SAndroid Build Coastguard Worker ui.MTimeDefined = db->MTime.GetItem((unsigned)ui.IndexInArchive, ui.MTime);
484*f6dc9357SAndroid Build Coastguard Worker }
485*f6dc9357SAndroid Build Coastguard Worker }
486*f6dc9357SAndroid Build Coastguard Worker
487*f6dc9357SAndroid Build Coastguard Worker if (ui.NewProps)
488*f6dc9357SAndroid Build Coastguard Worker {
489*f6dc9357SAndroid Build Coastguard Worker bool folderStatusIsDefined;
490*f6dc9357SAndroid Build Coastguard Worker if (need_Attrib)
491*f6dc9357SAndroid Build Coastguard Worker {
492*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
493*f6dc9357SAndroid Build Coastguard Worker RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop))
494*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_EMPTY)
495*f6dc9357SAndroid Build Coastguard Worker ui.AttribDefined = false;
496*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_UI4)
497*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
498*f6dc9357SAndroid Build Coastguard Worker else
499*f6dc9357SAndroid Build Coastguard Worker {
500*f6dc9357SAndroid Build Coastguard Worker ui.Attrib = prop.ulVal;
501*f6dc9357SAndroid Build Coastguard Worker ui.AttribDefined = true;
502*f6dc9357SAndroid Build Coastguard Worker }
503*f6dc9357SAndroid Build Coastguard Worker }
504*f6dc9357SAndroid Build Coastguard Worker
505*f6dc9357SAndroid Build Coastguard Worker // we need MTime to sort files.
506*f6dc9357SAndroid Build Coastguard Worker if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined))
507*f6dc9357SAndroid Build Coastguard Worker if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined))
508*f6dc9357SAndroid Build Coastguard Worker if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined))
509*f6dc9357SAndroid Build Coastguard Worker
510*f6dc9357SAndroid Build Coastguard Worker /*
511*f6dc9357SAndroid Build Coastguard Worker if (getRawProps)
512*f6dc9357SAndroid Build Coastguard Worker {
513*f6dc9357SAndroid Build Coastguard Worker const void *data;
514*f6dc9357SAndroid Build Coastguard Worker UInt32 dataSize;
515*f6dc9357SAndroid Build Coastguard Worker UInt32 propType;
516*f6dc9357SAndroid Build Coastguard Worker
517*f6dc9357SAndroid Build Coastguard Worker getRawProps->GetRawProp(i, kpidNtSecure, &data, &dataSize, &propType);
518*f6dc9357SAndroid Build Coastguard Worker if (dataSize != 0 && propType != NPropDataType::kRaw)
519*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
520*f6dc9357SAndroid Build Coastguard Worker ui.SecureIndex = secureBlocks.AddUniq((const Byte *)data, dataSize);
521*f6dc9357SAndroid Build Coastguard Worker }
522*f6dc9357SAndroid Build Coastguard Worker */
523*f6dc9357SAndroid Build Coastguard Worker
524*f6dc9357SAndroid Build Coastguard Worker {
525*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
526*f6dc9357SAndroid Build Coastguard Worker RINOK(updateCallback->GetProperty(i, kpidPath, &prop))
527*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_EMPTY)
528*f6dc9357SAndroid Build Coastguard Worker {
529*f6dc9357SAndroid Build Coastguard Worker }
530*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_BSTR)
531*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
532*f6dc9357SAndroid Build Coastguard Worker else
533*f6dc9357SAndroid Build Coastguard Worker {
534*f6dc9357SAndroid Build Coastguard Worker name = prop.bstrVal;
535*f6dc9357SAndroid Build Coastguard Worker NItemName::ReplaceSlashes_OsToUnix(name);
536*f6dc9357SAndroid Build Coastguard Worker }
537*f6dc9357SAndroid Build Coastguard Worker }
538*f6dc9357SAndroid Build Coastguard Worker {
539*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
540*f6dc9357SAndroid Build Coastguard Worker RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop))
541*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_EMPTY)
542*f6dc9357SAndroid Build Coastguard Worker folderStatusIsDefined = false;
543*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_BOOL)
544*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
545*f6dc9357SAndroid Build Coastguard Worker else
546*f6dc9357SAndroid Build Coastguard Worker {
547*f6dc9357SAndroid Build Coastguard Worker ui.IsDir = (prop.boolVal != VARIANT_FALSE);
548*f6dc9357SAndroid Build Coastguard Worker folderStatusIsDefined = true;
549*f6dc9357SAndroid Build Coastguard Worker }
550*f6dc9357SAndroid Build Coastguard Worker }
551*f6dc9357SAndroid Build Coastguard Worker
552*f6dc9357SAndroid Build Coastguard Worker {
553*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
554*f6dc9357SAndroid Build Coastguard Worker RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop))
555*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_EMPTY)
556*f6dc9357SAndroid Build Coastguard Worker ui.IsAnti = false;
557*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_BOOL)
558*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
559*f6dc9357SAndroid Build Coastguard Worker else
560*f6dc9357SAndroid Build Coastguard Worker ui.IsAnti = (prop.boolVal != VARIANT_FALSE);
561*f6dc9357SAndroid Build Coastguard Worker }
562*f6dc9357SAndroid Build Coastguard Worker
563*f6dc9357SAndroid Build Coastguard Worker /*
564*f6dc9357SAndroid Build Coastguard Worker {
565*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
566*f6dc9357SAndroid Build Coastguard Worker RINOK(updateCallback->GetProperty(i, kpidIsAltStream, &prop));
567*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_EMPTY)
568*f6dc9357SAndroid Build Coastguard Worker isAltStream = false;
569*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_BOOL)
570*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
571*f6dc9357SAndroid Build Coastguard Worker else
572*f6dc9357SAndroid Build Coastguard Worker isAltStream = (prop.boolVal != VARIANT_FALSE);
573*f6dc9357SAndroid Build Coastguard Worker }
574*f6dc9357SAndroid Build Coastguard Worker */
575*f6dc9357SAndroid Build Coastguard Worker
576*f6dc9357SAndroid Build Coastguard Worker if (ui.IsAnti)
577*f6dc9357SAndroid Build Coastguard Worker {
578*f6dc9357SAndroid Build Coastguard Worker ui.AttribDefined = false;
579*f6dc9357SAndroid Build Coastguard Worker
580*f6dc9357SAndroid Build Coastguard Worker ui.CTimeDefined = false;
581*f6dc9357SAndroid Build Coastguard Worker ui.ATimeDefined = false;
582*f6dc9357SAndroid Build Coastguard Worker ui.MTimeDefined = false;
583*f6dc9357SAndroid Build Coastguard Worker
584*f6dc9357SAndroid Build Coastguard Worker ui.Size = 0;
585*f6dc9357SAndroid Build Coastguard Worker }
586*f6dc9357SAndroid Build Coastguard Worker
587*f6dc9357SAndroid Build Coastguard Worker if (!folderStatusIsDefined && ui.AttribDefined)
588*f6dc9357SAndroid Build Coastguard Worker ui.SetDirStatusFromAttrib();
589*f6dc9357SAndroid Build Coastguard Worker }
590*f6dc9357SAndroid Build Coastguard Worker else
591*f6dc9357SAndroid Build Coastguard Worker {
592*f6dc9357SAndroid Build Coastguard Worker /*
593*f6dc9357SAndroid Build Coastguard Worker if (_db.SecureIDs.IsEmpty())
594*f6dc9357SAndroid Build Coastguard Worker ui.SecureIndex = secureBlocks.AddUniq(NULL, 0);
595*f6dc9357SAndroid Build Coastguard Worker else
596*f6dc9357SAndroid Build Coastguard Worker {
597*f6dc9357SAndroid Build Coastguard Worker int id = _db.SecureIDs[ui.IndexInArchive];
598*f6dc9357SAndroid Build Coastguard Worker size_t offs = _db.SecureOffsets[id];
599*f6dc9357SAndroid Build Coastguard Worker size_t size = _db.SecureOffsets[id + 1] - offs;
600*f6dc9357SAndroid Build Coastguard Worker ui.SecureIndex = secureBlocks.AddUniq(_db.SecureBuf + offs, size);
601*f6dc9357SAndroid Build Coastguard Worker }
602*f6dc9357SAndroid Build Coastguard Worker */
603*f6dc9357SAndroid Build Coastguard Worker }
604*f6dc9357SAndroid Build Coastguard Worker
605*f6dc9357SAndroid Build Coastguard Worker /*
606*f6dc9357SAndroid Build Coastguard Worker {
607*f6dc9357SAndroid Build Coastguard Worker int folderIndex = 0;
608*f6dc9357SAndroid Build Coastguard Worker if (_useParents)
609*f6dc9357SAndroid Build Coastguard Worker {
610*f6dc9357SAndroid Build Coastguard Worker int j;
611*f6dc9357SAndroid Build Coastguard Worker s.Empty();
612*f6dc9357SAndroid Build Coastguard Worker for (j = 0; j < name.Len(); j++)
613*f6dc9357SAndroid Build Coastguard Worker {
614*f6dc9357SAndroid Build Coastguard Worker wchar_t c = name[j];
615*f6dc9357SAndroid Build Coastguard Worker if (IsCharDirLimiter(c))
616*f6dc9357SAndroid Build Coastguard Worker {
617*f6dc9357SAndroid Build Coastguard Worker folderIndex = AddFolder(treeFolders, folderIndex, s);
618*f6dc9357SAndroid Build Coastguard Worker s.Empty();
619*f6dc9357SAndroid Build Coastguard Worker continue;
620*f6dc9357SAndroid Build Coastguard Worker }
621*f6dc9357SAndroid Build Coastguard Worker s += c;
622*f6dc9357SAndroid Build Coastguard Worker }
623*f6dc9357SAndroid Build Coastguard Worker if (isAltStream)
624*f6dc9357SAndroid Build Coastguard Worker {
625*f6dc9357SAndroid Build Coastguard Worker int colonPos = s.Find(':');
626*f6dc9357SAndroid Build Coastguard Worker if (colonPos < 0)
627*f6dc9357SAndroid Build Coastguard Worker {
628*f6dc9357SAndroid Build Coastguard Worker // isAltStream = false;
629*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
630*f6dc9357SAndroid Build Coastguard Worker }
631*f6dc9357SAndroid Build Coastguard Worker UString mainName = s.Left(colonPos);
632*f6dc9357SAndroid Build Coastguard Worker int newFolderIndex = AddFolder(treeFolders, folderIndex, mainName);
633*f6dc9357SAndroid Build Coastguard Worker if (treeFolders[newFolderIndex].UpdateItemIndex < 0)
634*f6dc9357SAndroid Build Coastguard Worker {
635*f6dc9357SAndroid Build Coastguard Worker for (int j = updateItems.Size() - 1; j >= 0; j--)
636*f6dc9357SAndroid Build Coastguard Worker {
637*f6dc9357SAndroid Build Coastguard Worker CUpdateItem &ui2 = updateItems[j];
638*f6dc9357SAndroid Build Coastguard Worker if (ui2.ParentFolderIndex == folderIndex
639*f6dc9357SAndroid Build Coastguard Worker && ui2.Name == mainName)
640*f6dc9357SAndroid Build Coastguard Worker {
641*f6dc9357SAndroid Build Coastguard Worker ui2.TreeFolderIndex = newFolderIndex;
642*f6dc9357SAndroid Build Coastguard Worker treeFolders[newFolderIndex].UpdateItemIndex = j;
643*f6dc9357SAndroid Build Coastguard Worker }
644*f6dc9357SAndroid Build Coastguard Worker }
645*f6dc9357SAndroid Build Coastguard Worker }
646*f6dc9357SAndroid Build Coastguard Worker folderIndex = newFolderIndex;
647*f6dc9357SAndroid Build Coastguard Worker s.Delete(0, colonPos + 1);
648*f6dc9357SAndroid Build Coastguard Worker }
649*f6dc9357SAndroid Build Coastguard Worker ui.Name = s;
650*f6dc9357SAndroid Build Coastguard Worker }
651*f6dc9357SAndroid Build Coastguard Worker else
652*f6dc9357SAndroid Build Coastguard Worker ui.Name = name;
653*f6dc9357SAndroid Build Coastguard Worker ui.IsAltStream = isAltStream;
654*f6dc9357SAndroid Build Coastguard Worker ui.ParentFolderIndex = folderIndex;
655*f6dc9357SAndroid Build Coastguard Worker ui.TreeFolderIndex = -1;
656*f6dc9357SAndroid Build Coastguard Worker if (ui.IsDir && !s.IsEmpty())
657*f6dc9357SAndroid Build Coastguard Worker {
658*f6dc9357SAndroid Build Coastguard Worker ui.TreeFolderIndex = AddFolder(treeFolders, folderIndex, s);
659*f6dc9357SAndroid Build Coastguard Worker treeFolders[ui.TreeFolderIndex].UpdateItemIndex = updateItems.Size();
660*f6dc9357SAndroid Build Coastguard Worker }
661*f6dc9357SAndroid Build Coastguard Worker }
662*f6dc9357SAndroid Build Coastguard Worker */
663*f6dc9357SAndroid Build Coastguard Worker ui.Name = name;
664*f6dc9357SAndroid Build Coastguard Worker
665*f6dc9357SAndroid Build Coastguard Worker if (ui.NewData)
666*f6dc9357SAndroid Build Coastguard Worker {
667*f6dc9357SAndroid Build Coastguard Worker ui.Size = 0;
668*f6dc9357SAndroid Build Coastguard Worker if (!ui.IsDir)
669*f6dc9357SAndroid Build Coastguard Worker {
670*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
671*f6dc9357SAndroid Build Coastguard Worker RINOK(updateCallback->GetProperty(i, kpidSize, &prop))
672*f6dc9357SAndroid Build Coastguard Worker if (prop.vt != VT_UI8)
673*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
674*f6dc9357SAndroid Build Coastguard Worker ui.Size = (UInt64)prop.uhVal.QuadPart;
675*f6dc9357SAndroid Build Coastguard Worker if (ui.Size != 0 && ui.IsAnti)
676*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
677*f6dc9357SAndroid Build Coastguard Worker }
678*f6dc9357SAndroid Build Coastguard Worker }
679*f6dc9357SAndroid Build Coastguard Worker
680*f6dc9357SAndroid Build Coastguard Worker updateItems.Add(ui);
681*f6dc9357SAndroid Build Coastguard Worker }
682*f6dc9357SAndroid Build Coastguard Worker
683*f6dc9357SAndroid Build Coastguard Worker /*
684*f6dc9357SAndroid Build Coastguard Worker FillSortIndex(treeFolders, 0, 0);
685*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < (UInt32)updateItems.Size(); i++)
686*f6dc9357SAndroid Build Coastguard Worker {
687*f6dc9357SAndroid Build Coastguard Worker CUpdateItem &ui = updateItems[i];
688*f6dc9357SAndroid Build Coastguard Worker ui.ParentSortIndex = treeFolders[ui.ParentFolderIndex].SortIndex;
689*f6dc9357SAndroid Build Coastguard Worker ui.ParentSortIndexEnd = treeFolders[ui.ParentFolderIndex].SortIndexEnd;
690*f6dc9357SAndroid Build Coastguard Worker }
691*f6dc9357SAndroid Build Coastguard Worker */
692*f6dc9357SAndroid Build Coastguard Worker
693*f6dc9357SAndroid Build Coastguard Worker CCompressionMethodMode methodMode, headerMethod;
694*f6dc9357SAndroid Build Coastguard Worker
695*f6dc9357SAndroid Build Coastguard Worker methodMode.MemoryUsageLimit = _memUsage_Compress;
696*f6dc9357SAndroid Build Coastguard Worker methodMode.MemoryUsageLimit_WasSet = _memUsage_WasSet;
697*f6dc9357SAndroid Build Coastguard Worker
698*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
699*f6dc9357SAndroid Build Coastguard Worker {
700*f6dc9357SAndroid Build Coastguard Worker UInt32 numThreads = _numThreads;
701*f6dc9357SAndroid Build Coastguard Worker const UInt32 kNumThreads_Max = 1024;
702*f6dc9357SAndroid Build Coastguard Worker if (numThreads > kNumThreads_Max)
703*f6dc9357SAndroid Build Coastguard Worker numThreads = kNumThreads_Max;
704*f6dc9357SAndroid Build Coastguard Worker methodMode.NumThreads = numThreads;
705*f6dc9357SAndroid Build Coastguard Worker methodMode.NumThreads_WasForced = _numThreads_WasForced;
706*f6dc9357SAndroid Build Coastguard Worker methodMode.MultiThreadMixer = _useMultiThreadMixer;
707*f6dc9357SAndroid Build Coastguard Worker // headerMethod.NumThreads = 1;
708*f6dc9357SAndroid Build Coastguard Worker headerMethod.MultiThreadMixer = _useMultiThreadMixer;
709*f6dc9357SAndroid Build Coastguard Worker }
710*f6dc9357SAndroid Build Coastguard Worker #endif
711*f6dc9357SAndroid Build Coastguard Worker
712*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = SetMainMethod(methodMode);
713*f6dc9357SAndroid Build Coastguard Worker RINOK(res)
714*f6dc9357SAndroid Build Coastguard Worker
715*f6dc9357SAndroid Build Coastguard Worker RINOK(SetHeaderMethod(headerMethod))
716*f6dc9357SAndroid Build Coastguard Worker
717*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
718*f6dc9357SAndroid Build Coastguard Worker ICryptoGetTextPassword2,
719*f6dc9357SAndroid Build Coastguard Worker getPassword2, updateCallback)
720*f6dc9357SAndroid Build Coastguard Worker
721*f6dc9357SAndroid Build Coastguard Worker methodMode.PasswordIsDefined = false;
722*f6dc9357SAndroid Build Coastguard Worker methodMode.Password.Wipe_and_Empty();
723*f6dc9357SAndroid Build Coastguard Worker if (getPassword2)
724*f6dc9357SAndroid Build Coastguard Worker {
725*f6dc9357SAndroid Build Coastguard Worker CMyComBSTR_Wipe password;
726*f6dc9357SAndroid Build Coastguard Worker Int32 passwordIsDefined;
727*f6dc9357SAndroid Build Coastguard Worker RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password))
728*f6dc9357SAndroid Build Coastguard Worker methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
729*f6dc9357SAndroid Build Coastguard Worker if (methodMode.PasswordIsDefined && password)
730*f6dc9357SAndroid Build Coastguard Worker methodMode.Password = password;
731*f6dc9357SAndroid Build Coastguard Worker }
732*f6dc9357SAndroid Build Coastguard Worker
733*f6dc9357SAndroid Build Coastguard Worker bool compressMainHeader = _compressHeaders; // check it
734*f6dc9357SAndroid Build Coastguard Worker
735*f6dc9357SAndroid Build Coastguard Worker bool encryptHeaders = false;
736*f6dc9357SAndroid Build Coastguard Worker
737*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
738*f6dc9357SAndroid Build Coastguard Worker if (!methodMode.PasswordIsDefined && _passwordIsDefined)
739*f6dc9357SAndroid Build Coastguard Worker {
740*f6dc9357SAndroid Build Coastguard Worker // if header is compressed, we use that password for updated archive
741*f6dc9357SAndroid Build Coastguard Worker methodMode.PasswordIsDefined = true;
742*f6dc9357SAndroid Build Coastguard Worker methodMode.Password = _password;
743*f6dc9357SAndroid Build Coastguard Worker }
744*f6dc9357SAndroid Build Coastguard Worker #endif
745*f6dc9357SAndroid Build Coastguard Worker
746*f6dc9357SAndroid Build Coastguard Worker if (methodMode.PasswordIsDefined)
747*f6dc9357SAndroid Build Coastguard Worker {
748*f6dc9357SAndroid Build Coastguard Worker if (_encryptHeadersSpecified)
749*f6dc9357SAndroid Build Coastguard Worker encryptHeaders = _encryptHeaders;
750*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
751*f6dc9357SAndroid Build Coastguard Worker else
752*f6dc9357SAndroid Build Coastguard Worker encryptHeaders = _passwordIsDefined;
753*f6dc9357SAndroid Build Coastguard Worker #endif
754*f6dc9357SAndroid Build Coastguard Worker compressMainHeader = true;
755*f6dc9357SAndroid Build Coastguard Worker if (encryptHeaders)
756*f6dc9357SAndroid Build Coastguard Worker {
757*f6dc9357SAndroid Build Coastguard Worker headerMethod.PasswordIsDefined = methodMode.PasswordIsDefined;
758*f6dc9357SAndroid Build Coastguard Worker headerMethod.Password = methodMode.Password;
759*f6dc9357SAndroid Build Coastguard Worker }
760*f6dc9357SAndroid Build Coastguard Worker }
761*f6dc9357SAndroid Build Coastguard Worker
762*f6dc9357SAndroid Build Coastguard Worker if (numItems < 2)
763*f6dc9357SAndroid Build Coastguard Worker compressMainHeader = false;
764*f6dc9357SAndroid Build Coastguard Worker
765*f6dc9357SAndroid Build Coastguard Worker const int level = GetLevel();
766*f6dc9357SAndroid Build Coastguard Worker
767*f6dc9357SAndroid Build Coastguard Worker CUpdateOptions options;
768*f6dc9357SAndroid Build Coastguard Worker options.Need_CTime = need_CTime;
769*f6dc9357SAndroid Build Coastguard Worker options.Need_ATime = need_ATime;
770*f6dc9357SAndroid Build Coastguard Worker options.Need_MTime = need_MTime;
771*f6dc9357SAndroid Build Coastguard Worker options.Need_Attrib = need_Attrib;
772*f6dc9357SAndroid Build Coastguard Worker // options.Need_Crc = (_crcSize != 0); // for debug
773*f6dc9357SAndroid Build Coastguard Worker
774*f6dc9357SAndroid Build Coastguard Worker options.Method = &methodMode;
775*f6dc9357SAndroid Build Coastguard Worker options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : NULL;
776*f6dc9357SAndroid Build Coastguard Worker options.UseFilters = (level != 0 && _autoFilter && !methodMode.Filter_was_Inserted);
777*f6dc9357SAndroid Build Coastguard Worker options.MaxFilter = (level >= 8);
778*f6dc9357SAndroid Build Coastguard Worker options.AnalysisLevel = GetAnalysisLevel();
779*f6dc9357SAndroid Build Coastguard Worker
780*f6dc9357SAndroid Build Coastguard Worker options.SetFilterSupporting_ver_enabled_disabled(
781*f6dc9357SAndroid Build Coastguard Worker _decoderCompatibilityVersion,
782*f6dc9357SAndroid Build Coastguard Worker _enabledFilters,
783*f6dc9357SAndroid Build Coastguard Worker _disabledFilters);
784*f6dc9357SAndroid Build Coastguard Worker
785*f6dc9357SAndroid Build Coastguard Worker options.HeaderOptions.CompressMainHeader = compressMainHeader;
786*f6dc9357SAndroid Build Coastguard Worker /*
787*f6dc9357SAndroid Build Coastguard Worker options.HeaderOptions.WriteCTime = Write_CTime;
788*f6dc9357SAndroid Build Coastguard Worker options.HeaderOptions.WriteATime = Write_ATime;
789*f6dc9357SAndroid Build Coastguard Worker options.HeaderOptions.WriteMTime = Write_MTime;
790*f6dc9357SAndroid Build Coastguard Worker options.HeaderOptions.WriteAttrib = Write_Attrib;
791*f6dc9357SAndroid Build Coastguard Worker */
792*f6dc9357SAndroid Build Coastguard Worker
793*f6dc9357SAndroid Build Coastguard Worker options.NumSolidFiles = _numSolidFiles;
794*f6dc9357SAndroid Build Coastguard Worker options.NumSolidBytes = _numSolidBytes;
795*f6dc9357SAndroid Build Coastguard Worker options.SolidExtension = _solidExtension;
796*f6dc9357SAndroid Build Coastguard Worker options.UseTypeSorting = _useTypeSorting;
797*f6dc9357SAndroid Build Coastguard Worker
798*f6dc9357SAndroid Build Coastguard Worker options.RemoveSfxBlock = _removeSfxBlock;
799*f6dc9357SAndroid Build Coastguard Worker // options.VolumeMode = _volumeMode;
800*f6dc9357SAndroid Build Coastguard Worker
801*f6dc9357SAndroid Build Coastguard Worker options.MultiThreadMixer = _useMultiThreadMixer;
802*f6dc9357SAndroid Build Coastguard Worker
803*f6dc9357SAndroid Build Coastguard Worker /*
804*f6dc9357SAndroid Build Coastguard Worker if (secureBlocks.Sorted.Size() > 1)
805*f6dc9357SAndroid Build Coastguard Worker {
806*f6dc9357SAndroid Build Coastguard Worker secureBlocks.GetReverseMap();
807*f6dc9357SAndroid Build Coastguard Worker for (int i = 0; i < updateItems.Size(); i++)
808*f6dc9357SAndroid Build Coastguard Worker {
809*f6dc9357SAndroid Build Coastguard Worker int &secureIndex = updateItems[i].SecureIndex;
810*f6dc9357SAndroid Build Coastguard Worker secureIndex = secureBlocks.BufIndexToSortedIndex[secureIndex];
811*f6dc9357SAndroid Build Coastguard Worker }
812*f6dc9357SAndroid Build Coastguard Worker }
813*f6dc9357SAndroid Build Coastguard Worker */
814*f6dc9357SAndroid Build Coastguard Worker
815*f6dc9357SAndroid Build Coastguard Worker return Update(
816*f6dc9357SAndroid Build Coastguard Worker EXTERNAL_CODECS_VARS
817*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_7Z_VOL
818*f6dc9357SAndroid Build Coastguard Worker volume ? volume->Stream: 0,
819*f6dc9357SAndroid Build Coastguard Worker volume ? db : 0,
820*f6dc9357SAndroid Build Coastguard Worker #else
821*f6dc9357SAndroid Build Coastguard Worker _inStream,
822*f6dc9357SAndroid Build Coastguard Worker db,
823*f6dc9357SAndroid Build Coastguard Worker #endif
824*f6dc9357SAndroid Build Coastguard Worker updateItems,
825*f6dc9357SAndroid Build Coastguard Worker // treeFolders,
826*f6dc9357SAndroid Build Coastguard Worker // secureBlocks,
827*f6dc9357SAndroid Build Coastguard Worker outStream, updateCallback, options);
828*f6dc9357SAndroid Build Coastguard Worker
829*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
830*f6dc9357SAndroid Build Coastguard Worker }
831*f6dc9357SAndroid Build Coastguard Worker
ParseBond(UString & srcString,UInt32 & coder,UInt32 & stream)832*f6dc9357SAndroid Build Coastguard Worker static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
833*f6dc9357SAndroid Build Coastguard Worker {
834*f6dc9357SAndroid Build Coastguard Worker stream = 0;
835*f6dc9357SAndroid Build Coastguard Worker {
836*f6dc9357SAndroid Build Coastguard Worker const unsigned index = ParseStringToUInt32(srcString, coder);
837*f6dc9357SAndroid Build Coastguard Worker if (index == 0)
838*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
839*f6dc9357SAndroid Build Coastguard Worker srcString.DeleteFrontal(index);
840*f6dc9357SAndroid Build Coastguard Worker }
841*f6dc9357SAndroid Build Coastguard Worker if (srcString[0] == 's')
842*f6dc9357SAndroid Build Coastguard Worker {
843*f6dc9357SAndroid Build Coastguard Worker srcString.Delete(0);
844*f6dc9357SAndroid Build Coastguard Worker const unsigned index = ParseStringToUInt32(srcString, stream);
845*f6dc9357SAndroid Build Coastguard Worker if (index == 0)
846*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
847*f6dc9357SAndroid Build Coastguard Worker srcString.DeleteFrontal(index);
848*f6dc9357SAndroid Build Coastguard Worker }
849*f6dc9357SAndroid Build Coastguard Worker return S_OK;
850*f6dc9357SAndroid Build Coastguard Worker }
851*f6dc9357SAndroid Build Coastguard Worker
InitProps7z()852*f6dc9357SAndroid Build Coastguard Worker void COutHandler::InitProps7z()
853*f6dc9357SAndroid Build Coastguard Worker {
854*f6dc9357SAndroid Build Coastguard Worker _removeSfxBlock = false;
855*f6dc9357SAndroid Build Coastguard Worker _compressHeaders = true;
856*f6dc9357SAndroid Build Coastguard Worker _encryptHeadersSpecified = false;
857*f6dc9357SAndroid Build Coastguard Worker _encryptHeaders = false;
858*f6dc9357SAndroid Build Coastguard Worker // _useParents = false;
859*f6dc9357SAndroid Build Coastguard Worker
860*f6dc9357SAndroid Build Coastguard Worker TimeOptions.Init();
861*f6dc9357SAndroid Build Coastguard Worker Write_Attrib.Init();
862*f6dc9357SAndroid Build Coastguard Worker
863*f6dc9357SAndroid Build Coastguard Worker _useMultiThreadMixer = true;
864*f6dc9357SAndroid Build Coastguard Worker
865*f6dc9357SAndroid Build Coastguard Worker // _volumeMode = false;
866*f6dc9357SAndroid Build Coastguard Worker
867*f6dc9357SAndroid Build Coastguard Worker InitSolid();
868*f6dc9357SAndroid Build Coastguard Worker _useTypeSorting = false;
869*f6dc9357SAndroid Build Coastguard Worker
870*f6dc9357SAndroid Build Coastguard Worker _decoderCompatibilityVersion = k_decoderCompatibilityVersion;
871*f6dc9357SAndroid Build Coastguard Worker _enabledFilters.Clear();
872*f6dc9357SAndroid Build Coastguard Worker _disabledFilters.Clear();
873*f6dc9357SAndroid Build Coastguard Worker }
874*f6dc9357SAndroid Build Coastguard Worker
InitProps()875*f6dc9357SAndroid Build Coastguard Worker void COutHandler::InitProps()
876*f6dc9357SAndroid Build Coastguard Worker {
877*f6dc9357SAndroid Build Coastguard Worker CMultiMethodProps::Init();
878*f6dc9357SAndroid Build Coastguard Worker InitProps7z();
879*f6dc9357SAndroid Build Coastguard Worker }
880*f6dc9357SAndroid Build Coastguard Worker
881*f6dc9357SAndroid Build Coastguard Worker
882*f6dc9357SAndroid Build Coastguard Worker
SetSolidFromString(const UString & s)883*f6dc9357SAndroid Build Coastguard Worker HRESULT COutHandler::SetSolidFromString(const UString &s)
884*f6dc9357SAndroid Build Coastguard Worker {
885*f6dc9357SAndroid Build Coastguard Worker UString s2 = s;
886*f6dc9357SAndroid Build Coastguard Worker s2.MakeLower_Ascii();
887*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < s2.Len();)
888*f6dc9357SAndroid Build Coastguard Worker {
889*f6dc9357SAndroid Build Coastguard Worker const wchar_t *start = ((const wchar_t *)s2) + i;
890*f6dc9357SAndroid Build Coastguard Worker const wchar_t *end;
891*f6dc9357SAndroid Build Coastguard Worker UInt64 v = ConvertStringToUInt64(start, &end);
892*f6dc9357SAndroid Build Coastguard Worker if (start == end)
893*f6dc9357SAndroid Build Coastguard Worker {
894*f6dc9357SAndroid Build Coastguard Worker if (s2[i++] != 'e')
895*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
896*f6dc9357SAndroid Build Coastguard Worker _solidExtension = true;
897*f6dc9357SAndroid Build Coastguard Worker continue;
898*f6dc9357SAndroid Build Coastguard Worker }
899*f6dc9357SAndroid Build Coastguard Worker i += (unsigned)(end - start);
900*f6dc9357SAndroid Build Coastguard Worker if (i == s2.Len())
901*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
902*f6dc9357SAndroid Build Coastguard Worker const wchar_t c = s2[i++];
903*f6dc9357SAndroid Build Coastguard Worker if (c == 'f')
904*f6dc9357SAndroid Build Coastguard Worker {
905*f6dc9357SAndroid Build Coastguard Worker if (v < 1)
906*f6dc9357SAndroid Build Coastguard Worker v = 1;
907*f6dc9357SAndroid Build Coastguard Worker _numSolidFiles = v;
908*f6dc9357SAndroid Build Coastguard Worker }
909*f6dc9357SAndroid Build Coastguard Worker else
910*f6dc9357SAndroid Build Coastguard Worker {
911*f6dc9357SAndroid Build Coastguard Worker unsigned numBits;
912*f6dc9357SAndroid Build Coastguard Worker switch (c)
913*f6dc9357SAndroid Build Coastguard Worker {
914*f6dc9357SAndroid Build Coastguard Worker case 'b': numBits = 0; break;
915*f6dc9357SAndroid Build Coastguard Worker case 'k': numBits = 10; break;
916*f6dc9357SAndroid Build Coastguard Worker case 'm': numBits = 20; break;
917*f6dc9357SAndroid Build Coastguard Worker case 'g': numBits = 30; break;
918*f6dc9357SAndroid Build Coastguard Worker case 't': numBits = 40; break;
919*f6dc9357SAndroid Build Coastguard Worker default: return E_INVALIDARG;
920*f6dc9357SAndroid Build Coastguard Worker }
921*f6dc9357SAndroid Build Coastguard Worker _numSolidBytes = (v << numBits);
922*f6dc9357SAndroid Build Coastguard Worker _numSolidBytesDefined = true;
923*f6dc9357SAndroid Build Coastguard Worker /*
924*f6dc9357SAndroid Build Coastguard Worker if (_numSolidBytes == 0)
925*f6dc9357SAndroid Build Coastguard Worker _numSolidFiles = 1;
926*f6dc9357SAndroid Build Coastguard Worker */
927*f6dc9357SAndroid Build Coastguard Worker }
928*f6dc9357SAndroid Build Coastguard Worker }
929*f6dc9357SAndroid Build Coastguard Worker return S_OK;
930*f6dc9357SAndroid Build Coastguard Worker }
931*f6dc9357SAndroid Build Coastguard Worker
SetSolidFromPROPVARIANT(const PROPVARIANT & value)932*f6dc9357SAndroid Build Coastguard Worker HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value)
933*f6dc9357SAndroid Build Coastguard Worker {
934*f6dc9357SAndroid Build Coastguard Worker bool isSolid;
935*f6dc9357SAndroid Build Coastguard Worker switch (value.vt)
936*f6dc9357SAndroid Build Coastguard Worker {
937*f6dc9357SAndroid Build Coastguard Worker case VT_EMPTY: isSolid = true; break;
938*f6dc9357SAndroid Build Coastguard Worker case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break;
939*f6dc9357SAndroid Build Coastguard Worker case VT_BSTR:
940*f6dc9357SAndroid Build Coastguard Worker if (StringToBool(value.bstrVal, isSolid))
941*f6dc9357SAndroid Build Coastguard Worker break;
942*f6dc9357SAndroid Build Coastguard Worker return SetSolidFromString(value.bstrVal);
943*f6dc9357SAndroid Build Coastguard Worker default: return E_INVALIDARG;
944*f6dc9357SAndroid Build Coastguard Worker }
945*f6dc9357SAndroid Build Coastguard Worker if (isSolid)
946*f6dc9357SAndroid Build Coastguard Worker InitSolid();
947*f6dc9357SAndroid Build Coastguard Worker else
948*f6dc9357SAndroid Build Coastguard Worker _numSolidFiles = 1;
949*f6dc9357SAndroid Build Coastguard Worker return S_OK;
950*f6dc9357SAndroid Build Coastguard Worker }
951*f6dc9357SAndroid Build Coastguard Worker
PROPVARIANT_to_BoolPair(const PROPVARIANT & prop,CBoolPair & dest)952*f6dc9357SAndroid Build Coastguard Worker static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest)
953*f6dc9357SAndroid Build Coastguard Worker {
954*f6dc9357SAndroid Build Coastguard Worker RINOK(PROPVARIANT_to_bool(prop, dest.Val))
955*f6dc9357SAndroid Build Coastguard Worker dest.Def = true;
956*f6dc9357SAndroid Build Coastguard Worker return S_OK;
957*f6dc9357SAndroid Build Coastguard Worker }
958*f6dc9357SAndroid Build Coastguard Worker
959*f6dc9357SAndroid Build Coastguard Worker struct C_Id_Name_pair
960*f6dc9357SAndroid Build Coastguard Worker {
961*f6dc9357SAndroid Build Coastguard Worker UInt32 Id;
962*f6dc9357SAndroid Build Coastguard Worker const char *Name;
963*f6dc9357SAndroid Build Coastguard Worker };
964*f6dc9357SAndroid Build Coastguard Worker
965*f6dc9357SAndroid Build Coastguard Worker static const C_Id_Name_pair g_filter_pairs[] =
966*f6dc9357SAndroid Build Coastguard Worker {
967*f6dc9357SAndroid Build Coastguard Worker { k_Delta, "Delta" },
968*f6dc9357SAndroid Build Coastguard Worker { k_ARM64, "ARM64" },
969*f6dc9357SAndroid Build Coastguard Worker { k_RISCV, "RISCV" },
970*f6dc9357SAndroid Build Coastguard Worker { k_SWAP2, "SWAP2" },
971*f6dc9357SAndroid Build Coastguard Worker { k_SWAP4, "SWAP4" },
972*f6dc9357SAndroid Build Coastguard Worker { k_BCJ, "BCJ" },
973*f6dc9357SAndroid Build Coastguard Worker { k_BCJ2 , "BCJ2" },
974*f6dc9357SAndroid Build Coastguard Worker { k_PPC, "PPC" },
975*f6dc9357SAndroid Build Coastguard Worker { k_IA64, "IA64" },
976*f6dc9357SAndroid Build Coastguard Worker { k_ARM, "ARM" },
977*f6dc9357SAndroid Build Coastguard Worker { k_ARMT, "ARMT" },
978*f6dc9357SAndroid Build Coastguard Worker { k_SPARC, "SPARC" }
979*f6dc9357SAndroid Build Coastguard Worker };
980*f6dc9357SAndroid Build Coastguard Worker
981*f6dc9357SAndroid Build Coastguard Worker
SetProperty(const wchar_t * nameSpec,const PROPVARIANT & value)982*f6dc9357SAndroid Build Coastguard Worker HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
983*f6dc9357SAndroid Build Coastguard Worker {
984*f6dc9357SAndroid Build Coastguard Worker UString name = nameSpec;
985*f6dc9357SAndroid Build Coastguard Worker name.MakeLower_Ascii();
986*f6dc9357SAndroid Build Coastguard Worker if (name.IsEmpty())
987*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
988*f6dc9357SAndroid Build Coastguard Worker
989*f6dc9357SAndroid Build Coastguard Worker if (name[0] == L's')
990*f6dc9357SAndroid Build Coastguard Worker {
991*f6dc9357SAndroid Build Coastguard Worker name.Delete(0);
992*f6dc9357SAndroid Build Coastguard Worker if (name.IsEmpty())
993*f6dc9357SAndroid Build Coastguard Worker return SetSolidFromPROPVARIANT(value);
994*f6dc9357SAndroid Build Coastguard Worker if (value.vt != VT_EMPTY)
995*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
996*f6dc9357SAndroid Build Coastguard Worker return SetSolidFromString(name);
997*f6dc9357SAndroid Build Coastguard Worker }
998*f6dc9357SAndroid Build Coastguard Worker
999*f6dc9357SAndroid Build Coastguard Worker UInt32 number;
1000*f6dc9357SAndroid Build Coastguard Worker const unsigned index = ParseStringToUInt32(name, number);
1001*f6dc9357SAndroid Build Coastguard Worker // UString realName = name.Ptr(index);
1002*f6dc9357SAndroid Build Coastguard Worker if (index == 0)
1003*f6dc9357SAndroid Build Coastguard Worker {
1004*f6dc9357SAndroid Build Coastguard Worker if (name.IsEqualTo("rsfx")) return PROPVARIANT_to_bool(value, _removeSfxBlock);
1005*f6dc9357SAndroid Build Coastguard Worker if (name.IsEqualTo("hc")) return PROPVARIANT_to_bool(value, _compressHeaders);
1006*f6dc9357SAndroid Build Coastguard Worker // if (name.IsEqualToNoCase(L"HS")) return PROPVARIANT_to_bool(value, _useParents);
1007*f6dc9357SAndroid Build Coastguard Worker
1008*f6dc9357SAndroid Build Coastguard Worker if (name.IsEqualTo("hcf"))
1009*f6dc9357SAndroid Build Coastguard Worker {
1010*f6dc9357SAndroid Build Coastguard Worker bool compressHeadersFull = true;
1011*f6dc9357SAndroid Build Coastguard Worker RINOK(PROPVARIANT_to_bool(value, compressHeadersFull))
1012*f6dc9357SAndroid Build Coastguard Worker return compressHeadersFull ? S_OK: E_INVALIDARG;
1013*f6dc9357SAndroid Build Coastguard Worker }
1014*f6dc9357SAndroid Build Coastguard Worker
1015*f6dc9357SAndroid Build Coastguard Worker if (name.IsEqualTo("he"))
1016*f6dc9357SAndroid Build Coastguard Worker {
1017*f6dc9357SAndroid Build Coastguard Worker RINOK(PROPVARIANT_to_bool(value, _encryptHeaders))
1018*f6dc9357SAndroid Build Coastguard Worker _encryptHeadersSpecified = true;
1019*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1020*f6dc9357SAndroid Build Coastguard Worker }
1021*f6dc9357SAndroid Build Coastguard Worker
1022*f6dc9357SAndroid Build Coastguard Worker {
1023*f6dc9357SAndroid Build Coastguard Worker bool processed;
1024*f6dc9357SAndroid Build Coastguard Worker RINOK(TimeOptions.Parse(name, value, processed))
1025*f6dc9357SAndroid Build Coastguard Worker if (processed)
1026*f6dc9357SAndroid Build Coastguard Worker {
1027*f6dc9357SAndroid Build Coastguard Worker if ( TimeOptions.Prec != (UInt32)(Int32)-1
1028*f6dc9357SAndroid Build Coastguard Worker && TimeOptions.Prec != k_PropVar_TimePrec_0
1029*f6dc9357SAndroid Build Coastguard Worker && TimeOptions.Prec != k_PropVar_TimePrec_HighPrec
1030*f6dc9357SAndroid Build Coastguard Worker && TimeOptions.Prec != k_PropVar_TimePrec_100ns)
1031*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
1032*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1033*f6dc9357SAndroid Build Coastguard Worker }
1034*f6dc9357SAndroid Build Coastguard Worker }
1035*f6dc9357SAndroid Build Coastguard Worker
1036*f6dc9357SAndroid Build Coastguard Worker if (name.IsEqualTo("tr")) return PROPVARIANT_to_BoolPair(value, Write_Attrib);
1037*f6dc9357SAndroid Build Coastguard Worker
1038*f6dc9357SAndroid Build Coastguard Worker if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
1039*f6dc9357SAndroid Build Coastguard Worker
1040*f6dc9357SAndroid Build Coastguard Worker if (name.IsEqualTo("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting);
1041*f6dc9357SAndroid Build Coastguard Worker
1042*f6dc9357SAndroid Build Coastguard Worker if (name.IsPrefixedBy_Ascii_NoCase("yv"))
1043*f6dc9357SAndroid Build Coastguard Worker {
1044*f6dc9357SAndroid Build Coastguard Worker name.Delete(0, 2);
1045*f6dc9357SAndroid Build Coastguard Worker UInt32 v = 1 << 16; // if no number is noit specified, we use big value
1046*f6dc9357SAndroid Build Coastguard Worker RINOK(ParsePropToUInt32(name, value, v))
1047*f6dc9357SAndroid Build Coastguard Worker _decoderCompatibilityVersion = v;
1048*f6dc9357SAndroid Build Coastguard Worker // if (v == 0) _decoderCompatibilityVersion = k_decoderCompatibilityVersion;
1049*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1050*f6dc9357SAndroid Build Coastguard Worker }
1051*f6dc9357SAndroid Build Coastguard Worker
1052*f6dc9357SAndroid Build Coastguard Worker if (name.IsPrefixedBy_Ascii_NoCase("yf"))
1053*f6dc9357SAndroid Build Coastguard Worker {
1054*f6dc9357SAndroid Build Coastguard Worker name.Delete(0, 2);
1055*f6dc9357SAndroid Build Coastguard Worker CUIntVector *vec;
1056*f6dc9357SAndroid Build Coastguard Worker if (name.IsEqualTo_Ascii_NoCase("a")) vec = &_enabledFilters;
1057*f6dc9357SAndroid Build Coastguard Worker else if (name.IsEqualTo_Ascii_NoCase("d")) vec = &_disabledFilters;
1058*f6dc9357SAndroid Build Coastguard Worker else return E_INVALIDARG;
1059*f6dc9357SAndroid Build Coastguard Worker
1060*f6dc9357SAndroid Build Coastguard Worker if (value.vt != VT_BSTR)
1061*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
1062*f6dc9357SAndroid Build Coastguard Worker for (unsigned k = 0;; k++)
1063*f6dc9357SAndroid Build Coastguard Worker {
1064*f6dc9357SAndroid Build Coastguard Worker if (k == Z7_ARRAY_SIZE(g_filter_pairs))
1065*f6dc9357SAndroid Build Coastguard Worker {
1066*f6dc9357SAndroid Build Coastguard Worker // maybe we can ignore unsupported filter names here?
1067*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
1068*f6dc9357SAndroid Build Coastguard Worker }
1069*f6dc9357SAndroid Build Coastguard Worker const C_Id_Name_pair &pair = g_filter_pairs[k];
1070*f6dc9357SAndroid Build Coastguard Worker if (StringsAreEqualNoCase_Ascii(value.bstrVal, pair.Name))
1071*f6dc9357SAndroid Build Coastguard Worker {
1072*f6dc9357SAndroid Build Coastguard Worker vec->AddToUniqueSorted(pair.Id);
1073*f6dc9357SAndroid Build Coastguard Worker break;
1074*f6dc9357SAndroid Build Coastguard Worker }
1075*f6dc9357SAndroid Build Coastguard Worker }
1076*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1077*f6dc9357SAndroid Build Coastguard Worker }
1078*f6dc9357SAndroid Build Coastguard Worker
1079*f6dc9357SAndroid Build Coastguard Worker // if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode);
1080*f6dc9357SAndroid Build Coastguard Worker }
1081*f6dc9357SAndroid Build Coastguard Worker return CMultiMethodProps::SetProperty(name, value);
1082*f6dc9357SAndroid Build Coastguard Worker }
1083*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::SetProperties (const wchar_t * const * names,const PROPVARIANT * values,UInt32 numProps))1084*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
1085*f6dc9357SAndroid Build Coastguard Worker {
1086*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
1087*f6dc9357SAndroid Build Coastguard Worker _bonds.Clear();
1088*f6dc9357SAndroid Build Coastguard Worker InitProps();
1089*f6dc9357SAndroid Build Coastguard Worker
1090*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numProps; i++)
1091*f6dc9357SAndroid Build Coastguard Worker {
1092*f6dc9357SAndroid Build Coastguard Worker UString name = names[i];
1093*f6dc9357SAndroid Build Coastguard Worker name.MakeLower_Ascii();
1094*f6dc9357SAndroid Build Coastguard Worker if (name.IsEmpty())
1095*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
1096*f6dc9357SAndroid Build Coastguard Worker
1097*f6dc9357SAndroid Build Coastguard Worker const PROPVARIANT &value = values[i];
1098*f6dc9357SAndroid Build Coastguard Worker
1099*f6dc9357SAndroid Build Coastguard Worker if (name.Find(L':') >= 0) // 'b' was used as NCoderPropID::kBlockSize2 before v23
1100*f6dc9357SAndroid Build Coastguard Worker if (name[0] == 'b')
1101*f6dc9357SAndroid Build Coastguard Worker {
1102*f6dc9357SAndroid Build Coastguard Worker if (value.vt != VT_EMPTY)
1103*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
1104*f6dc9357SAndroid Build Coastguard Worker name.Delete(0);
1105*f6dc9357SAndroid Build Coastguard Worker
1106*f6dc9357SAndroid Build Coastguard Worker CBond2 bond;
1107*f6dc9357SAndroid Build Coastguard Worker RINOK(ParseBond(name, bond.OutCoder, bond.OutStream))
1108*f6dc9357SAndroid Build Coastguard Worker if (name[0] != ':')
1109*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
1110*f6dc9357SAndroid Build Coastguard Worker name.Delete(0);
1111*f6dc9357SAndroid Build Coastguard Worker UInt32 inStream = 0;
1112*f6dc9357SAndroid Build Coastguard Worker RINOK(ParseBond(name, bond.InCoder, inStream))
1113*f6dc9357SAndroid Build Coastguard Worker if (inStream != 0)
1114*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
1115*f6dc9357SAndroid Build Coastguard Worker if (!name.IsEmpty())
1116*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
1117*f6dc9357SAndroid Build Coastguard Worker _bonds.Add(bond);
1118*f6dc9357SAndroid Build Coastguard Worker continue;
1119*f6dc9357SAndroid Build Coastguard Worker }
1120*f6dc9357SAndroid Build Coastguard Worker
1121*f6dc9357SAndroid Build Coastguard Worker RINOK(SetProperty(name, value))
1122*f6dc9357SAndroid Build Coastguard Worker }
1123*f6dc9357SAndroid Build Coastguard Worker
1124*f6dc9357SAndroid Build Coastguard Worker unsigned numEmptyMethods = GetNumEmptyMethods();
1125*f6dc9357SAndroid Build Coastguard Worker if (numEmptyMethods > 0)
1126*f6dc9357SAndroid Build Coastguard Worker {
1127*f6dc9357SAndroid Build Coastguard Worker unsigned k;
1128*f6dc9357SAndroid Build Coastguard Worker for (k = 0; k < _bonds.Size(); k++)
1129*f6dc9357SAndroid Build Coastguard Worker {
1130*f6dc9357SAndroid Build Coastguard Worker const CBond2 &bond = _bonds[k];
1131*f6dc9357SAndroid Build Coastguard Worker if (bond.InCoder < (UInt32)numEmptyMethods ||
1132*f6dc9357SAndroid Build Coastguard Worker bond.OutCoder < (UInt32)numEmptyMethods)
1133*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
1134*f6dc9357SAndroid Build Coastguard Worker }
1135*f6dc9357SAndroid Build Coastguard Worker for (k = 0; k < _bonds.Size(); k++)
1136*f6dc9357SAndroid Build Coastguard Worker {
1137*f6dc9357SAndroid Build Coastguard Worker CBond2 &bond = _bonds[k];
1138*f6dc9357SAndroid Build Coastguard Worker bond.InCoder -= (UInt32)numEmptyMethods;
1139*f6dc9357SAndroid Build Coastguard Worker bond.OutCoder -= (UInt32)numEmptyMethods;
1140*f6dc9357SAndroid Build Coastguard Worker }
1141*f6dc9357SAndroid Build Coastguard Worker _methods.DeleteFrontal(numEmptyMethods);
1142*f6dc9357SAndroid Build Coastguard Worker }
1143*f6dc9357SAndroid Build Coastguard Worker
1144*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (k, _bonds)
1145*f6dc9357SAndroid Build Coastguard Worker {
1146*f6dc9357SAndroid Build Coastguard Worker const CBond2 &bond = _bonds[k];
1147*f6dc9357SAndroid Build Coastguard Worker if (bond.InCoder >= (UInt32)_methods.Size() ||
1148*f6dc9357SAndroid Build Coastguard Worker bond.OutCoder >= (UInt32)_methods.Size())
1149*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
1150*f6dc9357SAndroid Build Coastguard Worker }
1151*f6dc9357SAndroid Build Coastguard Worker
1152*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1153*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
1154*f6dc9357SAndroid Build Coastguard Worker }
1155*f6dc9357SAndroid Build Coastguard Worker
1156*f6dc9357SAndroid Build Coastguard Worker }}
1157*f6dc9357SAndroid Build Coastguard Worker
1158*f6dc9357SAndroid Build Coastguard Worker #endif
1159