Upload 2.0.2
[physicsfs] / lzma / CPP / 7zip / Archive / Common / ParseProperties.cpp
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)
103   {
104     res = true;
105     return true;
106   }
107   if (s.CompareNoCase(L"OFF") == 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     /*
123     case VT_UI4:
124       dest = (value.ulVal != 0);
125       break;
126     */
127     case VT_BSTR:
128       return StringToBool(value.bstrVal, dest) ?  S_OK : E_INVALIDARG;
129   }
130   return E_INVALIDARG;
131 }
132
133 int ParseStringToUInt32(const UString &srcString, UInt32 &number)
134 {
135   const wchar_t *start = srcString;
136   const wchar_t *end;
137   UInt64 number64 = ConvertStringToUInt64(start, &end);
138   if (number64 > 0xFFFFFFFF) 
139   {
140     number = 0;
141     return 0;
142   }
143   number = (UInt32)number64;
144   return (int)(end - start);
145 }
146
147 HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
148 {
149   if (name.IsEmpty())
150   {
151     switch(prop.vt)
152     {
153       case VT_UI4:
154         numThreads = prop.ulVal;
155         break;
156       default:
157       {
158         bool val; 
159         RINOK(SetBoolProperty(val, prop));
160         numThreads = (val ? defaultNumThreads : 1);
161         break;
162       }
163     }
164   }
165   else
166   {
167     UInt32 number;
168     int index = ParseStringToUInt32(name, number);
169     if (index != name.Length())
170       return E_INVALIDARG;
171     numThreads = number;
172   }
173   return S_OK;
174 }