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