|
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 #include "Windows/Time.h" |
|
10 |
|
11 #include "UpdatePair.h" |
|
12 #include "SortUtils.h" |
|
13 |
|
14 using namespace NWindows; |
|
15 using namespace NTime; |
|
16 |
|
17 static int MyCompareTime(NFileTimeType::EEnum fileTimeType, |
|
18 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 if (!FileTimeToUnixTime(time1, unixTime1)) |
|
28 { |
|
29 unixTime1 = 0; |
|
30 // throw 4191614; |
|
31 } |
|
32 if (!FileTimeToUnixTime(time2, unixTime2)) |
|
33 { |
|
34 unixTime2 = 0; |
|
35 // throw 4191615; |
|
36 } |
|
37 return MyCompare(unixTime1, unixTime2); |
|
38 } |
|
39 case NFileTimeType::kDOS: |
|
40 { |
|
41 UInt32 dosTime1, dosTime2; |
|
42 FileTimeToDosTime(time1, dosTime1); |
|
43 FileTimeToDosTime(time2, dosTime2); |
|
44 /* |
|
45 if (!FileTimeToDosTime(time1, dosTime1)) |
|
46 throw 4191616; |
|
47 if (!FileTimeToDosTime(time2, dosTime2)) |
|
48 throw 4191617; |
|
49 */ |
|
50 return MyCompare(dosTime1, dosTime2); |
|
51 } |
|
52 } |
|
53 throw 4191618; |
|
54 } |
|
55 |
|
56 static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:"; |
|
57 |
|
58 /* |
|
59 static const char *kNotCensoredCollisionMessaged = "Internal file name collision:\n"; |
|
60 static const char *kSameTimeChangedSizeCollisionMessaged = |
|
61 "Collision between files with same date/time and different sizes:\n"; |
|
62 */ |
|
63 |
|
64 static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices) |
|
65 { |
|
66 for(int i = 0; i + 1 < indices.Size(); i++) |
|
67 if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0) |
|
68 { |
|
69 UString message = kDuplicateFileNameMessage; |
|
70 message += L"\n"; |
|
71 message += strings[indices[i]]; |
|
72 message += L"\n"; |
|
73 message += strings[indices[i + 1]]; |
|
74 throw message; |
|
75 } |
|
76 } |
|
77 |
|
78 void GetUpdatePairInfoList( |
|
79 const CObjectVector<CDirItem> &dirItems, |
|
80 const CObjectVector<CArchiveItem> &archiveItems, |
|
81 NFileTimeType::EEnum fileTimeType, |
|
82 CObjectVector<CUpdatePair> &updatePairs) |
|
83 { |
|
84 CIntVector dirIndices, archiveIndices; |
|
85 UStringVector dirNames, archiveNames; |
|
86 |
|
87 int numDirItems = dirItems.Size(); |
|
88 int i; |
|
89 for(i = 0; i < numDirItems; i++) |
|
90 dirNames.Add(dirItems[i].Name); |
|
91 SortFileNames(dirNames, dirIndices); |
|
92 TestDuplicateString(dirNames, dirIndices); |
|
93 |
|
94 int numArchiveItems = archiveItems.Size(); |
|
95 for(i = 0; i < numArchiveItems; i++) |
|
96 archiveNames.Add(archiveItems[i].Name); |
|
97 SortFileNames(archiveNames, archiveIndices); |
|
98 TestDuplicateString(archiveNames, archiveIndices); |
|
99 |
|
100 int dirItemIndex = 0, archiveItemIndex = 0; |
|
101 CUpdatePair pair; |
|
102 while(dirItemIndex < numDirItems && archiveItemIndex < numArchiveItems) |
|
103 { |
|
104 int dirItemIndex2 = dirIndices[dirItemIndex], |
|
105 archiveItemIndex2 = archiveIndices[archiveItemIndex]; |
|
106 const CDirItem &dirItem = dirItems[dirItemIndex2]; |
|
107 const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2]; |
|
108 int compareResult = CompareFileNames(dirItem.Name, archiveItem.Name); |
|
109 if (compareResult < 0) |
|
110 { |
|
111 pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; |
|
112 pair.DirItemIndex = dirItemIndex2; |
|
113 dirItemIndex++; |
|
114 } |
|
115 else if (compareResult > 0) |
|
116 { |
|
117 pair.State = archiveItem.Censored ? |
|
118 NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked; |
|
119 pair.ArchiveItemIndex = archiveItemIndex2; |
|
120 archiveItemIndex++; |
|
121 } |
|
122 else |
|
123 { |
|
124 if (!archiveItem.Censored) |
|
125 throw 1082022;; // TTString(kNotCensoredCollisionMessaged + dirItem.Name); |
|
126 pair.DirItemIndex = dirItemIndex2; |
|
127 pair.ArchiveItemIndex = archiveItemIndex2; |
|
128 switch (MyCompareTime(fileTimeType, dirItem.LastWriteTime, archiveItem.LastWriteTime)) |
|
129 { |
|
130 case -1: |
|
131 pair.State = NUpdateArchive::NPairState::kNewInArchive; |
|
132 break; |
|
133 case 1: |
|
134 pair.State = NUpdateArchive::NPairState::kOldInArchive; |
|
135 break; |
|
136 default: |
|
137 if (archiveItem.SizeIsDefined) |
|
138 if (dirItem.Size != archiveItem.Size) |
|
139 // throw 1082034; // kSameTimeChangedSizeCollisionMessaged; |
|
140 pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles; |
|
141 else |
|
142 pair.State = NUpdateArchive::NPairState::kSameFiles; |
|
143 else |
|
144 pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles; |
|
145 } |
|
146 dirItemIndex++; |
|
147 archiveItemIndex++; |
|
148 } |
|
149 updatePairs.Add(pair); |
|
150 } |
|
151 for(;dirItemIndex < numDirItems; dirItemIndex++) |
|
152 { |
|
153 pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; |
|
154 pair.DirItemIndex = dirIndices[dirItemIndex]; |
|
155 updatePairs.Add(pair); |
|
156 } |
|
157 for(;archiveItemIndex < numArchiveItems; archiveItemIndex++) |
|
158 { |
|
159 int archiveItemIndex2 = archiveIndices[archiveItemIndex]; |
|
160 const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2]; |
|
161 pair.State = archiveItem.Censored ? |
|
162 NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked; |
|
163 pair.ArchiveItemIndex = archiveItemIndex2; |
|
164 updatePairs.Add(pair); |
|
165 } |
|
166 } |