1 // UpdatePair.cpp 2 3 #include "StdAfx.h" 4 5 #include <time.h> 6 7 #include "Common/Defs.h" 8 #include "Common/Wildcard.h" 9 10 #include "Windows/Time.h" 11 12 #include "SortUtils.h" 13 #include "UpdatePair.h" 14 15 using namespace NWindows; 16 using namespace NTime; 17 18 static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2) 19 { 20 switch(fileTimeType) 21 { 22 case NFileTimeType::kWindows: 23 return ::CompareFileTime(&time1, &time2); 24 case NFileTimeType::kUnix: 25 { 26 UInt32 unixTime1, unixTime2; 27 FileTimeToUnixTime(time1, unixTime1); 28 FileTimeToUnixTime(time2, unixTime2); 29 return MyCompare(unixTime1, unixTime2); 30 } 31 case NFileTimeType::kDOS: 32 { 33 UInt32 dosTime1, dosTime2; 34 FileTimeToDosTime(time1, dosTime1); 35 FileTimeToDosTime(time2, dosTime2); 36 return MyCompare(dosTime1, dosTime2); 37 } 38 } 39 throw 4191618; 40 } 41 42 static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:"; 43 static const wchar_t *kNotCensoredCollisionMessaged = L"Internal file name collision (file on disk, file in archive):"; 44 45 static void ThrowError(const UString &message, const UString &s1, const UString &s2) 46 { 47 UString m = message; 48 m += L'\n'; 49 m += s1; 50 m += L'\n'; 51 m += s2; 52 throw m; 53 } 54 55 static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices) 56 { 57 for(int i = 0; i + 1 < indices.Size(); i++) 58 if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0) 59 ThrowError(kDuplicateFileNameMessage, strings[indices[i]], strings[indices[i + 1]]); 60 } 61 62 void GetUpdatePairInfoList( 63 const CDirItems &dirItems, 64 const CObjectVector<CArcItem> &arcItems, 65 NFileTimeType::EEnum fileTimeType, 66 CRecordVector<CUpdatePair> &updatePairs) 67 { 68 CIntVector dirIndices, arcIndices; 69 70 int numDirItems = dirItems.Items.Size(); 71 int numArcItems = arcItems.Size(); 72 73 74 { 75 UStringVector arcNames; 76 arcNames.Reserve(numArcItems); 77 for (int i = 0; i < numArcItems; i++) 78 arcNames.Add(arcItems[i].Name); 79 SortFileNames(arcNames, arcIndices); 80 TestDuplicateString(arcNames, arcIndices); 81 } 82 83 UStringVector dirNames; 84 { 85 dirNames.Reserve(numDirItems); 86 for (int i = 0; i < numDirItems; i++) 87 dirNames.Add(dirItems.GetLogPath(i)); 88 SortFileNames(dirNames, dirIndices); 89 TestDuplicateString(dirNames, dirIndices); 90 } 91 92 int dirIndex = 0, arcIndex = 0; 93 while (dirIndex < numDirItems && arcIndex < numArcItems) 94 { 95 CUpdatePair pair; 96 int dirIndex2 = dirIndices[dirIndex]; 97 int arcIndex2 = arcIndices[arcIndex]; 98 const CDirItem &di = dirItems.Items[dirIndex2]; 99 const CArcItem &ai = arcItems[arcIndex2]; 100 int compareResult = CompareFileNames(dirNames[dirIndex2], ai.Name); 101 if (compareResult < 0) 102 { 103 pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; 104 pair.DirIndex = dirIndex2; 105 dirIndex++; 106 } 107 else if (compareResult > 0) 108 { 109 pair.State = ai.Censored ? 110 NUpdateArchive::NPairState::kOnlyInArchive: 111 NUpdateArchive::NPairState::kNotMasked; 112 pair.ArcIndex = arcIndex2; 113 arcIndex++; 114 } 115 else 116 { 117 if (!ai.Censored) 118 ThrowError(kNotCensoredCollisionMessaged, dirNames[dirIndex2], ai.Name); 119 pair.DirIndex = dirIndex2; 120 pair.ArcIndex = arcIndex2; 121 switch (ai.MTimeDefined ? MyCompareTime( 122 ai.TimeType != - 1 ? (NFileTimeType::EEnum)ai.TimeType : fileTimeType, 123 di.MTime, ai.MTime): 0) 124 { 125 case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break; 126 case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break; 127 default: 128 pair.State = (ai.SizeDefined && di.Size == ai.Size) ? 129 NUpdateArchive::NPairState::kSameFiles : 130 NUpdateArchive::NPairState::kUnknowNewerFiles; 131 } 132 dirIndex++; 133 arcIndex++; 134 } 135 updatePairs.Add(pair); 136 } 137 138 for (; dirIndex < numDirItems; dirIndex++) 139 { 140 CUpdatePair pair; 141 pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; 142 pair.DirIndex = dirIndices[dirIndex]; 143 updatePairs.Add(pair); 144 } 145 146 for (; arcIndex < numArcItems; arcIndex++) 147 { 148 CUpdatePair pair; 149 int arcIndex2 = arcIndices[arcIndex]; 150 pair.State = arcItems[arcIndex2].Censored ? 151 NUpdateArchive::NPairState::kOnlyInArchive: 152 NUpdateArchive::NPairState::kNotMasked; 153 pair.ArcIndex = arcIndex2; 154 updatePairs.Add(pair); 155 } 156 157 updatePairs.ReserveDown(); 158 } 159