diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2015-08-16 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:55 +0300 |
commit | cba375916fb18db8b9101aedf4fa079e019311b3 (patch) | |
tree | 6275ae5fc2a8dd337ab0327180c871807e6ba5d4 /CPP/7zip/Archive/Tar | |
parent | 54490d51d5c6b0d794dcbad2d634d4c95fc25b6c (diff) |
15.0615.06
Diffstat (limited to 'CPP/7zip/Archive/Tar')
-rw-r--r-- | CPP/7zip/Archive/Tar/TarHandlerOut.cpp | 24 | ||||
-rw-r--r-- | CPP/7zip/Archive/Tar/TarUpdate.cpp | 24 | ||||
-rw-r--r-- | CPP/7zip/Archive/Tar/TarUpdate.h | 7 |
3 files changed, 45 insertions, 10 deletions
diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp index ae005ac5..8dd99869 100644 --- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp +++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp @@ -29,11 +29,13 @@ HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID pro { NCOM::CPropVariant prop; RINOK(callback->GetProperty(index, propId, &prop)); + if (prop.vt == VT_BSTR) { UString s = prop.bstrVal; if (convertSlash) s = NItemName::MakeLegalName(s); + if (codePage == CP_UTF8) { ConvertUnicodeToUTF8(s, res); @@ -44,9 +46,11 @@ HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID pro } else if (prop.vt != VT_EMPTY) return E_INVALIDARG; + return S_OK; } + // sort old files with original order. static int CompareUpdateItems(void *const *p1, void *const *p2, void *) @@ -57,33 +61,39 @@ static int CompareUpdateItems(void *const *p1, void *const *p2, void *) { if (u2.NewProps) return -1; - return MyCompare(u1.IndexInArchive, u2.IndexInArchive); + return MyCompare(u1.IndexInArc, u2.IndexInArc); } if (!u2.NewProps) return 1; return MyCompare(u1.IndexInClient, u2.IndexInClient); } + STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *callback) { COM_TRY_BEGIN + if ((_stream && (_error != k_ErrorType_OK /* || _isSparse */)) || _seqStream) return E_NOTIMPL; CObjectVector<CUpdateItem> updateItems; UINT codePage = (_forceCodePage ? _specifiedCodePage : _openCodePage); + for (UInt32 i = 0; i < numItems; i++) { CUpdateItem ui; Int32 newData; Int32 newProps; - UInt32 indexInArchive; + UInt32 indexInArc; + if (!callback) return E_FAIL; - RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); + + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)); + ui.NewProps = IntToBool(newProps); ui.NewData = IntToBool(newData); - ui.IndexInArchive = indexInArchive; + ui.IndexInArc = indexInArc; ui.IndexInClient = i; if (IntToBool(newProps)) @@ -109,6 +119,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt else ui.Mode = prop.ulVal; } + { NCOM::CPropVariant prop; RINOK(callback->GetProperty(i, kpidMTime, &prop)); @@ -119,6 +130,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt else ui.MTime = NTime::FileTimeToUnixTime64(prop.filetime); } + RINOK(GetPropString(callback, i, kpidPath, ui.Name, codePage, true)); if (ui.IsDir && !ui.Name.IsEmpty() && ui.Name.Back() != '/') ui.Name += '/'; @@ -139,14 +151,18 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt return E_INVALIDARG; */ } + updateItems.Add(ui); } + if (_thereIsPaxExtendedHeader) { // we restore original order of files, if there is pax header block updateItems.Sort(CompareUpdateItems, NULL); } + return UpdateArchive(_stream, outStream, _items, updateItems, codePage, callback); + COM_TRY_END } diff --git a/CPP/7zip/Archive/Tar/TarUpdate.cpp b/CPP/7zip/Archive/Tar/TarUpdate.cpp index 3adbdee9..0cdb30d1 100644 --- a/CPP/7zip/Archive/Tar/TarUpdate.cpp +++ b/CPP/7zip/Archive/Tar/TarUpdate.cpp @@ -43,7 +43,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, if (ui.NewData) complexity += ui.Size; else - complexity += inputItems[ui.IndexInArchive].GetFullSize(); + complexity += inputItems[ui.IndexInArc].GetFullSize(); } RINOK(updateCallback->SetTotal(complexity)); @@ -68,12 +68,14 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, const CUpdateItem &ui = updateItems[i]; CItem item; + if (ui.NewProps) { item.Mode = ui.Mode; item.Name = ui.Name; item.User = ui.User; item.Group = ui.Group; + if (ui.IsDir) { item.LinkFlag = NFileHeader::NLinkFlag::kDirectory; @@ -84,6 +86,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, item.LinkFlag = NFileHeader::NLinkFlag::kNormal; item.PackSize = ui.Size; } + item.MTime = ui.MTime; item.DeviceMajorDefined = false; item.DeviceMinorDefined = false; @@ -92,7 +95,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, memcpy(item.Magic, NFileHeader::NMagic::kUsTar_00, 8); } else - item = inputItems[ui.IndexInArchive]; + item = inputItems[ui.IndexInArc]; AString symLink; if (ui.NewData || ui.NewProps) @@ -116,6 +119,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, CMyComPtr<ISequentialInStream> fileInStream; bool needWrite = true; + if (!symLink.IsEmpty()) { item.PackSize = 0; @@ -124,6 +128,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, else { HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); + if (res == S_FALSE) needWrite = false; else @@ -141,10 +146,17 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, if (getProps->GetProps(&size2, NULL, NULL, &mTime, NULL) == S_OK) { item.PackSize = size2; + item.Size = size2; item.MTime = NWindows::NTime::FileTimeToUnixTime64(mTime);; } } } + else + { + item.PackSize = 0; + item.Size = 0; + } + { AString hardLink; RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidHardLink, hardLink, codePage, true)); @@ -183,13 +195,15 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, RINOK(outArchive.FillDataResidual(item.PackSize)); } } + complexity += item.PackSize; RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); } else { - const CItemEx &existItem = inputItems[ui.IndexInArchive]; + const CItemEx &existItem = inputItems[ui.IndexInArc]; UInt64 size; + if (ui.NewProps) { // memcpy(item.Magic, NFileHeader::NMagic::kEmpty, 8); @@ -225,12 +239,13 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, RINOK(inStream->Seek(existItem.HeaderPos, STREAM_SEEK_SET, NULL)); size = existItem.GetFullSize(); } + streamSpec->Init(size); if (opCallback) { RINOK(opCallback->ReportOperation( - NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArchive, + NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc, NUpdateNotifyOp::kReplicate)) } @@ -242,6 +257,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, complexity += size; } } + lps->InSize = lps->OutSize = complexity; RINOK(lps->SetCur()); return outArchive.WriteFinishHeader(); diff --git a/CPP/7zip/Archive/Tar/TarUpdate.h b/CPP/7zip/Archive/Tar/TarUpdate.h index c2393416..b758635f 100644 --- a/CPP/7zip/Archive/Tar/TarUpdate.h +++ b/CPP/7zip/Archive/Tar/TarUpdate.h @@ -4,6 +4,7 @@ #define __TAR_UPDATE_H #include "../IArchive.h" + #include "TarItem.h" namespace NArchive { @@ -11,10 +12,10 @@ namespace NTar { struct CUpdateItem { - int IndexInArchive; + int IndexInArc; int IndexInClient; - Int64 MTime; UInt64 Size; + Int64 MTime; UInt32 Mode; bool NewData; bool NewProps; @@ -22,6 +23,8 @@ struct CUpdateItem AString Name; AString User; AString Group; + + CUpdateItem(): Size(0), IsDir(false) {} }; HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, |