4.34 beta

This commit is contained in:
Igor Pavlov
2006-03-01 00:00:00 +00:00
committed by Kornel Lesiński
parent 02516d3fce
commit 0f60a4933b
77 changed files with 2173 additions and 832 deletions

View File

@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /c
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
@@ -70,7 +70,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
@@ -254,10 +254,6 @@ SOURCE=..\..\ICoder.h
# End Source File
# Begin Source File
SOURCE=..\..\ICoderProperties.h
# End Source File
# Begin Source File
SOURCE=..\..\IMyUnknown.h
# End Source File
# Begin Source File
@@ -436,6 +432,14 @@ SOURCE=..\Common\OutStreamWithCRC.cpp
SOURCE=..\Common\OutStreamWithCRC.h
# End Source File
# Begin Source File
SOURCE=..\Common\ParseProperties.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\ParseProperties.h
# End Source File
# End Group
# Begin Group "7-Zip Common"

View File

@@ -45,12 +45,18 @@ struct CCompressionMethodMode
{
CObjectVector<CMethodFull> Methods;
CRecordVector<CBind> Binds;
bool MultiThread;
#ifdef COMPRESS_MT
UInt32 NumThreads;
#endif
bool PasswordIsDefined;
UString Password;
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
CCompressionMethodMode(): PasswordIsDefined(false), MultiThread(false) {}
CCompressionMethodMode(): PasswordIsDefined(false)
#ifdef COMPRESS_MT
, NumThreads(1)
#endif
{}
};
}}

View File

@@ -155,6 +155,9 @@ HRESULT CDecoder::Decode(IInStream *inStream,
#ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPassword
#endif
#ifdef COMPRESS_MT
, bool mtMode, UInt32 numThreads
#endif
)
{
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
@@ -329,50 +332,60 @@ HRESULT CDecoder::Decode(IInStream *inStream,
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
HRESULT result = _decoders[coderIndex].QueryInterface(
IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties);
CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
if (result == S_OK)
{
const CByteBuffer &properties = altCoderInfo.Properties;
size_t size = properties.GetCapacity();
if (size > 0xFFFFFFFF)
return E_NOTIMPL;
if (size > 0)
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
HRESULT result = decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
if (setDecoderProperties)
{
RINOK(compressSetDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size));
const CByteBuffer &properties = altCoderInfo.Properties;
size_t size = properties.GetCapacity();
if (size > 0xFFFFFFFF)
return E_NOTIMPL;
if (size > 0)
{
RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size));
}
}
}
else if (result != E_NOINTERFACE)
return result;
#ifdef COMPRESS_MT
if (mtMode)
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
}
}
#endif
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
result = _decoders[coderIndex].QueryInterface(
IID_ICryptoSetPassword, &cryptoSetPassword);
if (result == S_OK)
{
if (getTextPassword == 0)
return E_FAIL;
CMyComBSTR password;
RINOK(getTextPassword->CryptoGetTextPassword(&password));
CByteBuffer buffer;
UString unicodePassword(password);
const UInt32 sizeInBytes = unicodePassword.Length() * 2;
buffer.SetCapacity(sizeInBytes);
for (int i = 0; i < unicodePassword.Length(); i++)
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
HRESULT result = decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
if (cryptoSetPassword)
{
wchar_t c = unicodePassword[i];
((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
if (getTextPassword == 0)
return E_FAIL;
CMyComBSTR password;
RINOK(getTextPassword->CryptoGetTextPassword(&password));
CByteBuffer buffer;
UString unicodePassword(password);
const UInt32 sizeInBytes = unicodePassword.Length() * 2;
buffer.SetCapacity(sizeInBytes);
for (int i = 0; i < unicodePassword.Length(); i++)
{
wchar_t c = unicodePassword[i];
((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
}
RINOK(cryptoSetPassword->CryptoSetPassword(
(const Byte *)buffer, sizeInBytes));
}
RINOK(cryptoSetPassword->CryptoSetPassword(
(const Byte *)buffer, sizeInBytes));
}
else if (result != E_NOINTERFACE)
return result;
#endif
coderIndex++;

View File

@@ -60,6 +60,9 @@ public:
#ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPasswordSpec
#endif
#ifdef COMPRESS_MT
, bool mtMode, UInt32 numThreads
#endif
);
};

View File

@@ -228,7 +228,20 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
reducedDictionarySize += step;
}
}
CMyComPtr<IUnknown> encoderCommon = methodFull.IsSimpleCoder() ? (IUnknown *)encoder : (IUnknown *)encoder2;
#ifdef COMPRESS_MT
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
}
}
#endif
if (methodFull.CoderProperties.Size() > 0)
{
CRecordVector<PROPID> propIDs;
@@ -246,16 +259,7 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
values[i] = value;
}
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
if (methodFull.IsSimpleCoder())
{
RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties,
&setCoderProperties));
}
else
{
RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties,
&setCoderProperties));
}
RINOK(encoderCommon.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties));
}
catch(...)
@@ -268,16 +272,7 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
if (methodFull.IsSimpleCoder())
{
encoder.QueryInterface(IID_ICompressWriteCoderProperties,
&writeCoderProperties);
}
else
{
encoder2.QueryInterface(IID_ICompressWriteCoderProperties,
&writeCoderProperties);
}
encoderCommon.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);
if (writeCoderProperties != NULL)
{
@@ -298,14 +293,7 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
}
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
if (methodFull.IsSimpleCoder())
{
encoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
}
else
{
encoder2.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
}
encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
if (cryptoSetPassword)
{
@@ -318,19 +306,13 @@ HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
}
RINOK(cryptoSetPassword->CryptoSetPassword(
(const Byte *)buffer, sizeInBytes));
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
}
// public ICompressWriteCoderProperties,
if (methodFull.IsSimpleCoder())
{
_mixerCoderSpec->AddCoder(encoder);
}
else
{
_mixerCoderSpec->AddCoder2(encoder2);
}
}
return S_OK;
}

View File

@@ -230,6 +230,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
#ifndef _NO_CRYPTO
, getTextPassword
#endif
#ifdef COMPRESS_MT
, true, _numThreads
#endif
);
if (result == S_FALSE)

View File

@@ -14,6 +14,12 @@
#include "../Common/MultiStream.h"
#endif
#ifdef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
#include "../Common/ParseProperties.h"
#endif
#endif
using namespace NWindows;
namespace NArchive {
@@ -21,6 +27,9 @@ namespace N7z {
CHandler::CHandler()
{
#ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
#endif
#ifndef EXTRACT_ONLY
Init();
#endif
@@ -708,4 +717,41 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
}
#endif
#ifdef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
{
COM_TRY_BEGIN
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
_numThreads = numProcessors;
for (int i = 0; i < numProperties; i++)
{
UString name = names[i];
name.MakeUpper();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
UInt32 number;
int index = ParseStringToUInt32(name, number);
if (index == 0)
{
if(name.Left(2).CompareNoCase(L"MT") == 0)
{
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
continue;
}
else
return E_INVALIDARG;
}
}
return S_OK;
COM_TRY_END
}
#endif
#endif
}}

View File

@@ -12,6 +12,10 @@
#include "7zMethods.h"
#endif
#ifdef COMPRESS_MT
#include "../../../Windows/System.h"
#endif
namespace NArchive {
namespace N7z {
@@ -54,14 +58,29 @@ struct COneMethodInfo
DEFINE_GUID(CLSID_CFormat7z,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
#ifdef COMPRESS_MT
#define __7Z_SET_PROPERTIES
#endif
#else
#define __7Z_SET_PROPERTIES
#endif
#endif
class CHandler:
public IInArchive,
#ifdef _7Z_VOL
public IInArchiveGetStream,
#endif
#ifdef __7Z_SET_PROPERTIES
public ISetProperties,
#endif
#ifndef EXTRACT_ONLY
public IOutArchive,
public ISetProperties,
#endif
public CMyUnknownImp
{
@@ -70,9 +89,11 @@ public:
#ifdef _7Z_VOL
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
#endif
#ifdef __7Z_SET_PROPERTIES
MY_QUERYINTERFACE_ENTRY(ISetProperties)
#endif
#ifndef EXTRACT_ONLY
MY_QUERYINTERFACE_ENTRY(IOutArchive)
MY_QUERYINTERFACE_ENTRY(ISetProperties)
#endif
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
@@ -101,6 +122,10 @@ public:
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
#endif
#ifdef __7Z_SET_PROPERTIES
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
#endif
#ifndef EXTRACT_ONLY
// IOutArchiveHandler
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
@@ -109,7 +134,6 @@ public:
STDMETHOD(GetFileTimeType)(UInt32 *type);
// ISetProperties
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
HRESULT SetSolidSettings(const UString &s);
HRESULT SetSolidSettings(const PROPVARIANT &value);
@@ -126,6 +150,10 @@ private:
NArchive::N7z::CArchiveDatabaseEx _database;
#endif
#ifdef COMPRESS_MT
UInt32 _numThreads;
#endif
#ifndef EXTRACT_ONLY
CObjectVector<COneMethodInfo> _methods;
CRecordVector<CBind> _binds;
@@ -144,18 +172,13 @@ private:
UInt32 _defaultDicSize;
UInt32 _defaultAlgorithm;
UInt32 _defaultFastBytes;
UInt32 _defaultPasses;
UString _defaultMatchFinder;
UInt32 _defaultBZip2Passes;
UInt32 _defaultPpmdMemSize;
UInt32 _defaultPpmdOrder;
UInt32 _defaultDeflateFastBytes;
UInt32 _defaultDeflatePasses;
bool _autoFilter;
bool _multiThread;
UInt32 _level;
bool _volumeMode;
@@ -168,8 +191,11 @@ private:
IArchiveUpdateCallback *updateCallback);
HRESULT SetCompressionMethod(CCompressionMethodMode &method,
CObjectVector<COneMethodInfo> &methodsInfo,
bool multiThread);
CObjectVector<COneMethodInfo> &methodsInfo
#ifdef COMPRESS_MT
, UInt32 numThreads
#endif
);
HRESULT SetCompressionMethod(
CCompressionMethodMode &method,
@@ -226,21 +252,19 @@ private:
_compressHeaders = true;
_compressHeadersFull = true;
_encryptHeaders = false;
_multiThread = false;
#ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
#endif
_copyMode = false;
_defaultDicSize = (1 << 22);
_defaultAlgorithm = 1;
_defaultFastBytes = 32;
_defaultMatchFinder = L"BT4";
_defaultDicSize =
_defaultAlgorithm =
_defaultFastBytes =
_defaultPasses =
_defaultPpmdMemSize =
_defaultPpmdOrder = 0xFFFFFFFF;
_defaultMatchFinder.Empty();
_defaultBZip2Passes = 1;
_defaultPpmdMemSize = (1 << 24);
_defaultPpmdOrder = 6;
_defaultDeflateFastBytes = 32;
_defaultDeflatePasses = 1;
_level = 5;
_autoFilter = true;

View File

@@ -8,12 +8,14 @@
#include "7zMethods.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Common/ComTry.h"
#include "../../../Common/StringToInt.h"
#include "../../IPassword.h"
#include "../../ICoder.h"
#include "../Common/ItemNameUtils.h"
#include "../Common/ParseProperties.h"
using namespace NWindows;
@@ -67,45 +69,53 @@ const wchar_t *kPpmdMethodName = L"PPMd";
const wchar_t *kDeflateMethodName = L"Deflate";
const wchar_t *kDeflate64MethodName = L"Deflate64";
static const wchar_t *kMatchFinderX1 = L"HC4";
static const wchar_t *kMatchFinderX3 = L"HC4";
static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
static const UInt32 kAlgorithmX1 = 0;
static const UInt32 kAlgorithmX3 = 0;
static const UInt32 kAlgorithmX7 = 1;
static const UInt32 kAlgorithmX9 = 1;
static const UInt32 kLzmaAlgorithmX1 = 0;
static const UInt32 kLzmaAlgorithmX5 = 1;
static const UInt32 kDicSizeX1 = 1 << 16;
static const UInt32 kDicSizeX3 = 1 << 20;
static const UInt32 kDicSizeX7 = 1 << 24;
static const UInt32 kDicSizeX9 = 1 << 26;
static const UInt32 kLzmaDicSizeX1 = 1 << 16;
static const UInt32 kLzmaDicSizeX3 = 1 << 20;
static const UInt32 kLzmaDicSizeX5 = 1 << 22;
static const UInt32 kLzmaDicSizeX7 = 1 << 24;
static const UInt32 kLzmaDicSizeX9 = 1 << 26;
static const UInt32 kFastBytesX7 = 64;
static const UInt32 kFastBytesX9 = 64;
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 kDeflateFastBytesX1 = 32;
static const UInt32 kDeflateFastBytesX7 = 64;
static const UInt32 kDeflatePassesX7 = 3;
static const UInt32 kDeflateFastBytesX9 = 128;
static const UInt32 kDeflateFastBytesX9 = 64;
static const UInt32 kDeflatePassesX1 = 1;
static const UInt32 kDeflatePassesX7 = 3;
static const UInt32 kDeflatePassesX9 = 10;
static const UInt32 kNumBZip2PassesX1 = 1;
static const UInt32 kNumBZip2PassesX7 = 2;
static const UInt32 kNumBZip2PassesX9 = 7;
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;
const wchar_t *kDefaultMethodName = kLZMAMethodName;
static const wchar_t *kMatchFinderForHeaders = L"BT2";
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
static const UInt32 kDictionaryForHeaders = 1 << 20;
static const UInt32 kNumFastBytesForHeaders = 273;
static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
static bool IsLZMAMethod(const UString &methodName)
{ return (methodName.CompareNoCase(kLZMAMethodName) == 0); }
@@ -168,9 +178,10 @@ CNameToPropID g_NameToPropID[] =
{ 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::kMultiThread, VT_BOOL, L"mt" }
{ NCoderPropID::kNumThreads, VT_UI4, L"mt" }
};
bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType,
@@ -209,7 +220,12 @@ HRESULT CHandler::SetCompressionMethod(
CCompressionMethodMode &methodMode,
CCompressionMethodMode &headerMethod)
{
RINOK(SetCompressionMethod(methodMode, _methods, _multiThread));
HRESULT res = SetCompressionMethod(methodMode, _methods
#ifdef COMPRESS_MT
, _numThreads
#endif
);
RINOK(res);
methodMode.Binds = _binds;
if (_compressHeadersFull)
_compressHeaders = true;
@@ -224,13 +240,13 @@ HRESULT CHandler::SetCompressionMethod(
{
CProperty property;
property.PropID = NCoderPropID::kMatchFinder;
property.Value = kMatchFinderForHeaders;
property.Value = kLzmaMatchFinderForHeaders;
oneMethodInfo.CoderProperties.Add(property);
}
{
CProperty property;
property.PropID = NCoderPropID::kAlgorithm;
property.Value = kAlgorithmX9;
property.Value = kAlgorithmForHeaders;
oneMethodInfo.CoderProperties.Add(property);
}
{
@@ -246,7 +262,12 @@ HRESULT CHandler::SetCompressionMethod(
oneMethodInfo.CoderProperties.Add(property);
}
headerMethodInfoVector.Add(oneMethodInfo);
RINOK(SetCompressionMethod(headerMethod, headerMethodInfoVector, false));
HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
#ifdef COMPRESS_MT
,1
#endif
);
RINOK(res);
}
return S_OK;
}
@@ -268,8 +289,11 @@ static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID,
HRESULT CHandler::SetCompressionMethod(
CCompressionMethodMode &methodMode,
CObjectVector<COneMethodInfo> &methodsInfo,
bool multiThread)
CObjectVector<COneMethodInfo> &methodsInfo
#ifdef COMPRESS_MT
, UInt32 numThreads
#endif
)
{
#ifndef EXCLUDE_COM
/*
@@ -287,6 +311,8 @@ HRESULT CHandler::SetCompressionMethod(
methodsInfo.Add(oneMethodInfo);
}
UInt32 level = _level;
for(int i = 0; i < methodsInfo.Size(); i++)
{
COneMethodInfo &oneMethodInfo = methodsInfo[i];
@@ -295,26 +321,94 @@ HRESULT CHandler::SetCompressionMethod(
if (IsLZMAMethod(oneMethodInfo.MethodName))
{
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, _defaultDicSize);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, _defaultAlgorithm);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, _defaultFastBytes);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, (const wchar_t *)_defaultMatchFinder);
if (multiThread)
SetOneMethodProp(oneMethodInfo, NCoderPropID::kMultiThread, true);
UInt32 dicSize = _defaultDicSize;
if (dicSize == 0xFFFFFFFF)
dicSize = (level >= 9 ? kLzmaDicSizeX9 :
(level >= 7 ? kLzmaDicSizeX7 :
(level >= 5 ? kLzmaDicSizeX5 :
(level >= 3 ? kLzmaDicSizeX3 :
kLzmaDicSizeX1))));
UInt32 algorithm = _defaultAlgorithm;
if (algorithm == 0xFFFFFFFF)
algorithm = (level >= 5 ? kLzmaAlgorithmX5 :
kLzmaAlgorithmX1);
UInt32 fastBytes = _defaultFastBytes;
if (fastBytes == 0xFFFFFFFF)
fastBytes = (level >= 7 ? kLzmaFastBytesX7 :
kLzmaFastBytesX1);
const wchar_t *matchFinder = 0;
if (_defaultMatchFinder.IsEmpty())
matchFinder = (level >= 5 ? kLzmaMatchFinderX5 :
kLzmaMatchFinderX1);
else
matchFinder = (const wchar_t *)_defaultMatchFinder;
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algorithm);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
#ifdef COMPRESS_MT
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
}
else if (IsDeflateMethod(oneMethodInfo.MethodName))
{
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, _defaultDeflateFastBytes);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, _defaultDeflatePasses);
UInt32 fastBytes = _defaultFastBytes;
if (fastBytes == 0xFFFFFFFF)
fastBytes = (level >= 9 ? kDeflateFastBytesX9 :
(level >= 7 ? kDeflateFastBytesX7 :
kDeflateFastBytesX1));
UInt32 numPasses = _defaultPasses;
if (numPasses == 0xFFFFFFFF)
numPasses = (level >= 9 ? kDeflatePassesX9 :
(level >= 7 ? kDeflatePassesX7 :
kDeflatePassesX1));
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
}
else if (IsBZip2Method(oneMethodInfo.MethodName))
{
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, _defaultBZip2Passes);
UInt32 numPasses = _defaultPasses;
if (numPasses == 0xFFFFFFFF)
numPasses = (level >= 9 ? kBZip2NumPassesX9 :
(level >= 7 ? kBZip2NumPassesX7 :
kBZip2NumPassesX1));
UInt32 dicSize = _defaultDicSize;
if (dicSize == 0xFFFFFFFF)
dicSize = (level >= 5 ? kBZip2DicSizeX5 :
(level >= 3 ? kBZip2DicSizeX3 :
kBZip2DicSizeX1));
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
#ifdef COMPRESS_MT
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
}
else if (IsPpmdMethod(oneMethodInfo.MethodName))
{
SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, _defaultPpmdMemSize);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, _defaultPpmdOrder);
UInt32 useMemSize = _defaultPpmdMemSize;
if (useMemSize == 0xFFFFFFFF)
useMemSize = (level >= 9 ? kPpmdMemSizeX9 :
(level >= 7 ? kPpmdMemSizeX7 :
(level >= 5 ? kPpmdMemSizeX5 :
kPpmdMemSizeX1)));
UInt32 order = _defaultPpmdOrder;
if (order == 0xFFFFFFFF)
order = (level >= 9 ? kPpmdOrderX9 :
(level >= 7 ? kPpmdOrderX7 :
(level >= 5 ? kPpmdOrderX5 :
kPpmdOrderX1)));
SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
}
@@ -602,11 +696,10 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CCompressionMethodMode methodMode, headerMethod;
RINOK(SetCompressionMethod(methodMode, headerMethod));
methodMode.MultiThread = _multiThread;
// methodMode.MultiThreadMult = _multiThreadMult;
headerMethod.MultiThread = false;
// headerMethod.MultiThreadMult = _multiThreadMult;
#ifdef COMPRESS_MT
methodMode.NumThreads = _numThreads;
headerMethod.NumThreads = 1;
#endif
RINOK(SetPassword(methodMode, updateCallback));
@@ -655,101 +748,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_END
}
static 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);
}
static const int kLogarithmicSizeLimit = 32;
static const char kByteSymbol = 'B';
static const char kKiloByteSymbol = 'K';
static const char kMegaByteSymbol = 'M';
HRESULT ParseDictionaryValues(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;
}
static inline UINT GetCurrentFileCodePage()
{
return AreFileApisANSI() ? CP_ACP : CP_OEMCP;
}
static HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
{
switch(value.vt)
{
case VT_EMPTY:
dest = true;
break;
/*
case VT_UI4:
dest = (value.ulVal != 0);
break;
*/
case VT_BSTR:
{
UString valueString = value.bstrVal;
valueString.MakeUpper();
if (valueString.Compare(L"ON") == 0)
dest = true;
else if (valueString.Compare(L"OFF") == 0)
dest = false;
else
return E_INVALIDARG;
break;
}
default:
return E_INVALIDARG;
}
return S_OK;
}
/*
static HRESULT SetComplexProperty(bool &boolStatus, UInt32 &number,
const PROPVARIANT &value)
@@ -852,7 +850,7 @@ HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, c
if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0)
{
UInt32 dicSize;
RINOK(ParseDictionaryValues(value, dicSize));
RINOK(ParsePropDictionaryValue(value, dicSize));
if (name.CompareNoCase(L"D") == 0)
property.PropID = NCoderPropID::kDictionarySize;
else
@@ -983,11 +981,14 @@ HRESULT CHandler::SetSolidSettings(const PROPVARIANT &value)
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
{
UINT codePage = GetCurrentFileCodePage();
COM_TRY_BEGIN
_methods.Clear();
_binds.Clear();
Init();
#ifdef COMPRESS_MT
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
#endif
UInt32 minNumber = 0;
for (int i = 0; i < numProperties; i++)
@@ -1002,82 +1003,11 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
if (name[0] == 'X')
{
name.Delete(0);
_level = 9;
if (value.vt == VT_UI4)
{
if (!name.IsEmpty())
return E_INVALIDARG;
_level = value.ulVal;
}
else if (value.vt == VT_EMPTY)
{
if(!name.IsEmpty())
{
int index = ParseStringToUInt32(name, _level);
if (index != name.Length())
return E_INVALIDARG;
}
}
else
return E_INVALIDARG;
RINOK(ParsePropValue(name, value, _level));
if (_level == 0)
{
_copyMode = true;
_defaultBZip2Passes = 1;
}
else if (_level < 3)
{
_defaultAlgorithm = kAlgorithmX1;
_defaultDicSize = kDicSizeX1;
_defaultMatchFinder = kMatchFinderX1;
_defaultBZip2Passes = 1;
_defaultPpmdMemSize = kPpmdMemSizeX1;
_defaultPpmdOrder = kPpmdOrderX1;
}
else if (_level < 5)
{
_defaultAlgorithm = kAlgorithmX3;
_defaultDicSize = kDicSizeX3;
_defaultMatchFinder = kMatchFinderX3;
_defaultBZip2Passes = 1;
_defaultPpmdMemSize = kPpmdMemSizeX1;
_defaultPpmdOrder = kPpmdOrderX1;
}
else if (_level < 7)
{
_defaultBZip2Passes = 1;
// normal;
}
else if(_level < 9)
{
_defaultAlgorithm = kAlgorithmX7;
_defaultDicSize = kDicSizeX7;
_defaultFastBytes = kFastBytesX7;
_defaultBZip2Passes = kNumBZip2PassesX7;
_defaultPpmdMemSize = kPpmdMemSizeX7;
_defaultPpmdOrder = kPpmdOrderX7;
_defaultDeflateFastBytes = kDeflateFastBytesX7;
_defaultDeflatePasses = kDeflatePassesX7;
}
else
{
_defaultAlgorithm = kAlgorithmX9;
_defaultDicSize = kDicSizeX9;
_defaultFastBytes = kFastBytesX9;
_defaultBZip2Passes = kNumBZip2PassesX9;
_defaultPpmdMemSize = kPpmdMemSizeX9;
_defaultPpmdOrder = kPpmdOrderX9;
_defaultDeflateFastBytes = kDeflateFastBytesX9;
_defaultDeflatePasses = kDeflatePassesX9;
}
continue;
}
@@ -1110,7 +1040,14 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
UString realName = name.Mid(index);
if (index == 0)
{
if (name.CompareNoCase(L"RSFX") == 0)
if(name.Left(2).CompareNoCase(L"MT") == 0)
{
#ifdef COMPRESS_MT
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
#endif
continue;
}
else if (name.CompareNoCase(L"RSFX") == 0)
{
RINOK(SetBoolProperty(_removeSfxBlock, value));
continue;
@@ -1135,13 +1072,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
RINOK(SetBoolProperty(_encryptHeaders, value));
continue;
}
else if (name.CompareNoCase(L"MT") == 0)
{
// _multiThreadMult = 200;
RINOK(SetBoolProperty(_multiThread, value));
// RINOK(SetComplexProperty(MultiThread, _multiThreadMult, value));
continue;
}
else if (name.CompareNoCase(L"V") == 0)
{
RINOK(SetBoolProperty(_volumeMode, value));
@@ -1173,26 +1103,19 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
else
{
CProperty property;
if (realName.CompareNoCase(L"D") == 0 || realName.CompareNoCase(L"MEM") == 0)
if (realName.Left(1).CompareNoCase(L"D") == 0)
{
UInt32 dicSize;
if (value.vt == VT_UI4)
{
UInt32 logDicSize = value.ulVal;
if (logDicSize >= 32)
return E_INVALIDARG;
dicSize = (UInt32)1 << logDicSize;
}
else if (value.vt == VT_BSTR)
{
RINOK(ParseDictionaryValues(value.bstrVal, dicSize));
}
else
return E_FAIL;
if (realName.CompareNoCase(L"D") == 0)
property.PropID = NCoderPropID::kDictionarySize;
else
property.PropID = NCoderPropID::kUsedMemorySize;
RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize));
property.PropID = NCoderPropID::kDictionarySize;
property.Value = dicSize;
oneMethodInfo.CoderProperties.Add(property);
}
else if (realName.Left(3).CompareNoCase(L"MEM") == 0)
{
UInt32 dicSize;
RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize));
property.PropID = NCoderPropID::kUsedMemorySize;
property.Value = dicSize;
oneMethodInfo.CoderProperties.Add(property);
}

View File

@@ -880,6 +880,9 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset,
#ifndef _NO_CRYPTO
, getTextPassword
#endif
#ifdef COMPRESS_MT
, false, 1
#endif
);
RINOK(result);

View File

@@ -1,6 +1,6 @@
PROG = 7z.dll
DEF_FILE = ../Archive.def
CFLAGS = $(CFLAGS) -I ../../../
CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
LIBS = $(LIBS) oleaut32.lib user32.lib
7Z_OBJS = \
@@ -61,6 +61,7 @@ AR_COMMON_OBJS = \
$O\ItemNameUtils.obj \
$O\MultiStream.obj \
$O\OutStreamWithCRC.obj \
$O\ParseProperties.obj \
OBJS = \
$O\StdAfx.obj \