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