Upload 2.0.2
[physicsfs] / lzma / CPP / 7zip / UI / Common / UpdatePair.cpp
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 }