mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-16 04:11:49 -06:00
Update to 7-Zip Version 22.00
See: https://sourceforge.net/p/sevenzip/discussion/45797/thread/9c2d9061ce/
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
// #include <stdio.h>
|
||||
|
||||
#include "../../../Windows/TimeUtils.h"
|
||||
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
@@ -15,18 +17,161 @@
|
||||
namespace NArchive {
|
||||
namespace NTar {
|
||||
|
||||
static void FILETIME_To_PaxTime(const FILETIME &ft, CPaxTime &pt)
|
||||
{
|
||||
UInt32 ns;
|
||||
pt.Sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(ft, ns);
|
||||
pt.Ns = ns * 100;
|
||||
pt.NumDigits = 7;
|
||||
}
|
||||
|
||||
|
||||
HRESULT Prop_To_PaxTime(const NWindows::NCOM::CPropVariant &prop, CPaxTime &pt)
|
||||
{
|
||||
pt.Clear();
|
||||
if (prop.vt == VT_EMPTY)
|
||||
{
|
||||
// pt.Sec = 0;
|
||||
return S_OK;
|
||||
}
|
||||
if (prop.vt != VT_FILETIME)
|
||||
return E_INVALIDARG;
|
||||
{
|
||||
UInt32 ns;
|
||||
pt.Sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(prop.filetime, ns);
|
||||
ns *= 100;
|
||||
pt.NumDigits = 7;
|
||||
const unsigned prec = prop.wReserved1;
|
||||
if (prec >= k_PropVar_TimePrec_Base)
|
||||
{
|
||||
pt.NumDigits = prec - k_PropVar_TimePrec_Base;
|
||||
if (prop.wReserved2 < 100)
|
||||
ns += prop.wReserved2;
|
||||
}
|
||||
pt.Ns = ns;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static HRESULT GetTime(IStreamGetProp *getProp, UInt32 pid, CPaxTime &pt)
|
||||
{
|
||||
pt.Clear();
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
RINOK(getProp->GetProperty(pid, &prop));
|
||||
return Prop_To_PaxTime(prop, pt);
|
||||
}
|
||||
|
||||
|
||||
static HRESULT GetUser(IStreamGetProp *getProp,
|
||||
UInt32 pidName, UInt32 pidId, AString &name, UInt32 &id,
|
||||
UINT codePage, unsigned utfFlags)
|
||||
{
|
||||
// printf("\nGetUser\n");
|
||||
// we keep old values, if both GetProperty() return VT_EMPTY
|
||||
// we clear old values, if any of GetProperty() returns non-VT_EMPTY;
|
||||
bool isSet = false;
|
||||
{
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
RINOK(getProp->GetProperty(pidId, &prop));
|
||||
if (prop.vt == VT_UI4)
|
||||
{
|
||||
isSet = true;
|
||||
id = prop.ulVal;
|
||||
name.Empty();
|
||||
}
|
||||
else if (prop.vt != VT_EMPTY)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
{
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
RINOK(getProp->GetProperty(pidName, &prop));
|
||||
if (prop.vt == VT_BSTR)
|
||||
{
|
||||
const UString s = prop.bstrVal;
|
||||
Get_AString_From_UString(s, name, codePage, utfFlags);
|
||||
// printf("\ngetProp->GetProperty(pidName, &prop) : %s" , name.Ptr());
|
||||
if (!isSet)
|
||||
id = 0;
|
||||
}
|
||||
else if (prop.vt == VT_UI4)
|
||||
{
|
||||
id = prop.ulVal;
|
||||
name.Empty();
|
||||
}
|
||||
else if (prop.vt != VT_EMPTY)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
static HRESULT GetDevice(IStreamGetProp *getProp,
|
||||
UInt32 &majo, UInt32 &mino, bool &majo_defined, bool &mino_defined)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
RINOK(getProp->GetProperty(kpidDevice, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
return S_OK;
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
{
|
||||
printf("\nTarUpdate.cpp :: GetDevice()\n");
|
||||
const UInt64 v = prop.uhVal.QuadPart;
|
||||
majo = MY_dev_major(v);
|
||||
mino = MY_dev_minor(v);
|
||||
majo_defined = true;
|
||||
mino_defined = true;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
static HRESULT GetDevice(IStreamGetProp *getProp,
|
||||
UInt32 pid, UInt32 &id, bool &defined)
|
||||
{
|
||||
defined = false;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
RINOK(getProp->GetProperty(pid, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
return S_OK;
|
||||
if (prop.vt == VT_UI4)
|
||||
{
|
||||
id = prop.ulVal;
|
||||
defined = true;
|
||||
return S_OK;
|
||||
}
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
|
||||
HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
const CObjectVector<NArchive::NTar::CItemEx> &inputItems,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
UINT codePage, unsigned utfFlags,
|
||||
const CUpdateOptions &options,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
COutArchive outArchive;
|
||||
outArchive.Create(outStream);
|
||||
outArchive.Pos = 0;
|
||||
outArchive.IsPosixMode = options.PosixMode;
|
||||
outArchive.TimeOptions = options.TimeOptions;
|
||||
|
||||
CMyComPtr<IOutStream> outSeekStream;
|
||||
outStream->QueryInterface(IID_IOutStream, (void **)&outSeekStream);
|
||||
if (outSeekStream)
|
||||
{
|
||||
/*
|
||||
// for debug
|
||||
Byte buf[1 << 14];
|
||||
memset (buf, 0, sizeof(buf));
|
||||
RINOK(outStream->Write(buf, sizeof(buf), NULL));
|
||||
*/
|
||||
// we need real outArchive.Pos, if outSeekStream->SetSize() will be used.
|
||||
RINOK(outSeekStream->Seek(0, STREAM_SEEK_CUR, &outArchive.Pos));
|
||||
}
|
||||
|
||||
|
||||
CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
|
||||
updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
|
||||
@@ -40,7 +185,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
if (ui.NewData)
|
||||
complexity += ui.Size;
|
||||
else
|
||||
complexity += inputItems[(unsigned)ui.IndexInArc].GetFullSize();
|
||||
complexity += inputItems[(unsigned)ui.IndexInArc].Get_FullSize_Aligned();
|
||||
}
|
||||
|
||||
RINOK(updateCallback->SetTotal(complexity));
|
||||
@@ -58,21 +203,31 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
|
||||
complexity = 0;
|
||||
|
||||
for (i = 0; i < updateItems.Size(); i++)
|
||||
// const int kNumReduceDigits = -1; // for debug
|
||||
|
||||
for (i = 0;; i++)
|
||||
{
|
||||
lps->InSize = lps->OutSize = complexity;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
if (i == updateItems.Size())
|
||||
return outArchive.WriteFinishHeader();
|
||||
|
||||
const CUpdateItem &ui = updateItems[i];
|
||||
CItem item;
|
||||
|
||||
if (ui.NewProps)
|
||||
{
|
||||
item.SetDefaultWriteFields();
|
||||
item.Mode = ui.Mode;
|
||||
item.SetMagic_Posix(options.PosixMode);
|
||||
item.Name = ui.Name;
|
||||
item.User = ui.User;
|
||||
item.Group = ui.Group;
|
||||
item.UID = ui.UID;
|
||||
item.GID = ui.GID;
|
||||
item.DeviceMajor = ui.DeviceMajor;
|
||||
item.DeviceMinor = ui.DeviceMinor;
|
||||
item.DeviceMajor_Defined = ui.DeviceMajor_Defined;
|
||||
item.DeviceMinor_Defined = ui.DeviceMinor_Defined;
|
||||
|
||||
if (ui.IsDir)
|
||||
{
|
||||
@@ -81,11 +236,15 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
}
|
||||
else
|
||||
{
|
||||
item.LinkFlag = NFileHeader::NLinkFlag::kNormal;
|
||||
item.PackSize = ui.Size;
|
||||
item.Set_LinkFlag_for_File(ui.Mode);
|
||||
}
|
||||
|
||||
item.MTime = ui.MTime;
|
||||
|
||||
// 22.00
|
||||
item.Mode = ui.Mode & ~(UInt32)MY_LIN_S_IFMT;
|
||||
item.PaxTimes = ui.PaxTimes;
|
||||
// item.PaxTimes.ReducePrecison(kNumReduceDigits); // for debug
|
||||
item.MTime = ui.PaxTimes.MTime.GetSec();
|
||||
}
|
||||
else
|
||||
item = inputItems[(unsigned)ui.IndexInArc];
|
||||
@@ -93,7 +252,8 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
AString symLink;
|
||||
if (ui.NewData || ui.NewProps)
|
||||
{
|
||||
RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidSymLink, symLink, codePage, utfFlags, true));
|
||||
RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidSymLink, symLink,
|
||||
options.CodePage, options.UtfFlags, true));
|
||||
if (!symLink.IsEmpty())
|
||||
{
|
||||
item.LinkFlag = NFileHeader::NLinkFlag::kSymLink;
|
||||
@@ -120,7 +280,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
}
|
||||
else
|
||||
{
|
||||
HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream);
|
||||
const HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream);
|
||||
|
||||
if (res == S_FALSE)
|
||||
needWrite = false;
|
||||
@@ -128,31 +288,105 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
{
|
||||
RINOK(res);
|
||||
|
||||
if (fileInStream)
|
||||
{
|
||||
CMyComPtr<IStreamGetProps> getProps;
|
||||
fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps);
|
||||
if (getProps)
|
||||
{
|
||||
FILETIME mTime;
|
||||
UInt64 size2;
|
||||
if (getProps->GetProps(&size2, NULL, NULL, &mTime, NULL) == S_OK)
|
||||
{
|
||||
item.PackSize = size2;
|
||||
item.Size = size2;
|
||||
item.MTime = NWindows::NTime::FileTimeToUnixTime64(mTime);;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!fileInStream)
|
||||
{
|
||||
item.PackSize = 0;
|
||||
item.Size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
CMyComPtr<IStreamGetProps> getProps;
|
||||
CMyComPtr<IStreamGetProp> getProp;
|
||||
fileInStream->QueryInterface(IID_IStreamGetProp, (void **)&getProp);
|
||||
if (getProp)
|
||||
{
|
||||
if (options.Write_MTime.Val) RINOK(GetTime(getProp, kpidMTime, item.PaxTimes.MTime))
|
||||
if (options.Write_ATime.Val) RINOK(GetTime(getProp, kpidATime, item.PaxTimes.ATime))
|
||||
if (options.Write_CTime.Val) RINOK(GetTime(getProp, kpidCTime, item.PaxTimes.CTime))
|
||||
|
||||
if (options.PosixMode)
|
||||
{
|
||||
/*
|
||||
RINOK(GetDevice(getProp, item.DeviceMajor, item.DeviceMinor,
|
||||
item.DeviceMajor_Defined, item.DeviceMinor_Defined));
|
||||
*/
|
||||
bool defined = false;
|
||||
UInt32 val = 0;
|
||||
RINOK(GetDevice(getProp, kpidDeviceMajor, val, defined));
|
||||
if (defined)
|
||||
{
|
||||
item.DeviceMajor = val;
|
||||
item.DeviceMajor_Defined = true;
|
||||
item.DeviceMinor = 0;
|
||||
item.DeviceMinor_Defined = false;
|
||||
RINOK(GetDevice(getProp, kpidDeviceMinor, item.DeviceMinor, item.DeviceMinor_Defined));
|
||||
}
|
||||
}
|
||||
|
||||
RINOK(GetUser(getProp, kpidUser, kpidUserId, item.User, item.UID, options.CodePage, options.UtfFlags));
|
||||
RINOK(GetUser(getProp, kpidGroup, kpidGroupId, item.Group, item.GID, options.CodePage, options.UtfFlags));
|
||||
|
||||
{
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
RINOK(getProp->GetProperty(kpidPosixAttrib, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
item.Mode =
|
||||
MY_LIN_S_IRWXO
|
||||
| MY_LIN_S_IRWXG
|
||||
| MY_LIN_S_IRWXU
|
||||
| (ui.IsDir ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG);
|
||||
else if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
item.Mode = prop.ulVal;
|
||||
// 21.07 : we clear high file type bits as GNU TAR.
|
||||
item.Set_LinkFlag_for_File(item.Mode);
|
||||
item.Mode &= ~(UInt32)MY_LIN_S_IFMT;
|
||||
}
|
||||
|
||||
{
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
RINOK(getProp->GetProperty(kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
const UInt64 size = prop.uhVal.QuadPart;
|
||||
item.PackSize = size;
|
||||
item.Size = size;
|
||||
}
|
||||
/*
|
||||
printf("\nNum digits = %d %d\n",
|
||||
(int)item.PaxTimes.MTime.NumDigits,
|
||||
(int)item.PaxTimes.MTime.Ns);
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps);
|
||||
if (getProps)
|
||||
{
|
||||
FILETIME mTime, aTime, cTime;
|
||||
UInt64 size2;
|
||||
if (getProps->GetProps(&size2,
|
||||
options.Write_CTime.Val ? &cTime : NULL,
|
||||
options.Write_ATime.Val ? &aTime : NULL,
|
||||
options.Write_MTime.Val ? &mTime : NULL,
|
||||
NULL) == S_OK)
|
||||
{
|
||||
item.PackSize = size2;
|
||||
item.Size = size2;
|
||||
if (options.Write_MTime.Val) FILETIME_To_PaxTime(mTime, item.PaxTimes.MTime);
|
||||
if (options.Write_ATime.Val) FILETIME_To_PaxTime(aTime, item.PaxTimes.ATime);
|
||||
if (options.Write_CTime.Val) FILETIME_To_PaxTime(cTime, item.PaxTimes.CTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// we must request kpidHardLink after updateCallback->GetStream()
|
||||
AString hardLink;
|
||||
RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidHardLink, hardLink, codePage, utfFlags, true));
|
||||
RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidHardLink, hardLink,
|
||||
options.CodePage, options.UtfFlags, true));
|
||||
if (!hardLink.IsEmpty())
|
||||
{
|
||||
item.LinkFlag = NFileHeader::NLinkFlag::kHardLink;
|
||||
@@ -165,37 +399,98 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
}
|
||||
}
|
||||
|
||||
// item.PaxTimes.ReducePrecison(kNumReduceDigits); // for debug
|
||||
|
||||
if (ui.NewProps)
|
||||
item.MTime = item.PaxTimes.MTime.GetSec();
|
||||
|
||||
if (needWrite)
|
||||
{
|
||||
UInt64 fileHeaderStartPos = outArchive.Pos;
|
||||
const UInt64 headerPos = outArchive.Pos;
|
||||
// item.PackSize = ((UInt64)1 << 33); // for debug
|
||||
RINOK(outArchive.WriteHeader(item));
|
||||
if (fileInStream)
|
||||
{
|
||||
RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress));
|
||||
outArchive.Pos += copyCoderSpec->TotalSize;
|
||||
if (copyCoderSpec->TotalSize != item.PackSize)
|
||||
for (unsigned numPasses = 0;; numPasses++)
|
||||
{
|
||||
/* we support 2 attempts to write header:
|
||||
pass-0: main pass:
|
||||
pass-1: additional pass, if size_of_file and size_of_header are changed */
|
||||
if (numPasses >= 2)
|
||||
{
|
||||
// opRes = NArchive::NUpdate::NOperationResult::kError_FileChanged;
|
||||
// break;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
const UInt64 dataPos = outArchive.Pos;
|
||||
RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress));
|
||||
outArchive.Pos += copyCoderSpec->TotalSize;
|
||||
RINOK(outArchive.Write_AfterDataResidual(copyCoderSpec->TotalSize));
|
||||
|
||||
// if (numPasses >= 10) // for debug
|
||||
if (copyCoderSpec->TotalSize == item.PackSize)
|
||||
break;
|
||||
|
||||
if (opCallback)
|
||||
{
|
||||
RINOK(opCallback->ReportOperation(
|
||||
NEventIndexType::kOutArcIndex, (UInt32)ui.IndexInClient,
|
||||
NUpdateNotifyOp::kInFileChanged))
|
||||
}
|
||||
|
||||
if (!outSeekStream)
|
||||
return E_FAIL;
|
||||
UInt64 backOffset = outArchive.Pos - fileHeaderStartPos;
|
||||
RINOK(outSeekStream->Seek(-(Int64)backOffset, STREAM_SEEK_CUR, NULL));
|
||||
outArchive.Pos = fileHeaderStartPos;
|
||||
const UInt64 nextPos = outArchive.Pos;
|
||||
RINOK(outSeekStream->Seek(-(Int64)(nextPos - headerPos), STREAM_SEEK_CUR, NULL));
|
||||
outArchive.Pos = headerPos;
|
||||
item.PackSize = copyCoderSpec->TotalSize;
|
||||
|
||||
RINOK(outArchive.WriteHeader(item));
|
||||
RINOK(outSeekStream->Seek((Int64)item.PackSize, STREAM_SEEK_CUR, NULL));
|
||||
outArchive.Pos += item.PackSize;
|
||||
|
||||
// if (numPasses >= 10) // for debug
|
||||
if (outArchive.Pos == dataPos)
|
||||
{
|
||||
const UInt64 alignedSize = nextPos - dataPos;
|
||||
if (alignedSize != 0)
|
||||
{
|
||||
RINOK(outSeekStream->Seek(alignedSize, STREAM_SEEK_CUR, NULL));
|
||||
outArchive.Pos += alignedSize;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// size of header was changed.
|
||||
// we remove data after header and try new attempt, if required
|
||||
CMyComPtr<IInStream> fileSeekStream;
|
||||
fileInStream->QueryInterface(IID_IInStream, (void **)&fileSeekStream);
|
||||
if (!fileSeekStream)
|
||||
return E_FAIL;
|
||||
RINOK(fileSeekStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
RINOK(outSeekStream->SetSize(outArchive.Pos));
|
||||
if (item.PackSize == 0)
|
||||
break;
|
||||
}
|
||||
RINOK(outArchive.FillDataResidual(item.PackSize));
|
||||
}
|
||||
}
|
||||
|
||||
complexity += item.PackSize;
|
||||
fileInStream.Release();
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
}
|
||||
else
|
||||
{
|
||||
// (ui.NewData == false)
|
||||
|
||||
if (opCallback)
|
||||
{
|
||||
RINOK(opCallback->ReportOperation(
|
||||
NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc,
|
||||
NUpdateNotifyOp::kReplicate))
|
||||
}
|
||||
|
||||
const CItemEx &existItem = inputItems[(unsigned)ui.IndexInArc];
|
||||
UInt64 size;
|
||||
UInt64 size, pos;
|
||||
|
||||
if (ui.NewProps)
|
||||
{
|
||||
@@ -216,44 +511,37 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
item.PackSize = existItem.PackSize;
|
||||
}
|
||||
|
||||
item.DeviceMajorDefined = existItem.DeviceMajorDefined;
|
||||
item.DeviceMinorDefined = existItem.DeviceMinorDefined;
|
||||
item.DeviceMajor_Defined = existItem.DeviceMajor_Defined;
|
||||
item.DeviceMinor_Defined = existItem.DeviceMinor_Defined;
|
||||
item.DeviceMajor = existItem.DeviceMajor;
|
||||
item.DeviceMinor = existItem.DeviceMinor;
|
||||
item.UID = existItem.UID;
|
||||
item.GID = existItem.GID;
|
||||
|
||||
RINOK(outArchive.WriteHeader(item));
|
||||
RINOK(inStream->Seek((Int64)existItem.GetDataPosition(), STREAM_SEEK_SET, NULL));
|
||||
size = existItem.PackSize;
|
||||
size = existItem.Get_PackSize_Aligned();
|
||||
pos = existItem.Get_DataPos();
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(inStream->Seek((Int64)existItem.HeaderPos, STREAM_SEEK_SET, NULL));
|
||||
size = existItem.GetFullSize();
|
||||
size = existItem.Get_FullSize_Aligned();
|
||||
pos = existItem.HeaderPos;
|
||||
}
|
||||
|
||||
streamSpec->Init(size);
|
||||
|
||||
if (opCallback)
|
||||
if (size != 0)
|
||||
{
|
||||
RINOK(opCallback->ReportOperation(
|
||||
NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc,
|
||||
NUpdateNotifyOp::kReplicate))
|
||||
RINOK(inStream->Seek((Int64)pos, STREAM_SEEK_SET, NULL));
|
||||
streamSpec->Init(size);
|
||||
// 22.00 : we copy Residual data from old archive to new archive instead of zeroing
|
||||
RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
|
||||
if (copyCoderSpec->TotalSize != size)
|
||||
return E_FAIL;
|
||||
outArchive.Pos += size;
|
||||
// RINOK(outArchive.Write_AfterDataResidual(existItem.PackSize));
|
||||
complexity += size;
|
||||
}
|
||||
|
||||
RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
|
||||
if (copyCoderSpec->TotalSize != size)
|
||||
return E_FAIL;
|
||||
outArchive.Pos += size;
|
||||
RINOK(outArchive.FillDataResidual(existItem.PackSize));
|
||||
complexity += size;
|
||||
}
|
||||
}
|
||||
|
||||
lps->InSize = lps->OutSize = complexity;
|
||||
RINOK(lps->SetCur());
|
||||
return outArchive.WriteFinishHeader();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user