📄 7zhandlerout.cpp
字号:
// 7z/OutHandler.cpp
#include "StdAfx.h"
#include "7zHandler.h"
#include "7zOut.h"
#include "7zUpdate.h"
#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"
using namespace NWindows;
namespace NArchive {
namespace N7z {
#ifdef COMPRESS_LZMA
static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
#endif
#ifdef COMPRESS_PPMD
static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
#endif
#ifdef COMPRESS_BCJ_X86
static CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
#endif
#ifdef COMPRESS_BCJ2
static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
#endif
#ifdef COMPRESS_COPY
static CMethodID k_Copy = { { 0x0 }, 1 };
#endif
#ifdef COMPRESS_DEFLATE
#ifndef COMPRESS_DEFLATE_ENCODER
#define COMPRESS_DEFLATE_ENCODER
#endif
#endif
#ifdef COMPRESS_DEFLATE_ENCODER
static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
#endif
#ifdef COMPRESS_BZIP2
#ifndef COMPRESS_BZIP2_ENCODER
#define COMPRESS_BZIP2_ENCODER
#endif
#endif
#ifdef COMPRESS_BZIP2_ENCODER
static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
#endif
const wchar_t *kCopyMethod = L"Copy";
const wchar_t *kLZMAMethodName = L"LZMA";
const wchar_t *kBZip2MethodName = L"BZip2";
const UInt32 kAlgorithmForX7 = 2;
const UInt32 kDicSizeForX7 = 1 << 23;
const UInt32 kFastBytesForX7 = 64;
const UInt32 kAlgorithmForX9 = 2;
const UInt32 kDicSizeForX9 = 1 << 25;
const UInt32 kFastBytesForX9 = 64;
static const wchar_t *kMatchFinderForX9 = L"BT4b";
const UInt32 kAlgorithmForFast = 0;
const UInt32 kDicSizeForFast = 1 << 15;
static const wchar_t *kMatchFinderForFast = L"HC3";
const wchar_t *kDefaultMethodName = kLZMAMethodName;
static const wchar_t *kMatchFinderForHeaders = L"BT2";
static const UInt32 kDictionaryForHeaders = 1 << 20;
static const UInt32 kNumFastBytesForHeaders = 254;
static bool IsLZMAMethod(const UString &methodName)
{ return (methodName.CompareNoCase(kLZMAMethodName) == 0); }
static bool IsLZMethod(const UString &methodName)
{ return IsLZMAMethod(methodName); }
static bool IsBZip2Method(const UString &methodName)
{ return (methodName.CompareNoCase(kBZip2MethodName) == 0); }
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
*type = NFileTimeType::kWindows;
return S_OK;
}
HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
IArchiveUpdateCallback *updateCallback)
{
CMyComPtr<ICryptoGetTextPassword2> getTextPassword;
if (!getTextPassword)
{
CMyComPtr<IArchiveUpdateCallback> udateCallback2(updateCallback);
udateCallback2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
}
if (getTextPassword)
{
CMyComBSTR password;
Int32 passwordIsDefined;
RINOK(getTextPassword->CryptoGetTextPassword2(
&passwordIsDefined, &password));
if (methodMode.PasswordIsDefined = IntToBool(passwordIsDefined))
methodMode.Password = password;
}
else
methodMode.PasswordIsDefined = false;
return S_OK;
}
struct CNameToPropID
{
PROPID PropID;
VARTYPE VarType;
const wchar_t *Name;
};
CNameToPropID g_NameToPropID[] =
{
{ 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::kNumPasses, VT_UI4, L"Pass" },
{ NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
{ NCoderPropID::kAlgorithm, VT_UI4, L"a" },
{ NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
{ NCoderPropID::kMultiThread, VT_BOOL, L"mt" }
};
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;
}
}
return false;
}
const int kNumNameToPropIDItems = sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]);
int FindPropIdFromStringName(const UString &name)
{
for (int i = 0; i < kNumNameToPropIDItems; i++)
if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
return i;
return -1;
}
HRESULT CHandler::SetCompressionMethod(
CCompressionMethodMode &methodMode,
CCompressionMethodMode &headerMethod)
{
RINOK(SetCompressionMethod(methodMode, _methods, _multiThread));
methodMode.Binds = _binds;
if (_compressHeadersFull)
_compressHeaders = true;
if (_compressHeaders)
{
// headerMethod.Methods.Add(methodMode.Methods.Back());
CObjectVector<COneMethodInfo> headerMethodInfoVector;
COneMethodInfo oneMethodInfo;
oneMethodInfo.MethodName = kLZMAMethodName;
{
CProperty property;
property.PropID = NCoderPropID::kMatchFinder;
property.Value = kMatchFinderForHeaders;
oneMethodInfo.CoderProperties.Add(property);
}
{
CProperty property;
property.PropID = NCoderPropID::kAlgorithm;
property.Value = kAlgorithmForX9;
oneMethodInfo.CoderProperties.Add(property);
}
{
CProperty property;
property.PropID = NCoderPropID::kNumFastBytes;
property.Value = UInt32(kNumFastBytesForHeaders);
oneMethodInfo.CoderProperties.Add(property);
}
{
CProperty property;
property.PropID = NCoderPropID::kDictionarySize;
property.Value = UInt32(kDictionaryForHeaders);
oneMethodInfo.CoderProperties.Add(property);
}
headerMethodInfoVector.Add(oneMethodInfo);
RINOK(SetCompressionMethod(headerMethod, headerMethodInfoVector, false));
}
return S_OK;
}
static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID,
const NWindows::NCOM::CPropVariant &value)
{
int j;
for (j = 0; j < oneMethodInfo.CoderProperties.Size(); j++)
if (oneMethodInfo.CoderProperties[j].PropID == propID)
break;
if (j != oneMethodInfo.CoderProperties.Size())
return;
CProperty property;
property.PropID = propID;
property.Value = value;
oneMethodInfo.CoderProperties.Add(property);
}
HRESULT CHandler::SetCompressionMethod(
CCompressionMethodMode &methodMode,
CObjectVector<COneMethodInfo> &methodsInfo,
bool multiThread)
{
#ifndef EXCLUDE_COM
/*
CObjectVector<CMethodInfo2> methodInfoVector;
if (!NRegistryInfo::EnumerateAllMethods(methodInfoVector))
return E_FAIL;
*/
#endif
if (methodsInfo.IsEmpty())
{
COneMethodInfo oneMethodInfo;
oneMethodInfo.MethodName = _copyMode ? kCopyMethod : kDefaultMethodName;
methodsInfo.Add(oneMethodInfo);
}
for(int i = 0; i < methodsInfo.Size(); i++)
{
COneMethodInfo &oneMethodInfo = methodsInfo[i];
if (oneMethodInfo.MethodName.IsEmpty())
oneMethodInfo.MethodName = kDefaultMethodName;
if (IsLZMethod(oneMethodInfo.MethodName))
{
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);
}
}
else if (IsBZip2Method(oneMethodInfo.MethodName))
{
SetOneMethodProp(oneMethodInfo,
NCoderPropID::kNumPasses, _defaultBZip2Passes);
}
CMethodFull methodFull;
methodFull.NumInStreams = 1;
methodFull.NumOutStreams = 1;
bool defined = false;
#ifdef COMPRESS_LZMA
if (oneMethodInfo.MethodName.CompareNoCase(L"LZMA") == 0)
{
defined = true;
methodFull.MethodID = k_LZMA;
}
#endif
#ifdef COMPRESS_PPMD
if (oneMethodInfo.MethodName.CompareNoCase(L"PPMD") == 0)
{
defined = true;
methodFull.MethodID = k_PPMD;
}
#endif
#ifdef COMPRESS_BCJ_X86
if (oneMethodInfo.MethodName.CompareNoCase(L"BCJ") == 0)
{
defined = true;
methodFull.MethodID = k_BCJ_X86;
}
#endif
#ifdef COMPRESS_BCJ2
if (oneMethodInfo.MethodName.CompareNoCase(L"BCJ2") == 0)
{
defined = true;
methodFull.MethodID = k_BCJ2;
methodFull.NumInStreams = 4;
methodFull.NumOutStreams = 1;
}
#endif
#ifdef COMPRESS_DEFLATE_ENCODER
if (oneMethodInfo.MethodName.CompareNoCase(L"Deflate") == 0)
{
defined = true;
methodFull.MethodID = k_Deflate;
}
#endif
#ifdef COMPRESS_BZIP2_ENCODER
if (oneMethodInfo.MethodName.CompareNoCase(L"BZip2") == 0)
{
defined = true;
methodFull.MethodID = k_BZip2;
}
#endif
#ifdef COMPRESS_COPY
if (oneMethodInfo.MethodName.CompareNoCase(L"Copy") == 0)
{
defined = true;
methodFull.MethodID = k_Copy;
}
#endif
#ifdef EXCLUDE_COM
if (defined)
{
methodFull.CoderProperties = oneMethodInfo.CoderProperties;
methodMode.Methods.Add(methodFull);
continue;
}
#else
CMethodInfo2 methodInfo;
if (!GetMethodInfo(oneMethodInfo.MethodName, methodInfo))
return E_FAIL;
if (!methodInfo.EncoderIsAssigned)
return E_FAIL;
methodFull.MethodID = methodInfo.MethodID;
methodFull.NumInStreams = methodInfo.NumInStreams;
methodFull.NumOutStreams = methodInfo.NumOutStreams;
methodFull.EncoderClassID = methodInfo.Encoder;
methodFull.FilePath = methodInfo.FilePath;
methodFull.CoderProperties = oneMethodInfo.CoderProperties;
defined = true;
#endif
if (!defined)
return E_FAIL;
methodMode.Methods.Add(methodFull);
}
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -