This commit is contained in:
Igor Pavlov
2011-04-11 00:00:00 +00:00
committed by Kornel Lesiński
parent de4f8c22fe
commit 35596517f2
322 changed files with 9989 additions and 7759 deletions

View File

@@ -214,7 +214,7 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
for (i = 0; i < _coders.Size(); i++)
if (i != _progressCoderIndex)
_coders[i].WaitFinish();
_coders[i].WaitExecuteFinish();
RINOK(ReturnIfError(E_ABORT));
RINOK(ReturnIfError(E_OUTOFMEMORY));

View File

@@ -19,6 +19,7 @@ struct CCoder2: public CCoderInfo2, public CVirtThread
CRecordVector<ISequentialOutStream*> OutStreamPointers;
CCoder2(UInt32 numInStreams, UInt32 numOutStreams);
~CCoder2() { CVirtThread::WaitThreadFinish(); }
void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
virtual void Execute();
void Code(ICompressProgressInfo *progress);

View File

@@ -4,7 +4,7 @@
#include "CoderMixer2ST.h"
namespace NCoderMixer2 {
namespace NCoderMixer {
CCoderMixer2ST::CCoderMixer2ST() {}
@@ -42,7 +42,7 @@ HRESULT CCoderMixer2ST::GetInStream(
{
CMyComPtr<ISequentialInStream> seqInStream;
int i;
for(i = 0; i < _bindInfo.InStreams.Size(); i++)
for (i = 0; i < _bindInfo.InStreams.Size(); i++)
if (_bindInfo.InStreams[i] == streamIndex)
{
seqInStream = inStreams[i];
@@ -57,7 +57,7 @@ HRESULT CCoderMixer2ST::GetInStream(
_bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex,
coderIndex, coderStreamIndex);
CCoderInfo &coder = _coders[coderIndex];
CCoderInfo2 &coder = _coders[coderIndex];
if (!coder.Coder)
return E_NOTIMPL;
coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream);
@@ -91,7 +91,7 @@ HRESULT CCoderMixer2ST::GetOutStream(
{
CMyComPtr<ISequentialOutStream> seqOutStream;
int i;
for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
if (_bindInfo.OutStreams[i] == streamIndex)
{
seqOutStream = outStreams[i];
@@ -106,7 +106,7 @@ HRESULT CCoderMixer2ST::GetOutStream(
_bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex,
coderIndex, coderStreamIndex);
CCoderInfo &coder = _coders[coderIndex];
CCoderInfo2 &coder = _coders[coderIndex];
if (!coder.Coder)
return E_NOTIMPL;
coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream);
@@ -169,7 +169,7 @@ STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
// _mainCoderIndex = 0;
// _mainCoderIndex = _coders.Size() - 1;
CCoderInfo &mainCoder = _coders[_mainCoderIndex];
CCoderInfo2 &mainCoder = _coders[_mainCoderIndex];
CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
@@ -198,7 +198,7 @@ STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
{
if (i == _mainCoderIndex)
continue;
CCoderInfo &coder = _coders[i];
CCoderInfo2 &coder = _coders[i];
CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
if (setOutStreamSize)

View File

@@ -7,7 +7,7 @@
#include "../../../Common/MyCom.h"
#include "../../ICoder.h"
namespace NCoderMixer2 {
namespace NCoderMixer {
// SetBindInfo()
// for each coder
@@ -26,11 +26,11 @@ namespace NCoderMixer2 {
// Code
// }
struct CSTCoderInfo: public CCoderInfo
struct CSTCoderInfo: public CCoderInfo2
{
bool IsMain;
CSTCoderInfo(UInt32 numInStreams, UInt32 numOutStreams, bool isMain):
CCoderInfo(numInStreams, numOutStreams),IsMain(isMain) {}
CCoderInfo2(numInStreams, numOutStreams), IsMain(isMain) {}
};
class CCoderMixer2ST:
@@ -84,5 +84,5 @@ public:
};
}
#endif
#endif

View File

@@ -73,7 +73,7 @@ STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream,
for (i = 0; i < _coders.Size(); i++)
if (i != _progressCoderIndex)
_coders[i].WaitFinish();
_coders[i].WaitExecuteFinish();
RINOK(ReturnIfError(E_ABORT));
RINOK(ReturnIfError(E_OUTOFMEMORY));

View File

@@ -18,6 +18,7 @@ struct CCoder: public CCoderInfo, public CVirtThread
virtual void Execute();
void Code(ICompressProgressInfo *progress);
~CCoder() { CVirtThread::WaitThreadFinish(); }
};
/*

View File

@@ -2,16 +2,10 @@
#include "StdAfx.h"
#include "../../../Common/StringToInt.h"
#include "../../../Windows/PropVariant.h"
#ifndef _7ZIP_ST
#include "../../../Windows/System.h"
#endif
#include "../../ICoder.h"
#include "../Common/ParseProperties.h"
#include "HandlerOut.h"
@@ -20,487 +14,40 @@ using namespace NWindows;
namespace NArchive {
static const wchar_t *kCopyMethod = L"Copy";
static const wchar_t *kLZMAMethodName = L"LZMA";
static const wchar_t *kLZMA2MethodName = L"LZMA2";
static const wchar_t *kBZip2MethodName = L"BZip2";
static const wchar_t *kPpmdMethodName = L"PPMd";
static const wchar_t *kDeflateMethodName = L"Deflate";
static const wchar_t *kDeflate64MethodName = L"Deflate64";
static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
static const UInt32 kLzmaAlgoX1 = 0;
static const UInt32 kLzmaAlgoX5 = 1;
static const UInt32 kLzmaDicSizeX1 = 1 << 16;
static const UInt32 kLzmaDicSizeX3 = 1 << 20;
static const UInt32 kLzmaDicSizeX5 = 1 << 24;
static const UInt32 kLzmaDicSizeX7 = 1 << 25;
static const UInt32 kLzmaDicSizeX9 = 1 << 26;
static const UInt32 kLzmaFastBytesX1 = 32;
static const UInt32 kLzmaFastBytesX7 = 64;
static const UInt32 kPpmdMemSizeX1 = (1 << 22);
static const UInt32 kPpmdMemSizeX5 = (1 << 24);
static const UInt32 kPpmdMemSizeX7 = (1 << 26);
static const UInt32 kPpmdMemSizeX9 = (192 << 20);
static const UInt32 kPpmdOrderX1 = 4;
static const UInt32 kPpmdOrderX5 = 6;
static const UInt32 kPpmdOrderX7 = 16;
static const UInt32 kPpmdOrderX9 = 32;
static const UInt32 kDeflateAlgoX1 = 0;
static const UInt32 kDeflateAlgoX5 = 1;
static const UInt32 kDeflateFastBytesX1 = 32;
static const UInt32 kDeflateFastBytesX7 = 64;
static const UInt32 kDeflateFastBytesX9 = 128;
static const UInt32 kDeflatePassesX1 = 1;
static const UInt32 kDeflatePassesX7 = 3;
static const UInt32 kDeflatePassesX9 = 10;
static const UInt32 kBZip2NumPassesX1 = 1;
static const UInt32 kBZip2NumPassesX7 = 2;
static const UInt32 kBZip2NumPassesX9 = 7;
static const UInt32 kBZip2DicSizeX1 = 100000;
static const UInt32 kBZip2DicSizeX3 = 500000;
static const UInt32 kBZip2DicSizeX5 = 900000;
static const wchar_t *kDefaultMethodName = kLZMAMethodName;
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
static const UInt32 kDictionaryForHeaders = 1 << 20;
static const UInt32 kNumFastBytesForHeaders = 273;
static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5;
static bool AreEqual(const UString &methodName, const wchar_t *s)
{ return (methodName.CompareNoCase(s) == 0); }
bool COneMethodInfo::IsLzma() const
static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
{
return
AreEqual(MethodName, kLZMAMethodName) ||
AreEqual(MethodName, kLZMA2MethodName);
if (m.FindProp(propID) < 0)
m.AddProp32(propID, value);
}
static inline bool IsBZip2Method(const UString &methodName)
{ return AreEqual(methodName, kBZip2MethodName); }
static inline bool IsPpmdMethod(const UString &methodName)
{ return AreEqual(methodName, kPpmdMethodName); }
static inline bool IsDeflateMethod(const UString &methodName)
{
return
AreEqual(methodName, kDeflateMethodName) ||
AreEqual(methodName, kDeflate64MethodName);
}
struct CNameToPropID
{
PROPID PropID;
VARTYPE VarType;
const wchar_t *Name;
};
static CNameToPropID g_NameToPropID[] =
{
{ NCoderPropID::kBlockSize, VT_UI4, L"C" },
{ NCoderPropID::kDictionarySize, VT_UI4, L"D" },
{ NCoderPropID::kUsedMemorySize, VT_UI4, L"MEM" },
{ NCoderPropID::kOrder, VT_UI4, L"O" },
{ NCoderPropID::kPosStateBits, VT_UI4, L"PB" },
{ NCoderPropID::kLitContextBits, VT_UI4, L"LC" },
{ NCoderPropID::kLitPosBits, VT_UI4, L"LP" },
{ NCoderPropID::kEndMarker, VT_BOOL, L"eos" },
{ NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
{ NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
{ NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
{ NCoderPropID::kAlgorithm, VT_UI4, L"a" },
{ NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
{ NCoderPropID::kNumThreads, VT_UI4, L"mt" },
{ NCoderPropID::kDefaultProp, VT_UI4, L"" }
};
static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)
{
if (varType == srcProp.vt)
{
destProp = srcProp;
return true;
}
if (varType == VT_UI1)
{
if (srcProp.vt == VT_UI4)
{
UInt32 value = srcProp.ulVal;
if (value > 0xFF)
return false;
destProp = (Byte)value;
return true;
}
}
else if (varType == VT_BOOL)
{
bool res;
if (SetBoolProperty(res, srcProp) != S_OK)
return false;
destProp = res;
return true;
}
return false;
}
static int FindPropIdExact(const UString &name)
{
for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
return i;
return -1;
}
static int FindPropIdStart(const UString &name)
{
for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
{
UString t = g_NameToPropID[i].Name;
if (t.CompareNoCase(name.Left(t.Length())) == 0)
return i;
}
return -1;
}
static void SetMethodProp(COneMethodInfo &m, PROPID propID, const NCOM::CPropVariant &value)
{
for (int j = 0; j < m.Props.Size(); j++)
if (m.Props[j].Id == propID)
return;
CProp prop;
prop.Id = propID;
prop.Value = value;
m.Props.Add(prop);
}
void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
void CMultiMethodProps::SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
)
{
UInt32 level = _level;
if (oneMethodInfo.MethodName.IsEmpty())
oneMethodInfo.MethodName = kDefaultMethodName;
if (oneMethodInfo.IsLzma())
{
UInt32 dicSize =
(level >= 9 ? kLzmaDicSizeX9 :
(level >= 7 ? kLzmaDicSizeX7 :
(level >= 5 ? kLzmaDicSizeX5 :
(level >= 3 ? kLzmaDicSizeX3 :
kLzmaDicSizeX1))));
UInt32 algo =
(level >= 5 ? kLzmaAlgoX5 :
kLzmaAlgoX1);
UInt32 fastBytes =
(level >= 7 ? kLzmaFastBytesX7 :
kLzmaFastBytesX1);
const wchar_t *matchFinder =
(level >= 5 ? kLzmaMatchFinderX5 :
kLzmaMatchFinderX1);
SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
SetMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
#ifndef _7ZIP_ST
SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
}
else if (IsDeflateMethod(oneMethodInfo.MethodName))
{
UInt32 fastBytes =
(level >= 9 ? kDeflateFastBytesX9 :
(level >= 7 ? kDeflateFastBytesX7 :
kDeflateFastBytesX1));
UInt32 numPasses =
(level >= 9 ? kDeflatePassesX9 :
(level >= 7 ? kDeflatePassesX7 :
kDeflatePassesX1));
UInt32 algo =
(level >= 5 ? kDeflateAlgoX5 :
kDeflateAlgoX1);
SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
}
else if (IsBZip2Method(oneMethodInfo.MethodName))
{
UInt32 numPasses =
(level >= 9 ? kBZip2NumPassesX9 :
(level >= 7 ? kBZip2NumPassesX7 :
kBZip2NumPassesX1));
UInt32 dicSize =
(level >= 5 ? kBZip2DicSizeX5 :
(level >= 3 ? kBZip2DicSizeX3 :
kBZip2DicSizeX1));
SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
#ifndef _7ZIP_ST
SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
}
else if (IsPpmdMethod(oneMethodInfo.MethodName))
{
UInt32 useMemSize =
(level >= 9 ? kPpmdMemSizeX9 :
(level >= 7 ? kPpmdMemSizeX7 :
(level >= 5 ? kPpmdMemSizeX5 :
kPpmdMemSizeX1)));
UInt32 order =
(level >= 9 ? kPpmdOrderX9 :
(level >= 7 ? kPpmdOrderX7 :
(level >= 5 ? kPpmdOrderX5 :
kPpmdOrderX1)));
SetMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
SetMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
}
}
static void SplitParams(const UString &srcString, UStringVector &subStrings)
{
subStrings.Clear();
UString name;
int len = srcString.Length();
if (len == 0)
return;
for (int i = 0; i < len; i++)
{
wchar_t c = srcString[i];
if (c == L':')
{
subStrings.Add(name);
name.Empty();
}
else
name += c;
}
subStrings.Add(name);
}
static void SplitParam(const UString &param, UString &name, UString &value)
{
int eqPos = param.Find(L'=');
if (eqPos >= 0)
{
name = param.Left(eqPos);
value = param.Mid(eqPos + 1);
return;
}
for(int i = 0; i < param.Length(); i++)
{
wchar_t c = param[i];
if (c >= L'0' && c <= L'9')
{
name = param.Left(i);
value = param.Mid(i);
return;
}
}
name = param;
}
HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)
{
CProp prop;
int index = FindPropIdExact(name);
if (index < 0)
return E_INVALIDARG;
const CNameToPropID &nameToPropID = g_NameToPropID[index];
prop.Id = nameToPropID.PropID;
if (prop.Id == NCoderPropID::kBlockSize ||
prop.Id == NCoderPropID::kDictionarySize ||
prop.Id == NCoderPropID::kUsedMemorySize)
{
UInt32 dicSize;
RINOK(ParsePropDictionaryValue(value, dicSize));
prop.Value = dicSize;
}
else
{
NCOM::CPropVariant propValue;
if (nameToPropID.VarType == VT_BSTR)
propValue = value;
else if (nameToPropID.VarType == VT_BOOL)
{
bool res;
if (!StringToBool(value, res))
return E_INVALIDARG;
propValue = res;
}
else
{
UInt32 number;
if (ParseStringToUInt32(value, number) == value.Length())
propValue = number;
else
propValue = value;
}
if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value))
return E_INVALIDARG;
}
oneMethodInfo.Props.Add(prop);
return S_OK;
}
HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString)
{
UStringVector params;
SplitParams(srcString, params);
if (params.Size() > 0)
oneMethodInfo.MethodName = params[0];
for (int i = 1; i < params.Size(); i++)
{
const UString &param = params[i];
UString name, value;
SplitParam(param, name, value);
RINOK(SetParam(oneMethodInfo, name, value));
}
return S_OK;
}
HRESULT COutHandler::SetSolidSettings(const UString &s)
{
UString s2 = s;
s2.MakeUpper();
for (int i = 0; i < s2.Length();)
{
const wchar_t *start = ((const wchar_t *)s2) + i;
const wchar_t *end;
UInt64 v = ConvertStringToUInt64(start, &end);
if (start == end)
{
if (s2[i++] != 'E')
return E_INVALIDARG;
_solidExtension = true;
continue;
}
i += (int)(end - start);
if (i == s2.Length())
return E_INVALIDARG;
wchar_t c = s2[i++];
switch(c)
{
case 'F':
if (v < 1)
v = 1;
_numSolidFiles = v;
break;
case 'B':
_numSolidBytes = v;
_numSolidBytesDefined = true;
break;
case 'K':
_numSolidBytes = (v << 10);
_numSolidBytesDefined = true;
break;
case 'M':
_numSolidBytes = (v << 20);
_numSolidBytesDefined = true;
break;
case 'G':
_numSolidBytes = (v << 30);
_numSolidBytesDefined = true;
break;
default:
return E_INVALIDARG;
}
}
return S_OK;
}
HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value)
{
bool isSolid;
switch(value.vt)
{
case VT_EMPTY:
isSolid = true;
break;
case VT_BOOL:
isSolid = (value.boolVal != VARIANT_FALSE);
break;
case VT_BSTR:
if (StringToBool(value.bstrVal, isSolid))
break;
return SetSolidSettings(value.bstrVal);
default:
return E_INVALIDARG;
}
if (isSolid)
InitSolid();
else
_numSolidFiles = 1;
return S_OK;
}
void COutHandler::Init()
{
_removeSfxBlock = false;
_compressHeaders = true;
_encryptHeadersSpecified = false;
_encryptHeaders = false;
WriteCTime = false;
WriteATime = false;
WriteMTime = true;
if (level != (UInt32)(UInt32)-1)
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
#ifndef _7ZIP_ST
_numThreads = NSystem::GetNumberOfProcessors();
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
}
void CMultiMethodProps::Init()
{
#ifndef _7ZIP_ST
_numProcessors = _numThreads = NSystem::GetNumberOfProcessors();
#endif
_level = 5;
_level = (UInt32)(UInt32)-1;
_autoFilter = true;
_volumeMode = false;
_crcSize = 4;
InitSolid();
_filterMethod.Clear();
_methods.Clear();
}
void COutHandler::BeforeSetProperty()
{
Init();
#ifndef _7ZIP_ST
numProcessors = NSystem::GetNumberOfProcessors();
#endif
mainDicSize = 0xFFFFFFFF;
mainDicMethodIndex = 0xFFFFFFFF;
minNumber = 0;
_crcSize = 4;
}
HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
UString name = nameSpec;
name.MakeUpper();
@@ -511,24 +58,14 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
{
name.Delete(0);
_level = 9;
return ParsePropValue(name, value, _level);
}
if (name[0] == L'S')
{
name.Delete(0);
if (name.IsEmpty())
return SetSolidSettings(value);
if (value.vt != VT_EMPTY)
return E_INVALIDARG;
return SetSolidSettings(name);
return ParsePropToUInt32(name, value, _level);
}
if (name == L"CRC")
{
_crcSize = 4;
name.Delete(0, 3);
return ParsePropValue(name, value, _crcSize);
_crcSize = 4;
return ParsePropToUInt32(name, value, _crcSize);
}
UInt32 number;
@@ -536,86 +73,67 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
UString realName = name.Mid(index);
if (index == 0)
{
if(name.Left(2).CompareNoCase(L"MT") == 0)
if (name.Left(2).CompareNoCase(L"MT") == 0)
{
#ifndef _7ZIP_ST
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
RINOK(ParseMtProp(name.Mid(2), value, _numProcessors, _numThreads));
#endif
return S_OK;
}
if (name.CompareNoCase(L"RSFX") == 0) return SetBoolProperty(_removeSfxBlock, value);
if (name.CompareNoCase(L"F") == 0) return SetBoolProperty(_autoFilter, value);
if (name.CompareNoCase(L"HC") == 0) return SetBoolProperty(_compressHeaders, value);
if (name.CompareNoCase(L"HCF") == 0)
if (name.CompareNoCase(L"F") == 0)
{
bool compressHeadersFull = true;
RINOK(SetBoolProperty(compressHeadersFull, value));
if (!compressHeadersFull)
HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
if (res == S_OK)
return res;
if (value.vt != VT_BSTR)
return E_INVALIDARG;
return S_OK;
return _filterMethod.ParseMethodFromPROPVARIANT(L"", value);
}
if (name.CompareNoCase(L"HE") == 0)
{
RINOK(SetBoolProperty(_encryptHeaders, value));
_encryptHeadersSpecified = true;
return S_OK;
}
if (name.CompareNoCase(L"TC") == 0) return SetBoolProperty(WriteCTime, value);
if (name.CompareNoCase(L"TA") == 0) return SetBoolProperty(WriteATime, value);
if (name.CompareNoCase(L"TM") == 0) return SetBoolProperty(WriteMTime, value);
if (name.CompareNoCase(L"V") == 0) return SetBoolProperty(_volumeMode, value);
number = 0;
}
if (number > 10000)
if (number > 64)
return E_FAIL;
if (number < minNumber)
return E_INVALIDARG;
number -= minNumber;
for(int j = _methods.Size(); j <= (int)number; j++)
{
COneMethodInfo oneMethodInfo;
_methods.Add(oneMethodInfo);
}
COneMethodInfo &oneMethodInfo = _methods[number];
if (realName.Length() == 0)
{
if (value.vt != VT_BSTR)
return E_INVALIDARG;
RINOK(SetParams(oneMethodInfo, value.bstrVal));
}
else
{
int index = FindPropIdStart(realName);
if (index < 0)
return E_INVALIDARG;
const CNameToPropID &nameToPropID = g_NameToPropID[index];
CProp prop;
prop.Id = nameToPropID.PropID;
for (int j = _methods.Size(); j <= (int)number; j++)
_methods.Add(COneMethodInfo());
return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
}
if (prop.Id == NCoderPropID::kBlockSize ||
prop.Id == NCoderPropID::kDictionarySize ||
prop.Id == NCoderPropID::kUsedMemorySize)
void CSingleMethodProps::Init()
{
Clear();
#ifndef _7ZIP_ST
_numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
AddNumThreadsProp(_numThreads);
#endif
_level = (UInt32)(UInt32)-1;
}
HRESULT CSingleMethodProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
Init();
for (int i = 0; i < numProps; i++)
{
UString name = names[i];
name.MakeUpper();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
if (name[0] == L'X')
{
UInt32 dicSize;
RINOK(ParsePropDictionaryValue(realName.Mid(MyStringLen(nameToPropID.Name)), value, dicSize));
prop.Value = dicSize;
if (number <= mainDicMethodIndex)
mainDicSize = dicSize;
UInt32 a = 9;
RINOK(ParsePropToUInt32(name.Mid(1), value, a));
_level = a;
AddLevelProp(a);
}
else if (name.Left(2).CompareNoCase(L"MT") == 0)
{
#ifndef _7ZIP_ST
RINOK(ParseMtProp(name.Mid(2), value, _numProcessors, _numThreads));
AddNumThreadsProp(_numThreads);
#endif
}
else
{
int index = FindPropIdExact(realName);
if (index < 0)
return E_INVALIDARG;
const CNameToPropID &nameToPropID = g_NameToPropID[index];
prop.Id = nameToPropID.PropID;
if (!ConvertProperty(value, nameToPropID.VarType, prop.Value))
return E_INVALIDARG;
}
oneMethodInfo.Props.Add(prop);
return ParseParamsFromPROPVARIANT(name, value);
}
return S_OK;
}

View File

@@ -3,83 +3,61 @@
#ifndef __HANDLER_OUT_H
#define __HANDLER_OUT_H
#include "../../../Common/MyString.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
struct COneMethodInfo
{
CObjectVector<CProp> Props;
UString MethodName;
bool IsLzma() const;
};
class COutHandler
class CMultiMethodProps
{
UInt32 _level;
public:
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
HRESULT SetSolidSettings(const UString &s);
HRESULT SetSolidSettings(const PROPVARIANT &value);
#ifndef _7ZIP_ST
UInt32 _numThreads;
UInt32 _numProcessors;
#endif
UInt32 _crcSize;
CObjectVector<COneMethodInfo> _methods;
bool _removeSfxBlock;
UInt64 _numSolidFiles;
UInt64 _numSolidBytes;
bool _numSolidBytesDefined;
bool _solidExtension;
bool _compressHeaders;
bool _encryptHeadersSpecified;
bool _encryptHeaders;
bool WriteCTime;
bool WriteATime;
bool WriteMTime;
COneMethodInfo _filterMethod;
bool _autoFilter;
UInt32 _level;
bool _volumeMode;
HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
void SetCompressionMethod2(COneMethodInfo &oneMethodInfo
void SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
);
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
void InitSolid()
int GetNumEmptyMethods() const
{
InitSolidFiles();
InitSolidSize();
_solidExtension = false;
_numSolidBytesDefined = false;
int i;
for (i = 0; i < _methods.Size(); i++)
if (!_methods[i].IsEmpty())
break;
return i;
}
int GetLevel() const { return _level == (UInt32)(UInt32)-1 ? 5 : (int)_level; }
void Init();
COutHandler() { Init(); }
CMultiMethodProps() { Init(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
void BeforeSetProperty();
class CSingleMethodProps: public CMethodProps
{
UInt32 _level;
void Init();
public:
#ifndef _7ZIP_ST
UInt32 _numThreads;
UInt32 _numProcessors;
#endif
UInt32 minNumber;
UInt32 numProcessors;
UInt32 mainDicSize;
UInt32 mainDicMethodIndex;
CSingleMethodProps() { Init(); }
int GetLevel() const { return _level == (UInt32)(UInt32)-1 ? 5 : (int)_level; }
HRESULT SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
};
}

View File

@@ -31,8 +31,8 @@ UString GetOSName2(const UString &name)
if (name.IsEmpty())
return UString();
UString newName = GetOSName(name);
if (newName[newName.Length() - 1] == kOSDirDelimiter)
newName.Delete(newName.Length() - 1);
if (newName.Back() == kOSDirDelimiter)
newName.DeleteBack();
return newName;
}

View File

@@ -1,177 +1,3 @@
// ParseProperties.cpp
#include "StdAfx.h"
#include "ParseProperties.h"
#include "Common/StringToInt.h"
#include "Common/MyCom.h"
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
{
if (prop.vt == VT_UI4)
{
if (!name.IsEmpty())
return E_INVALIDARG;
resValue = prop.ulVal;
}
else if (prop.vt == VT_EMPTY)
{
if(!name.IsEmpty())
{
const wchar_t *start = name;
const wchar_t *end;
UInt64 v = ConvertStringToUInt64(start, &end);
if (end - start != name.Length())
return E_INVALIDARG;
resValue = (UInt32)v;
}
}
else
return E_INVALIDARG;
return S_OK;
}
static const int kLogarithmicSizeLimit = 32;
static const wchar_t kByteSymbol = L'B';
static const wchar_t kKiloByteSymbol = L'K';
static const wchar_t kMegaByteSymbol = L'M';
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
{
UString srcString = srcStringSpec;
srcString.MakeUpper();
const wchar_t *start = srcString;
const wchar_t *end;
UInt64 number = ConvertStringToUInt64(start, &end);
int numDigits = (int)(end - start);
if (numDigits == 0 || srcString.Length() > numDigits + 1)
return E_INVALIDARG;
if (srcString.Length() == numDigits)
{
if (number >= kLogarithmicSizeLimit)
return E_INVALIDARG;
dicSize = (UInt32)1 << (int)number;
return S_OK;
}
switch (srcString[numDigits])
{
case kByteSymbol:
if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
return E_INVALIDARG;
dicSize = (UInt32)number;
break;
case kKiloByteSymbol:
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
return E_INVALIDARG;
dicSize = (UInt32)(number << 10);
break;
case kMegaByteSymbol:
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
return E_INVALIDARG;
dicSize = (UInt32)(number << 20);
break;
default:
return E_INVALIDARG;
}
return S_OK;
}
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
{
if (name.IsEmpty())
{
if (prop.vt == VT_UI4)
{
UInt32 logDicSize = prop.ulVal;
if (logDicSize >= 32)
return E_INVALIDARG;
resValue = (UInt32)1 << logDicSize;
return S_OK;
}
if (prop.vt == VT_BSTR)
return ParsePropDictionaryValue(prop.bstrVal, resValue);
return E_INVALIDARG;
}
return ParsePropDictionaryValue(name, resValue);
}
bool StringToBool(const UString &s, bool &res)
{
if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0)
{
res = true;
return true;
}
if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0)
{
res = false;
return true;
}
return false;
}
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
{
switch(value.vt)
{
case VT_EMPTY:
dest = true;
return S_OK;
case VT_BOOL:
dest = (value.boolVal != VARIANT_FALSE);
return S_OK;
/*
case VT_UI4:
dest = (value.ulVal != 0);
break;
*/
case VT_BSTR:
return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG;
}
return E_INVALIDARG;
}
int ParseStringToUInt32(const UString &srcString, UInt32 &number)
{
const wchar_t *start = srcString;
const wchar_t *end;
UInt64 number64 = ConvertStringToUInt64(start, &end);
if (number64 > 0xFFFFFFFF)
{
number = 0;
return 0;
}
number = (UInt32)number64;
return (int)(end - start);
}
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
{
if (name.IsEmpty())
{
switch(prop.vt)
{
case VT_UI4:
numThreads = prop.ulVal;
break;
default:
{
bool val;
RINOK(SetBoolProperty(val, prop));
numThreads = (val ? defaultNumThreads : 1);
break;
}
}
}
else
{
UInt32 number;
int index = ParseStringToUInt32(name, number);
if (index != name.Length())
return E_INVALIDARG;
numThreads = number;
}
return S_OK;
}

View File

@@ -1,18 +1,6 @@
// ParseProperties.h
#ifndef __PARSEPROPERTIES_H
#define __PARSEPROPERTIES_H
#include "Common/MyString.h"
#include "Common/Types.h"
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
bool StringToBool(const UString &s, bool &res);
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);
int ParseStringToUInt32(const UString &srcString, UInt32 &number);
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
#ifndef __PARSE_PROPERTIES_H
#define __PARSE_PROPERTIES_H
#endif