mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 20:06:58 -06:00
9.34
This commit is contained in:
committed by
Kornel Lesiński
parent
83f8ddcc5b
commit
f08f4dcc3c
203
CPP/7zip/UI/Common/UpdatePair.cpp
Executable file → Normal file
203
CPP/7zip/UI/Common/UpdatePair.cpp
Executable file → Normal file
@@ -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);
|
||||
{
|
||||
UStringVector arcNames;
|
||||
arcNames.Reserve(numArcItems);
|
||||
for (int i = 0; i < numArcItems; i++)
|
||||
arcNames.Add(arcItems[i].Name);
|
||||
SortFileNames(arcNames, arcIndices);
|
||||
TestDuplicateString(arcNames, arcIndices);
|
||||
int *vals = &duplicatedArcItem[0];
|
||||
for (unsigned i = 0; i < numArcItems; i++)
|
||||
vals[i] = 0;
|
||||
}
|
||||
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user