From 8457830abdca9d5769e2ec1bdbfb793a05e6c5dd Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Mon, 21 Feb 2011 16:30:31 +0100 Subject: init commit --- .../unix/CPP/7zip/UI/Agent/AgentProxy.cpp | 246 +++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/AgentProxy.cpp (limited to 'installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/AgentProxy.cpp') diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/AgentProxy.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/AgentProxy.cpp new file mode 100644 index 000000000..9686cf345 --- /dev/null +++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/AgentProxy.cpp @@ -0,0 +1,246 @@ +// AgentProxy.cpp + +#include "StdAfx.h" + +#include "../../../../C/Sort.h" + +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" + +#include "../Common/OpenArchive.h" + +#include "AgentProxy.h" + +using namespace NWindows; + +int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const +{ + int left = 0, right = Folders.Size(); + for (;;) + { + if (left == right) + { + insertPos = left; + return -1; + } + int mid = (left + right) / 2; + int compare = name.CompareNoCase(Folders[mid].Name); + if (compare == 0) + return mid; + if (compare < 0) + right = mid; + else + left = mid + 1; + } +} + +int CProxyFolder::FindDirSubItemIndex(const UString &name) const +{ + int insertPos; + return FindDirSubItemIndex(name, insertPos); +} + +void CProxyFolder::AddFileSubItem(UInt32 index, const UString &name) +{ + Files.Add(CProxyFile()); + Files.Back().Name = name; + Files.Back().Index = index; +} + +CProxyFolder* CProxyFolder::AddDirSubItem(UInt32 index, bool leaf, const UString &name) +{ + int insertPos; + int folderIndex = FindDirSubItemIndex(name, insertPos); + if (folderIndex >= 0) + { + CProxyFolder *item = &Folders[folderIndex]; + if (leaf) + { + item->Index = index; + item->IsLeaf = true; + } + return item; + } + Folders.Insert(insertPos, CProxyFolder()); + CProxyFolder *item = &Folders[insertPos]; + item->Name = name; + item->Index = index; + item->Parent = this; + item->IsLeaf = leaf; + return item; +} + +void CProxyFolder::Clear() +{ + Folders.Clear(); + Files.Clear(); +} + +void CProxyFolder::GetPathParts(UStringVector &pathParts) const +{ + pathParts.Clear(); + UString result; + const CProxyFolder *current = this; + while (current->Parent != NULL) + { + pathParts.Insert(0, (const wchar_t *)current->Name); + current = current->Parent; + } +} + +UString CProxyFolder::GetFullPathPrefix() const +{ + UString result; + const CProxyFolder *current = this; + while (current->Parent != NULL) + { + result = current->Name + UString(WCHAR_PATH_SEPARATOR) + result; + current = current->Parent; + } + return result; +} + +UString CProxyFolder::GetItemName(UInt32 index) const +{ + if (index < (UInt32)Folders.Size()) + return Folders[index].Name; + return Files[index - Folders.Size()].Name; +} + +void CProxyFolder::AddRealIndices(CUIntVector &realIndices) const +{ + if (IsLeaf) + realIndices.Add(Index); + int i; + for (i = 0; i < Folders.Size(); i++) + Folders[i].AddRealIndices(realIndices); + for (i = 0; i < Files.Size(); i++) + realIndices.Add(Files[i].Index); +} + +void CProxyFolder::GetRealIndices(const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const +{ + realIndices.Clear(); + for (UInt32 i = 0; i < numItems; i++) + { + int index = indices[i]; + int numDirItems = Folders.Size(); + if (index < numDirItems) + Folders[index].AddRealIndices(realIndices); + else + realIndices.Add(Files[index - numDirItems].Index); + } + HeapSort(&realIndices.Front(), realIndices.Size()); +} + +/////////////////////////////////////////////// +// CProxyArchive + +static UInt64 GetSize(IInArchive *archive, UInt32 index, PROPID propID) +{ + NCOM::CPropVariant prop; + if (archive->GetProperty(index, propID, &prop) == S_OK) + if (prop.vt != VT_EMPTY) + return ConvertPropVariantToUInt64(prop); + return 0; +} + +void CProxyFolder::CalculateSizes(IInArchive *archive) +{ + Size = PackSize = 0; + NumSubFolders = Folders.Size(); + NumSubFiles = Files.Size(); + CrcIsDefined = true; + Crc = 0; + int i; + for (i = 0; i < Files.Size(); i++) + { + UInt32 index = Files[i].Index; + Size += GetSize(archive, index, kpidSize); + PackSize += GetSize(archive, index, kpidPackSize); + { + NCOM::CPropVariant prop; + if (archive->GetProperty(index, kpidCRC, &prop) == S_OK && prop.vt == VT_UI4) + Crc += prop.ulVal; + else + CrcIsDefined = false; + } + } + for (i = 0; i < Folders.Size(); i++) + { + CProxyFolder &f = Folders[i]; + f.CalculateSizes(archive); + Size += f.Size; + PackSize += f.PackSize; + NumSubFiles += f.NumSubFiles; + NumSubFolders += f.NumSubFolders; + Crc += f.Crc; + if (!f.CrcIsDefined) + CrcIsDefined = false; + } +} + +HRESULT CProxyArchive::Load(const CArc &arc, IProgress *progress) +{ + RootFolder.Clear(); + IInArchive *archive = arc.Archive; + { + ThereIsPathProp = false; + UInt32 numProps; + archive->GetNumberOfProperties(&numProps); + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE varType; + RINOK(archive->GetPropertyInfo(i, &name, &propID, &varType)); + if (propID == kpidPath) + { + ThereIsPathProp = true; + break; + } + } + } + + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)); + if (progress != NULL) + { + UInt64 totalItems = numItems; + RINOK(progress->SetTotal(totalItems)); + } + UString fileName; + for (UInt32 i = 0; i < numItems; i++) + { + if (progress != NULL && (i & 0xFFFFF) == 0) + { + UInt64 currentItemIndex = i; + RINOK(progress->SetCompleted(¤tItemIndex)); + } + UString filePath; + RINOK(arc.GetItemPath(i, filePath)); + CProxyFolder *curItem = &RootFolder; + int len = filePath.Length(); + fileName.Empty(); + for (int j = 0; j < len; j++) + { + wchar_t c = filePath[j]; + if (c == WCHAR_PATH_SEPARATOR || c == L'/') + { + curItem = curItem->AddDirSubItem((UInt32)(Int32)-1, false, fileName); + fileName.Empty(); + } + else + fileName += c; + } + + bool isFolder; + RINOK(IsArchiveItemFolder(archive, i, isFolder)); + if (isFolder) + curItem->AddDirSubItem(i, true, fileName); + else + curItem->AddFileSubItem(i, fileName); + } + RootFolder.CalculateSizes(archive); + return S_OK; +} -- cgit v1.2.3