1 // HandlerOut.cpp
2 
3 #include "StdAfx.h"
4 
5 #ifndef _7ZIP_ST
6 #include "../../../Windows/System.h"
7 #endif
8 
9 #include "../Common/ParseProperties.h"
10 
11 #include "HandlerOut.h"
12 
13 using namespace NWindows;
14 
15 namespace NArchive {
16 
SetMethodProp32(COneMethodInfo & m,PROPID propID,UInt32 value)17 static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
18 {
19   if (m.FindProp(propID) < 0)
20     m.AddProp32(propID, value);
21 }
22 
SetGlobalLevelAndThreads(COneMethodInfo & oneMethodInfo,UInt32 numThreads)23 void CMultiMethodProps::SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
24     #ifndef _7ZIP_ST
25     , UInt32 numThreads
26     #endif
27     )
28 {
29   UInt32 level = _level;
30   if (level != (UInt32)(Int32)-1)
31     SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
32   #ifndef _7ZIP_ST
33   SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
34   #endif
35 }
36 
Init()37 void CMultiMethodProps::Init()
38 {
39   #ifndef _7ZIP_ST
40   _numProcessors = _numThreads = NSystem::GetNumberOfProcessors();
41   #endif
42 
43   _level = (UInt32)(Int32)-1;
44   _autoFilter = true;
45   _crcSize = 4;
46   _filterMethod.Clear();
47   _methods.Clear();
48 }
49 
SetProperty(const wchar_t * nameSpec,const PROPVARIANT & value)50 HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
51 {
52   UString name = nameSpec;
53   name.MakeLower_Ascii();
54   if (name.IsEmpty())
55     return E_INVALIDARG;
56 
57   if (name[0] == 'x')
58   {
59     name.Delete(0);
60     _level = 9;
61     return ParsePropToUInt32(name, value, _level);
62   }
63 
64   if (name == L"crc")
65   {
66     name.Delete(0, 3);
67     _crcSize = 4;
68     return ParsePropToUInt32(name, value, _crcSize);
69   }
70 
71   UInt32 number;
72   int index = ParseStringToUInt32(name, number);
73   UString realName = name.Ptr(index);
74   if (index == 0)
75   {
76     if (name.IsPrefixedBy(L"mt"))
77     {
78       #ifndef _7ZIP_ST
79       RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads));
80       #endif
81       return S_OK;
82     }
83     if (name.IsEqualTo("f"))
84     {
85       HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
86       if (res == S_OK)
87         return res;
88       if (value.vt != VT_BSTR)
89         return E_INVALIDARG;
90       return _filterMethod.ParseMethodFromPROPVARIANT(L"", value);
91     }
92     number = 0;
93   }
94   if (number > 64)
95     return E_FAIL;
96   for (int j = _methods.Size(); j <= (int)number; j++)
97     _methods.Add(COneMethodInfo());
98   return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
99 }
100 
Init()101 void CSingleMethodProps::Init()
102 {
103   Clear();
104   #ifndef _7ZIP_ST
105   _numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
106   AddNumThreadsProp(_numThreads);
107   #endif
108   _level = (UInt32)(Int32)-1;
109 }
110 
SetProperties(const wchar_t ** names,const PROPVARIANT * values,UInt32 numProps)111 HRESULT CSingleMethodProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
112 {
113   Init();
114   for (UInt32 i = 0; i < numProps; i++)
115   {
116     UString name = names[i];
117     name.MakeLower_Ascii();
118     if (name.IsEmpty())
119       return E_INVALIDARG;
120     const PROPVARIANT &value = values[i];
121     if (name[0] == L'x')
122     {
123       UInt32 a = 9;
124       RINOK(ParsePropToUInt32(name.Ptr(1), value, a));
125       _level = a;
126       AddLevelProp(a);
127     }
128     else if (name.IsPrefixedBy(L"mt"))
129     {
130       #ifndef _7ZIP_ST
131       RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads));
132       AddNumThreadsProp(_numThreads);
133       #endif
134     }
135     else
136       return ParseMethodFromPROPVARIANT(names[i], value);
137   }
138   return S_OK;
139 }
140 
141 }
142