summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp')
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp162
1 files changed, 115 insertions, 47 deletions
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp
index e21151974be..99b0aafb281 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp
@@ -3,6 +3,7 @@
#include "StdAfx.h"
#include <time.h>
+// #include <stdio.h>
#include "../../../Common/Wildcard.h"
@@ -14,38 +15,99 @@
using namespace NWindows;
using namespace NTime;
-static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2)
+
+/*
+ a2.Prec =
+ {
+ 0 (k_PropVar_TimePrec_0):
+ if GetProperty(kpidMTime) returned 0 and
+ GetProperty(kpidTimeType) did not returned VT_UI4.
+ 7z, wim, tar in 7-Zip before v21)
+ in that case we use
+ (prec) that is set by IOutArchive::GetFileTimeType()
+ }
+*/
+
+static int MyCompareTime(unsigned prec, const CFiTime &f1, const CArcTime &a2)
{
- switch (fileTimeType)
+ // except of precision, we also have limitation, when timestamp is out of range
+
+ /* if (Prec) in archive item is defined, then use global (prec) */
+ if (a2.Prec != k_PropVar_TimePrec_0)
+ prec = a2.Prec;
+
+ CArcTime a1;
+ a1.Set_From_FiTime(f1);
+ /* Set_From_FiTime() must set full form precision:
+ k_PropVar_TimePrec_Base + numDigits
+ windows: 7 digits, non-windows: 9 digits */
+
+ if (prec == k_PropVar_TimePrec_DOS)
{
- case NFileTimeType::kWindows:
- return ::CompareFileTime(&time1, &time2);
- case NFileTimeType::kUnix:
- {
- UInt32 unixTime1, unixTime2;
- FileTimeToUnixTime(time1, unixTime1);
- FileTimeToUnixTime(time2, unixTime2);
- return MyCompare(unixTime1, unixTime2);
- }
- case NFileTimeType::kDOS:
- {
- UInt32 dosTime1, dosTime2;
- FileTimeToDosTime(time1, dosTime1);
- FileTimeToDosTime(time2, dosTime2);
- return MyCompare(dosTime1, dosTime2);
- }
+ const UInt32 dosTime1 = a1.Get_DosTime();
+ const UInt32 dosTime2 = a2.Get_DosTime();
+ return MyCompare(dosTime1, dosTime2);
}
- throw 4191618;
+
+ if (prec == k_PropVar_TimePrec_Unix)
+ {
+ const Int64 u2 = FileTime_To_UnixTime64(a2.FT);
+ if (u2 == 0 || u2 == (UInt32)0xFFFFFFFF)
+ {
+ // timestamp probably was saturated in archive to 32-bit
+ // so we use saturated 32-bit value for disk file too.
+ UInt32 u1;
+ FileTime_To_UnixTime(a1.FT, u1);
+ const UInt32 u2_32 = (UInt32)u2;
+ return MyCompare(u1, u2_32);
+ }
+
+ const Int64 u1 = FileTime_To_UnixTime64(a1.FT);
+ return MyCompare(u1, u2);
+ // prec = k_PropVar_TimePrec_Base; // for debug
+ }
+
+ if (prec == k_PropVar_TimePrec_0)
+ prec = k_PropVar_TimePrec_Base + 7;
+ else if (prec == k_PropVar_TimePrec_HighPrec)
+ prec = k_PropVar_TimePrec_Base + 9;
+ else if (prec < k_PropVar_TimePrec_Base)
+ prec = k_PropVar_TimePrec_Base;
+ else if (prec > k_PropVar_TimePrec_Base + 9)
+ prec = k_PropVar_TimePrec_Base + 7;
+
+ // prec now is full form: k_PropVar_TimePrec_Base + numDigits;
+ if (prec > a1.Prec && a1.Prec >= k_PropVar_TimePrec_Base)
+ prec = a1.Prec;
+
+ const unsigned numDigits = prec - k_PropVar_TimePrec_Base;
+ if (numDigits >= 7)
+ {
+ const int comp = CompareFileTime(&a1.FT, &a2.FT);
+ if (comp != 0 || numDigits == 7)
+ return comp;
+ return MyCompare(a1.Ns100, a2.Ns100);
+ }
+ UInt32 d = 1;
+ for (unsigned k = numDigits; k < 7; k++)
+ d *= 10;
+ const UInt64 v1 = a1.Get_FILETIME_as_UInt64() / d * d;
+ const UInt64 v2 = a2.Get_FILETIME_as_UInt64() / d * d;
+ // printf("\ndelta=%d numDigits=%d\n", (unsigned)(v1- v2), numDigits);
+ return MyCompare(v1, v2);
}
-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 char *message, const UString &s1, const UString &s2)
+
+static const char * const k_Duplicate_inArc_Message = "Duplicate filename in archive:";
+static const char * const k_Duplicate_inDir_Message = "Duplicate filename on disk:";
+static const char * const k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):";
+
+Z7_ATTR_NORETURN
+static
+void ThrowError(const char *message, const UString &s1, const UString &s2)
{
- UString m;
- m.SetFromAscii(message);
+ UString m (message);
m.Add_LF(); m += s1;
m.Add_LF(); m += s2;
throw m;
@@ -53,7 +115,7 @@ static void ThrowError(const char *message, const UString &s1, const UString &s2
static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2)
{
- int res = CompareFileNames(ai1.Name, ai2.Name);
+ const int res = CompareFileNames(ai1.Name, ai2.Name);
if (res != 0)
return res;
if (ai1.IsDir != ai2.IsDir)
@@ -63,10 +125,10 @@ static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2)
static int CompareArcItems(const unsigned *p1, const unsigned *p2, void *param)
{
- unsigned i1 = *p1;
- unsigned i2 = *p2;
+ const unsigned i1 = *p1;
+ const unsigned i2 = *p2;
const CObjectVector<CArcItem> &arcItems = *(const CObjectVector<CArcItem> *)param;
- int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]);
+ const int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]);
if (res != 0)
return res;
return MyCompare(i1, i2);
@@ -80,8 +142,8 @@ void GetUpdatePairInfoList(
{
CUIntVector dirIndices, arcIndices;
- unsigned numDirItems = dirItems.Items.Size();
- unsigned numArcItems = arcItems.Size();
+ const unsigned numDirItems = dirItems.Items.Size();
+ const unsigned numArcItems = arcItems.Size();
CIntArr duplicatedArcItem(numArcItems);
{
@@ -145,18 +207,18 @@ void GetUpdatePairInfoList(
if (dirIndex < numDirItems)
{
- dirIndex2 = dirIndices[dirIndex];
- di = &dirItems.Items[dirIndex2];
+ dirIndex2 = (int)dirIndices[dirIndex];
+ di = &dirItems.Items[(unsigned)dirIndex2];
}
if (arcIndex < numArcItems)
{
- arcIndex2 = arcIndices[arcIndex];
- ai = &arcItems[arcIndex2];
+ arcIndex2 = (int)arcIndices[arcIndex];
+ ai = &arcItems[(unsigned)arcIndex2];
compareResult = 1;
if (dirIndex < numDirItems)
{
- compareResult = CompareFileNames(dirNames[dirIndex2], ai->Name);
+ compareResult = CompareFileNames(dirNames[(unsigned)dirIndex2], ai->Name);
if (compareResult == 0)
{
if (di->IsDir() != ai->IsDir)
@@ -167,7 +229,7 @@ void GetUpdatePairInfoList(
if (compareResult < 0)
{
- name = &dirNames[dirIndex2];
+ name = &dirNames[(unsigned)dirIndex2];
pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
pair.DirIndex = dirIndex2;
dirIndex++;
@@ -183,25 +245,28 @@ void GetUpdatePairInfoList(
}
else
{
- int dupl = duplicatedArcItem[arcIndex];
+ const int dupl = duplicatedArcItem[arcIndex];
if (dupl != 0)
- ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[arcIndex + dupl]].Name);
+ ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[(unsigned)((int)arcIndex + dupl)]].Name);
- name = &dirNames[dirIndex2];
+ name = &dirNames[(unsigned)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)
+ int compResult = 0;
+ if (ai->MTime.Def)
+ {
+ compResult = MyCompareTime((unsigned)fileTimeType, di->MTime, ai->MTime);
+ }
+ switch (compResult)
{
case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break;
case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break;
default:
- pair.State = (ai->SizeDefined && di->Size == ai->Size) ?
+ pair.State = (ai->Size_Defined && di->Size == ai->Size) ?
NUpdateArchive::NPairState::kSameFiles :
NUpdateArchive::NPairState::kUnknowNewerFiles;
}
@@ -210,12 +275,15 @@ void GetUpdatePairInfoList(
arcIndex++;
}
- if ((di && di->IsAltStream) ||
+ if (
+ #ifdef _WIN32
+ (di && di->IsAltStream) ||
+ #endif
(ai && ai->IsAltStream))
{
if (prevHostName)
{
- unsigned hostLen = prevHostName->Len();
+ const unsigned hostLen = prevHostName->Len();
if (name->Len() > hostLen)
if ((*name)[hostLen] == ':' && CompareFileNames(*prevHostName, name->Left(hostLen)) == 0)
pair.HostIndex = prevHostFile;
@@ -223,7 +291,7 @@ void GetUpdatePairInfoList(
}
else
{
- prevHostFile = updatePairs.Size();
+ prevHostFile = (int)updatePairs.Size();
prevHostName = name;
}