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:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2011-04-11 04:00:00 +0400
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:16:05 +0300
commit35596517f203f1c4970413b3b5b2e216b849e462 (patch)
tree93240df3eb4ddbd8eebbe6a5fc65e93f2ccb6495 /CPP/7zip/Archive/Zip
parentde4f8c22fe4b9e59b60495b84db2e81de50999a9 (diff)
9.219.21
Diffstat (limited to 'CPP/7zip/Archive/Zip')
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipAddCommon.cpp101
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipCompressionMode.h56
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandler.cpp44
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandler.h41
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandlerOut.cpp298
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipIn.cpp4
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipItem.cpp62
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipItem.h13
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipUpdate.cpp69
9 files changed, 262 insertions, 426 deletions
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
index 4c5fd38d..da42f3bd 100755
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
@@ -33,6 +33,7 @@ static const UInt32 kLzmaHeaderSize = 4 + kLzmaPropsSize;
class CLzmaEncoder:
public ICompressCoder,
+ public ICompressSetCoderProperties,
public CMyUnknownImp
{
NCompress::NLzma::CEncoder *EncoderSpec;
@@ -41,12 +42,12 @@ class CLzmaEncoder:
public:
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
- HRESULT SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
};
-HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+STDMETHODIMP CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
{
if (!Encoder)
{
@@ -67,7 +68,7 @@ HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIAN
return S_OK;
}
-HRESULT CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+STDMETHODIMP CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
RINOK(WriteStream(outStream, Header, kLzmaHeaderSize));
@@ -210,52 +211,12 @@ HRESULT CAddCommon::Compress(
_compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_LZMA;
CLzmaEncoder *_lzmaEncoder = new CLzmaEncoder();
_compressEncoder = _lzmaEncoder;
- NWindows::NCOM::CPropVariant props[] =
- {
- #ifndef _7ZIP_ST
- _options.NumThreads,
- #endif
- _options.Algo,
- _options.DicSize,
- _options.NumFastBytes,
- const_cast<BSTR>((const wchar_t *)_options.MatchFinder),
- _options.NumMatchFinderCycles
- };
- PROPID propIDs[] =
- {
- #ifndef _7ZIP_ST
- NCoderPropID::kNumThreads,
- #endif
- NCoderPropID::kAlgorithm,
- NCoderPropID::kDictionarySize,
- NCoderPropID::kNumFastBytes,
- NCoderPropID::kMatchFinder,
- NCoderPropID::kMatchFinderCycles
- };
- int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
- if (!_options.NumMatchFinderCyclesDefined)
- numProps--;
- RINOK(_lzmaEncoder->SetCoderProperties(propIDs, props, numProps));
}
else if (method == NFileHeader::NCompressionMethod::kPPMd)
{
_compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_PPMd;
NCompress::NPpmdZip::CEncoder *encoder = new NCompress::NPpmdZip::CEncoder();
_compressEncoder = encoder;
- NWindows::NCOM::CPropVariant props[] =
- {
- _options.Algo,
- _options.MemSize,
- _options.Order
-
- };
- PROPID propIDs[] =
- {
- NCoderPropID::kAlgorithm,
- NCoderPropID::kUsedMemorySize,
- NCoderPropID::kOrder
- };
- RINOK(encoder->SetCoderProperties(propIDs, props, sizeof(propIDs) / sizeof(propIDs[0])));
}
else
{
@@ -282,56 +243,20 @@ HRESULT CAddCommon::Compress(
if (method == NFileHeader::NCompressionMethod::kDeflated ||
method == NFileHeader::NCompressionMethod::kDeflated64)
{
- NWindows::NCOM::CPropVariant props[] =
- {
- _options.Algo,
- _options.NumPasses,
- _options.NumFastBytes,
- _options.NumMatchFinderCycles
- };
- PROPID propIDs[] =
- {
- NCoderPropID::kAlgorithm,
- NCoderPropID::kNumPasses,
- NCoderPropID::kNumFastBytes,
- NCoderPropID::kMatchFinderCycles
- };
- int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
- if (!_options.NumMatchFinderCyclesDefined)
- numProps--;
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
- if (setCoderProperties)
- {
- RINOK(setCoderProperties->SetCoderProperties(propIDs, props, numProps));
- }
}
else if (method == NFileHeader::NCompressionMethod::kBZip2)
{
- NWindows::NCOM::CPropVariant props[] =
- {
- _options.DicSize,
- _options.NumPasses
- #ifndef _7ZIP_ST
- , _options.NumThreads
- #endif
- };
- PROPID propIDs[] =
- {
- NCoderPropID::kDictionarySize,
- NCoderPropID::kNumPasses
- #ifndef _7ZIP_ST
- , NCoderPropID::kNumThreads
- #endif
- };
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
- if (setCoderProperties)
+ }
+ }
+ {
+ CMyComPtr<ICompressSetCoderProperties> setCoderProps;
+ _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProps);
+ if (setCoderProps)
{
- RINOK(setCoderProperties->SetCoderProperties(propIDs, props, sizeof(propIDs) / sizeof(propIDs[0])));
+ RINOK(_options.MethodInfo.SetCoderProps(setCoderProps,
+ _options._dataSizeReduceDefined ? &_options._dataSizeReduce : NULL));
}
}
- }
}
CMyComPtr<ISequentialOutStream> outStreamNew;
if (_options.PasswordIsDefined)
diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
index 7ef7cfb2..5be33166 100755
--- a/CPP/7zip/Archive/Zip/ZipCompressionMode.h
+++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
@@ -5,36 +5,54 @@
#include "Common/MyString.h"
+#ifndef _7ZIP_ST
+#include "../../../Windows/System.h"
+#endif
+
+#include "../Common/HandlerOut.h"
+
namespace NArchive {
namespace NZip {
-struct CCompressionMethodMode
+struct CBaseProps
{
- CRecordVector<Byte> MethodSequence;
- UString MatchFinder;
- UInt32 Algo;
- UInt32 NumPasses;
- UInt32 NumFastBytes;
- bool NumMatchFinderCyclesDefined;
- UInt32 NumMatchFinderCycles;
- UInt32 DicSize;
- UInt32 MemSize;
- UInt32 Order;
+ CMethodProps MethodInfo;
+ Int32 Level;
#ifndef _7ZIP_ST
UInt32 NumThreads;
+ bool NumThreadsWasChanged;
#endif
- bool PasswordIsDefined;
- AString Password;
bool IsAesMode;
Byte AesKeyMode;
+
+ void Init()
+ {
+ MethodInfo.Clear();
+ Level = -1;
+ #ifndef _7ZIP_ST
+ NumThreads = NWindows::NSystem::GetNumberOfProcessors();;
+ NumThreadsWasChanged = false;
+ #endif
+ IsAesMode = false;
+ AesKeyMode = 3;
+ }
+};
+
+struct CCompressionMethodMode: public CBaseProps
+{
+ CRecordVector<Byte> MethodSequence;
+ bool PasswordIsDefined;
+ AString Password;
+
+ UInt64 _dataSizeReduce;
+ bool _dataSizeReduceDefined;
- CCompressionMethodMode():
- NumMatchFinderCyclesDefined(false),
- PasswordIsDefined(false),
- IsAesMode(false),
- AesKeyMode(3)
- {}
+ CCompressionMethodMode(): PasswordIsDefined(false)
+ {
+ _dataSizeReduceDefined = false;
+ _dataSizeReduce = 0;
+ }
};
}}
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp
index bd156322..2281ed5b 100755
--- a/CPP/7zip/Archive/Zip/ZipHandler.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp
@@ -107,7 +107,7 @@ static struct CStrongCryptoPair
{ NStrongCryptoFlags::kRC4, "RC4" }
};
-static STATPROPSTG kProps[] =
+static const STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
@@ -117,6 +117,7 @@ static STATPROPSTG kProps[] =
{ NULL, kpidCTime, VT_FILETIME},
{ NULL, kpidATime, VT_FILETIME},
{ NULL, kpidAttrib, VT_UI4},
+ // { NULL, kpidPosixAttrib, VT_UI4},
{ NULL, kpidEncrypted, VT_BOOL},
{ NULL, kpidComment, VT_BSTR},
{ NULL, kpidCRC, VT_UI4},
@@ -125,7 +126,7 @@ static STATPROPSTG kProps[] =
{ NULL, kpidUnpackVer, VT_UI4}
};
-static STATPROPSTG kArcProps[] =
+static const STATPROPSTG kArcProps[] =
{
{ NULL, kpidBit64, VT_BOOL},
{ NULL, kpidComment, VT_BSTR},
@@ -135,7 +136,7 @@ static STATPROPSTG kArcProps[] =
CHandler::CHandler()
{
- InitMethodProperties();
+ InitMethodProps();
}
static AString BytesToString(const CByteBuffer &data)
@@ -165,6 +166,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidComment: prop = MultiByteToUnicodeString(BytesToString(m_Archive.ArcInfo.Comment), CP_ACP); break;
case kpidPhySize: prop = m_Archive.ArcInfo.GetPhySize(); break;
case kpidOffset: if (m_Archive.ArcInfo.StartPosition != 0) prop = m_Archive.ArcInfo.StartPosition; break;
+ case kpidError: if (!m_Archive.IsOkHeaders) prop = "Incorrect headers"; break;
}
prop.Detach(value);
COM_TRY_END
@@ -194,7 +196,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
UInt32 unixTime;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
prop = (UInt32)NFileTimeType::kWindows;
- else if (item.CentralExtra.GetUnixTime(NFileHeader::NUnixTime::kMTime, unixTime))
+ else if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
prop = (UInt32)NFileTimeType::kUnix;
else
prop = (UInt32)NFileTimeType::kDOS;
@@ -220,7 +222,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
{
UInt32 unixTime;
- if (item.CentralExtra.GetUnixTime(NFileHeader::NUnixTime::kMTime, unixTime))
+ if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
NTime::UnixTimeToFileTime(unixTime, utc);
else
{
@@ -233,7 +235,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = utc;
break;
}
- case kpidAttrib: prop = item.GetWinAttributes(); break;
+ case kpidAttrib: prop = item.GetWinAttrib(); break;
+ case kpidPosixAttrib:
+ {
+ UInt32 attrib;
+ if (item.GetPosixAttrib(attrib))
+ prop = attrib;
+ break;
+ }
case kpidEncrypted: prop = item.IsEncrypted(); break;
case kpidComment: prop = item.GetUnicodeString(BytesToString(item.Comment)); break;
case kpidCRC: if (item.IsThereCrc()) prop = item.FileCRC; break;
@@ -435,7 +444,10 @@ public:
ISequentialOutStream *realOutStream,
IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress,
- UInt32 numThreads, Int32 &res);
+ #ifndef _7ZIP_ST
+ UInt32 numThreads,
+ #endif
+ Int32 &res);
};
HRESULT CZipDecoder::Decode(
@@ -444,7 +456,10 @@ HRESULT CZipDecoder::Decode(
ISequentialOutStream *realOutStream,
IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress,
- UInt32 numThreads, Int32 &res)
+ #ifndef _7ZIP_ST
+ UInt32 numThreads,
+ #endif
+ Int32 &res)
{
res = NExtract::NOperationResult::kDataError;
CInStreamReleaser inStreamReleaser;
@@ -805,15 +820,22 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->PrepareOperation(askMode));
Int32 res;
- RINOK(myDecoder.Decode(
+ HRESULT hres = myDecoder.Decode(
EXTERNAL_CODECS_VARS
m_Archive, item, realOutStream, extractCallback,
- progress, _numThreads, res));
+ progress,
+ #ifndef _7ZIP_ST
+ _props.NumThreads,
+ #endif
+ res);
+ RINOK(hres);
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(res))
}
- return S_OK;
+ lps->InSize = currentTotalPacked;
+ lps->OutSize = currentTotalUnPacked;
+ return lps->SetCur();
COM_TRY_END
}
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h
index fdb60aaf..33cf6fdc 100755
--- a/CPP/7zip/Archive/Zip/ZipHandler.h
+++ b/CPP/7zip/Archive/Zip/ZipHandler.h
@@ -12,10 +12,6 @@
#include "ZipIn.h"
#include "ZipCompressionMode.h"
-#ifndef _7ZIP_ST
-#include "../../../Windows/System.h"
-#endif
-
namespace NArchive {
namespace NZip {
@@ -46,53 +42,24 @@ private:
CObjectVector<CItemEx> m_Items;
CInArchive m_Archive;
- int m_Level;
- int m_MainMethod;
- UInt32 m_DicSize;
- UInt32 m_Algo;
- UInt32 m_NumPasses;
- UInt32 m_NumFastBytes;
- UInt32 m_NumMatchFinderCycles;
- UInt32 m_MemSize;
- UInt32 m_Order;
-
- bool m_NumMatchFinderCyclesDefined;
+ CBaseProps _props;
+ int m_MainMethod;
bool m_ForceAesMode;
- bool m_IsAesMode;
- Byte m_AesKeyMode;
-
bool m_WriteNtfsTimeExtra;
bool m_ForceLocal;
bool m_ForceUtf8;
- #ifndef _7ZIP_ST
- UInt32 _numThreads;
- #endif
-
DECL_EXTERNAL_CODECS_VARS
- void InitMethodProperties()
+ void InitMethodProps()
{
- m_Level = -1;
+ _props.Init();
m_MainMethod = -1;
- m_Algo =
- m_DicSize =
- m_NumPasses =
- m_NumFastBytes =
- m_Order =
- m_MemSize =
- m_NumMatchFinderCycles = 0xFFFFFFFF;
- m_NumMatchFinderCyclesDefined = false;
m_ForceAesMode = false;
- m_IsAesMode = false;
- m_AesKeyMode = 3; // aes-256
m_WriteNtfsTimeExtra = true;
m_ForceLocal = false;
m_ForceUtf8 = false;
- #ifndef _7ZIP_ST
- _numThreads = NWindows::NSystem::GetNumberOfProcessors();;
- #endif
}
};
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;
}
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index b36b61be..e930488f 100755
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -756,6 +756,7 @@ void CEcd64::Parse(const Byte *p)
HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress)
{
+ IsOkHeaders = true;
// m_Signature must be kLocalFileHeaderSignature or
// kEndOfCentralDirSignature
// m_Position points to next byte after signature
@@ -852,6 +853,8 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0)
throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
+ if (numCdItems != items.Size())
+ IsOkHeaders = false;
if ((UInt16)ecd64.numEntriesInCDOnThisDisk != ((UInt16)numCdItems) ||
(UInt16)ecd64.numEntriesInCD != ((UInt16)numCdItems) ||
(UInt32)ecd64.cdSize != (UInt32)cdSize ||
@@ -861,7 +864,6 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
_inBufMode = false;
_inBuffer.Free();
- IsOkHeaders = (numCdItems == items.Size());
ArcInfo.FinishPosition = m_Position;
return S_OK;
}
diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp
index 139b0129..ad89f558 100755
--- a/CPP/7zip/Archive/Zip/ZipItem.cpp
+++ b/CPP/7zip/Archive/Zip/ZipItem.cpp
@@ -51,7 +51,7 @@ bool CExtraSubBlock::ExtractNtfsTime(int index, FILETIME &ft) const
return false;
}
-bool CExtraSubBlock::ExtractUnixTime(int index, UInt32 &res) const
+bool CExtraSubBlock::ExtractUnixTime(bool isCentral, int index, UInt32 &res) const
{
res = 0;
UInt32 size = (UInt32)Data.GetCapacity();
@@ -60,6 +60,15 @@ bool CExtraSubBlock::ExtractUnixTime(int index, UInt32 &res) const
const Byte *p = (const Byte *)Data;
Byte flags = *p++;
size--;
+ if (isCentral)
+ {
+ if (index != NFileHeader::NUnixTime::kMTime ||
+ (flags & (1 << NFileHeader::NUnixTime::kMTime)) == 0 ||
+ size < 4)
+ return false;
+ res = GetUi32(p);
+ return true;
+ }
for (int i = 0; i < 3; i++)
if ((flags & (1 << i)) != 0)
{
@@ -88,7 +97,7 @@ bool CItem::IsDir() const
if (!FromCentral)
return false;
WORD highAttributes = WORD((ExternalAttributes >> 16 ) & 0xFFFF);
- switch(MadeByVersion.HostOS)
+ switch (MadeByVersion.HostOS)
{
case NFileHeader::NHostOS::kAMIGA:
switch (highAttributes & NFileHeader::NAmigaAttribute::kIFMT)
@@ -109,44 +118,41 @@ bool CItem::IsDir() const
case NFileHeader::NHostOS::kAcorn:
case NFileHeader::NHostOS::kMVS:
return false; // change it throw kUnknownAttributes;
+ case NFileHeader::NHostOS::kUnix:
+ return (highAttributes & NFileHeader::NUnixAttribute::kIFDIR) != 0;
default:
- /*
- switch (highAttributes & NFileHeader::NUnixAttribute::kIFMT)
- {
- case NFileHeader::NUnixAttribute::kIFDIR:
- return true;
- default:
- return false;
- }
- */
return false;
}
}
-UInt32 CLocalItem::GetWinAttributes() const
-{
- DWORD winAttributes = 0;
- if (IsDir())
- winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
- return winAttributes;
-}
-
-UInt32 CItem::GetWinAttributes() const
+UInt32 CItem::GetWinAttrib() const
{
- DWORD winAttributes = 0;
- switch(MadeByVersion.HostOS)
+ DWORD winAttrib = 0;
+ switch (MadeByVersion.HostOS)
{
case NFileHeader::NHostOS::kFAT:
case NFileHeader::NHostOS::kNTFS:
if (FromCentral)
- winAttributes = ExternalAttributes;
+ winAttrib = ExternalAttributes;
break;
- default:
- winAttributes = 0; // must be converted from unix value;
}
- if (IsDir()) // test it;
- winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
- return winAttributes;
+ if (IsDir()) // test it;
+ winAttrib |= FILE_ATTRIBUTE_DIRECTORY;
+ return winAttrib;
+}
+
+bool CItem::GetPosixAttrib(UInt32 &attrib) const
+{
+ // some archivers can store PosixAttrib in high 16 bits even with HostOS=FAT.
+ if (FromCentral && MadeByVersion.HostOS == NFileHeader::NHostOS::kUnix)
+ {
+ attrib = ExternalAttributes >> 16;
+ return (attrib != 0);
+ }
+ attrib = 0;
+ if (IsDir())
+ attrib = NFileHeader::NUnixAttribute::kIFDIR;
+ return false;
}
void CLocalItem::SetFlagBits(int startBitNumber, int numBits, int value)
diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
index 31f2de73..5efd433a 100755
--- a/CPP/7zip/Archive/Zip/ZipItem.h
+++ b/CPP/7zip/Archive/Zip/ZipItem.h
@@ -3,7 +3,6 @@
#ifndef __ARCHIVE_ZIP_ITEM_H
#define __ARCHIVE_ZIP_ITEM_H
-#include "Common/Types.h"
#include "Common/MyString.h"
#include "Common/Buffer.h"
#include "Common/UTFConvert.h"
@@ -28,7 +27,7 @@ struct CExtraSubBlock
UInt16 ID;
CByteBuffer Data;
bool ExtractNtfsTime(int index, FILETIME &ft) const;
- bool ExtractUnixTime(int index, UInt32 &res) const;
+ bool ExtractUnixTime(bool isCentral, int index, UInt32 &res) const;
};
struct CWzAesExtraField
@@ -152,13 +151,13 @@ struct CExtraBlock
return false;
}
- bool GetUnixTime(int index, UInt32 &res) const
+ bool GetUnixTime(bool isCentral, int index, UInt32 &res) const
{
for (int i = 0; i < SubBlocks.Size(); i++)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
- return sb.ExtractUnixTime(index, res);
+ return sb.ExtractUnixTime(isCentral, index, res);
}
return false;
}
@@ -205,7 +204,6 @@ public:
bool IsDir() const;
bool IgnoreItem() const { return false; }
- UInt32 GetWinAttributes() const;
bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; }
@@ -252,7 +250,8 @@ public:
bool NtfsTimeIsDefined;
bool IsDir() const;
- UInt32 GetWinAttributes() const;
+ UInt32 GetWinAttrib() const;
+ bool GetPosixAttrib(UInt32 &attrib) const;
bool IsThereCrc() const
{
@@ -277,5 +276,3 @@ public:
}}
#endif
-
-
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
index d4fdee3d..490d9e26 100755
--- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
@@ -473,6 +473,9 @@ static HRESULT Update2St(
items.Add(item);
lps->ProgressOffset += NFileHeader::kLocalBlockSize;
}
+ lps->InSize = unpackSizeTotal;
+ lps->OutSize = packSizeTotal;
+ RINOK(lps->SetCur());
archive.WriteCentralDir(items, comment);
return S_OK;
}
@@ -493,7 +496,7 @@ static HRESULT Update2(
UInt64 numBytesToCompress = 0;
int i;
- for(i = 0; i < updateItems.Size(); i++)
+ for (i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &ui = updateItems[i];
if (ui.NewData)
@@ -527,6 +530,10 @@ static HRESULT Update2(
complexity = 0;
+ CCompressionMethodMode options2;
+ if (options != 0)
+ options2 = *options;
+
#ifndef _7ZIP_ST
const size_t kNumMaxThreads = (1 << 10);
@@ -537,53 +544,58 @@ static HRESULT Update2(
const size_t kMemPerThread = (1 << 25);
const size_t kBlockSize = 1 << 16;
- CCompressionMethodMode options2;
- if (options != 0)
- options2 = *options;
-
bool mtMode = ((options != 0) && (numThreads > 1));
if (numFilesToCompress <= 1)
mtMode = false;
- if (mtMode)
+ if (!mtMode)
+ {
+ if (numThreads < 2)
+ if (options2.MethodInfo.FindProp(NCoderPropID::kNumThreads) < 0 &&
+ options2.NumThreadsWasChanged)
+ options2.MethodInfo.AddNumThreadsProp(1);
+ }
+ else
{
Byte method = options->MethodSequence.Front();
if (method == NFileHeader::NCompressionMethod::kStored && !options->PasswordIsDefined)
- mtMode = false;
+ numThreads = 1;
if (method == NFileHeader::NCompressionMethod::kBZip2)
{
- UInt64 averageSize = numBytesToCompress / numFilesToCompress;
- UInt32 blockSize = options->DicSize;
- if (blockSize == 0)
- blockSize = 1;
- UInt64 averageNumberOfBlocks = averageSize / blockSize;
- UInt32 numBZip2Threads = 32;
- if (averageNumberOfBlocks < numBZip2Threads)
- numBZip2Threads = (UInt32)averageNumberOfBlocks;
- if (numBZip2Threads < 1)
- numBZip2Threads = 1;
- numThreads = numThreads / numBZip2Threads;
- options2.NumThreads = numBZip2Threads;
- if (numThreads <= 1)
- mtMode = false;
+ bool fixedNumber;
+ UInt32 numBZip2Threads = options2.MethodInfo.Get_BZip2_NumThreads(fixedNumber);
+ if (!fixedNumber)
+ {
+ UInt64 averageSize = numBytesToCompress / numFilesToCompress;
+ UInt32 blockSize = options2.MethodInfo.Get_BZip2_BlockSize();
+ UInt64 averageNumberOfBlocks = averageSize / blockSize + 1;
+ numBZip2Threads = 32;
+ if (averageNumberOfBlocks < numBZip2Threads)
+ numBZip2Threads = (UInt32)averageNumberOfBlocks;
+ options2.MethodInfo.AddNumThreadsProp(numBZip2Threads);
+ }
+ numThreads /= numBZip2Threads;
}
if (method == NFileHeader::NCompressionMethod::kLZMA)
{
- UInt32 numLZMAThreads = (options->Algo > 0 ? 2 : 1);
+ bool fixedNumber;
+ // we suppose that default LZMA is 2 thread. So we don't change it
+ UInt32 numLZMAThreads = options2.MethodInfo.Get_Lzma_NumThreads(fixedNumber);
numThreads /= numLZMAThreads;
- options2.NumThreads = numLZMAThreads;
- if (numThreads <= 1)
- mtMode = false;
}
+ if (numThreads > numFilesToCompress)
+ numThreads = (UInt32)numFilesToCompress;
+ if (numThreads <= 1)
+ mtMode = false;
}
if (!mtMode)
#endif
return Update2St(
EXTERNAL_CODECS_LOC_VARS
- archive, inArchive,inStream,
- inputItems, updateItems, options, comment, updateCallback);
+ archive, inArchive, inStream,
+ inputItems, updateItems, &options2, comment, updateCallback);
#ifndef _7ZIP_ST
@@ -606,7 +618,7 @@ static HRESULT Update2(
{
RINOK(memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize)));
- for(i = 0; i < updateItems.Size(); i++)
+ for (i = 0; i < updateItems.Size(); i++)
refs.Refs.Add(CMemBlocks2());
UInt32 i;
@@ -796,6 +808,7 @@ static HRESULT Update2(
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
itemIndex++;
}
+ RINOK(mtCompressProgressMixer.SetRatioInfo(0, NULL, NULL));
archive.WriteCentralDir(items, comment);
return S_OK;
#endif