summaryrefslogtreecommitdiffstats
path: root/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/AgentProxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/AgentProxy.cpp')
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/AgentProxy.cpp246
1 files changed, 246 insertions, 0 deletions
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(&currentItemIndex));
+ }
+ 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;
+}