1 // MethodProps.h
2 
3 #ifndef __7Z_METHOD_PROPS_H
4 #define __7Z_METHOD_PROPS_H
5 
6 #include "../../Common/MyString.h"
7 #include "../../Common/Defs.h"
8 
9 #include "../../Windows/Defs.h"
10 
11 #include "../../Windows/PropVariant.h"
12 
13 #include "../ICoder.h"
14 
15 bool StringToBool(const wchar_t *s, bool &res);
16 HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest);
17 unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number);
18 HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
19 
20 HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
21 
22 struct CProp
23 {
24   PROPID Id;
25   bool IsOptional;
26   NWindows::NCOM::CPropVariant Value;
CPropCProp27   CProp(): IsOptional(false) {}
28 };
29 
30 struct CProps
31 {
32   CObjectVector<CProp> Props;
33 
ClearCProps34   void Clear() { Props.Clear(); }
35 
AreThereNonOptionalPropsCProps36   bool AreThereNonOptionalProps() const
37   {
38     FOR_VECTOR (i, Props)
39       if (!Props[i].IsOptional)
40         return true;
41     return false;
42   }
43 
44   void AddProp32(PROPID propid, UInt32 val);
45 
46   void AddPropBool(PROPID propid, bool val);
47 
AddProp_AsciiCProps48   void AddProp_Ascii(PROPID propid, const char *s)
49   {
50     CProp &prop = Props.AddNew();
51     prop.IsOptional = true;
52     prop.Id = propid;
53     prop.Value = s;
54   }
55 
56   HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const;
57 };
58 
59 class CMethodProps: public CProps
60 {
61   HRESULT SetParam(const UString &name, const UString &value);
62 public:
63   int GetLevel() const;
Get_NumThreads()64   int Get_NumThreads() const
65   {
66     int i = FindProp(NCoderPropID::kNumThreads);
67     if (i >= 0)
68       if (Props[i].Value.vt == VT_UI4)
69         return (int)Props[i].Value.ulVal;
70     return -1;
71   }
72 
Get_DicSize(UInt32 & res)73   bool Get_DicSize(UInt32 &res) const
74   {
75     res = 0;
76     int i = FindProp(NCoderPropID::kDictionarySize);
77     if (i >= 0)
78       if (Props[i].Value.vt == VT_UI4)
79       {
80         res = Props[i].Value.ulVal;
81         return true;
82       }
83     return false;
84   }
85 
86   int FindProp(PROPID id) const;
87 
Get_Lzma_Algo()88   UInt32 Get_Lzma_Algo() const
89   {
90     int i = FindProp(NCoderPropID::kAlgorithm);
91     if (i >= 0)
92       if (Props[i].Value.vt == VT_UI4)
93         return Props[i].Value.ulVal;
94     return GetLevel() >= 5 ? 1 : 0;
95   }
96 
Get_Lzma_DicSize()97   UInt32 Get_Lzma_DicSize() const
98   {
99     int i = FindProp(NCoderPropID::kDictionarySize);
100     if (i >= 0)
101       if (Props[i].Value.vt == VT_UI4)
102         return Props[i].Value.ulVal;
103     int level = GetLevel();
104     return level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26));
105   }
106 
Get_Lzma_Eos()107   bool Get_Lzma_Eos() const
108   {
109     int i = FindProp(NCoderPropID::kEndMarker);
110     if (i >= 0)
111     {
112       const NWindows::NCOM::CPropVariant &val = Props[i].Value;
113       if (val.vt == VT_BOOL)
114         return VARIANT_BOOLToBool(val.boolVal);
115     }
116     return false;
117   }
118 
Are_Lzma_Model_Props_Defined()119   bool Are_Lzma_Model_Props_Defined() const
120   {
121     if (FindProp(NCoderPropID::kPosStateBits) >= 0) return true;
122     if (FindProp(NCoderPropID::kLitContextBits) >= 0) return true;
123     if (FindProp(NCoderPropID::kLitPosBits) >= 0) return true;
124     return false;
125   }
126 
Get_Lzma_NumThreads()127   UInt32 Get_Lzma_NumThreads() const
128   {
129     if (Get_Lzma_Algo() == 0)
130       return 1;
131     int numThreads = Get_NumThreads();
132     if (numThreads >= 0)
133       return numThreads < 2 ? 1 : 2;
134     return 2;
135   }
136 
Get_Xz_NumThreads(UInt32 & lzmaThreads)137   int Get_Xz_NumThreads(UInt32 &lzmaThreads) const
138   {
139     lzmaThreads = 1;
140     int numThreads = Get_NumThreads();
141     if (numThreads >= 0 && numThreads <= 1)
142       return 1;
143     if (Get_Lzma_Algo() != 0)
144       lzmaThreads = 2;
145     return numThreads;
146   }
147 
GetProp_BlockSize(PROPID id)148   UInt64 GetProp_BlockSize(PROPID id) const
149   {
150     int i = FindProp(id);
151     if (i >= 0)
152     {
153       const NWindows::NCOM::CPropVariant &val = Props[i].Value;
154       if (val.vt == VT_UI4) { return val.ulVal; }
155       if (val.vt == VT_UI8) { return val.uhVal.QuadPart; }
156     }
157     return 0;
158   }
159 
Get_Xz_BlockSize()160   UInt64 Get_Xz_BlockSize() const
161   {
162     {
163       UInt64 blockSize1 = GetProp_BlockSize(NCoderPropID::kBlockSize);
164       UInt64 blockSize2 = GetProp_BlockSize(NCoderPropID::kBlockSize2);
165       UInt64 minSize = MyMin(blockSize1, blockSize2);
166       if (minSize != 0)
167         return minSize;
168       UInt64 maxSize = MyMax(blockSize1, blockSize2);
169       if (maxSize != 0)
170         return maxSize;
171     }
172     const UInt32 kMinSize = (UInt32)1 << 20;
173     const UInt32 kMaxSize = (UInt32)1 << 28;
174     UInt32 dictSize = Get_Lzma_DicSize();
175     UInt64 blockSize = (UInt64)dictSize << 2;
176     if (blockSize < kMinSize) blockSize = kMinSize;
177     if (blockSize > kMaxSize) blockSize = kMaxSize;
178     if (blockSize < dictSize) blockSize = dictSize;
179     blockSize += (kMinSize - 1);
180     blockSize &= ~(UInt64)(kMinSize - 1);
181     return blockSize;
182   }
183 
184 
Get_BZip2_NumThreads(bool & fixedNumber)185   UInt32 Get_BZip2_NumThreads(bool &fixedNumber) const
186   {
187     fixedNumber = false;
188     int numThreads = Get_NumThreads();
189     if (numThreads >= 0)
190     {
191       fixedNumber = true;
192       if (numThreads < 1) return 1;
193       const unsigned kNumBZip2ThreadsMax = 64;
194       if (numThreads > kNumBZip2ThreadsMax) return kNumBZip2ThreadsMax;
195       return numThreads;
196     }
197     return 1;
198   }
199 
Get_BZip2_BlockSize()200   UInt32 Get_BZip2_BlockSize() const
201   {
202     int i = FindProp(NCoderPropID::kDictionarySize);
203     if (i >= 0)
204       if (Props[i].Value.vt == VT_UI4)
205       {
206         UInt32 blockSize = Props[i].Value.ulVal;
207         const UInt32 kDicSizeMin = 100000;
208         const UInt32 kDicSizeMax = 900000;
209         if (blockSize < kDicSizeMin) blockSize = kDicSizeMin;
210         if (blockSize > kDicSizeMax) blockSize = kDicSizeMax;
211         return blockSize;
212       }
213     int level = GetLevel();
214     return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1));
215   }
216 
Get_Ppmd_MemSize()217   UInt32 Get_Ppmd_MemSize() const
218   {
219     int i = FindProp(NCoderPropID::kUsedMemorySize);
220     if (i >= 0)
221       if (Props[i].Value.vt == VT_UI4)
222         return Props[i].Value.ulVal;
223     int level = GetLevel();
224     return level >= 9 ? (192 << 20) : ((UInt32)1 << (level + 19));
225   }
226 
AddProp_Level(UInt32 level)227   void AddProp_Level(UInt32 level)
228   {
229     AddProp32(NCoderPropID::kLevel, level);
230   }
231 
AddProp_NumThreads(UInt32 numThreads)232   void AddProp_NumThreads(UInt32 numThreads)
233   {
234     AddProp32(NCoderPropID::kNumThreads, numThreads);
235   }
236 
AddProp_EndMarker_if_NotFound(bool eos)237   void AddProp_EndMarker_if_NotFound(bool eos)
238   {
239     if (FindProp(NCoderPropID::kEndMarker) < 0)
240       AddPropBool(NCoderPropID::kEndMarker, eos);
241   }
242 
243   HRESULT ParseParamsFromString(const UString &srcString);
244   HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
245 };
246 
247 class COneMethodInfo: public CMethodProps
248 {
249 public:
250   AString MethodName;
251   UString PropsString;
252 
Clear()253   void Clear()
254   {
255     CMethodProps::Clear();
256     MethodName.Empty();
257     PropsString.Empty();
258   }
IsEmpty()259   bool IsEmpty() const { return MethodName.IsEmpty() && Props.IsEmpty(); }
260   HRESULT ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
261   HRESULT ParseMethodFromString(const UString &s);
262 };
263 
264 #endif
265