diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2007-06-26 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:52 +0300 |
commit | fd8b1d78b496fe38193bf8c5e86af3b43f0b022d (patch) | |
tree | 5b1e3812ed4d8b6037e5035faf3b638849f618e2 /CPP/7zip/Archive/7z/7zHandlerOut.cpp | |
parent | 0b33f700a66fcf7f55f92b92e0b3e5c7014d769a (diff) |
4.48 beta
Diffstat (limited to 'CPP/7zip/Archive/7z/7zHandlerOut.cpp')
-rwxr-xr-x | CPP/7zip/Archive/7z/7zHandlerOut.cpp | 612 |
1 files changed, 30 insertions, 582 deletions
diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp index 80d63931..af4b9427 100755 --- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp +++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp @@ -1,4 +1,4 @@ -// 7z/OutHandler.cpp +// 7zHandlerOut.cpp #include "StdAfx.h" @@ -21,90 +21,19 @@ using namespace NWindows; namespace NArchive { namespace N7z { -const wchar_t *kCopyMethod = L"Copy"; -const wchar_t *kLZMAMethodName = L"LZMA"; -const wchar_t *kLZMA2MethodName = L"LZMA2"; -const wchar_t *kBZip2MethodName = L"BZip2"; -const wchar_t *kPpmdMethodName = L"PPMd"; -const wchar_t *kDeflateMethodName = L"Deflate"; -const wchar_t *kDeflate64MethodName = L"Deflate64"; +static const wchar_t *kLZMAMethodName = L"LZMA"; +static const wchar_t *kCopyMethod = L"Copy"; +static const wchar_t *kDefaultMethodName = kLZMAMethodName; -static const wchar_t *kLzmaMatchFinderX1 = L"HC4"; -static const wchar_t *kLzmaMatchFinderX5 = L"BT4"; - -static const UInt32 kLzmaAlgorithmX1 = 0; static const UInt32 kLzmaAlgorithmX5 = 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; - -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 = kLzmaAlgorithmX5; -static bool IsCopyMethod(const UString &methodName) +static inline bool IsCopyMethod(const UString &methodName) { return (methodName.CompareNoCase(kCopyMethod) == 0); } -static bool IsLZMAMethod(const UString &methodName) -{ - return - (methodName.CompareNoCase(kLZMAMethodName) == 0) || - (methodName.CompareNoCase(kLZMA2MethodName) == 0); -} - -/* -static bool IsLZMethod(const UString &methodName) - { return IsLZMAMethod(methodName); } -*/ - -static bool IsBZip2Method(const UString &methodName) - { return (methodName.CompareNoCase(kBZip2MethodName) == 0); } - -static bool IsPpmdMethod(const UString &methodName) - { return (methodName.CompareNoCase(kPpmdMethodName) == 0); } - -static bool IsDeflateMethod(const UString &methodName) - { return (methodName.CompareNoCase(kDeflateMethodName) == 0) || - (methodName.CompareNoCase(kDeflate64MethodName) == 0); } - STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) { *type = NFileTimeType::kWindows; @@ -136,60 +65,6 @@ HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode, 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::kMatchFinderCycles, VT_UI4, L"mc" }, - { NCoderPropID::kAlgorithm, VT_UI4, L"a" }, - { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" }, - { NCoderPropID::kNumThreads, VT_UI4, 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) @@ -210,28 +85,28 @@ HRESULT CHandler::SetCompressionMethod( COneMethodInfo oneMethodInfo; oneMethodInfo.MethodName = kLZMAMethodName; { - CProperty property; - property.PropID = NCoderPropID::kMatchFinder; + CProp property; + property.Id = NCoderPropID::kMatchFinder; property.Value = kLzmaMatchFinderForHeaders; - oneMethodInfo.CoderProperties.Add(property); + oneMethodInfo.Properties.Add(property); } { - CProperty property; - property.PropID = NCoderPropID::kAlgorithm; + CProp property; + property.Id = NCoderPropID::kAlgorithm; property.Value = kAlgorithmForHeaders; - oneMethodInfo.CoderProperties.Add(property); + oneMethodInfo.Properties.Add(property); } { - CProperty property; - property.PropID = NCoderPropID::kNumFastBytes; + CProp property; + property.Id = NCoderPropID::kNumFastBytes; property.Value = UInt32(kNumFastBytesForHeaders); - oneMethodInfo.CoderProperties.Add(property); + oneMethodInfo.Properties.Add(property); } { - CProperty property; - property.PropID = NCoderPropID::kDictionarySize; + CProp property; + property.Id = NCoderPropID::kDictionarySize; property.Value = UInt32(kDictionaryForHeaders); - oneMethodInfo.CoderProperties.Add(property); + oneMethodInfo.Properties.Add(property); } headerMethodInfoVector.Add(oneMethodInfo); HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector @@ -244,21 +119,6 @@ HRESULT CHandler::SetCompressionMethod( 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 @@ -280,113 +140,31 @@ HRESULT CHandler::SetCompressionMethod( for(int i = 0; i < methodsInfo.Size(); i++) { COneMethodInfo &oneMethodInfo = methodsInfo[i]; - if (oneMethodInfo.MethodName.IsEmpty()) - oneMethodInfo.MethodName = kDefaultMethodName; - - if (!IsCopyMethod(oneMethodInfo.MethodName)) - needSolid = true; - - if (IsLZMAMethod(oneMethodInfo.MethodName)) - { - UInt32 dicSize = - (level >= 9 ? kLzmaDicSizeX9 : - (level >= 7 ? kLzmaDicSizeX7 : - (level >= 5 ? kLzmaDicSizeX5 : - (level >= 3 ? kLzmaDicSizeX3 : - kLzmaDicSizeX1)))); - - UInt32 algorithm = - (level >= 5 ? kLzmaAlgorithmX5 : - kLzmaAlgorithmX1); - - UInt32 fastBytes = - (level >= 7 ? kLzmaFastBytesX7 : - kLzmaFastBytesX1); - - const wchar_t *matchFinder = - (level >= 5 ? kLzmaMatchFinderX5 : - kLzmaMatchFinderX1); - - 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)) - { - UInt32 fastBytes = - (level >= 9 ? kDeflateFastBytesX9 : - (level >= 7 ? kDeflateFastBytesX7 : - kDeflateFastBytesX1)); - - UInt32 numPasses = - (level >= 9 ? kDeflatePassesX9 : - (level >= 7 ? kDeflatePassesX7 : - kDeflatePassesX1)); - UInt32 algo = - (level >= 5 ? kDeflateAlgoX5 : - kDeflateAlgoX1); - - SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo); - SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); - SetOneMethodProp(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)); - - SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); - SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); + SetCompressionMethod2(oneMethodInfo #ifdef COMPRESS_MT - SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); + , 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))); - - SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize); - SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order); - } + ); + if (!IsCopyMethod(oneMethodInfo.MethodName)) + needSolid = true; CMethodFull methodFull; if (!FindMethod( EXTERNAL_CODECS_VARS - oneMethodInfo.MethodName, methodFull.MethodID, methodFull.NumInStreams, methodFull.NumOutStreams)) + oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams)) return E_INVALIDARG; - methodFull.CoderProperties = oneMethodInfo.CoderProperties; + methodFull.Properties = oneMethodInfo.Properties; methodMode.Methods.Add(methodFull); if (!_numSolidBytesDefined) { - for (int j = 0; j < methodFull.CoderProperties.Size(); j++) + for (int j = 0; j < methodFull.Properties.Size(); j++) { - const CProperty &prop = methodFull.CoderProperties[j]; - if ((prop.PropID == NCoderPropID::kDictionarySize || - prop.PropID == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4) + const CProp &prop = methodFull.Properties[j]; + if ((prop.Id == NCoderPropID::kDictionarySize || + prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4) { _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7; const UInt64 kMinSize = (1 << 24); @@ -652,198 +430,11 @@ static HRESULT GetBindInfo(UString &srcString, CBind &bind) return S_OK; } -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 ¶m, 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 CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value) -{ - CProperty property; - if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0) - { - UInt32 dicSize; - RINOK(ParsePropDictionaryValue(value, dicSize)); - if (name.CompareNoCase(L"D") == 0) - property.PropID = NCoderPropID::kDictionarySize; - else - property.PropID = NCoderPropID::kUsedMemorySize; - property.Value = dicSize; - oneMethodInfo.CoderProperties.Add(property); - } - else - { - int index = FindPropIdFromStringName(name); - if (index < 0) - return E_INVALIDARG; - - const CNameToPropID &nameToPropID = g_NameToPropID[index]; - property.PropID = nameToPropID.PropID; - - NCOM::CPropVariant propValue; - - - if (nameToPropID.VarType == VT_BSTR) - propValue = value; - else - { - UInt32 number; - if (ParseStringToUInt32(value, number) == value.Length()) - propValue = number; - else - propValue = value; - } - - if (!ConvertProperty(propValue, nameToPropID.VarType, property.Value)) - return E_INVALIDARG; - - oneMethodInfo.CoderProperties.Add(property); - } - return S_OK; -} - -HRESULT CHandler::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 ¶m = params[i]; - UString name, value; - SplitParam(param, name, value); - RINOK(SetParam(oneMethodInfo, name, value)); - } - return S_OK; -} - -HRESULT CHandler::SetSolidSettings(const UString &s) -{ - UString s2 = s; - s2.MakeUpper(); - if (s2.IsEmpty() || s2.Compare(L"ON") == 0) - { - InitSolid(); - return S_OK; - } - if (s2.Compare(L"OFF") == 0) - { - _numSolidFiles = 1; - return S_OK; - } - 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 CHandler::SetSolidSettings(const PROPVARIANT &value) -{ - switch(value.vt) - { - case VT_EMPTY: - InitSolid(); - return S_OK; - case VT_BSTR: - return SetSolidSettings(value.bstrVal); - default: - return E_INVALIDARG; - } -} - STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) { COM_TRY_BEGIN - _methods.Clear(); _binds.Clear(); - Init(); - #ifdef COMPRESS_MT - const UInt32 numProcessors = NSystem::GetNumberOfProcessors(); - #endif - - UInt32 mainDicSize = 0xFFFFFFFF; - UInt32 mainDicMethodIndex = 0xFFFFFFFF; - - UInt32 minNumber = 0; + BeforeSetProperty(); for (int i = 0; i < numProperties; i++) { @@ -854,14 +445,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v const PROPVARIANT &value = values[i]; - if (name[0] == 'X') - { - name.Delete(0); - _level = 9; - RINOK(ParsePropValue(name, value, _level)); - continue; - } - if (name[0] == 'B') { name.Delete(0); @@ -871,142 +454,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v continue; } - if (name[0] == L'S') - { - name.Delete(0); - if (name.IsEmpty()) - { - RINOK(SetSolidSettings(value)); - } - else - { - RINOK(SetSolidSettings(name)); - } - continue; - } - - - UInt32 number; - int index = ParseStringToUInt32(name, number); - UString realName = name.Mid(index); - if (index == 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; - } - else if (name.CompareNoCase(L"F") == 0) - { - RINOK(SetBoolProperty(_autoFilter, value)); - continue; - } - else if (name.CompareNoCase(L"HC") == 0) - { - RINOK(SetBoolProperty(_compressHeaders, value)); - continue; - } - else if (name.CompareNoCase(L"HCF") == 0) - { - bool compressHeadersFull = true; - RINOK(SetBoolProperty(compressHeadersFull, value)); - if (!compressHeadersFull) - return E_INVALIDARG; - continue; - } - else if (name.CompareNoCase(L"HE") == 0) - { - RINOK(SetBoolProperty(_encryptHeaders, value)); - continue; - } - else if (name.CompareNoCase(L"TM") == 0) - { - RINOK(SetBoolProperty(WriteModified, value)); - continue; - } - else if (name.CompareNoCase(L"TC") == 0) - { - RINOK(SetBoolProperty(WriteCreated, value)); - continue; - } - else if (name.CompareNoCase(L"TA") == 0) - { - RINOK(SetBoolProperty(WriteAccessed, value)); - continue; - } - else if (name.CompareNoCase(L"V") == 0) - { - RINOK(SetBoolProperty(_volumeMode, value)); - continue; - } - number = 0; - } - if (number > 10000) - 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; - - // oneMethodInfo.MethodName = UnicodeStringToMultiByte(UString(value.bstrVal)); - RINOK(SetParams(oneMethodInfo, value.bstrVal)); - } - else - { - CProperty property; - if (realName.Left(1).CompareNoCase(L"D") == 0) - { - UInt32 dicSize; - RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize)); - property.PropID = NCoderPropID::kDictionarySize; - property.Value = dicSize; - oneMethodInfo.CoderProperties.Add(property); - if (number <= mainDicMethodIndex) - mainDicSize = dicSize; - } - 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); - if (number <= mainDicMethodIndex) - mainDicSize = dicSize; - } - else - { - int index = FindPropIdFromStringName(realName); - if (index < 0) - return E_INVALIDARG; - - const CNameToPropID &nameToPropID = g_NameToPropID[index]; - property.PropID = nameToPropID.PropID; - - if (!ConvertProperty(value, nameToPropID.VarType, property.Value)) - return E_INVALIDARG; - - oneMethodInfo.CoderProperties.Add(property); - } - } + RINOK(SetProperty(name, value)); } return S_OK; |