summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp')
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp427
1 files changed, 353 insertions, 74 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp b/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp
index 09f7b29cc24..fe60f610064 100644
--- a/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp
@@ -8,9 +8,39 @@
using namespace NWindows;
-bool StringToBool(const UString &s, bool &res)
+UInt64 Calc_From_Val_Percents(UInt64 val, UInt64 percents)
{
- if (s.IsEmpty() || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON"))
+ // if (percents == 0) return 0;
+ const UInt64 q = percents / 100;
+ const UInt32 r = (UInt32)(percents % 100);
+ UInt64 res = 0;
+
+ if (q != 0)
+ {
+ if (val > (UInt64)(Int64)-1 / q)
+ return (UInt64)(Int64)-1;
+ res = val * q;
+ }
+
+ if (r != 0)
+ {
+ UInt64 v2;
+ if (val <= (UInt64)(Int64)-1 / r)
+ v2 = val * r / 100;
+ else
+ v2 = val / 100 * r;
+ res += v2;
+ if (res < v2)
+ return (UInt64)(Int64)-1;
+ }
+
+ return res;
+}
+
+
+bool StringToBool(const wchar_t *s, bool &res)
+{
+ if (s[0] == 0 || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON"))
{
res = true;
return true;
@@ -42,10 +72,18 @@ unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number)
return (unsigned)(end - start);
}
+static unsigned ParseStringToUInt64(const UString &srcString, UInt64 &number)
+{
+ const wchar_t *start = srcString;
+ const wchar_t *end;
+ number = ConvertStringToUInt64(start, &end);
+ return (unsigned)(end - start);
+}
+
HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
{
// =VT_UI4
- // =VT_EMPTY
+ // =VT_EMPTY : it doesn't change (resValue), and returns S_OK
// {stringUInt32}=VT_EMPTY
if (prop.vt == VT_UI4)
@@ -66,66 +104,151 @@ HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &
return S_OK;
}
-HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
+
+
+HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force)
{
+ force = false;
+ UString s;
if (name.IsEmpty())
{
- switch (prop.vt)
+ if (prop.vt == VT_UI4)
+ {
+ numThreads = prop.ulVal;
+ force = true;
+ return S_OK;
+ }
+ bool val;
+ HRESULT res = PROPVARIANT_to_bool(prop, val);
+ if (res == S_OK)
{
- case VT_UI4:
- numThreads = prop.ulVal;
- break;
- default:
+ if (!val)
{
- bool val;
- RINOK(PROPVARIANT_to_bool(prop, val));
- numThreads = (val ? defaultNumThreads : 1);
- break;
+ numThreads = 1;
+ force = true;
}
+ // force = true; for debug
+ // "(VT_BOOL = VARIANT_TRUE)" set "force = false" and doesn't change numThreads
+ return S_OK;
}
- return S_OK;
+ if (prop.vt != VT_BSTR)
+ return res;
+ s.SetFromBstr(prop.bstrVal);
+ if (s.IsEmpty())
+ return E_INVALIDARG;
}
- if (prop.vt != VT_EMPTY)
+ else
+ {
+ if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ s = name;
+ }
+
+ s.MakeLower_Ascii();
+ const wchar_t *start = s;
+ UInt32 v = numThreads;
+
+ /* we force up, if threads number specified
+ only `d` will force it down */
+ bool force_loc = true;
+ for (;;)
+ {
+ const wchar_t c = *start;
+ if (!c)
+ break;
+ if (c == 'd')
+ {
+ force_loc = false; // force down
+ start++;
+ continue;
+ }
+ if (c == 'u')
+ {
+ force_loc = true; // force up
+ start++;
+ continue;
+ }
+ bool isPercent = false;
+ if (c == 'p')
+ {
+ isPercent = true;
+ start++;
+ }
+ const wchar_t *end;
+ v = ConvertStringToUInt32(start, &end);
+ if (end == start)
+ return E_INVALIDARG;
+ if (isPercent)
+ v = numThreads * v / 100;
+ start = end;
+ }
+
+ numThreads = v;
+ force = force_loc;
+ return S_OK;
+}
+
+
+
+static HRESULT SetLogSizeProp(UInt64 number, NCOM::CPropVariant &destProp)
+{
+ if (number >= 64)
return E_INVALIDARG;
- return ParsePropToUInt32(name, prop, numThreads);
+ UInt32 val32;
+ if (number < 32)
+ val32 = (UInt32)1 << (unsigned)number;
+ /*
+ else if (number == 32 && reduce_4GB_to_32bits)
+ val32 = (UInt32)(Int32)-1;
+ */
+ else
+ {
+ destProp = (UInt64)((UInt64)1 << (unsigned)number);
+ return S_OK;
+ }
+ destProp = (UInt32)val32;
+ return S_OK;
}
static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp)
{
+ /* if (reduce_4GB_to_32bits) we can reduce (4 GiB) property to (4 GiB - 1).
+ to fit the value to UInt32 for clients that do not support 64-bit values */
+
const wchar_t *end;
- UInt32 number = ConvertStringToUInt32(s, &end);
- unsigned numDigits = (unsigned)(end - s);
+ const UInt64 number = ConvertStringToUInt64(s, &end);
+ const unsigned numDigits = (unsigned)(end - s.Ptr());
if (numDigits == 0 || s.Len() > numDigits + 1)
return E_INVALIDARG;
if (s.Len() == numDigits)
- {
- if (number >= 64)
- return E_INVALIDARG;
- if (number < 32)
- destProp = (UInt32)((UInt32)1 << (unsigned)number);
- else
- destProp = (UInt64)((UInt64)1 << (unsigned)number);
- return S_OK;
- }
+ return SetLogSizeProp(number, destProp);
unsigned numBits;
switch (MyCharLower_Ascii(s[numDigits]))
{
- case 'b': destProp = number; return S_OK;
+ case 'b': numBits = 0; break;
case 'k': numBits = 10; break;
case 'm': numBits = 20; break;
case 'g': numBits = 30; break;
default: return E_INVALIDARG;
}
- if (number < ((UInt32)1 << (32 - numBits)))
- destProp = (UInt32)(number << numBits);
+ const UInt64 range4g = ((UInt64)1 << (32 - numBits));
+ if (number < range4g)
+ destProp = (UInt32)((UInt32)number << numBits);
+ /*
+ else if (number == range4g && reduce_4GB_to_32bits)
+ destProp = (UInt32)(Int32)-1;
+ */
+ else if (numBits == 0)
+ destProp = (UInt64)number;
+ else if (number >= ((UInt64)1 << (64 - numBits)))
+ return E_INVALIDARG;
else
destProp = (UInt64)((UInt64)number << numBits);
-
return S_OK;
}
@@ -133,28 +256,32 @@ static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp)
static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVariant &destProp)
{
if (prop.vt == VT_UI4)
+ return SetLogSizeProp(prop.ulVal, destProp);
+
+ if (prop.vt == VT_BSTR)
{
- UInt32 v = prop.ulVal;
- if (v >= 64)
- return E_INVALIDARG;
- if (v < 32)
- destProp = (UInt32)((UInt32)1 << (unsigned)v);
- else
- destProp = (UInt64)((UInt64)1 << (unsigned)v);
- return S_OK;
+ UString s;
+ s = prop.bstrVal;
+ return StringToDictSize(s, destProp);
}
- if (prop.vt == VT_BSTR)
- return StringToDictSize(prop.bstrVal, destProp);
return E_INVALIDARG;
}
-void CProps::AddProp32(PROPID propid, UInt32 level)
+void CProps::AddProp32(PROPID propid, UInt32 val)
+{
+ CProp &prop = Props.AddNew();
+ prop.IsOptional = true;
+ prop.Id = propid;
+ prop.Value = (UInt32)val;
+}
+
+void CProps::AddPropBool(PROPID propid, bool val)
{
CProp &prop = Props.AddNew();
prop.IsOptional = true;
prop.Id = propid;
- prop.Value = (UInt32)level;
+ prop.Value = val;
}
class CCoderProps
@@ -164,10 +291,12 @@ class CCoderProps
unsigned _numProps;
unsigned _numPropsMax;
public:
- CCoderProps(unsigned numPropsMax)
+ CCoderProps(unsigned numPropsMax):
+ _propIDs(NULL),
+ _props(NULL),
+ _numProps(0),
+ _numPropsMax(numPropsMax)
{
- _numPropsMax = numPropsMax;
- _numProps = 0;
_propIDs = new PROPID[numPropsMax];
_props = new NCOM::CPropVariant[numPropsMax];
}
@@ -194,7 +323,15 @@ void CCoderProps::AddProp(const CProp &prop)
HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const
{
- CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0));
+ return SetCoderProps_DSReduce_Aff(scp, dataSizeReduce, NULL);
+}
+
+HRESULT CProps::SetCoderProps_DSReduce_Aff(
+ ICompressSetCoderProperties *scp,
+ const UInt64 *dataSizeReduce,
+ const UInt64 *affinity) const
+{
+ CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0) + (affinity ? 1 : 0) );
FOR_VECTOR (i, Props)
coderProps.AddProp(Props[i]);
if (dataSizeReduce)
@@ -204,27 +341,34 @@ HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *da
prop.Value = *dataSizeReduce;
coderProps.AddProp(prop);
}
+ if (affinity)
+ {
+ CProp prop;
+ prop.Id = NCoderPropID::kAffinity;
+ prop.Value = *affinity;
+ coderProps.AddProp(prop);
+ }
return coderProps.SetProps(scp);
}
int CMethodProps::FindProp(PROPID id) const
{
- for (int i = Props.Size() - 1; i >= 0; i--)
- if (Props[i].Id == id)
- return i;
+ for (unsigned i = Props.Size(); i != 0;)
+ if (Props[--i].Id == id)
+ return (int)i;
return -1;
}
-int CMethodProps::GetLevel() const
+unsigned CMethodProps::GetLevel() const
{
int i = FindProp(NCoderPropID::kLevel);
if (i < 0)
return 5;
- if (Props[i].Value.vt != VT_UI4)
+ if (Props[(unsigned)i].Value.vt != VT_UI4)
return 9;
- UInt32 level = Props[i].Value.ulVal;
- return level > 9 ? 9 : (int)level;
+ UInt32 level = Props[(unsigned)i].Value.ulVal;
+ return level > 9 ? 9 : (unsigned)level;
}
struct CNameToPropID
@@ -233,13 +377,16 @@ struct CNameToPropID
const char *Name;
};
+
+// the following are related to NCoderPropID::EEnum values
+// NCoderPropID::k_NUM_DEFINED
static const CNameToPropID g_NameToPropID[] =
{
{ VT_UI4, "" },
{ VT_UI4, "d" },
{ VT_UI4, "mem" },
{ VT_UI4, "o" },
- { VT_UI4, "c" },
+ { VT_UI8, "c" },
{ VT_UI4, "pb" },
{ VT_UI4, "lc" },
{ VT_UI4, "lp" },
@@ -251,14 +398,61 @@ static const CNameToPropID g_NameToPropID[] =
{ VT_UI4, "mt" },
{ VT_BOOL, "eos" },
{ VT_UI4, "x" },
- { VT_UI4, "reduceSize" }
+ { VT_UI8, "reduce" },
+ { VT_UI8, "expect" },
+ { VT_UI8, "cc" }, // "cc" in v23, "b" in v22.01
+ { VT_UI4, "check" },
+ { VT_BSTR, "filter" },
+ { VT_UI8, "memuse" },
+ { VT_UI8, "aff" },
+ { VT_UI4, "offset" },
+ { VT_UI4, "zhb" }
+ /*
+ ,
+ // { VT_UI4, "zhc" },
+ // { VT_UI4, "zhd" },
+ // { VT_UI4, "zcb" },
+ { VT_UI4, "dc" },
+ { VT_UI4, "zx" },
+ { VT_UI4, "zf" },
+ { VT_UI4, "zmml" },
+ { VT_UI4, "zov" },
+ { VT_BOOL, "zmfr" },
+ { VT_BOOL, "zle" }, // long enable
+ // { VT_UI4, "zldb" },
+ { VT_UI4, "zld" },
+ { VT_UI4, "zlhb" },
+ { VT_UI4, "zlmml" },
+ { VT_UI4, "zlbb" },
+ { VT_UI4, "zlhrb" },
+ { VT_BOOL, "zwus" },
+ { VT_BOOL, "zshp" },
+ { VT_BOOL, "zshs" },
+ { VT_BOOL, "zshe" },
+ { VT_BOOL, "zshg" },
+ { VT_UI4, "zpsm" }
+ */
+ // { VT_UI4, "mcb" }, // mc log version
+ // { VT_UI4, "ztlen" }, // fb ?
};
+/*
+#if defined(static_assert) || (defined(__cplusplus) && __cplusplus >= 200410L) || (defined(_MSC_VER) && _MSC_VER >= 1600)
+
+#if (defined(__cplusplus) && __cplusplus < 201103L) \
+ && defined(__clang__) && __clang_major__ >= 4
+#pragma GCC diagnostic ignored "-Wc11-extensions"
+#endif
+ static_assert(Z7_ARRAY_SIZE(g_NameToPropID) == NCoderPropID::k_NUM_DEFINED,
+ "g_NameToPropID doesn't match NCoderPropID enum");
+#endif
+*/
+
static int FindPropIdExact(const UString &name)
{
- for (unsigned i = 0; i < ARRAY_SIZE(g_NameToPropID); i++)
+ for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NameToPropID); i++)
if (StringsAreEqualNoCase_Ascii(name, g_NameToPropID[i].Name))
- return i;
+ return (int)i;
return -1;
}
@@ -269,6 +463,13 @@ static bool ConvertProperty(const PROPVARIANT &srcProp, VARTYPE varType, NCOM::C
destProp = srcProp;
return true;
}
+
+ if (varType == VT_UI8 && srcProp.vt == VT_UI4)
+ {
+ destProp = (UInt64)srcProp.ulVal;
+ return true;
+ }
+
if (varType == VT_BOOL)
{
bool res;
@@ -311,8 +512,8 @@ static void SplitParam(const UString &param, UString &name, UString &value)
int eqPos = param.Find(L'=');
if (eqPos >= 0)
{
- name.SetFrom(param, eqPos);
- value = param.Ptr(eqPos + 1);
+ name.SetFrom(param, (unsigned)eqPos);
+ value = param.Ptr((unsigned)(eqPos + 1));
return;
}
unsigned i;
@@ -333,7 +534,12 @@ static bool IsLogSizeProp(PROPID propid)
case NCoderPropID::kDictionarySize:
case NCoderPropID::kUsedMemorySize:
case NCoderPropID::kBlockSize:
- case NCoderPropID::kReduceSize:
+ case NCoderPropID::kBlockSize2:
+ /*
+ case NCoderPropID::kChainSize:
+ case NCoderPropID::kLdmWindowSize:
+ */
+ // case NCoderPropID::kReduceSize:
return true;
}
return false;
@@ -343,14 +549,19 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value)
{
int index = FindPropIdExact(name);
if (index < 0)
- return E_INVALIDARG;
+ {
+ // 'b' was used as NCoderPropID::kBlockSize2 before v23
+ if (!name.IsEqualTo_Ascii_NoCase("b") || value.Find(L':') >= 0)
+ return E_INVALIDARG;
+ index = NCoderPropID::kBlockSize2;
+ }
const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index];
CProp prop;
- prop.Id = index;
+ prop.Id = (unsigned)index;
if (IsLogSizeProp(prop.Id))
{
- RINOK(StringToDictSize(value, prop.Value));
+ RINOK(StringToDictSize(value, prop.Value))
}
else
{
@@ -366,9 +577,22 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value)
}
else if (!value.IsEmpty())
{
- UInt32 number;
- if (ParseStringToUInt32(value, number) == value.Len())
- propValue = number;
+ if (nameToPropID.VarType == VT_UI4)
+ {
+ UInt32 number;
+ if (ParseStringToUInt32(value, number) == value.Len())
+ propValue = number;
+ else
+ propValue = value;
+ }
+ else if (nameToPropID.VarType == VT_UI8)
+ {
+ UInt64 number;
+ if (ParseStringToUInt64(value, number) == value.Len())
+ propValue = number;
+ else
+ propValue = value;
+ }
else
propValue = value;
}
@@ -388,7 +612,7 @@ HRESULT CMethodProps::ParseParamsFromString(const UString &srcString)
const UString &param = params[i];
UString name, value;
SplitParam(param, name, value);
- RINOK(SetParam(name, value));
+ RINOK(SetParam(name, value))
}
return S_OK;
}
@@ -409,16 +633,16 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const
}
// {realName}=value
- int index = FindPropIdExact(realName);
+ const int index = FindPropIdExact(realName);
if (index < 0)
return E_INVALIDARG;
const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index];
CProp prop;
- prop.Id = index;
+ prop.Id = (unsigned)index;
if (IsLogSizeProp(prop.Id))
{
- RINOK(PROPVARIANT_to_DictSize(value, prop.Value));
+ RINOK(PROPVARIANT_to_DictSize(value, prop.Value))
}
else
{
@@ -429,6 +653,59 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const
return S_OK;
}
+
+static UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads)
+{
+ UInt32 hs = dict - 1;
+ hs |= (hs >> 1);
+ hs |= (hs >> 2);
+ hs |= (hs >> 4);
+ hs |= (hs >> 8);
+ hs >>= 1;
+ if (hs >= (1 << 24))
+ hs >>= 1;
+ hs |= (1 << 16) - 1;
+ // if (numHashBytes >= 5)
+ if (!isBt)
+ hs |= (256 << 10) - 1;
+ hs++;
+ UInt64 size1 = (UInt64)hs * 4;
+ size1 += (UInt64)dict * 4;
+ if (isBt)
+ size1 += (UInt64)dict * 4;
+ size1 += (2 << 20);
+
+ if (numThreads > 1 && isBt)
+ size1 += (2 << 20) + (4 << 20);
+ return size1;
+}
+
+static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28;
+
+UInt64 CMethodProps::Get_Lzma_MemUsage(bool addSlidingWindowSize) const
+{
+ const UInt64 dicSize = Get_Lzma_DicSize();
+ const bool isBt = Get_Lzma_MatchFinder_IsBt();
+ const UInt32 dict32 = (dicSize >= kLzmaMaxDictSize ? kLzmaMaxDictSize : (UInt32)dicSize);
+ const UInt32 numThreads = Get_Lzma_NumThreads();
+ UInt64 size = GetMemoryUsage_LZMA(dict32, isBt, numThreads);
+
+ if (addSlidingWindowSize)
+ {
+ const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16);
+ UInt64 blockSize = (UInt64)dict32 + (1 << 16)
+ + (numThreads > 1 ? (1 << 20) : 0);
+ blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2));
+ if (blockSize >= kBlockSizeMax)
+ blockSize = kBlockSizeMax;
+ size += blockSize;
+ }
+ return size;
+}
+
+
+
+
HRESULT COneMethodInfo::ParseMethodFromString(const UString &s)
{
MethodName.Empty();
@@ -436,14 +713,14 @@ HRESULT COneMethodInfo::ParseMethodFromString(const UString &s)
{
UString temp = s;
if (splitPos >= 0)
- temp.DeleteFrom(splitPos);
+ temp.DeleteFrom((unsigned)splitPos);
if (!temp.IsAscii())
return E_INVALIDARG;
MethodName.SetFromWStr_if_Ascii(temp);
}
if (splitPos < 0)
return S_OK;
- PropsString = s.Ptr(splitPos + 1);
+ PropsString = s.Ptr((unsigned)(splitPos + 1));
return ParseParamsFromString(PropsString);
}
@@ -454,5 +731,7 @@ HRESULT COneMethodInfo::ParseMethodFromPROPVARIANT(const UString &realName, cons
// -m{N}=method
if (value.vt != VT_BSTR)
return E_INVALIDARG;
- return ParseMethodFromString(value.bstrVal);
+ UString s;
+ s = value.bstrVal;
+ return ParseMethodFromString(s);
}