Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Archive/Zip/ZipHandlerOut.cpp')
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandlerOut.cpp298
1 files changed, 92 insertions, 206 deletions
diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
index a5e0f59d..427b0c31 100755
--- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -28,37 +28,6 @@ using namespace NTime;
namespace NArchive {
namespace NZip {
-static const UInt32 kLzAlgoX1 = 0;
-static const UInt32 kLzAlgoX5 = 1;
-
-static const UInt32 kDeflateNumPassesX1 = 1;
-static const UInt32 kDeflateNumPassesX7 = 3;
-static const UInt32 kDeflateNumPassesX9 = 10;
-
-static const UInt32 kDeflateNumFastBytesX1 = 32;
-static const UInt32 kDeflateNumFastBytesX7 = 64;
-static const UInt32 kDeflateNumFastBytesX9 = 128;
-
-static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
-static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
-
-static const UInt32 kLzmaNumFastBytesX1 = 32;
-static const UInt32 kLzmaNumFastBytesX7 = 64;
-
-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 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;
-
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
{
*timeType = NFileTimeType::kDOS;
@@ -99,6 +68,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_BEGIN2
CObjectVector<CUpdateItem> updateItems;
bool thereAreAesUpdates = false;
+ UInt64 largestSize = 0;
+ bool largestSizeDefined = false;
for (UInt32 i = 0; i < numItems; i++)
{
CUpdateItem ui;
@@ -178,7 +149,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
const wchar_t kSlash = L'/';
if (!name.IsEmpty())
{
- if (name[name.Length() - 1] == kSlash)
+ if (name.Back() == kSlash)
{
if (!ui.IsDir)
return E_INVALIDARG;
@@ -235,6 +206,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
+ if (largestSize < size)
+ largestSize = size;
+ largestSizeDefined = true;
}
ui.Size = size;
}
@@ -247,6 +221,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
}
CCompressionMethodMode options;
+ (CBaseProps &)options = _props;
+ options._dataSizeReduce = largestSize;
+ options._dataSizeReduceDefined = largestSizeDefined;
if (getTextPassword)
{
@@ -256,8 +233,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.PasswordIsDefined = IntToBool(passwordIsDefined);
if (options.PasswordIsDefined)
{
- options.IsAesMode = (m_ForceAesMode ? m_IsAesMode : thereAreAesUpdates);
- options.AesKeyMode = m_AesKeyMode;
+ if (!m_ForceAesMode)
+ options.IsAesMode = thereAreAesUpdates;
if (!IsAsciiString((const wchar_t *)password))
return E_INVALIDARG;
@@ -272,13 +249,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
else
options.PasswordIsDefined = false;
- int level = m_Level;
- if (level < 0)
- level = 5;
-
Byte mainMethod;
if (m_MainMethod < 0)
- mainMethod = (Byte)(((level == 0) ?
+ mainMethod = (Byte)(((_props.Level == 0) ?
NFileHeader::NCompressionMethod::kStored :
NFileHeader::NCompressionMethod::kDeflated));
else
@@ -286,83 +259,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.MethodSequence.Add(mainMethod);
if (mainMethod != NFileHeader::NCompressionMethod::kStored)
options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);
- bool isDeflate = (mainMethod == NFileHeader::NCompressionMethod::kDeflated) ||
- (mainMethod == NFileHeader::NCompressionMethod::kDeflated64);
- bool isLZMA = (mainMethod == NFileHeader::NCompressionMethod::kLZMA);
- bool isLz = (isLZMA || isDeflate);
- options.NumPasses = m_NumPasses;
- options.DicSize = m_DicSize;
- options.NumFastBytes = m_NumFastBytes;
- options.NumMatchFinderCycles = m_NumMatchFinderCycles;
- options.NumMatchFinderCyclesDefined = m_NumMatchFinderCyclesDefined;
- options.Algo = m_Algo;
- options.MemSize = m_MemSize;
- options.Order = m_Order;
- #ifndef _7ZIP_ST
- options.NumThreads = _numThreads;
- #endif
- if (isLz)
- {
- if (isDeflate)
- {
- if (options.NumPasses == 0xFFFFFFFF)
- options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 :
- (level >= 7 ? kDeflateNumPassesX7 :
- kDeflateNumPassesX1));
- if (options.NumFastBytes == 0xFFFFFFFF)
- options.NumFastBytes = (level >= 9 ? kDeflateNumFastBytesX9 :
- (level >= 7 ? kDeflateNumFastBytesX7 :
- kDeflateNumFastBytesX1));
- }
- else if (isLZMA)
- {
- if (options.DicSize == 0xFFFFFFFF)
- options.DicSize =
- (level >= 9 ? kLzmaDicSizeX9 :
- (level >= 7 ? kLzmaDicSizeX7 :
- (level >= 5 ? kLzmaDicSizeX5 :
- (level >= 3 ? kLzmaDicSizeX3 :
- kLzmaDicSizeX1))));
-
- if (options.NumFastBytes == 0xFFFFFFFF)
- options.NumFastBytes = (level >= 7 ? kLzmaNumFastBytesX7 :
- kLzmaNumFastBytesX1);
-
- options.MatchFinder =
- (level >= 5 ? kLzmaMatchFinderX5 :
- kLzmaMatchFinderX1);
- }
-
- if (options.Algo == 0xFFFFFFFF)
- options.Algo = (level >= 5 ? kLzAlgoX5 :
- kLzAlgoX1);
- }
- if (mainMethod == NFileHeader::NCompressionMethod::kBZip2)
- {
- if (options.NumPasses == 0xFFFFFFFF)
- options.NumPasses = (level >= 9 ? kBZip2NumPassesX9 :
- (level >= 7 ? kBZip2NumPassesX7 :
- kBZip2NumPassesX1));
- if (options.DicSize == 0xFFFFFFFF)
- options.DicSize = (level >= 5 ? kBZip2DicSizeX5 :
- (level >= 3 ? kBZip2DicSizeX3 :
- kBZip2DicSizeX1));
- }
- if (mainMethod == NFileHeader::NCompressionMethod::kPPMd)
- {
- int level2 = level;
- if (level2 < 1) level2 = 1;
- if (level2 > 9) level2 = 9;
-
- if (options.MemSize == 0xFFFFFFFF)
- options.MemSize = (1 << (19 + (level2 > 8 ? 8 : level2)));
-
- if (options.Order == 0xFFFFFFFF)
- options.Order = 3 + level2;
-
- if (options.Algo == 0xFFFFFFFF)
- options.Algo = (level2 >= 7 ? 1 : 0);
- }
return Update(
EXTERNAL_CODECS_VARS
@@ -371,16 +267,34 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_END2
}
-STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+struct CMethodIndexToName
+{
+ unsigned Method;
+ const wchar_t *Name;
+};
+
+static const CMethodIndexToName k_SupportedMethods[] =
{
+ { NFileHeader::NCompressionMethod::kStored, L"COPY" },
+ { NFileHeader::NCompressionMethod::kDeflated, L"DEFLATE" },
+ { NFileHeader::NCompressionMethod::kDeflated64, L"DEFLATE64" },
+ { NFileHeader::NCompressionMethod::kBZip2, L"BZIP2" },
+ { NFileHeader::NCompressionMethod::kLZMA, L"LZMA" },
+ { NFileHeader::NCompressionMethod::kPPMd, L"PPMD" }
+};
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
+{
+ InitMethodProps();
#ifndef _7ZIP_ST
- const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
- _numThreads = numProcessors;
+ const UInt32 numProcessors = _props.NumThreads;
#endif
- InitMethodProperties();
- for (int i = 0; i < numProperties; i++)
+
+ for (int i = 0; i < numProps; i++)
{
- UString name = UString(names[i]);
+ UString name = names[i];
name.MakeUpper();
if (name.IsEmpty())
return E_INVALIDARG;
@@ -390,140 +304,112 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
if (name[0] == L'X')
{
UInt32 level = 9;
- RINOK(ParsePropValue(name.Mid(1), prop, level));
- m_Level = level;
- continue;
+ RINOK(ParsePropToUInt32(name.Mid(1), prop, level));
+ _props.Level = level;
+ _props.MethodInfo.AddLevelProp(level);
}
else if (name == L"M")
{
if (prop.vt == VT_BSTR)
{
- UString m = prop.bstrVal;
+ UString m = prop.bstrVal, m2;
m.MakeUpper();
- if (m == L"COPY") m_MainMethod = NFileHeader::NCompressionMethod::kStored;
- else if (m == L"DEFLATE") m_MainMethod = NFileHeader::NCompressionMethod::kDeflated;
- else if (m == L"DEFLATE64") m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64;
- else if (m == L"BZIP2") m_MainMethod = NFileHeader::NCompressionMethod::kBZip2;
- else if (m == L"LZMA") m_MainMethod = NFileHeader::NCompressionMethod::kLZMA;
- else if (m == L"PPMD") m_MainMethod = NFileHeader::NCompressionMethod::kPPMd;
- else return E_INVALIDARG;
+ int colonPos = m.Find(L':');
+ if (colonPos >= 0)
+ {
+ m2 = m.Mid(colonPos + 1);
+ m = m.Left(colonPos);
+ }
+ int k;
+ for (k = 0; k < ARRAY_SIZE(k_SupportedMethods); k++)
+ {
+ const CMethodIndexToName &pair = k_SupportedMethods[k];
+ if (m == pair.Name)
+ {
+ if (!m2.IsEmpty())
+ {
+ RINOK(_props.MethodInfo.ParseParamsFromString(m2));
+ }
+ m_MainMethod = pair.Method;
+ break;
+ }
+ }
+ if (k == ARRAY_SIZE(k_SupportedMethods))
+ return E_INVALIDARG;
}
else if (prop.vt == VT_UI4)
{
- switch(prop.ulVal)
+ int k;
+ for (k = 0; k < ARRAY_SIZE(k_SupportedMethods); k++)
{
- case NFileHeader::NCompressionMethod::kStored:
- case NFileHeader::NCompressionMethod::kDeflated:
- case NFileHeader::NCompressionMethod::kDeflated64:
- case NFileHeader::NCompressionMethod::kBZip2:
- case NFileHeader::NCompressionMethod::kLZMA:
- m_MainMethod = (Byte)prop.ulVal;
+ unsigned method = k_SupportedMethods[k].Method;
+ if (prop.ulVal == method)
+ {
+ m_MainMethod = method;
break;
- default:
- return E_INVALIDARG;
+ }
}
+ if (k == ARRAY_SIZE(k_SupportedMethods))
+ return E_INVALIDARG;
}
else
return E_INVALIDARG;
}
else if (name.Left(2) == L"EM")
{
- if (prop.vt == VT_BSTR)
+ if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
{
- UString valueString = prop.bstrVal;
- valueString.MakeUpper();
- if (valueString.Left(3) == L"AES")
+ UString m = prop.bstrVal;
+ m.MakeUpper();
+ if (m.Left(3) == L"AES")
{
- valueString = valueString.Mid(3);
- if (valueString == L"128")
- m_AesKeyMode = 1;
- else if (valueString == L"192")
- m_AesKeyMode = 2;
- else if (valueString == L"256" || valueString.IsEmpty())
- m_AesKeyMode = 3;
+ m = m.Mid(3);
+ if (m == L"128")
+ _props.AesKeyMode = 1;
+ else if (m == L"192")
+ _props.AesKeyMode = 2;
+ else if (m == L"256" || m.IsEmpty())
+ _props.AesKeyMode = 3;
else
return E_INVALIDARG;
- m_IsAesMode = true;
+ _props.IsAesMode = true;
m_ForceAesMode = true;
}
- else if (valueString == L"ZIPCRYPTO")
+ else if (m == L"ZIPCRYPTO")
{
- m_IsAesMode = false;
+ _props.IsAesMode = false;
m_ForceAesMode = true;
}
else
return E_INVALIDARG;
}
- else
- return E_INVALIDARG;
- }
- else if (name[0] == L'D')
- {
- UInt32 dicSize = kBZip2DicSizeX5;
- RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
- m_DicSize = dicSize;
- }
- else if (name.Left(3) == L"MEM")
- {
- UInt32 memSize = 1 << 24;
- RINOK(ParsePropDictionaryValue(name.Mid(3), prop, memSize));
- m_MemSize = memSize;
- }
- else if (name[0] == L'O')
- {
- UInt32 order = 8;
- RINOK(ParsePropValue(name.Mid(1), prop, order));
- m_Order = order;
- }
- else if (name.Left(4) == L"PASS")
- {
- UInt32 num = kDeflateNumPassesX9;
- RINOK(ParsePropValue(name.Mid(4), prop, num));
- m_NumPasses = num;
- }
- else if (name.Left(2) == L"FB")
- {
- UInt32 num = kDeflateNumFastBytesX9;
- RINOK(ParsePropValue(name.Mid(2), prop, num));
- m_NumFastBytes = num;
- }
- else if (name.Left(2) == L"MC")
- {
- UInt32 num = 0xFFFFFFFF;
- RINOK(ParsePropValue(name.Mid(2), prop, num));
- m_NumMatchFinderCycles = num;
- m_NumMatchFinderCyclesDefined = true;
}
else if (name.Left(2) == L"MT")
{
#ifndef _7ZIP_ST
- RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
+ RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _props.NumThreads));
+ _props.NumThreadsWasChanged = true;
#endif
}
- else if (name.Left(1) == L"A")
- {
- UInt32 num = kLzAlgoX5;
- RINOK(ParsePropValue(name.Mid(1), prop, num));
- m_Algo = num;
- }
else if (name.CompareNoCase(L"TC") == 0)
{
- RINOK(SetBoolProperty(m_WriteNtfsTimeExtra, prop));
+ RINOK(PROPVARIANT_to_bool(prop, m_WriteNtfsTimeExtra));
}
else if (name.CompareNoCase(L"CL") == 0)
{
- RINOK(SetBoolProperty(m_ForceLocal, prop));
+ RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal));
if (m_ForceLocal)
m_ForceUtf8 = false;
}
else if (name.CompareNoCase(L"CU") == 0)
{
- RINOK(SetBoolProperty(m_ForceUtf8, prop));
+ RINOK(PROPVARIANT_to_bool(prop, m_ForceUtf8));
if (m_ForceUtf8)
m_ForceLocal = false;
}
else
- return E_INVALIDARG;
+ return _props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop);
}
return S_OK;
}