• 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   bool percentMode = false;
31   {
32     const wchar_t c = *s;
33     if (MyCharLower_Ascii(c) == 'p')
34     {
35       percentMode = true;
36       s++;
37     }
38   }
39 
40   const wchar_t *end;
41   const UInt64 v = ConvertStringToUInt64(s, &end);
42   if (s == end)
43     return false;
44   const wchar_t c = *end;
45 
46   if (percentMode)
47   {
48     if (c != 0)
49       return false;
50     res = Calc_From_Val_Percents(percentsBase, v);
51     return true;
52   }
53 
54   if (c == 0)
55   {
56     res = v;
57     return true;
58   }
59   if (end[1] != 0)
60     return false;
61 
62   if (c == '%')
63   {
64     res = Calc_From_Val_Percents(percentsBase, v);
65     return true;
66   }
67 
68   unsigned numBits;
69   switch (MyCharLower_Ascii(c))
70   {
71     case 'b': numBits =  0; break;
72     case 'k': numBits = 10; break;
73     case 'm': numBits = 20; break;
74     case 'g': numBits = 30; break;
75     case 't': numBits = 40; break;
76     default: return false;
77   }
78   const UInt64 val2 = v << numBits;
79   if ((val2 >> numBits) != v)
80     return false;
81   res = val2;
82   return true;
83 }
84 
SetCommonProperty(const UString & name,const PROPVARIANT & value,HRESULT & hres)85 bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres)
86 {
87   hres = S_OK;
88 
89   if (name.IsPrefixedBy_Ascii_NoCase("mt"))
90   {
91     #ifndef Z7_ST
92     _numThreads = _numProcessors;
93     _numThreads_WasForced = false;
94     hres = ParseMtProp2(name.Ptr(2), value, _numThreads, _numThreads_WasForced);
95     // "mt" means "_numThreads_WasForced = false" here
96     #endif
97     return true;
98   }
99 
100   if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
101   {
102     UInt64 v;
103     if (!ParseSizeString(name.Ptr(6), value, _memAvail, v))
104       hres = E_INVALIDARG;
105     _memUsage_Decompress = v;
106     _memUsage_Compress = v;
107     _memUsage_WasSet = true;
108     return true;
109   }
110 
111   return false;
112 }
113 
114 
115 #ifndef Z7_EXTRACT_ONLY
116 
SetMethodProp32(CMethodProps & m,PROPID propID,UInt32 value)117 static void SetMethodProp32(CMethodProps &m, PROPID propID, UInt32 value)
118 {
119   if (m.FindProp(propID) < 0)
120     m.AddProp32(propID, value);
121 }
122 
SetGlobalLevelTo(COneMethodInfo & oneMethodInfo) const123 void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
124 {
125   UInt32 level = _level;
126   if (level != (UInt32)(Int32)-1)
127     SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
128 }
129 
130 #ifndef Z7_ST
131 
SetMethodProp32_Replace(CMethodProps & m,PROPID propID,UInt32 value)132 static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value)
133 {
134   const int i = m.FindProp(propID);
135   if (i >= 0)
136   {
137     NWindows::NCOM::CPropVariant &val = m.Props[(unsigned)i].Value;
138     val = (UInt32)value;
139     return;
140   }
141   m.AddProp32(propID, value);
142 }
143 
SetMethodThreadsTo_IfNotFinded(CMethodProps & oneMethodInfo,UInt32 numThreads)144 void CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(CMethodProps &oneMethodInfo, UInt32 numThreads)
145 {
146   SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
147 }
148 
SetMethodThreadsTo_Replace(CMethodProps & oneMethodInfo,UInt32 numThreads)149 void CMultiMethodProps::SetMethodThreadsTo_Replace(CMethodProps &oneMethodInfo, UInt32 numThreads)
150 {
151   SetMethodProp32_Replace(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
152 }
153 
154 #endif // Z7_ST
155 
156 
InitMulti()157 void CMultiMethodProps::InitMulti()
158 {
159   _level = (UInt32)(Int32)-1;
160   _analysisLevel = -1;
161   _crcSize = 4;
162   _autoFilter = true;
163 }
164 
Init()165 void CMultiMethodProps::Init()
166 {
167   InitCommon();
168   InitMulti();
169   _methods.Clear();
170   _filterMethod.Clear();
171 }
172 
173 
SetProperty(const wchar_t * nameSpec,const PROPVARIANT & value)174 HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
175 {
176   UString name = nameSpec;
177   name.MakeLower_Ascii();
178   if (name.IsEmpty())
179     return E_INVALIDARG;
180 
181   if (name[0] == 'x')
182   {
183     name.Delete(0);
184     _level = 9;
185     return ParsePropToUInt32(name, value, _level);
186   }
187 
188   if (name.IsPrefixedBy_Ascii_NoCase("yx"))
189   {
190     name.Delete(0, 2);
191     UInt32 v = 9;
192     RINOK(ParsePropToUInt32(name, value, v))
193     _analysisLevel = (int)v;
194     return S_OK;
195   }
196 
197   if (name.IsPrefixedBy_Ascii_NoCase("crc"))
198   {
199     name.Delete(0, 3);
200     _crcSize = 4;
201     return ParsePropToUInt32(name, value, _crcSize);
202   }
203 
204   {
205     HRESULT hres;
206     if (SetCommonProperty(name, value, hres))
207       return hres;
208   }
209 
210   UInt32 number;
211   const unsigned index = ParseStringToUInt32(name, number);
212   const UString realName = name.Ptr(index);
213   if (index == 0)
214   {
215     if (name.IsEqualTo("f"))
216     {
217       const HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
218       if (res == S_OK)
219         return res;
220       if (value.vt != VT_BSTR)
221         return E_INVALIDARG;
222       return _filterMethod.ParseMethodFromPROPVARIANT(UString(), value);
223     }
224     number = 0;
225   }
226   if (number > 64)
227     return E_INVALIDARG;
228   for (unsigned j = _methods.Size(); j <= number; j++)
229     _methods.AddNew();
230   return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
231 }
232 
233 
234 
Init()235 void CSingleMethodProps::Init()
236 {
237   InitCommon();
238   InitSingle();
239   Clear();
240 }
241 
242 
SetProperty(const wchar_t * name2,const PROPVARIANT & value)243 HRESULT CSingleMethodProps::SetProperty(const wchar_t *name2, const PROPVARIANT &value)
244 {
245   // processed = false;
246   UString name = name2;
247   name.MakeLower_Ascii();
248   if (name.IsEmpty())
249     return E_INVALIDARG;
250   if (name.IsPrefixedBy_Ascii_NoCase("x"))
251   {
252     UInt32 a = 9;
253     RINOK(ParsePropToUInt32(name.Ptr(1), value, a))
254     _level = a;
255     AddProp_Level(a);
256     // processed = true;
257     return S_OK;
258   }
259   {
260     HRESULT hres;
261     if (SetCommonProperty(name, value, hres))
262     {
263       // processed = true;
264       return S_OK;
265     }
266   }
267   RINOK(ParseMethodFromPROPVARIANT(name, value))
268   return S_OK;
269 }
270 
271 
SetProperties(const wchar_t * const * names,const PROPVARIANT * values,UInt32 numProps)272 HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
273 {
274   Init();
275 
276   for (UInt32 i = 0; i < numProps; i++)
277   {
278     RINOK(SetProperty(names[i], values[i]))
279   }
280 
281   return S_OK;
282 }
283 
284 #endif
285 
286 
PROPVARIANT_to_BoolPair(const PROPVARIANT & prop,CBoolPair & dest)287 static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest)
288 {
289   RINOK(PROPVARIANT_to_bool(prop, dest.Val))
290   dest.Def = true;
291   return S_OK;
292 }
293 
Parse(const UString & name,const PROPVARIANT & prop,bool & processed)294 HRESULT CHandlerTimeOptions::Parse(const UString &name, const PROPVARIANT &prop, bool &processed)
295 {
296   processed = true;
297   if (name.IsEqualTo_Ascii_NoCase("tm")) { return PROPVARIANT_to_BoolPair(prop, Write_MTime); }
298   if (name.IsEqualTo_Ascii_NoCase("ta")) { return PROPVARIANT_to_BoolPair(prop, Write_ATime); }
299   if (name.IsEqualTo_Ascii_NoCase("tc")) { return PROPVARIANT_to_BoolPair(prop, Write_CTime); }
300   if (name.IsPrefixedBy_Ascii_NoCase("tp"))
301   {
302     UInt32 v = 0;
303     RINOK(ParsePropToUInt32(name.Ptr(2), prop, v))
304     Prec = v;
305     return S_OK;
306   }
307   processed = false;
308   return S_OK;
309 }
310 
311 }
312