diff options
Diffstat (limited to 'src/samples/Dtf/DDiff/CabDiffEngine.cs')
-rw-r--r-- | src/samples/Dtf/DDiff/CabDiffEngine.cs | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/samples/Dtf/DDiff/CabDiffEngine.cs b/src/samples/Dtf/DDiff/CabDiffEngine.cs new file mode 100644 index 00000000..6100ced8 --- /dev/null +++ b/src/samples/Dtf/DDiff/CabDiffEngine.cs | |||
@@ -0,0 +1,131 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | using System; | ||
4 | using System.IO; | ||
5 | using System.Collections; | ||
6 | using System.Collections.Generic; | ||
7 | using WixToolset.Dtf.Compression.Cab; | ||
8 | |||
9 | namespace WixToolset.Dtf.Samples.DDiff | ||
10 | { | ||
11 | public class CabDiffEngine : IDiffEngine | ||
12 | { | ||
13 | public CabDiffEngine() | ||
14 | { | ||
15 | } | ||
16 | |||
17 | private bool IsCabinetFile(string file) | ||
18 | { | ||
19 | using(FileStream fileStream = File.OpenRead(file)) | ||
20 | { | ||
21 | return new CabEngine().IsArchive(fileStream); | ||
22 | } | ||
23 | } | ||
24 | |||
25 | public virtual float GetDiffQuality(string diffInput1, string diffInput2, string[] options, IDiffEngineFactory diffFactory) | ||
26 | { | ||
27 | if(diffInput1 != null && File.Exists(diffInput1) && | ||
28 | diffInput2 != null && File.Exists(diffInput2) && | ||
29 | (IsCabinetFile(diffInput1) || IsCabinetFile(diffInput2))) | ||
30 | { | ||
31 | return .80f; | ||
32 | } | ||
33 | else | ||
34 | { | ||
35 | return 0; | ||
36 | } | ||
37 | } | ||
38 | |||
39 | public bool GetDiff(string diffInput1, string diffInput2, string[] options, TextWriter diffOutput, string linePrefix, IDiffEngineFactory diffFactory) | ||
40 | { | ||
41 | bool difference = false; | ||
42 | IComparer caseInsComp = CaseInsensitiveComparer.Default; | ||
43 | |||
44 | // TODO: Make this faster by extracting the whole cab at once. | ||
45 | // TODO: Optimize for the match case by first comparing the whole cab files. | ||
46 | |||
47 | CabInfo cab1 = new CabInfo(diffInput1); | ||
48 | CabInfo cab2 = new CabInfo(diffInput2); | ||
49 | IList<CabFileInfo> cabFilesList1 = cab1.GetFiles(); | ||
50 | IList<CabFileInfo> cabFilesList2 = cab2.GetFiles(); | ||
51 | CabFileInfo[] cabFiles1 = new CabFileInfo[cabFilesList1.Count]; | ||
52 | CabFileInfo[] cabFiles2 = new CabFileInfo[cabFilesList2.Count]; | ||
53 | cabFilesList1.CopyTo(cabFiles1, 0); | ||
54 | cabFilesList2.CopyTo(cabFiles2, 0); | ||
55 | string[] files1 = new string[cabFiles1.Length]; | ||
56 | string[] files2 = new string[cabFiles2.Length]; | ||
57 | for(int i1 = 0; i1 < cabFiles1.Length; i1++) files1[i1] = cabFiles1[i1].Name; | ||
58 | for(int i2 = 0; i2 < cabFiles2.Length; i2++) files2[i2] = cabFiles2[i2].Name; | ||
59 | Array.Sort(files1, cabFiles1, caseInsComp); | ||
60 | Array.Sort(files2, cabFiles2, caseInsComp); | ||
61 | |||
62 | |||
63 | for(int i1 = 0, i2 = 0; i1 < files1.Length || i2 < files2.Length; ) | ||
64 | { | ||
65 | int comp; | ||
66 | if(i1 == files1.Length) | ||
67 | { | ||
68 | comp = 1; | ||
69 | } | ||
70 | else if(i2 == files2.Length) | ||
71 | { | ||
72 | comp = -1; | ||
73 | } | ||
74 | else | ||
75 | { | ||
76 | comp = caseInsComp.Compare(files1[i1], files2[i2]); | ||
77 | } | ||
78 | if(comp < 0) | ||
79 | { | ||
80 | diffOutput.WriteLine("{0}< {1}", linePrefix, files1[i1]); | ||
81 | i1++; | ||
82 | difference = true; | ||
83 | } | ||
84 | else if(comp > 0) | ||
85 | { | ||
86 | diffOutput.WriteLine("{0}> {1}", linePrefix, files2[i2]); | ||
87 | i2++; | ||
88 | difference = true; | ||
89 | } | ||
90 | else | ||
91 | { | ||
92 | string tempFile1 = Path.GetTempFileName(); | ||
93 | string tempFile2 = Path.GetTempFileName(); | ||
94 | cabFiles1[i1].CopyTo(tempFile1, true); | ||
95 | cabFiles2[i2].CopyTo(tempFile2, true); | ||
96 | IDiffEngine diffEngine = diffFactory.GetDiffEngine(tempFile1, tempFile2, options); | ||
97 | StringWriter sw = new StringWriter(); | ||
98 | if(diffEngine.GetDiff(tempFile1, tempFile2, options, sw, linePrefix + " ", diffFactory)) | ||
99 | { | ||
100 | diffOutput.WriteLine("{0}{1}", linePrefix, files1[i1]); | ||
101 | diffOutput.Write(sw.ToString()); | ||
102 | difference = true; | ||
103 | } | ||
104 | |||
105 | File.SetAttributes(tempFile1, File.GetAttributes(tempFile1) & ~FileAttributes.ReadOnly); | ||
106 | File.SetAttributes(tempFile2, File.GetAttributes(tempFile2) & ~FileAttributes.ReadOnly); | ||
107 | try | ||
108 | { | ||
109 | File.Delete(tempFile1); | ||
110 | File.Delete(tempFile2); | ||
111 | } | ||
112 | catch(IOException) | ||
113 | { | ||
114 | #if DEBUG | ||
115 | Console.WriteLine("Could not delete temporary files {0} and {1}", tempFile1, tempFile2); | ||
116 | #endif | ||
117 | } | ||
118 | i1++; | ||
119 | i2++; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | return difference; | ||
124 | } | ||
125 | |||
126 | public virtual IDiffEngine Clone() | ||
127 | { | ||
128 | return new CabDiffEngine(); | ||
129 | } | ||
130 | } | ||
131 | } | ||