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
ParsePropValue(const UString & name,const PROPVARIANT & prop,UInt32 & resValue)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
ParsePropDictionaryValue(const UString & srcStringSpec,UInt32 & dicSize)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
ParsePropDictionaryValue(const UString & name,const PROPVARIANT & prop,UInt32 & resValue)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
StringToBool(const UString & s,bool & res)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
SetBoolProperty(bool & dest,const PROPVARIANT & value)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
ParseStringToUInt32(const UString & srcString,UInt32 & number)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
ParseMtProp(const UString & name,const PROPVARIANT & prop,UInt32 defaultNumThreads,UInt32 & numThreads)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