summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.cpp')
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.cpp207
1 files changed, 141 insertions, 66 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.cpp
index a43a9e770..95afdd694 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.cpp
+++ b/src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.cpp
@@ -4,10 +4,9 @@
#include <time.h>
-#include "Common/Defs.h"
-#include "Common/Wildcard.h"
+#include "../../../Common/Wildcard.h"
-#include "Windows/Time.h"
+#include "../../../Windows/TimeUtils.h"
#include "SortUtils.h"
#include "UpdatePair.h"
@@ -17,7 +16,7 @@ using namespace NTime;
static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2)
{
- switch(fileTimeType)
+ switch (fileTimeType)
{
case NFileTimeType::kWindows:
return ::CompareFileTime(&time1, &time2);
@@ -39,24 +38,38 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time
throw 4191618;
}
-static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:";
-static const wchar_t *kNotCensoredCollisionMessaged = L"Internal file name collision (file on disk, file in archive):";
+static const char *k_Duplicate_inArc_Message = "Duplicate filename in archive:";
+static const char *k_Duplicate_inDir_Message = "Duplicate filename on disk:";
+static const char *k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):";
-static void ThrowError(const UString &message, const UString &s1, const UString &s2)
+static void ThrowError(const char *message, const UString &s1, const UString &s2)
{
- UString m = message;
- m += L'\n';
- m += s1;
- m += L'\n';
- m += s2;
+ UString m;
+ m.SetFromAscii(message);
+ m += L'\n'; m += s1;
+ m += L'\n'; m += s2;
throw m;
}
-static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices)
+static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2)
{
- for(int i = 0; i + 1 < indices.Size(); i++)
- if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0)
- ThrowError(kDuplicateFileNameMessage, strings[indices[i]], strings[indices[i + 1]]);
+ int res = CompareFileNames(ai1.Name, ai2.Name);
+ if (res != 0)
+ return res;
+ if (ai1.IsDir != ai2.IsDir)
+ return ai1.IsDir ? -1 : 1;
+ return 0;
+}
+
+static int CompareArcItems(const unsigned *p1, const unsigned *p2, void *param)
+{
+ unsigned i1 = *p1;
+ unsigned i2 = *p2;
+ const CObjectVector<CArcItem> &arcItems = *(const CObjectVector<CArcItem> *)param;
+ int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]);
+ if (res != 0)
+ return res;
+ return MyCompare(i1, i2);
}
void GetUpdatePairInfoList(
@@ -65,48 +78,103 @@ void GetUpdatePairInfoList(
NFileTimeType::EEnum fileTimeType,
CRecordVector<CUpdatePair> &updatePairs)
{
- CIntVector dirIndices, arcIndices;
-
- int numDirItems = dirItems.Items.Size();
- int numArcItems = arcItems.Size();
-
-
+ CUIntVector dirIndices, arcIndices;
+
+ unsigned numDirItems = dirItems.Items.Size();
+ unsigned numArcItems = arcItems.Size();
+
+ CIntArr duplicatedArcItem(numArcItems);
+ {
+ int *vals = &duplicatedArcItem[0];
+ for (unsigned i = 0; i < numArcItems; i++)
+ vals[i] = 0;
+ }
+
{
- UStringVector arcNames;
- arcNames.Reserve(numArcItems);
- for (int i = 0; i < numArcItems; i++)
- arcNames.Add(arcItems[i].Name);
- SortFileNames(arcNames, arcIndices);
- TestDuplicateString(arcNames, arcIndices);
+ arcIndices.ClearAndSetSize(numArcItems);
+ {
+ unsigned *vals = &arcIndices[0];
+ for (unsigned i = 0; i < numArcItems; i++)
+ vals[i] = i;
+ }
+ arcIndices.Sort(CompareArcItems, (void *)&arcItems);
+ for (unsigned i = 0; i + 1 < numArcItems; i++)
+ if (CompareArcItemsBase(
+ arcItems[arcIndices[i]],
+ arcItems[arcIndices[i + 1]]) == 0)
+ {
+ duplicatedArcItem[i] = 1;
+ duplicatedArcItem[i + 1] = -1;
+ }
}
UStringVector dirNames;
{
- dirNames.Reserve(numDirItems);
- for (int i = 0; i < numDirItems; i++)
- dirNames.Add(dirItems.GetLogPath(i));
+ dirNames.ClearAndReserve(numDirItems);
+ unsigned i;
+ for (i = 0; i < numDirItems; i++)
+ dirNames.AddInReserved(dirItems.GetLogPath(i));
SortFileNames(dirNames, dirIndices);
- TestDuplicateString(dirNames, dirIndices);
+ for (i = 0; i + 1 < numDirItems; i++)
+ {
+ const UString &s1 = dirNames[dirIndices[i]];
+ const UString &s2 = dirNames[dirIndices[i + 1]];
+ if (CompareFileNames(s1, s2) == 0)
+ ThrowError(k_Duplicate_inDir_Message, s1, s2);
+ }
}
-
- int dirIndex = 0, arcIndex = 0;
- while (dirIndex < numDirItems && arcIndex < numArcItems)
+
+ unsigned dirIndex = 0;
+ unsigned arcIndex = 0;
+
+ int prevHostFile = -1;
+ const UString *prevHostName = NULL;
+
+ while (dirIndex < numDirItems || arcIndex < numArcItems)
{
CUpdatePair pair;
- int dirIndex2 = dirIndices[dirIndex];
- int arcIndex2 = arcIndices[arcIndex];
- const CDirItem &di = dirItems.Items[dirIndex2];
- const CArcItem &ai = arcItems[arcIndex2];
- int compareResult = CompareFileNames(dirNames[dirIndex2], ai.Name);
+
+ int dirIndex2 = -1;
+ int arcIndex2 = -1;
+ const CDirItem *di = NULL;
+ const CArcItem *ai = NULL;
+
+ int compareResult = -1;
+ const UString *name = NULL;
+
+ if (dirIndex < numDirItems)
+ {
+ dirIndex2 = dirIndices[dirIndex];
+ di = &dirItems.Items[dirIndex2];
+ }
+
+ if (arcIndex < numArcItems)
+ {
+ arcIndex2 = arcIndices[arcIndex];
+ ai = &arcItems[arcIndex2];
+ compareResult = 1;
+ if (dirIndex < numDirItems)
+ {
+ compareResult = CompareFileNames(dirNames[dirIndex2], ai->Name);
+ if (compareResult == 0)
+ {
+ if (di->IsDir() != ai->IsDir)
+ compareResult = (ai->IsDir ? 1 : -1);
+ }
+ }
+ }
+
if (compareResult < 0)
{
+ name = &dirNames[dirIndex2];
pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
pair.DirIndex = dirIndex2;
dirIndex++;
}
else if (compareResult > 0)
{
- pair.State = ai.Censored ?
+ name = &ai->Name;
+ pair.State = ai->Censored ?
NUpdateArchive::NPairState::kOnlyInArchive:
NUpdateArchive::NPairState::kNotMasked;
pair.ArcIndex = arcIndex2;
@@ -114,43 +182,50 @@ void GetUpdatePairInfoList(
}
else
{
- if (!ai.Censored)
- ThrowError(kNotCensoredCollisionMessaged, dirNames[dirIndex2], ai.Name);
+ int dupl = duplicatedArcItem[arcIndex];
+ if (dupl != 0)
+ ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[arcIndex + dupl]].Name);
+
+ name = &dirNames[dirIndex2];
+ if (!ai->Censored)
+ ThrowError(k_NotCensoredCollision_Message, *name, ai->Name);
+
pair.DirIndex = dirIndex2;
pair.ArcIndex = arcIndex2;
- switch (ai.MTimeDefined ? MyCompareTime(
- ai.TimeType != - 1 ? (NFileTimeType::EEnum)ai.TimeType : fileTimeType,
- di.MTime, ai.MTime): 0)
+
+ switch (ai->MTimeDefined ? MyCompareTime(
+ ai->TimeType != - 1 ? (NFileTimeType::EEnum)ai->TimeType : fileTimeType,
+ di->MTime, ai->MTime): 0)
{
case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break;
- case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break;
+ case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break;
default:
- pair.State = (ai.SizeDefined && di.Size == ai.Size) ?
+ pair.State = (ai->SizeDefined && di->Size == ai->Size) ?
NUpdateArchive::NPairState::kSameFiles :
NUpdateArchive::NPairState::kUnknowNewerFiles;
}
+
dirIndex++;
arcIndex++;
}
- updatePairs.Add(pair);
- }
- for (; dirIndex < numDirItems; dirIndex++)
- {
- CUpdatePair pair;
- pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
- pair.DirIndex = dirIndices[dirIndex];
- updatePairs.Add(pair);
- }
-
- for (; arcIndex < numArcItems; arcIndex++)
- {
- CUpdatePair pair;
- int arcIndex2 = arcIndices[arcIndex];
- pair.State = arcItems[arcIndex2].Censored ?
- NUpdateArchive::NPairState::kOnlyInArchive:
- NUpdateArchive::NPairState::kNotMasked;
- pair.ArcIndex = arcIndex2;
+ if ((di && di->IsAltStream) ||
+ (ai && ai->IsAltStream))
+ {
+ if (prevHostName)
+ {
+ unsigned hostLen = prevHostName->Len();
+ if (name->Len() > hostLen)
+ if ((*name)[hostLen] == ':' && CompareFileNames(*prevHostName, name->Left(hostLen)) == 0)
+ pair.HostIndex = prevHostFile;
+ }
+ }
+ else
+ {
+ prevHostFile = updatePairs.Size();
+ prevHostName = name;
+ }
+
updatePairs.Add(pair);
}