summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp')
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp425
1 files changed, 299 insertions, 126 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
index 2b86ed26ab7..ff8735f0f7e 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
@@ -13,16 +13,19 @@
#include "7zOut.h"
#include "7zUpdate.h"
+#ifndef Z7_EXTRACT_ONLY
+
using namespace NWindows;
namespace NArchive {
namespace N7z {
-static const char *k_LZMA_Name = "LZMA";
-static const char *kDefaultMethodName = "LZMA2";
-static const char *k_Copy_Name = "Copy";
+#define k_LZMA_Name "LZMA"
+#define kDefaultMethodName "LZMA2"
+#define k_Copy_Name "Copy"
+
+#define k_MatchFinder_ForHeaders "BT2"
-static const char *k_MatchFinder_ForHeaders = "BT2";
static const UInt32 k_NumFastBytes_ForHeaders = 273;
static const UInt32 k_Level_ForHeaders = 5;
static const UInt32 k_Dictionary_ForHeaders =
@@ -32,7 +35,7 @@ static const UInt32 k_Dictionary_ForHeaders =
1 << 20;
#endif
-STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
+Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type))
{
*type = NFileTimeType::kWindows;
return S_OK;
@@ -40,9 +43,12 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
{
- if (!FindMethod(
+ bool isFilter;
+ dest.CodecIndex = FindMethod_Index(
EXTERNAL_CODECS_VARS
- m.MethodName, dest.Id, dest.NumStreams))
+ m.MethodName, true,
+ dest.Id, dest.NumStreams, isFilter);
+ if (dest.CodecIndex < 0)
return E_INVALIDARG;
(CProps &)dest = (CProps &)m;
return S_OK;
@@ -64,15 +70,12 @@ HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
return PropsMethod_To_FullMethod(methodFull, m);
}
-HRESULT CHandler::SetMainMethod(
- CCompressionMethodMode &methodMode
- #ifndef _7ZIP_ST
- , UInt32 numThreads
- #endif
- )
+
+HRESULT CHandler::SetMainMethod(CCompressionMethodMode &methodMode)
{
methodMode.Bonds = _bonds;
+ // we create local copy of _methods. So we can modify it.
CObjectVector<COneMethodInfo> methods = _methods;
{
@@ -106,60 +109,200 @@ HRESULT CHandler::SetMainMethod(
}
const UInt64 kSolidBytes_Min = (1 << 24);
- const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
+ const UInt64 kSolidBytes_Max = ((UInt64)1 << 32);
bool needSolid = false;
FOR_VECTOR (i, methods)
{
COneMethodInfo &oneMethodInfo = methods[i];
- SetGlobalLevelAndThreads(oneMethodInfo
- #ifndef _7ZIP_ST
- , numThreads
- #endif
- );
+
+ SetGlobalLevelTo(oneMethodInfo);
+
+ #ifndef Z7_ST
+ const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0);
+ if (!numThreads_WasSpecifiedInMethod)
+ {
+ // here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already
+ CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, methodMode.NumThreads);
+ }
+ #endif
CMethodFull &methodFull = methodMode.Methods.AddNew();
- RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
+ RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo))
+
+ #ifndef Z7_ST
+ methodFull.Set_NumThreads = true;
+ methodFull.NumThreads = methodMode.NumThreads;
+ #endif
if (methodFull.Id != k_Copy)
needSolid = true;
- if (_numSolidBytesDefined)
- continue;
-
- UInt32 dicSize;
+ UInt64 dicSize;
switch (methodFull.Id)
{
case k_LZMA:
case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break;
case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break;
case k_Deflate: dicSize = (UInt32)1 << 15; break;
+ case k_Deflate64: dicSize = (UInt32)1 << 16; break;
case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
+ // case k_ZSTD: dicSize = 1 << 23; break;
default: continue;
}
-
- _numSolidBytes = (UInt64)dicSize << 7;
- if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
- if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
+
+ UInt64 numSolidBytes;
+
+ /*
+ if (methodFull.Id == k_ZSTD)
+ {
+ // continue;
+ NCompress::NZstd::CEncoderProps encoderProps;
+ RINOK(oneMethodInfo.Set_PropsTo_zstd(encoderProps));
+ CZstdEncProps &zstdProps = encoderProps.EncProps;
+ ZstdEncProps_NormalizeFull(&zstdProps);
+ UInt64 cs = (UInt64)(zstdProps.jobSize);
+ UInt32 winSize = (UInt32)(1 << zstdProps.windowLog);
+ if (cs < winSize)
+ cs = winSize;
+ numSolidBytes = cs << 6;
+ const UInt64 kSolidBytes_Zstd_Max = ((UInt64)1 << 34);
+ if (numSolidBytes > kSolidBytes_Zstd_Max)
+ numSolidBytes = kSolidBytes_Zstd_Max;
+
+ methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder
+
+ #ifndef Z7_ST
+ if (!numThreads_WasSpecifiedInMethod
+ && !methodMode.NumThreads_WasForced
+ && methodMode.MemoryUsageLimit_WasSet
+ )
+ {
+ const UInt32 numThreads_Original = methodMode.NumThreads;
+ const UInt32 numThreads_New = ZstdEncProps_GetNumThreads_for_MemUsageLimit(
+ &zstdProps,
+ methodMode.MemoryUsageLimit,
+ numThreads_Original);
+ if (numThreads_Original != numThreads_New)
+ {
+ CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New);
+ }
+ }
+ #endif
+ }
+ else
+ */
+ if (methodFull.Id == k_LZMA2)
+ {
+ // he we calculate default chunk Size for LZMA2 as defined in LZMA2 encoder code
+ /* lzma2 code use dictionary up to fake 4 GiB to calculate ChunkSize.
+ So we do same */
+ UInt64 cs = (UInt64)dicSize << 2;
+ const UInt32 kMinSize = (UInt32)1 << 20;
+ const UInt32 kMaxSize = (UInt32)1 << 28;
+ if (cs < kMinSize) cs = kMinSize;
+ if (cs > kMaxSize) cs = kMaxSize;
+ if (cs < dicSize) cs = dicSize;
+ cs += (kMinSize - 1);
+ cs &= ~(UInt64)(kMinSize - 1);
+ // we want to use at least 64 chunks (threads) per one solid block.
+
+ // here we don't use chunkSize property
+ numSolidBytes = cs << 6;
+
+ // here we get real chunkSize
+ cs = oneMethodInfo.Get_Xz_BlockSize();
+ if (dicSize > cs)
+ dicSize = cs;
+
+ const UInt64 kSolidBytes_Lzma2_Max = ((UInt64)1 << 34);
+ if (numSolidBytes > kSolidBytes_Lzma2_Max)
+ numSolidBytes = kSolidBytes_Lzma2_Max;
+
+ methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder
+
+ #ifndef Z7_ST
+ if (!numThreads_WasSpecifiedInMethod
+ && !methodMode.NumThreads_WasForced
+ && methodMode.MemoryUsageLimit_WasSet
+ )
+ {
+ const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads();
+ const UInt32 numBlockThreads_Original = methodMode.NumThreads / lzmaThreads;
+
+ if (numBlockThreads_Original > 1)
+ {
+ /*
+ const UInt32 kNumThreads_Max = 1024;
+ if (numBlockThreads > kNumMaxThreads)
+ numBlockThreads = kNumMaxThreads;
+ */
+
+ UInt32 numBlockThreads = numBlockThreads_Original;
+ const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false); // solid
+
+ for (; numBlockThreads > 1; numBlockThreads--)
+ {
+ UInt64 size = numBlockThreads * (lzmaMemUsage + cs);
+ UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1;
+ if (cs < ((UInt32)1 << 26)) numPackChunks++;
+ if (cs < ((UInt32)1 << 24)) numPackChunks++;
+ if (cs < ((UInt32)1 << 22)) numPackChunks++;
+ size += numPackChunks * cs;
+ // printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20));
+ if (size <= methodMode.MemoryUsageLimit)
+ break;
+ }
+
+ if (numBlockThreads == 0)
+ numBlockThreads = 1;
+ if (numBlockThreads != numBlockThreads_Original)
+ {
+ const UInt32 numThreads_New = numBlockThreads * lzmaThreads;
+ CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New);
+ }
+ }
+ }
+ #endif
+ }
+ else
+ {
+ numSolidBytes = (UInt64)dicSize << 7;
+ if (numSolidBytes > kSolidBytes_Max)
+ numSolidBytes = kSolidBytes_Max;
+ }
+
+ if (_numSolidBytesDefined)
+ continue;
+
+ if (numSolidBytes < kSolidBytes_Min)
+ numSolidBytes = kSolidBytes_Min;
+ _numSolidBytes = numSolidBytes;
_numSolidBytesDefined = true;
}
if (!_numSolidBytesDefined)
+ {
if (needSolid)
_numSolidBytes = kSolidBytes_Max;
else
_numSolidBytes = 0;
+ }
_numSolidBytesDefined = true;
+
+
return S_OK;
}
-static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, UInt64 &ft, bool &ftDefined)
+
+
+static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, unsigned index, PROPID propID, UInt64 &ft, bool &ftDefined)
{
// ft = 0;
// ftDefined = false;
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(index, propID, &prop));
+ RINOK(updateCallback->GetProperty(index, propID, &prop))
if (prop.vt == VT_FILETIME)
{
ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32);
@@ -242,13 +385,13 @@ static int AddFolder(CObjectVector<CTreeFolder> &treeFolders, int cur, const USt
}
*/
-STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
- IArchiveUpdateCallback *updateCallback)
+Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback))
{
COM_TRY_BEGIN
- const CDbEx *db = 0;
- #ifdef _7Z_VOL
+ const CDbEx *db = NULL;
+ #ifdef Z7_7Z_VOL
if (_volumes.Size() > 1)
return E_FAIL;
const CVolume *volume = 0;
@@ -258,13 +401,17 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
db = &volume->Database;
}
#else
- if (_inStream != 0)
+ if (_inStream)
db = &_db;
#endif
+ if (db && !db->CanUpdate())
+ return E_NOTIMPL;
+
/*
- CMyComPtr<IArchiveGetRawProps> getRawProps;
- updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps);
+ Z7_DECL_CMyComPtr_QI_FROM(
+ IArchiveGetRawProps,
+ getRawProps, updateCallback)
CUniqBlocks secureBlocks;
secureBlocks.AddUniq(NULL, 0);
@@ -279,18 +426,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CObjectVector<CUpdateItem> updateItems;
- bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
- bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
- bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
+ bool need_CTime = (TimeOptions.Write_CTime.Def && TimeOptions.Write_CTime.Val);
+ bool need_ATime = (TimeOptions.Write_ATime.Def && TimeOptions.Write_ATime.Val);
+ bool need_MTime = (TimeOptions.Write_MTime.Def ? TimeOptions.Write_MTime.Val : true);
+ bool need_Attrib = (Write_Attrib.Def ? Write_Attrib.Val : true);
if (db && !db->Files.IsEmpty())
{
- if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
- if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
- if (!Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
+ if (!TimeOptions.Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
+ if (!TimeOptions.Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
+ if (!TimeOptions.Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
+ if (!Write_Attrib.Def) need_Attrib = !db->Attrib.Defs.IsEmpty();
}
- UString s;
+ // UString s;
+ UString name;
for (UInt32 i = 0; i < numItems; i++)
{
@@ -298,45 +448,46 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
UInt32 indexInArchive;
if (!updateCallback)
return E_FAIL;
- RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive));
+ RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive))
CUpdateItem ui;
ui.NewProps = IntToBool(newProps);
ui.NewData = IntToBool(newData);
- ui.IndexInArchive = indexInArchive;
+ ui.IndexInArchive = (int)indexInArchive;
ui.IndexInClient = i;
ui.IsAnti = false;
ui.Size = 0;
- UString name;
+ name.Empty();
// bool isAltStream = false;
if (ui.IndexInArchive != -1)
{
- if (db == 0 || (unsigned)ui.IndexInArchive >= db->Files.Size())
+ if (!db || (unsigned)ui.IndexInArchive >= db->Files.Size())
return E_INVALIDARG;
- const CFileItem &fi = db->Files[ui.IndexInArchive];
+ const CFileItem &fi = db->Files[(unsigned)ui.IndexInArchive];
if (!ui.NewProps)
{
- _db.GetPath(ui.IndexInArchive, name);
+ _db.GetPath((unsigned)ui.IndexInArchive, name);
}
ui.IsDir = fi.IsDir;
ui.Size = fi.Size;
// isAltStream = fi.IsAltStream;
- ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
+ ui.IsAnti = db->IsItemAnti((unsigned)ui.IndexInArchive);
if (!ui.NewProps)
{
- ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
- ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
- ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
+ ui.CTimeDefined = db->CTime.GetItem((unsigned)ui.IndexInArchive, ui.CTime);
+ ui.ATimeDefined = db->ATime.GetItem((unsigned)ui.IndexInArchive, ui.ATime);
+ ui.MTimeDefined = db->MTime.GetItem((unsigned)ui.IndexInArchive, ui.MTime);
}
}
if (ui.NewProps)
{
bool folderStatusIsDefined;
+ if (need_Attrib)
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
+ RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop))
if (prop.vt == VT_EMPTY)
ui.AttribDefined = false;
else if (prop.vt != VT_UI4)
@@ -349,9 +500,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
// we need MTime to sort files.
- if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined));
- if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined));
- if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined));
+ if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined))
+ if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined))
+ if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined))
/*
if (getRawProps)
@@ -369,7 +520,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
+ RINOK(updateCallback->GetProperty(i, kpidPath, &prop))
if (prop.vt == VT_EMPTY)
{
}
@@ -377,12 +528,13 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
else
{
- name = NItemName::MakeLegalName(prop.bstrVal);
+ name = prop.bstrVal;
+ NItemName::ReplaceSlashes_OsToUnix(name);
}
}
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop));
+ RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop))
if (prop.vt == VT_EMPTY)
folderStatusIsDefined = false;
else if (prop.vt != VT_BOOL)
@@ -396,7 +548,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop));
+ RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop))
if (prop.vt == VT_EMPTY)
ui.IsAnti = false;
else if (prop.vt != VT_BOOL)
@@ -513,7 +665,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (!ui.IsDir)
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
+ RINOK(updateCallback->GetProperty(i, kpidSize, &prop))
if (prop.vt != VT_UI8)
return E_INVALIDARG;
ui.Size = (UInt64)prop.uhVal.QuadPart;
@@ -537,32 +689,39 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CCompressionMethodMode methodMode, headerMethod;
- HRESULT res = SetMainMethod(methodMode
- #ifndef _7ZIP_ST
- , _numThreads
- #endif
- );
- RINOK(res);
+ methodMode.MemoryUsageLimit = _memUsage_Compress;
+ methodMode.MemoryUsageLimit_WasSet = _memUsage_WasSet;
- RINOK(SetHeaderMethod(headerMethod));
-
- #ifndef _7ZIP_ST
- methodMode.NumThreads = _numThreads;
- methodMode.MultiThreadMixer = _useMultiThreadMixer;
- headerMethod.NumThreads = 1;
- headerMethod.MultiThreadMixer = _useMultiThreadMixer;
+ #ifndef Z7_ST
+ {
+ UInt32 numThreads = _numThreads;
+ const UInt32 kNumThreads_Max = 1024;
+ if (numThreads > kNumThreads_Max)
+ numThreads = kNumThreads_Max;
+ methodMode.NumThreads = numThreads;
+ methodMode.NumThreads_WasForced = _numThreads_WasForced;
+ methodMode.MultiThreadMixer = _useMultiThreadMixer;
+ // headerMethod.NumThreads = 1;
+ headerMethod.MultiThreadMixer = _useMultiThreadMixer;
+ }
#endif
- CMyComPtr<ICryptoGetTextPassword2> getPassword2;
- updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2);
+ const HRESULT res = SetMainMethod(methodMode);
+ RINOK(res)
+
+ RINOK(SetHeaderMethod(headerMethod))
+
+ Z7_DECL_CMyComPtr_QI_FROM(
+ ICryptoGetTextPassword2,
+ getPassword2, updateCallback)
methodMode.PasswordIsDefined = false;
- methodMode.Password.Empty();
+ methodMode.Password.Wipe_and_Empty();
if (getPassword2)
{
- CMyComBSTR password;
+ CMyComBSTR_Wipe password;
Int32 passwordIsDefined;
- RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));
+ RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password))
methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
if (methodMode.PasswordIsDefined && password)
methodMode.Password = password;
@@ -572,7 +731,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
bool encryptHeaders = false;
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
if (!methodMode.PasswordIsDefined && _passwordIsDefined)
{
// if header is compressed, we use that password for updated archive
@@ -585,7 +744,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
if (_encryptHeadersSpecified)
encryptHeaders = _encryptHeaders;
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
else
encryptHeaders = _passwordIsDefined;
#endif
@@ -600,9 +759,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (numItems < 2)
compressMainHeader = false;
- int level = GetLevel();
+ const int level = GetLevel();
CUpdateOptions options;
+ options.Need_CTime = need_CTime;
+ options.Need_ATime = need_ATime;
+ options.Need_MTime = need_MTime;
+ options.Need_Attrib = need_Attrib;
+ // options.Need_Crc = (_crcSize != 0); // for debug
+
options.Method = &methodMode;
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : NULL;
options.UseFilters = (level != 0 && _autoFilter && !methodMode.Filter_was_Inserted);
@@ -614,6 +779,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.HeaderOptions.WriteCTime = Write_CTime;
options.HeaderOptions.WriteATime = Write_ATime;
options.HeaderOptions.WriteMTime = Write_MTime;
+ options.HeaderOptions.WriteAttrib = Write_Attrib;
*/
options.NumSolidFiles = _numSolidFiles;
@@ -626,12 +792,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.MultiThreadMixer = _useMultiThreadMixer;
- COutArchive archive;
- CArchiveDatabaseOut newDatabase;
-
- CMyComPtr<ICryptoGetTextPassword> getPassword;
- updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword);
-
/*
if (secureBlocks.Sorted.Size() > 1)
{
@@ -644,9 +804,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
*/
- res = Update(
+ return Update(
EXTERNAL_CODECS_VARS
- #ifdef _7Z_VOL
+ #ifdef Z7_7Z_VOL
volume ? volume->Stream: 0,
volume ? db : 0,
#else
@@ -656,18 +816,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
updateItems,
// treeFolders,
// secureBlocks,
- archive, newDatabase, outStream, updateCallback, options
- #ifndef _NO_CRYPTO
- , getPassword
- #endif
- );
-
- RINOK(res);
-
- updateItems.ClearAndFree();
-
- return archive.WriteDatabase(EXTERNAL_CODECS_VARS
- newDatabase, options.HeaderMethod, options.HeaderOptions);
+ outStream, updateCallback, options);
COM_TRY_END
}
@@ -676,7 +825,7 @@ static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
{
stream = 0;
{
- unsigned index = ParseStringToUInt32(srcString, coder);
+ const unsigned index = ParseStringToUInt32(srcString, coder);
if (index == 0)
return E_INVALIDARG;
srcString.DeleteFrontal(index);
@@ -684,7 +833,7 @@ static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
if (srcString[0] == 's')
{
srcString.Delete(0);
- unsigned index = ParseStringToUInt32(srcString, stream);
+ const unsigned index = ParseStringToUInt32(srcString, stream);
if (index == 0)
return E_INVALIDARG;
srcString.DeleteFrontal(index);
@@ -692,19 +841,16 @@ static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
return S_OK;
}
-void COutHandler::InitProps()
+void COutHandler::InitProps7z()
{
- CMultiMethodProps::Init();
-
_removeSfxBlock = false;
_compressHeaders = true;
_encryptHeadersSpecified = false;
_encryptHeaders = false;
// _useParents = false;
- Write_CTime.Init();
- Write_ATime.Init();
- Write_MTime.Init();
+ TimeOptions.Init();
+ Write_Attrib.Init();
_useMultiThreadMixer = true;
@@ -714,6 +860,14 @@ void COutHandler::InitProps()
_useTypeSorting = false;
}
+void COutHandler::InitProps()
+{
+ CMultiMethodProps::Init();
+ InitProps7z();
+}
+
+
+
HRESULT COutHandler::SetSolidFromString(const UString &s)
{
UString s2 = s;
@@ -730,10 +884,10 @@ HRESULT COutHandler::SetSolidFromString(const UString &s)
_solidExtension = true;
continue;
}
- i += (int)(end - start);
+ i += (unsigned)(end - start);
if (i == s2.Len())
return E_INVALIDARG;
- wchar_t c = s2[i++];
+ const wchar_t c = s2[i++];
if (c == 'f')
{
if (v < 1)
@@ -754,6 +908,10 @@ HRESULT COutHandler::SetSolidFromString(const UString &s)
}
_numSolidBytes = (v << numBits);
_numSolidBytesDefined = true;
+ /*
+ if (_numSolidBytes == 0)
+ _numSolidFiles = 1;
+ */
}
}
return S_OK;
@@ -781,7 +939,7 @@ HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value)
static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest)
{
- RINOK(PROPVARIANT_to_bool(prop, dest.Val));
+ RINOK(PROPVARIANT_to_bool(prop, dest.Val))
dest.Def = true;
return S_OK;
}
@@ -802,9 +960,9 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
return E_INVALIDARG;
return SetSolidFromString(name);
}
-
+
UInt32 number;
- int index = ParseStringToUInt32(name, number);
+ const unsigned index = ParseStringToUInt32(name, number);
// UString realName = name.Ptr(index);
if (index == 0)
{
@@ -815,20 +973,32 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
if (name.IsEqualTo("hcf"))
{
bool compressHeadersFull = true;
- RINOK(PROPVARIANT_to_bool(value, compressHeadersFull));
+ RINOK(PROPVARIANT_to_bool(value, compressHeadersFull))
return compressHeadersFull ? S_OK: E_INVALIDARG;
}
if (name.IsEqualTo("he"))
{
- RINOK(PROPVARIANT_to_bool(value, _encryptHeaders));
+ RINOK(PROPVARIANT_to_bool(value, _encryptHeaders))
_encryptHeadersSpecified = true;
return S_OK;
}
- if (name.IsEqualTo("tc")) return PROPVARIANT_to_BoolPair(value, Write_CTime);
- if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
- if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
+ {
+ bool processed;
+ RINOK(TimeOptions.Parse(name, value, processed))
+ if (processed)
+ {
+ if ( TimeOptions.Prec != (UInt32)(Int32)-1
+ && TimeOptions.Prec != k_PropVar_TimePrec_0
+ && TimeOptions.Prec != k_PropVar_TimePrec_HighPrec
+ && TimeOptions.Prec != k_PropVar_TimePrec_100ns)
+ return E_INVALIDARG;
+ return S_OK;
+ }
+ }
+
+ if (name.IsEqualTo("tr")) return PROPVARIANT_to_BoolPair(value, Write_Attrib);
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
@@ -839,7 +1009,7 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
return CMultiMethodProps::SetProperty(name, value);
}
-STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
+Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
{
COM_TRY_BEGIN
_bonds.Clear();
@@ -854,6 +1024,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
const PROPVARIANT &value = values[i];
+ if (name.Find(L':') >= 0) // 'b' was used as NCoderPropID::kBlockSize2 before v23
if (name[0] == 'b')
{
if (value.vt != VT_EMPTY)
@@ -861,12 +1032,12 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
name.Delete(0);
CBond2 bond;
- RINOK(ParseBond(name, bond.OutCoder, bond.OutStream));
+ RINOK(ParseBond(name, bond.OutCoder, bond.OutStream))
if (name[0] != ':')
return E_INVALIDARG;
name.Delete(0);
UInt32 inStream = 0;
- RINOK(ParseBond(name, bond.InCoder, inStream));
+ RINOK(ParseBond(name, bond.InCoder, inStream))
if (inStream != 0)
return E_INVALIDARG;
if (!name.IsEmpty())
@@ -875,7 +1046,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
continue;
}
- RINOK(SetProperty(name, value));
+ RINOK(SetProperty(name, value))
}
unsigned numEmptyMethods = GetNumEmptyMethods();
@@ -911,3 +1082,5 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
}
}}
+
+#endif