1 // ParseProperties.cpp 2 3 #include "StdAfx.h" 4 5 #include "ParseProperties.h" 6 7 #include "Common/StringToInt.h" 8 #include "Common/MyCom.h" 9 10 HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) 11 { 12 if (prop.vt == VT_UI4) 13 { 14 if (!name.IsEmpty()) 15 return E_INVALIDARG; 16 resValue = prop.ulVal; 17 } 18 else if (prop.vt == VT_EMPTY) 19 { 20 if(!name.IsEmpty()) 21 { 22 const wchar_t *start = name; 23 const wchar_t *end; 24 UInt64 v = ConvertStringToUInt64(start, &end); 25 if (end - start != name.Length()) 26 return E_INVALIDARG; 27 resValue = (UInt32)v; 28 } 29 } 30 else 31 return E_INVALIDARG; 32 return S_OK; 33 } 34 35 static const int kLogarithmicSizeLimit = 32; 36 static const wchar_t kByteSymbol = L'B'; 37 static const wchar_t kKiloByteSymbol = L'K'; 38 static const wchar_t kMegaByteSymbol = L'M'; 39 40 HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize) 41 { 42 UString srcString = srcStringSpec; 43 srcString.MakeUpper(); 44 45 const wchar_t *start = srcString; 46 const wchar_t *end; 47 UInt64 number = ConvertStringToUInt64(start, &end); 48 int numDigits = (int)(end - start); 49 if (numDigits == 0 || srcString.Length() > numDigits + 1) 50 return E_INVALIDARG; 51 if (srcString.Length() == numDigits) 52 { 53 if (number >= kLogarithmicSizeLimit) 54 return E_INVALIDARG; 55 dicSize = (UInt32)1 << (int)number; 56 return S_OK; 57 } 58 switch (srcString[numDigits]) 59 { 60 case kByteSymbol: 61 if (number >= ((UInt64)1 << kLogarithmicSizeLimit)) 62 return E_INVALIDARG; 63 dicSize = (UInt32)number; 64 break; 65 case kKiloByteSymbol: 66 if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10))) 67 return E_INVALIDARG; 68 dicSize = (UInt32)(number << 10); 69 break; 70 case kMegaByteSymbol: 71 if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20))) 72 return E_INVALIDARG; 73 dicSize = (UInt32)(number << 20); 74 break; 75 default: 76 return E_INVALIDARG; 77 } 78 return S_OK; 79 } 80 81 HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) 82 { 83 if (name.IsEmpty()) 84 { 85 if (prop.vt == VT_UI4) 86 { 87 UInt32 logDicSize = prop.ulVal; 88 if (logDicSize >= 32) 89 return E_INVALIDARG; 90 resValue = (UInt32)1 << logDicSize; 91 return S_OK; 92 } 93 if (prop.vt == VT_BSTR) 94 return ParsePropDictionaryValue(prop.bstrVal, resValue); 95 return E_INVALIDARG; 96 } 97 return ParsePropDictionaryValue(name, resValue); 98 } 99 100 bool StringToBool(const UString &s, bool &res) 101 { 102 if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0) 103 { 104 res = true; 105 return true; 106 } 107 if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0) 108 { 109 res = false; 110 return true; 111 } 112 return false; 113 } 114 115 HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value) 116 { 117 switch(value.vt) 118 { 119 case VT_EMPTY: 120 dest = true; 121 return S_OK; 122 case VT_BOOL: 123 dest = (value.boolVal != VARIANT_FALSE); 124 return S_OK; 125 /* 126 case VT_UI4: 127 dest = (value.ulVal != 0); 128 break; 129 */ 130 case VT_BSTR: 131 return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG; 132 } 133 return E_INVALIDARG; 134 } 135 136 int ParseStringToUInt32(const UString &srcString, UInt32 &number) 137 { 138 const wchar_t *start = srcString; 139 const wchar_t *end; 140 UInt64 number64 = ConvertStringToUInt64(start, &end); 141 if (number64 > 0xFFFFFFFF) 142 { 143 number = 0; 144 return 0; 145 } 146 number = (UInt32)number64; 147 return (int)(end - start); 148 } 149 150 HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads) 151 { 152 if (name.IsEmpty()) 153 { 154 switch(prop.vt) 155 { 156 case VT_UI4: 157 numThreads = prop.ulVal; 158 break; 159 default: 160 { 161 bool val; 162 RINOK(SetBoolProperty(val, prop)); 163 numThreads = (val ? defaultNumThreads : 1); 164 break; 165 } 166 } 167 } 168 else 169 { 170 UInt32 number; 171 int index = ParseStringToUInt32(name, number); 172 if (index != name.Length()) 173 return E_INVALIDARG; 174 numThreads = number; 175 } 176 return S_OK; 177 } 178