OLD | NEW |
| (Empty) |
1 // HandlerOut.cpp | |
2 | |
3 #include "StdAfx.h" | |
4 | |
5 #include "../../../Common/StringToInt.h" | |
6 | |
7 #include "../../../Windows/PropVariant.h" | |
8 | |
9 #ifdef COMPRESS_MT | |
10 #include "../../../Windows/System.h" | |
11 #endif | |
12 | |
13 #include "../../ICoder.h" | |
14 | |
15 #include "../Common/ParseProperties.h" | |
16 | |
17 #include "HandlerOut.h" | |
18 | |
19 using namespace NWindows; | |
20 | |
21 namespace NArchive { | |
22 | |
23 static const wchar_t *kCopyMethod = L"Copy"; | |
24 static const wchar_t *kLZMAMethodName = L"LZMA"; | |
25 static const wchar_t *kLZMA2MethodName = L"LZMA2"; | |
26 static const wchar_t *kBZip2MethodName = L"BZip2"; | |
27 static const wchar_t *kPpmdMethodName = L"PPMd"; | |
28 static const wchar_t *kDeflateMethodName = L"Deflate"; | |
29 static const wchar_t *kDeflate64MethodName = L"Deflate64"; | |
30 | |
31 static const wchar_t *kLzmaMatchFinderX1 = L"HC4"; | |
32 static const wchar_t *kLzmaMatchFinderX5 = L"BT4"; | |
33 | |
34 static const UInt32 kLzmaAlgoX1 = 0; | |
35 static const UInt32 kLzmaAlgoX5 = 1; | |
36 | |
37 static const UInt32 kLzmaDicSizeX1 = 1 << 16; | |
38 static const UInt32 kLzmaDicSizeX3 = 1 << 20; | |
39 static const UInt32 kLzmaDicSizeX5 = 1 << 24; | |
40 static const UInt32 kLzmaDicSizeX7 = 1 << 25; | |
41 static const UInt32 kLzmaDicSizeX9 = 1 << 26; | |
42 | |
43 static const UInt32 kLzmaFastBytesX1 = 32; | |
44 static const UInt32 kLzmaFastBytesX7 = 64; | |
45 | |
46 static const UInt32 kPpmdMemSizeX1 = (1 << 22); | |
47 static const UInt32 kPpmdMemSizeX5 = (1 << 24); | |
48 static const UInt32 kPpmdMemSizeX7 = (1 << 26); | |
49 static const UInt32 kPpmdMemSizeX9 = (192 << 20); | |
50 | |
51 static const UInt32 kPpmdOrderX1 = 4; | |
52 static const UInt32 kPpmdOrderX5 = 6; | |
53 static const UInt32 kPpmdOrderX7 = 16; | |
54 static const UInt32 kPpmdOrderX9 = 32; | |
55 | |
56 static const UInt32 kDeflateAlgoX1 = 0; | |
57 static const UInt32 kDeflateAlgoX5 = 1; | |
58 | |
59 static const UInt32 kDeflateFastBytesX1 = 32; | |
60 static const UInt32 kDeflateFastBytesX7 = 64; | |
61 static const UInt32 kDeflateFastBytesX9 = 128; | |
62 | |
63 static const UInt32 kDeflatePassesX1 = 1; | |
64 static const UInt32 kDeflatePassesX7 = 3; | |
65 static const UInt32 kDeflatePassesX9 = 10; | |
66 | |
67 static const UInt32 kBZip2NumPassesX1 = 1; | |
68 static const UInt32 kBZip2NumPassesX7 = 2; | |
69 static const UInt32 kBZip2NumPassesX9 = 7; | |
70 | |
71 static const UInt32 kBZip2DicSizeX1 = 100000; | |
72 static const UInt32 kBZip2DicSizeX3 = 500000; | |
73 static const UInt32 kBZip2DicSizeX5 = 900000; | |
74 | |
75 static const wchar_t *kDefaultMethodName = kLZMAMethodName; | |
76 | |
77 static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2"; | |
78 static const UInt32 kDictionaryForHeaders = 1 << 20; | |
79 static const UInt32 kNumFastBytesForHeaders = 273; | |
80 static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5; | |
81 | |
82 static bool AreEqual(const UString &methodName, const wchar_t *s) | |
83 { return (methodName.CompareNoCase(s) == 0); } | |
84 | |
85 static inline bool IsLZMAMethod(const UString &methodName) | |
86 { | |
87 return | |
88 AreEqual(methodName, kLZMAMethodName) || | |
89 AreEqual(methodName, kLZMA2MethodName); | |
90 } | |
91 | |
92 static inline bool IsBZip2Method(const UString &methodName) | |
93 { return AreEqual(methodName, kBZip2MethodName); } | |
94 | |
95 static inline bool IsPpmdMethod(const UString &methodName) | |
96 { return AreEqual(methodName, kPpmdMethodName); } | |
97 | |
98 static inline bool IsDeflateMethod(const UString &methodName) | |
99 { | |
100 return | |
101 AreEqual(methodName, kDeflateMethodName) || | |
102 AreEqual(methodName, kDeflate64MethodName); | |
103 } | |
104 | |
105 struct CNameToPropID | |
106 { | |
107 PROPID PropID; | |
108 VARTYPE VarType; | |
109 const wchar_t *Name; | |
110 }; | |
111 | |
112 CNameToPropID g_NameToPropID[] = | |
113 { | |
114 { NCoderPropID::kOrder, VT_UI4, L"O" }, | |
115 { NCoderPropID::kPosStateBits, VT_UI4, L"PB" }, | |
116 { NCoderPropID::kLitContextBits, VT_UI4, L"LC" }, | |
117 { NCoderPropID::kLitPosBits, VT_UI4, L"LP" }, | |
118 { NCoderPropID::kEndMarker, VT_BOOL, L"eos" }, | |
119 | |
120 { NCoderPropID::kNumPasses, VT_UI4, L"Pass" }, | |
121 { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" }, | |
122 { NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" }, | |
123 { NCoderPropID::kAlgorithm, VT_UI4, L"a" }, | |
124 { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" }, | |
125 { NCoderPropID::kNumThreads, VT_UI4, L"mt" } | |
126 }; | |
127 | |
128 static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVar
iant &destProp) | |
129 { | |
130 if (varType == srcProp.vt) | |
131 { | |
132 destProp = srcProp; | |
133 return true; | |
134 } | |
135 if (varType == VT_UI1) | |
136 { | |
137 if (srcProp.vt == VT_UI4) | |
138 { | |
139 UInt32 value = srcProp.ulVal; | |
140 if (value > 0xFF) | |
141 return false; | |
142 destProp = (Byte)value; | |
143 return true; | |
144 } | |
145 } | |
146 else if (varType == VT_BOOL) | |
147 { | |
148 bool res; | |
149 if (SetBoolProperty(res, srcProp) != S_OK) | |
150 return false; | |
151 destProp = res; | |
152 return true; | |
153 } | |
154 return false; | |
155 } | |
156 | |
157 static int FindPropIdFromStringName(const UString &name) | |
158 { | |
159 for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++) | |
160 if (name.CompareNoCase(g_NameToPropID[i].Name) == 0) | |
161 return i; | |
162 return -1; | |
163 } | |
164 | |
165 static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID, | |
166 const NWindows::NCOM::CPropVariant &value) | |
167 { | |
168 for (int j = 0; j < oneMethodInfo.Props.Size(); j++) | |
169 if (oneMethodInfo.Props[j].Id == propID) | |
170 return; | |
171 CProp prop; | |
172 prop.Id = propID; | |
173 prop.Value = value; | |
174 oneMethodInfo.Props.Add(prop); | |
175 } | |
176 | |
177 void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo | |
178 #ifdef COMPRESS_MT | |
179 , UInt32 numThreads | |
180 #endif | |
181 ) | |
182 { | |
183 UInt32 level = _level; | |
184 if (oneMethodInfo.MethodName.IsEmpty()) | |
185 oneMethodInfo.MethodName = kDefaultMethodName; | |
186 | |
187 if (IsLZMAMethod(oneMethodInfo.MethodName)) | |
188 { | |
189 UInt32 dicSize = | |
190 (level >= 9 ? kLzmaDicSizeX9 : | |
191 (level >= 7 ? kLzmaDicSizeX7 : | |
192 (level >= 5 ? kLzmaDicSizeX5 : | |
193 (level >= 3 ? kLzmaDicSizeX3 : | |
194 kLzmaDicSizeX1)))); | |
195 | |
196 UInt32 algo = | |
197 (level >= 5 ? kLzmaAlgoX5 : | |
198 kLzmaAlgoX1); | |
199 | |
200 UInt32 fastBytes = | |
201 (level >= 7 ? kLzmaFastBytesX7 : | |
202 kLzmaFastBytesX1); | |
203 | |
204 const wchar_t *matchFinder = | |
205 (level >= 5 ? kLzmaMatchFinderX5 : | |
206 kLzmaMatchFinderX1); | |
207 | |
208 SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); | |
209 SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo); | |
210 SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); | |
211 SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder); | |
212 #ifdef COMPRESS_MT | |
213 SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); | |
214 #endif | |
215 } | |
216 else if (IsDeflateMethod(oneMethodInfo.MethodName)) | |
217 { | |
218 UInt32 fastBytes = | |
219 (level >= 9 ? kDeflateFastBytesX9 : | |
220 (level >= 7 ? kDeflateFastBytesX7 : | |
221 kDeflateFastBytesX1)); | |
222 | |
223 UInt32 numPasses = | |
224 (level >= 9 ? kDeflatePassesX9 : | |
225 (level >= 7 ? kDeflatePassesX7 : | |
226 kDeflatePassesX1)); | |
227 | |
228 UInt32 algo = | |
229 (level >= 5 ? kDeflateAlgoX5 : | |
230 kDeflateAlgoX1); | |
231 | |
232 SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo); | |
233 SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); | |
234 SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); | |
235 } | |
236 else if (IsBZip2Method(oneMethodInfo.MethodName)) | |
237 { | |
238 UInt32 numPasses = | |
239 (level >= 9 ? kBZip2NumPassesX9 : | |
240 (level >= 7 ? kBZip2NumPassesX7 : | |
241 kBZip2NumPassesX1)); | |
242 | |
243 UInt32 dicSize = | |
244 (level >= 5 ? kBZip2DicSizeX5 : | |
245 (level >= 3 ? kBZip2DicSizeX3 : | |
246 kBZip2DicSizeX1)); | |
247 | |
248 SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); | |
249 SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); | |
250 #ifdef COMPRESS_MT | |
251 SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); | |
252 #endif | |
253 } | |
254 else if (IsPpmdMethod(oneMethodInfo.MethodName)) | |
255 { | |
256 UInt32 useMemSize = | |
257 (level >= 9 ? kPpmdMemSizeX9 : | |
258 (level >= 7 ? kPpmdMemSizeX7 : | |
259 (level >= 5 ? kPpmdMemSizeX5 : | |
260 kPpmdMemSizeX1))); | |
261 | |
262 UInt32 order = | |
263 (level >= 9 ? kPpmdOrderX9 : | |
264 (level >= 7 ? kPpmdOrderX7 : | |
265 (level >= 5 ? kPpmdOrderX5 : | |
266 kPpmdOrderX1))); | |
267 | |
268 SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize); | |
269 SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order); | |
270 } | |
271 } | |
272 | |
273 static void SplitParams(const UString &srcString, UStringVector &subStrings) | |
274 { | |
275 subStrings.Clear(); | |
276 UString name; | |
277 int len = srcString.Length(); | |
278 if (len == 0) | |
279 return; | |
280 for (int i = 0; i < len; i++) | |
281 { | |
282 wchar_t c = srcString[i]; | |
283 if (c == L':') | |
284 { | |
285 subStrings.Add(name); | |
286 name.Empty(); | |
287 } | |
288 else | |
289 name += c; | |
290 } | |
291 subStrings.Add(name); | |
292 } | |
293 | |
294 static void SplitParam(const UString ¶m, UString &name, UString &value) | |
295 { | |
296 int eqPos = param.Find(L'='); | |
297 if (eqPos >= 0) | |
298 { | |
299 name = param.Left(eqPos); | |
300 value = param.Mid(eqPos + 1); | |
301 return; | |
302 } | |
303 for(int i = 0; i < param.Length(); i++) | |
304 { | |
305 wchar_t c = param[i]; | |
306 if (c >= L'0' && c <= L'9') | |
307 { | |
308 name = param.Left(i); | |
309 value = param.Mid(i); | |
310 return; | |
311 } | |
312 } | |
313 name = param; | |
314 } | |
315 | |
316 HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name
, const UString &value) | |
317 { | |
318 CProp prop; | |
319 if (name.CompareNoCase(L"D") == 0 || | |
320 name.CompareNoCase(L"MEM") == 0) | |
321 { | |
322 UInt32 dicSize; | |
323 RINOK(ParsePropDictionaryValue(value, dicSize)); | |
324 prop.Id = (name.CompareNoCase(L"D") == 0) ? | |
325 NCoderPropID::kDictionarySize : | |
326 NCoderPropID::kUsedMemorySize; | |
327 prop.Value = dicSize; | |
328 } | |
329 else | |
330 { | |
331 int index = FindPropIdFromStringName(name); | |
332 if (index < 0) | |
333 return E_INVALIDARG; | |
334 | |
335 const CNameToPropID &nameToPropID = g_NameToPropID[index]; | |
336 prop.Id = nameToPropID.PropID; | |
337 | |
338 NCOM::CPropVariant propValue; | |
339 | |
340 if (nameToPropID.VarType == VT_BSTR) | |
341 propValue = value; | |
342 else if (nameToPropID.VarType == VT_BOOL) | |
343 { | |
344 bool res; | |
345 if (!StringToBool(value, res)) | |
346 return E_INVALIDARG; | |
347 propValue = res; | |
348 } | |
349 else | |
350 { | |
351 UInt32 number; | |
352 if (ParseStringToUInt32(value, number) == value.Length()) | |
353 propValue = number; | |
354 else | |
355 propValue = value; | |
356 } | |
357 | |
358 if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value)) | |
359 return E_INVALIDARG; | |
360 } | |
361 oneMethodInfo.Props.Add(prop); | |
362 return S_OK; | |
363 } | |
364 | |
365 HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &src
String) | |
366 { | |
367 UStringVector params; | |
368 SplitParams(srcString, params); | |
369 if (params.Size() > 0) | |
370 oneMethodInfo.MethodName = params[0]; | |
371 for (int i = 1; i < params.Size(); i++) | |
372 { | |
373 const UString ¶m = params[i]; | |
374 UString name, value; | |
375 SplitParam(param, name, value); | |
376 RINOK(SetParam(oneMethodInfo, name, value)); | |
377 } | |
378 return S_OK; | |
379 } | |
380 | |
381 HRESULT COutHandler::SetSolidSettings(const UString &s) | |
382 { | |
383 UString s2 = s; | |
384 s2.MakeUpper(); | |
385 for (int i = 0; i < s2.Length();) | |
386 { | |
387 const wchar_t *start = ((const wchar_t *)s2) + i; | |
388 const wchar_t *end; | |
389 UInt64 v = ConvertStringToUInt64(start, &end); | |
390 if (start == end) | |
391 { | |
392 if (s2[i++] != 'E') | |
393 return E_INVALIDARG; | |
394 _solidExtension = true; | |
395 continue; | |
396 } | |
397 i += (int)(end - start); | |
398 if (i == s2.Length()) | |
399 return E_INVALIDARG; | |
400 wchar_t c = s2[i++]; | |
401 switch(c) | |
402 { | |
403 case 'F': | |
404 if (v < 1) | |
405 v = 1; | |
406 _numSolidFiles = v; | |
407 break; | |
408 case 'B': | |
409 _numSolidBytes = v; | |
410 _numSolidBytesDefined = true; | |
411 break; | |
412 case 'K': | |
413 _numSolidBytes = (v << 10); | |
414 _numSolidBytesDefined = true; | |
415 break; | |
416 case 'M': | |
417 _numSolidBytes = (v << 20); | |
418 _numSolidBytesDefined = true; | |
419 break; | |
420 case 'G': | |
421 _numSolidBytes = (v << 30); | |
422 _numSolidBytesDefined = true; | |
423 break; | |
424 default: | |
425 return E_INVALIDARG; | |
426 } | |
427 } | |
428 return S_OK; | |
429 } | |
430 | |
431 HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value) | |
432 { | |
433 bool isSolid; | |
434 switch(value.vt) | |
435 { | |
436 case VT_EMPTY: | |
437 isSolid = true; | |
438 break; | |
439 case VT_BOOL: | |
440 isSolid = (value.boolVal != VARIANT_FALSE); | |
441 break; | |
442 case VT_BSTR: | |
443 if (StringToBool(value.bstrVal, isSolid)) | |
444 break; | |
445 return SetSolidSettings(value.bstrVal); | |
446 default: | |
447 return E_INVALIDARG; | |
448 } | |
449 if (isSolid) | |
450 InitSolid(); | |
451 else | |
452 _numSolidFiles = 1; | |
453 return S_OK; | |
454 } | |
455 | |
456 void COutHandler::Init() | |
457 { | |
458 _removeSfxBlock = false; | |
459 _compressHeaders = true; | |
460 _encryptHeadersSpecified = false; | |
461 _encryptHeaders = false; | |
462 | |
463 WriteCTime = false; | |
464 WriteATime = false; | |
465 WriteMTime = true; | |
466 | |
467 #ifdef COMPRESS_MT | |
468 _numThreads = NWindows::NSystem::GetNumberOfProcessors(); | |
469 #endif | |
470 | |
471 _level = 5; | |
472 _autoFilter = true; | |
473 _volumeMode = false; | |
474 _crcSize = 4; | |
475 InitSolid(); | |
476 } | |
477 | |
478 void COutHandler::BeforeSetProperty() | |
479 { | |
480 Init(); | |
481 #ifdef COMPRESS_MT | |
482 numProcessors = NSystem::GetNumberOfProcessors(); | |
483 #endif | |
484 | |
485 mainDicSize = 0xFFFFFFFF; | |
486 mainDicMethodIndex = 0xFFFFFFFF; | |
487 minNumber = 0; | |
488 _crcSize = 4; | |
489 } | |
490 | |
491 HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
ue) | |
492 { | |
493 UString name = nameSpec; | |
494 name.MakeUpper(); | |
495 if (name.IsEmpty()) | |
496 return E_INVALIDARG; | |
497 | |
498 if (name[0] == 'X') | |
499 { | |
500 name.Delete(0); | |
501 _level = 9; | |
502 return ParsePropValue(name, value, _level); | |
503 } | |
504 | |
505 if (name[0] == L'S') | |
506 { | |
507 name.Delete(0); | |
508 if (name.IsEmpty()) | |
509 return SetSolidSettings(value); | |
510 if (value.vt != VT_EMPTY) | |
511 return E_INVALIDARG; | |
512 return SetSolidSettings(name); | |
513 } | |
514 | |
515 if (name == L"CRC") | |
516 { | |
517 _crcSize = 4; | |
518 name.Delete(0, 3); | |
519 return ParsePropValue(name, value, _crcSize); | |
520 } | |
521 | |
522 UInt32 number; | |
523 int index = ParseStringToUInt32(name, number); | |
524 UString realName = name.Mid(index); | |
525 if (index == 0) | |
526 { | |
527 if(name.Left(2).CompareNoCase(L"MT") == 0) | |
528 { | |
529 #ifdef COMPRESS_MT | |
530 RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads)); | |
531 #endif | |
532 return S_OK; | |
533 } | |
534 if (name.CompareNoCase(L"RSFX") == 0) return SetBoolProperty(_removeSfxBloc
k, value); | |
535 if (name.CompareNoCase(L"F") == 0) return SetBoolProperty(_autoFilter, value
); | |
536 if (name.CompareNoCase(L"HC") == 0) return SetBoolProperty(_compressHeaders,
value); | |
537 if (name.CompareNoCase(L"HCF") == 0) | |
538 { | |
539 bool compressHeadersFull = true; | |
540 RINOK(SetBoolProperty(compressHeadersFull, value)); | |
541 if (!compressHeadersFull) | |
542 return E_INVALIDARG; | |
543 return S_OK; | |
544 } | |
545 if (name.CompareNoCase(L"HE") == 0) | |
546 { | |
547 RINOK(SetBoolProperty(_encryptHeaders, value)); | |
548 _encryptHeadersSpecified = true; | |
549 return S_OK; | |
550 } | |
551 if (name.CompareNoCase(L"TC") == 0) return SetBoolProperty(WriteCTime, value
); | |
552 if (name.CompareNoCase(L"TA") == 0) return SetBoolProperty(WriteATime, value
); | |
553 if (name.CompareNoCase(L"TM") == 0) return SetBoolProperty(WriteMTime, value
); | |
554 if (name.CompareNoCase(L"V") == 0) return SetBoolProperty(_volumeMode, value
); | |
555 number = 0; | |
556 } | |
557 if (number > 10000) | |
558 return E_FAIL; | |
559 if (number < minNumber) | |
560 return E_INVALIDARG; | |
561 number -= minNumber; | |
562 for(int j = _methods.Size(); j <= (int)number; j++) | |
563 { | |
564 COneMethodInfo oneMethodInfo; | |
565 _methods.Add(oneMethodInfo); | |
566 } | |
567 | |
568 COneMethodInfo &oneMethodInfo = _methods[number]; | |
569 | |
570 if (realName.Length() == 0) | |
571 { | |
572 if (value.vt != VT_BSTR) | |
573 return E_INVALIDARG; | |
574 | |
575 RINOK(SetParams(oneMethodInfo, value.bstrVal)); | |
576 } | |
577 else | |
578 { | |
579 CProp prop; | |
580 if (realName.Left(1).CompareNoCase(L"D") == 0) | |
581 { | |
582 UInt32 dicSize; | |
583 RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize)); | |
584 prop.Id = NCoderPropID::kDictionarySize; | |
585 prop.Value = dicSize; | |
586 if (number <= mainDicMethodIndex) | |
587 mainDicSize = dicSize; | |
588 } | |
589 else if (realName.Left(1).CompareNoCase(L"C") == 0) | |
590 { | |
591 UInt32 blockSize; | |
592 RINOK(ParsePropDictionaryValue(realName.Mid(1), value, blockSize)); | |
593 prop.Id = NCoderPropID::kBlockSize; | |
594 prop.Value = blockSize; | |
595 } | |
596 else if (realName.Left(3).CompareNoCase(L"MEM") == 0) | |
597 { | |
598 UInt32 dicSize; | |
599 RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize)); | |
600 prop.Id = NCoderPropID::kUsedMemorySize; | |
601 prop.Value = dicSize; | |
602 if (number <= mainDicMethodIndex) | |
603 mainDicSize = dicSize; | |
604 } | |
605 else | |
606 { | |
607 int index = FindPropIdFromStringName(realName); | |
608 if (index < 0) | |
609 return E_INVALIDARG; | |
610 const CNameToPropID &nameToPropID = g_NameToPropID[index]; | |
611 prop.Id = nameToPropID.PropID; | |
612 if (!ConvertProperty(value, nameToPropID.VarType, prop.Value)) | |
613 return E_INVALIDARG; | |
614 } | |
615 oneMethodInfo.Props.Add(prop); | |
616 } | |
617 return S_OK; | |
618 } | |
619 | |
620 } | |
OLD | NEW |