HandlerOut.cpp (4951B)
1 // HandlerOut.cpp 2 3 #include "StdAfx.h" 4 5 #include "../../../Common/StringToInt.h" 6 7 #include "../Common/ParseProperties.h" 8 9 #include "HandlerOut.h" 10 11 namespace NArchive { 12 13 bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res) 14 { 15 if (*s == 0) 16 { 17 switch (prop.vt) 18 { 19 case VT_UI4: res = prop.ulVal; return true; 20 case VT_UI8: res = prop.uhVal.QuadPart; return true; 21 case VT_BSTR: 22 s = prop.bstrVal; 23 break; 24 default: return false; 25 } 26 } 27 else if (prop.vt != VT_EMPTY) 28 return false; 29 30 const wchar_t *end; 31 UInt64 v = ConvertStringToUInt64(s, &end); 32 if (s == end) 33 return false; 34 wchar_t c = *end; 35 if (c == 0) 36 { 37 res = v; 38 return true; 39 } 40 if (end[1] != 0) 41 return false; 42 43 if (c == '%') 44 { 45 res = percentsBase / 100 * v; 46 return true; 47 } 48 49 unsigned numBits; 50 switch (MyCharLower_Ascii(c)) 51 { 52 case 'b': numBits = 0; break; 53 case 'k': numBits = 10; break; 54 case 'm': numBits = 20; break; 55 case 'g': numBits = 30; break; 56 case 't': numBits = 40; break; 57 default: return false; 58 } 59 UInt64 val2 = v << numBits; 60 if ((val2 >> numBits) != v) 61 return false; 62 res = val2; 63 return true; 64 } 65 66 bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres) 67 { 68 hres = S_OK; 69 70 if (name.IsPrefixedBy_Ascii_NoCase("mt")) 71 { 72 #ifndef _7ZIP_ST 73 hres = ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads); 74 #endif 75 return true; 76 } 77 78 if (name.IsPrefixedBy_Ascii_NoCase("memuse")) 79 { 80 if (!ParseSizeString(name.Ptr(6), value, _memAvail, _memUsage)) 81 hres = E_INVALIDARG; 82 return true; 83 } 84 85 return false; 86 } 87 88 89 #ifndef EXTRACT_ONLY 90 91 static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value) 92 { 93 if (m.FindProp(propID) < 0) 94 m.AddProp32(propID, value); 95 } 96 97 void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const 98 { 99 UInt32 level = _level; 100 if (level != (UInt32)(Int32)-1) 101 SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level); 102 } 103 104 #ifndef _7ZIP_ST 105 void CMultiMethodProps::SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads) 106 { 107 SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); 108 } 109 #endif 110 111 void CMultiMethodProps::InitMulti() 112 { 113 _level = (UInt32)(Int32)-1; 114 _analysisLevel = -1; 115 _crcSize = 4; 116 _autoFilter = true; 117 } 118 119 void CMultiMethodProps::Init() 120 { 121 InitCommon(); 122 InitMulti(); 123 _methods.Clear(); 124 _filterMethod.Clear(); 125 } 126 127 128 HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) 129 { 130 UString name = nameSpec; 131 name.MakeLower_Ascii(); 132 if (name.IsEmpty()) 133 return E_INVALIDARG; 134 135 if (name[0] == 'x') 136 { 137 name.Delete(0); 138 _level = 9; 139 return ParsePropToUInt32(name, value, _level); 140 } 141 142 if (name.IsPrefixedBy_Ascii_NoCase("yx")) 143 { 144 name.Delete(0, 2); 145 UInt32 v = 9; 146 RINOK(ParsePropToUInt32(name, value, v)); 147 _analysisLevel = (int)v; 148 return S_OK; 149 } 150 151 if (name.IsPrefixedBy_Ascii_NoCase("crc")) 152 { 153 name.Delete(0, 3); 154 _crcSize = 4; 155 return ParsePropToUInt32(name, value, _crcSize); 156 } 157 158 { 159 HRESULT hres; 160 if (SetCommonProperty(name, value, hres)) 161 return hres; 162 } 163 164 UInt32 number; 165 unsigned index = ParseStringToUInt32(name, number); 166 UString realName = name.Ptr(index); 167 if (index == 0) 168 { 169 if (name.IsEqualTo("f")) 170 { 171 HRESULT res = PROPVARIANT_to_bool(value, _autoFilter); 172 if (res == S_OK) 173 return res; 174 if (value.vt != VT_BSTR) 175 return E_INVALIDARG; 176 return _filterMethod.ParseMethodFromPROPVARIANT(UString(), value); 177 } 178 number = 0; 179 } 180 if (number > 64) 181 return E_FAIL; 182 for (int j = _methods.Size(); j <= (int)number; j++) 183 _methods.Add(COneMethodInfo()); 184 return _methods[number].ParseMethodFromPROPVARIANT(realName, value); 185 } 186 187 188 189 void CSingleMethodProps::Init() 190 { 191 InitCommon(); 192 InitSingle(); 193 Clear(); 194 } 195 196 197 HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) 198 { 199 Init(); 200 201 for (UInt32 i = 0; i < numProps; i++) 202 { 203 UString name = names[i]; 204 name.MakeLower_Ascii(); 205 if (name.IsEmpty()) 206 return E_INVALIDARG; 207 const PROPVARIANT &value = values[i]; 208 if (name[0] == L'x') 209 { 210 UInt32 a = 9; 211 RINOK(ParsePropToUInt32(name.Ptr(1), value, a)); 212 _level = a; 213 AddProp_Level(a); 214 continue; 215 } 216 { 217 HRESULT hres; 218 if (SetCommonProperty(name, value, hres)) 219 { 220 RINOK(hres) 221 continue; 222 } 223 } 224 RINOK(ParseMethodFromPROPVARIANT(names[i], value)); 225 } 226 227 return S_OK; 228 } 229 230 #endif 231 232 }