summaryrefslogtreecommitdiff
path: root/src/libs/WixToolset.Versioning/WixVersionComparer.cs
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2022-10-02 19:37:55 -0700
committerRob Mensching <rob@firegiant.com>2022-10-04 10:44:49 -0700
commit5c509f5611a45bdf9d252b88605537bd28f24a35 (patch)
treef2ac4c1509fe69f6489c56f257b59f4e346a51c7 /src/libs/WixToolset.Versioning/WixVersionComparer.cs
parente901e04cfb8f1b759903f41b5c8f2f91e3f877aa (diff)
downloadwix-5c509f5611a45bdf9d252b88605537bd28f24a35.tar.gz
wix-5c509f5611a45bdf9d252b88605537bd28f24a35.tar.bz2
wix-5c509f5611a45bdf9d252b88605537bd28f24a35.zip
Move WixVersion to new WixToolset.Versioning package in libs segment
WixVersion is already used by the Core toolset but could also be useful for bootstrapper applications parsing bundle versions. The WixToolset.Data assembly contains a significant amount of data that bloats its size that bootstrapper applications would never need. Extracting WixVersion to its own assembly makes it much more useable. Fixes 6943
Diffstat (limited to 'src/libs/WixToolset.Versioning/WixVersionComparer.cs')
-rw-r--r--src/libs/WixToolset.Versioning/WixVersionComparer.cs253
1 files changed, 253 insertions, 0 deletions
diff --git a/src/libs/WixToolset.Versioning/WixVersionComparer.cs b/src/libs/WixToolset.Versioning/WixVersionComparer.cs
new file mode 100644
index 00000000..be203634
--- /dev/null
+++ b/src/libs/WixToolset.Versioning/WixVersionComparer.cs
@@ -0,0 +1,253 @@
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
3namespace WixToolset.Versioning
4{
5 using System;
6 using System.Collections.Generic;
7
8 /// <summary>
9 /// WixVersion comparer.
10 /// </summary>
11 public class WixVersionComparer : IEqualityComparer<WixVersion>, IComparer<WixVersion>
12 {
13 /// <summary>
14 /// Default WixVersion comparer.
15 /// </summary>
16 public static readonly WixVersionComparer Default = new WixVersionComparer();
17
18 /// <inheritdoc />
19 public int Compare(WixVersion x, WixVersion y)
20 {
21 if ((object)x == y)
22 {
23 return 0;
24 }
25
26 if (x is null)
27 {
28 return -1;
29 }
30
31 if (y is null)
32 {
33 return 1;
34 }
35
36 var result = x.Major.CompareTo(y.Major);
37 if (result != 0)
38 {
39 return result;
40 }
41
42 result = x.Minor.CompareTo(y.Minor);
43 if (result != 0)
44 {
45 return result;
46 }
47
48 result = x.Patch.CompareTo(y.Patch);
49 if (result != 0)
50 {
51 return result;
52 }
53
54 result = x.Revision.CompareTo(y.Revision);
55 if (result != 0)
56 {
57 return result;
58 }
59
60 var xLabelCount = x.Labels?.Length ?? 0;
61 var yLabelCount = y.Labels?.Length ?? 0;
62 var maxLabelCount = Math.Max(xLabelCount, yLabelCount);
63
64 if (xLabelCount > 0)
65 {
66 if (yLabelCount == 0)
67 {
68 return -1;
69 }
70 }
71 else if (yLabelCount > 0)
72 {
73 return 1;
74 }
75
76 for (var i = 0; i < maxLabelCount; ++i)
77 {
78 var xLabel = i < xLabelCount ? x.Labels[i] : null;
79 var yLabel = i < yLabelCount ? y.Labels[i] : null;
80
81 result = CompareReleaseLabel(xLabel, yLabel);
82 if (result != 0)
83 {
84 return result;
85 }
86 }
87
88 var compareMetadata = false;
89
90 if (x.Invalid)
91 {
92 if (!y.Invalid)
93 {
94 return -1;
95 }
96 else
97 {
98 compareMetadata = true;
99 }
100 }
101 else if (y.Invalid)
102 {
103 return 1;
104 }
105
106 if (compareMetadata)
107 {
108 result = String.Compare(x.Metadata, y.Metadata, StringComparison.OrdinalIgnoreCase);
109 }
110
111 return (result == 0) ? 0 : (result < 0) ? -1 : 1;
112 }
113
114 /// <inheritdoc />
115 public bool Equals(WixVersion x, WixVersion y)
116 {
117 if ((object)x == y)
118 {
119 return true;
120 }
121
122 if (x is null)
123 {
124 return false;
125 }
126
127 if (y is null)
128 {
129 return false;
130 }
131
132 if (x.Major != y.Major)
133 {
134 return false;
135 }
136
137 if (x.Minor != y.Minor)
138 {
139 return false;
140 }
141
142 if (x.Patch != y.Patch)
143 {
144 return false;
145 }
146
147 if (x.Revision != y.Revision)
148 {
149 return false;
150 }
151
152 var labelCount = x.Labels?.Length ?? 0;
153 if (labelCount != (y.Labels?.Length ?? 0))
154 {
155 return false;
156 }
157
158 for (var i = 0; i < labelCount; ++i)
159 {
160 var result = CompareReleaseLabel(x.Labels[i], y.Labels[i]);
161 if (result != 0)
162 {
163 return false;
164 }
165 }
166
167 if (x.Invalid)
168 {
169 if (y.Invalid)
170 {
171 return String.Equals(x.Metadata, y.Metadata, StringComparison.OrdinalIgnoreCase);
172 }
173 else
174 {
175 return false;
176 }
177 }
178 else if (y.Invalid)
179 {
180 return false;
181 }
182
183 return true;
184 }
185
186 /// <inheritdoc />
187 public int GetHashCode(WixVersion version)
188 {
189 var hash = 23L;
190 hash = hash * 37 + (version.Prefix ?? '\0');
191 hash = hash * 37 + version.Major;
192 hash = hash * 37 + version.Minor;
193 hash = hash * 37 + version.Patch;
194 hash = hash * 37 + version.Revision;
195 hash = hash * 37 + (version.Invalid ? 1 : 0);
196 hash = hash * 37 + (version.HasMajor ? 1 : 0);
197 hash = hash * 37 + (version.HasMinor ? 1 : 0);
198 hash = hash * 37 + (version.HasPatch ? 1 : 0);
199 hash = hash * 37 + (version.HasRevision ? 1 : 0);
200
201 if (version.Labels != null)
202 {
203 foreach (var label in version.Labels)
204 {
205 hash = hash * 37 + label.Label.GetHashCode();
206 }
207 }
208
209 hash = hash * 37 + version.Metadata?.GetHashCode() ?? 0;
210
211 return unchecked((int)hash);
212 }
213
214 private static int CompareReleaseLabel(WixVersionLabel l1, WixVersionLabel l2)
215 {
216 if (l1 == l2)
217 {
218 return 0;
219 }
220 else if (l2 == null)
221 {
222 return 1;
223 }
224 else if (l1 == null)
225 {
226 return -1;
227 }
228
229 if (l1.Numeric.HasValue)
230 {
231 if (l2.Numeric.HasValue)
232 {
233 return l1.Numeric.Value.CompareTo(l2.Numeric.Value);
234 }
235 else
236 {
237 return -1;
238 }
239 }
240 else
241 {
242 if (l2.Numeric.HasValue)
243 {
244 return 1;
245 }
246 else
247 {
248 return String.Compare(l1.Label, l2.Label, StringComparison.OrdinalIgnoreCase);
249 }
250 }
251 }
252 }
253}