ZipUpdate.cpp (p7zip_15.14.1_src_all) | : | ZipUpdate.cpp (p7zip_16.02_src_all) | ||
---|---|---|---|---|
skipping to change at line 55 | skipping to change at line 55 | |||
static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored ; | static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored ; | |||
static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, UInt64 size, | static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, UInt64 size, | |||
COutArchive &outArchive, ICompressProgressInfo *progress) | COutArchive &outArchive, ICompressProgressInfo *progress) | |||
{ | { | |||
CMyComPtr<ISequentialOutStream> outStream; | CMyComPtr<ISequentialOutStream> outStream; | |||
outArchive.CreateStreamForCopying(&outStream); | outArchive.CreateStreamForCopying(&outStream); | |||
return NCompress::CopyStream_ExactSize(inStream, outStream, size, progress); | return NCompress::CopyStream_ExactSize(inStream, outStream, size, progress); | |||
} | } | |||
static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive, | ||||
const CUpdateRange &range, ICompressProgressInfo *progress) | ||||
{ | ||||
UInt64 position; | ||||
RINOK(inStream->Seek(range.Position, STREAM_SEEK_SET, &position)); | ||||
RINOK(CopyBlockToArchive(inStream, range.Size, outArchive, progress)); | ||||
return progress->SetRatioInfo(&range.Size, &range.Size); | ||||
} | ||||
static void SetFileHeader( | static void SetFileHeader( | |||
COutArchive &archive, | COutArchive &archive, | |||
const CCompressionMethodMode &options, | const CCompressionMethodMode &options, | |||
const CUpdateItem &ui, | const CUpdateItem &ui, | |||
// bool isSeqMode, | // bool isSeqMode, | |||
CItemOut &item) | CItemOut &item) | |||
{ | { | |||
item.Size = ui.Size; | item.Size = ui.Size; | |||
bool isDir; | bool isDir; | |||
skipping to change at line 356 | skipping to change at line 347 | |||
NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc, | NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc, | |||
NUpdateNotifyOp::kReplicate)) | NUpdateNotifyOp::kReplicate)) | |||
} | } | |||
if (ui.NewProps) | if (ui.NewProps) | |||
{ | { | |||
if (item.HasDescriptor()) | if (item.HasDescriptor()) | |||
return E_NOTIMPL; | return E_NOTIMPL; | |||
// use old name size. | // use old name size. | |||
// CUpdateRange range(item.GetLocalExtraPosition(), item.LocalExtraSize + it | ||||
em.PackSize); | CMyComPtr<ISequentialInStream> packStream; | |||
CUpdateRange range(inArchive->GetOffsetInStream(itemEx.GetDataPosition()), i | RINOK(inArchive->GetItemStream(itemEx, true, packStream)); | |||
temEx.PackSize); | if (!packStream) | |||
return E_NOTIMPL; | ||||
// we keep ExternalAttrib and some another properties from old archive | // we keep ExternalAttrib and some another properties from old archive | |||
// item.ExternalAttrib = ui.Attrib; | // item.ExternalAttrib = ui.Attrib; | |||
item.Name = ui.Name; | item.Name = ui.Name; | |||
item.SetUtf8(ui.IsUtf8); | item.SetUtf8(ui.IsUtf8); | |||
item.Time = ui.Time; | item.Time = ui.Time; | |||
item.Ntfs_MTime = ui.Ntfs_MTime; | item.Ntfs_MTime = ui.Ntfs_MTime; | |||
item.Ntfs_ATime = ui.Ntfs_ATime; | item.Ntfs_ATime = ui.Ntfs_ATime; | |||
item.Ntfs_CTime = ui.Ntfs_CTime; | item.Ntfs_CTime = ui.Ntfs_CTime; | |||
item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; | item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; | |||
item.CentralExtra.RemoveUnknownSubBlocks(); | item.CentralExtra.RemoveUnknownSubBlocks(); | |||
item.LocalExtra.RemoveUnknownSubBlocks(); | item.LocalExtra.RemoveUnknownSubBlocks(); | |||
item.LocalHeaderPos = archive.GetCurPos(); | item.LocalHeaderPos = archive.GetCurPos(); | |||
archive.PrepareWriteCompressedData2(item.Name.Len(), item.Size, item.PackSiz e, item.LocalExtra.HasWzAes()); | archive.PrepareWriteCompressedData2(item.Name.Len(), item.Size, item.PackSiz e, item.LocalExtra.HasWzAes()); | |||
archive.WriteLocalHeader(item); | archive.WriteLocalHeader(item); | |||
RINOK(WriteRange(inArchive->Stream, archive, range, progress)); | ||||
complexity += range.Size; | RINOK(CopyBlockToArchive(packStream, itemEx.PackSize, archive, progress)); | |||
complexity += itemEx.PackSize; | ||||
} | } | |||
else | else | |||
{ | { | |||
CUpdateRange range(inArchive->GetOffsetInStream(itemEx.LocalHeaderPos), item | CMyComPtr<ISequentialInStream> packStream; | |||
Ex.GetLocalFullSize()); | RINOK(inArchive->GetItemStream(itemEx, false, packStream)); | |||
if (!packStream) | ||||
return E_NOTIMPL; | ||||
// set new header position | // set new header position | |||
item.LocalHeaderPos = archive.GetCurPos(); | item.LocalHeaderPos = archive.GetCurPos(); | |||
RINOK(WriteRange(inArchive->Stream, archive, range, progress)); | const UInt64 rangeSize = itemEx.GetLocalFullSize(); | |||
complexity += range.Size; | ||||
archive.MoveCurPos(range.Size); | RINOK(CopyBlockToArchive(packStream, rangeSize, archive, progress)); | |||
complexity += rangeSize; | ||||
archive.MoveCurPos(rangeSize); | ||||
} | } | |||
return S_OK; | return S_OK; | |||
} | } | |||
static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *o ptions, | static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *o ptions, | |||
const CUpdateItem &ui, CItemOut &item) | const CUpdateItem &ui, CItemOut &item) | |||
{ | { | |||
SetFileHeader(archive, *options, ui, item); | SetFileHeader(archive, *options, ui, item); | |||
archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, | archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, | |||
skipping to change at line 589 | skipping to change at line 591 | |||
IArchiveUpdateCallback *updateCallback) | IArchiveUpdateCallback *updateCallback) | |||
{ | { | |||
CMyComPtr<IArchiveUpdateCallbackFile> opCallback; | CMyComPtr<IArchiveUpdateCallbackFile> opCallback; | |||
updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCal lback); | updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCal lback); | |||
UInt64 complexity = 0; | UInt64 complexity = 0; | |||
UInt64 numFilesToCompress = 0; | UInt64 numFilesToCompress = 0; | |||
UInt64 numBytesToCompress = 0; | UInt64 numBytesToCompress = 0; | |||
unsigned i; | unsigned i; | |||
for (i = 0; i < updateItems.Size(); i++) | for (i = 0; i < updateItems.Size(); i++) | |||
{ | { | |||
const CUpdateItem &ui = updateItems[i]; | const CUpdateItem &ui = updateItems[i]; | |||
if (ui.NewData) | if (ui.NewData) | |||
{ | { | |||
complexity += ui.Size; | complexity += ui.Size; | |||
numBytesToCompress += ui.Size; | numBytesToCompress += ui.Size; | |||
numFilesToCompress++; | numFilesToCompress++; | |||
/* | /* | |||
if (ui.Commented) | if (ui.Commented) | |||
skipping to change at line 729 | skipping to change at line 732 | |||
CThreads threads; | CThreads threads; | |||
CRecordVector<HANDLE> compressingCompletedEvents; | CRecordVector<HANDLE> compressingCompletedEvents; | |||
CUIntVector threadIndices; // list threads in order of updateItems | CUIntVector threadIndices; // list threads in order of updateItems | |||
{ | { | |||
RINOK(memManager.AllocateSpaceAlways(&synchroForOutStreamSpec,(size_t)numThr eads * (kMemPerThread / kBlockSize))); | RINOK(memManager.AllocateSpaceAlways(&synchroForOutStreamSpec,(size_t)numThr eads * (kMemPerThread / kBlockSize))); | |||
for (i = 0; i < updateItems.Size(); i++) | for (i = 0; i < updateItems.Size(); i++) | |||
refs.Refs.Add(CMemBlocks2()); | refs.Refs.Add(CMemBlocks2()); | |||
UInt32 i; | ||||
for (i = 0; i < numThreads; i++) | for (i = 0; i < numThreads; i++) | |||
threads.Threads.Add(CThreadInfo(options2)); | threads.Threads.Add(CThreadInfo(options2)); | |||
for (i = 0; i < numThreads; i++) | for (i = 0; i < numThreads; i++) | |||
{ | { | |||
CThreadInfo &threadInfo = threads.Threads[i]; | CThreadInfo &threadInfo = threads.Threads[i]; | |||
#ifdef EXTERNAL_CODECS | #ifdef EXTERNAL_CODECS | |||
threadInfo.__externalCodecs = __externalCodecs; | threadInfo.__externalCodecs = __externalCodecs; | |||
#endif | #endif | |||
RINOK(threadInfo.CreateEvents(&synchroForCompressingCompletedEvents)); | RINOK(threadInfo.CreateEvents(&synchroForCompressingCompletedEvents)); | |||
skipping to change at line 802 | skipping to change at line 804 | |||
refs.Refs[mtItemIndex - 1].Skip = true; | refs.Refs[mtItemIndex - 1].Skip = true; | |||
continue; | continue; | |||
} | } | |||
RINOK(res); | RINOK(res); | |||
if (!fileInStream) | if (!fileInStream) | |||
return E_INVALIDARG; | return E_INVALIDARG; | |||
UpdatePropsFromStream(ui, fileInStream, updateCallback, totalComplexity) ; | UpdatePropsFromStream(ui, fileInStream, updateCallback, totalComplexity) ; | |||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationRe sult::kOK)); | RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationRe sult::kOK)); | |||
} | } | |||
for (UInt32 i = 0; i < numThreads; i++) | for (UInt32 k = 0; k < numThreads; k++) | |||
{ | { | |||
CThreadInfo &threadInfo = threads.Threads[i]; | CThreadInfo &threadInfo = threads.Threads[k]; | |||
if (threadInfo.IsFree) | if (threadInfo.IsFree) | |||
{ | { | |||
threadInfo.IsFree = false; | threadInfo.IsFree = false; | |||
threadInfo.InStream = fileInStream; | threadInfo.InStream = fileInStream; | |||
// !!!!! we must release ref before sending event | // !!!!! we must release ref before sending event | |||
// BUG was here in v4.43 and v4.44. It could change ref counter in two threads in same time | // BUG was here in v4.43 and v4.44. It could change ref counter in two threads in same time | |||
fileInStream.Release(); | fileInStream.Release(); | |||
threadInfo.OutStreamSpec->Init(); | threadInfo.OutStreamSpec->Init(); | |||
threadInfo.ProgressSpec->Reinit(); | threadInfo.ProgressSpec->Reinit(); | |||
threadInfo.CompressEvent.Set(); | threadInfo.CompressEvent.Set(); | |||
threadInfo.UpdateIndex = mtItemIndex - 1; | threadInfo.UpdateIndex = mtItemIndex - 1; | |||
compressingCompletedEvents.Add(threadInfo.CompressionCompletedEvent); | compressingCompletedEvents.Add(threadInfo.CompressionCompletedEvent); | |||
threadIndices.Add(i); | threadIndices.Add(k); | |||
break; | break; | |||
} | } | |||
} | } | |||
continue; | continue; | |||
} | } | |||
if (refs.Refs[itemIndex].Skip) | if (refs.Refs[itemIndex].Skip) | |||
{ | { | |||
itemIndex++; | itemIndex++; | |||
skipping to change at line 926 | skipping to change at line 928 | |||
{ | { | |||
RINOK(threadInfo.OutStreamSpec->WriteToRealStream()); | RINOK(threadInfo.OutStreamSpec->WriteToRealStream()); | |||
threadInfo.OutStreamSpec->ReleaseOutStream(); | threadInfo.OutStreamSpec->ReleaseOutStream(); | |||
SetFileHeader(archive, *options, ui, item); | SetFileHeader(archive, *options, ui, item); | |||
SetItemInfoFromCompressingResult(threadInfo.CompressingResult, | SetItemInfoFromCompressingResult(threadInfo.CompressingResult, | |||
options->IsRealAesMode(), options->AesKeyMode, item); | options->IsRealAesMode(), options->AesKeyMode, item); | |||
archive.WriteLocalHeader_And_SeekToNextFile(item); | archive.WriteLocalHeader_And_SeekToNextFile(item); | |||
} | } | |||
else | else | |||
{ | { | |||
CMemBlocks2 &memRef = refs.Refs[threadInfo.UpdateIndex]; | CMemBlocks2 &memRef2 = refs.Refs[threadInfo.UpdateIndex]; | |||
threadInfo.OutStreamSpec->DetachData(memRef); | threadInfo.OutStreamSpec->DetachData(memRef2); | |||
memRef.CompressingResult = threadInfo.CompressingResult; | memRef2.CompressingResult = threadInfo.CompressingResult; | |||
memRef.Defined = true; | memRef2.Defined = true; | |||
continue; | continue; | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
else | else | |||
{ | { | |||
RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, op Callback, complexity)); | RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, op Callback, complexity)); | |||
} | } | |||
skipping to change at line 1188 | skipping to change at line 1190 | |||
CMyComPtr<IOutStream> outStream; | CMyComPtr<IOutStream> outStream; | |||
{ | { | |||
CMyComPtr<IOutStream> outStreamReal; | CMyComPtr<IOutStream> outStreamReal; | |||
seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStreamReal); | seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStreamReal); | |||
if (!outStreamReal) | if (!outStreamReal) | |||
return E_NOTIMPL; | return E_NOTIMPL; | |||
if (inArchive) | if (inArchive) | |||
{ | { | |||
if (inArchive->ArcInfo.Base > 0 && !removeSfx) | if (!inArchive->IsMultiVol && inArchive->ArcInfo.Base > 0 && !removeSfx) | |||
{ | { | |||
RINOK(inArchive->Stream->Seek(0, STREAM_SEEK_SET, NULL)); | IInStream *baseStream = inArchive->GetBaseStream(); | |||
RINOK(NCompress::CopyStream_ExactSize(inArchive->Stream, outStreamReal, | RINOK(baseStream->Seek(0, STREAM_SEEK_SET, NULL)); | |||
inArchive->ArcInfo.Base, NULL)); | RINOK(NCompress::CopyStream_ExactSize(baseStream, outStreamReal, inArchi | |||
ve->ArcInfo.Base, NULL)); | ||||
} | } | |||
} | } | |||
CCacheOutStream *cacheStream = new CCacheOutStream(); | CCacheOutStream *cacheStream = new CCacheOutStream(); | |||
outStream = cacheStream; | outStream = cacheStream; | |||
if (!cacheStream->Allocate()) | if (!cacheStream->Allocate()) | |||
return E_OUTOFMEMORY; | return E_OUTOFMEMORY; | |||
RINOK(cacheStream->Init(outStreamReal)); | RINOK(cacheStream->Init(outStreamReal)); | |||
} | } | |||
COutArchive outArchive; | COutArchive outArchive; | |||
RINOK(outArchive.Create(outStream)); | RINOK(outArchive.Create(outStream)); | |||
if (inArchive) | if (inArchive) | |||
{ | { | |||
if ((Int64)inArchive->ArcInfo.MarkerPos2 > inArchive->ArcInfo.Base) | if (!inArchive->IsMultiVol && (Int64)inArchive->ArcInfo.MarkerPos2 > inArchi ve->ArcInfo.Base) | |||
{ | { | |||
RINOK(inArchive->Stream->Seek(inArchive->ArcInfo.Base, STREAM_SEEK_SET, NU | IInStream *baseStream = inArchive->GetBaseStream(); | |||
LL)); | RINOK(baseStream->Seek(inArchive->ArcInfo.Base, STREAM_SEEK_SET, NULL)); | |||
UInt64 embStubSize = inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Ba se; | UInt64 embStubSize = inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Ba se; | |||
RINOK(NCompress::CopyStream_ExactSize(inArchive->Stream, outStream, embStu bSize, NULL)); | RINOK(NCompress::CopyStream_ExactSize(baseStream, outStream, embStubSize, NULL)); | |||
outArchive.MoveCurPos(embStubSize); | outArchive.MoveCurPos(embStubSize); | |||
} | } | |||
} | } | |||
return Update2( | return Update2( | |||
EXTERNAL_CODECS_LOC_VARS | EXTERNAL_CODECS_LOC_VARS | |||
outArchive, inArchive, | outArchive, inArchive, | |||
inputItems, updateItems, | inputItems, updateItems, | |||
compressionMethodMode, | compressionMethodMode, | |||
inArchive ? &inArchive->ArcInfo.Comment : NULL, | inArchive ? &inArchive->ArcInfo.Comment : NULL, | |||
End of changes. 16 change blocks. | ||||
36 lines changed or deleted | 36 lines changed or added |