aboutsummaryrefslogtreecommitdiff
path: root/src/tools/Dtf/DDiff/CabDiffEngine.cs
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2022-07-14 15:19:53 -0700
committerRob Mensching <rob@firegiant.com>2022-07-14 16:02:24 -0700
commit229242cf7c328b89b5aa65ed7a04e33c8b93b393 (patch)
treede0a9547e73e46490b0946d6850228d5b30258b8 /src/tools/Dtf/DDiff/CabDiffEngine.cs
parentf46ca6a9dce91607ffc9855270dd6998216e1a8b (diff)
downloadwix-229242cf7c328b89b5aa65ed7a04e33c8b93b393.tar.gz
wix-229242cf7c328b89b5aa65ed7a04e33c8b93b393.tar.bz2
wix-229242cf7c328b89b5aa65ed7a04e33c8b93b393.zip
Rename "samples" segment to "tools"
This segment is a bit of a "miscellaneous section" in the WiX repo. As such it has been difficult to name. I originally eschewed the name "tools" because what is in the "wix" segment was once called "tools". However, now that wix.exe is firmly established as the entry point for WiX operations, I've become comfortable with its segment being named "wix". That meant "tools" was again available and "tools" better describes the content of this section.
Diffstat (limited to 'src/tools/Dtf/DDiff/CabDiffEngine.cs')
-rw-r--r--src/tools/Dtf/DDiff/CabDiffEngine.cs131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/tools/Dtf/DDiff/CabDiffEngine.cs b/src/tools/Dtf/DDiff/CabDiffEngine.cs
new file mode 100644
index 00000000..b3bafaa3
--- /dev/null
+++ b/src/tools/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
3using System;
4using System.IO;
5using System.Collections;
6using System.Collections.Generic;
7using WixToolset.Dtf.Compression.Cab;
8
9namespace WixToolset.Dtf.Tools.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}