| 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 |