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