• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // HandlerOut.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../Common/StringToInt.h"
6 
7 #include "../Common/ParseProperties.h"
8 
9 #include "HandlerOut.h"
10 
11 namespace NArchive {
12 
ParseSizeString(const wchar_t * s,const PROPVARIANT & prop,UInt64 percentsBase,UInt64 & res)13 bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res)
14 {
15   if (*s == 0)
16   {
17     switch (prop.vt)
18     {
19       case VT_UI4: res = prop.ulVal; return true;
20       case VT_UI8: res = prop.uhVal.QuadPart; return true;
21       case VT_BSTR:
22         s = prop.bstrVal;
23         break;
24       default: return false;
25     }
26   }
27   else if (prop.vt != VT_EMPTY)
28     return false;
29 
30   const wchar_t *end;
31   UInt64 v = ConvertStringToUInt64(s, &end);
32   if (s == end)
33     return false;
34   wchar_t c = *end;
35   if (c == 0)
36   {
37     res = v;
38     return true;
39   }
40   if (end[1] != 0)
41     return false;
42 
43   if (c == '%')
44   {
45     res = percentsBase / 100 * v;
46     return true;
47   }
48 
49   unsigned numBits;
50   switch (MyCharLower_Ascii(c))
51   {
52     case 'b': numBits =  0; break;
53     case 'k': numBits = 10; break;
54     case 'm': numBits = 20; break;
55     case 'g': numBits = 30; break;
56     case 't': numBits = 40; break;
57     default: return false;
58   }
59   UInt64 val2 = v << numBits;
60   if ((val2 >> numBits) != v)
61     return false;
62   res = val2;
63   return true;
64 }
65 
SetCommonProperty(const UString & name,const PROPVARIANT & value,HRESULT & hres)66 bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres)
67 {
68   hres = S_OK;
69 
70   if (name.IsPrefixedBy_Ascii_NoCase("mt"))
71   {
72     #ifndef _7ZIP_ST
73     hres = ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads);
74     #endif
75     return true;
76   }
77 
78   if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
79   {
80     if (!ParseSizeString(name.Ptr(6), value, _memAvail, _memUsage))
81       hres = E_INVALIDARG;
82     return true;
83   }
84 
85   return false;
86 }
87 
88 
89 #ifndef EXTRACT_ONLY
90 
SetMethodProp32(COneMethodInfo & m,PROPID propID,UInt32 value)91 static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
92 {
93   if (m.FindProp(propID) < 0)
94     m.AddProp32(propID, value);
95 }
96 
SetGlobalLevelTo(COneMethodInfo & oneMethodInfo) const97 void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
98 {
99   UInt32 level = _level;
100   if (level != (UInt32)(Int32)-1)
101     SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
102 }
103 
104 #ifndef _7ZIP_ST
SetMethodThreadsTo(COneMethodInfo & oneMethodInfo,UInt32 numThreads)105 void CMultiMethodProps::SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads)
106 {
107   SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
108 }
109 #endif
110 
InitMulti()111 void CMultiMethodProps::InitMulti()
112 {
113   _level = (UInt32)(Int32)-1;
114   _analysisLevel = -1;
115   _crcSize = 4;
116   _autoFilter = true;
117 }
118 
Init()119 void CMultiMethodProps::Init()
120 {
121   InitCommon();
122   InitMulti();
123   _methods.Clear();
124   _filterMethod.Clear();
125 }
126 
127 
SetProperty(const wchar_t * nameSpec,const PROPVARIANT & value)128 HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
129 {
130   UString name = nameSpec;
131   name.MakeLower_Ascii();
132   if (name.IsEmpty())
133     return E_INVALIDARG;
134 
135   if (name[0] == 'x')
136   {
137     name.Delete(0);
138     _level = 9;
139     return ParsePropToUInt32(name, value, _level);
140   }
141 
142   if (name.IsPrefixedBy_Ascii_NoCase("yx"))
143   {
144     name.Delete(0, 2);
145     UInt32 v = 9;
146     RINOK(ParsePropToUInt32(name, value, v));
147     _analysisLevel = (int)v;
148     return S_OK;
149   }
150 
151   if (name.IsPrefixedBy_Ascii_NoCase("crc"))
152   {
153     name.Delete(0, 3);
154     _crcSize = 4;
155     return ParsePropToUInt32(name, value, _crcSize);
156   }
157 
158   {
159     HRESULT hres;
160     if (SetCommonProperty(name, value, hres))
161       return hres;
162   }
163 
164   UInt32 number;
165   unsigned index = ParseStringToUInt32(name, number);
166   UString realName = name.Ptr(index);
167   if (index == 0)
168   {
169     if (name.IsEqualTo("f"))
170     {
171       HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
172       if (res == S_OK)
173         return res;
174       if (value.vt != VT_BSTR)
175         return E_INVALIDARG;
176       return _filterMethod.ParseMethodFromPROPVARIANT(UString(), value);
177     }
178     number = 0;
179   }
180   if (number > 64)
181     return E_FAIL;
182   for (int j = _methods.Size(); j <= (int)number; j++)
183     _methods.Add(COneMethodInfo());
184   return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
185 }
186 
187 
188 
Init()189 void CSingleMethodProps::Init()
190 {
191   InitCommon();
192   InitSingle();
193   Clear();
194 }
195 
196 
SetProperties(const wchar_t * const * names,const PROPVARIANT * values,UInt32 numProps)197 HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
198 {
199   Init();
200 
201   for (UInt32 i = 0; i < numProps; i++)
202   {
203     UString name = names[i];
204     name.MakeLower_Ascii();
205     if (name.IsEmpty())
206       return E_INVALIDARG;
207     const PROPVARIANT &value = values[i];
208     if (name[0] == L'x')
209     {
210       UInt32 a = 9;
211       RINOK(ParsePropToUInt32(name.Ptr(1), value, a));
212       _level = a;
213       AddProp_Level(a);
214       continue;
215     }
216     {
217       HRESULT hres;
218       if (SetCommonProperty(name, value, hres))
219       {
220         RINOK(hres)
221         continue;
222       }
223     }
224     RINOK(ParseMethodFromPROPVARIANT(names[i], value));
225   }
226 
227   return S_OK;
228 }
229 
230 #endif
231 
232 }
233