diff options
Diffstat (limited to 'src/api/wix/WixToolset.Data/IntermediateFieldExtensions.cs')
-rw-r--r-- | src/api/wix/WixToolset.Data/IntermediateFieldExtensions.cs | 481 |
1 files changed, 481 insertions, 0 deletions
diff --git a/src/api/wix/WixToolset.Data/IntermediateFieldExtensions.cs b/src/api/wix/WixToolset.Data/IntermediateFieldExtensions.cs new file mode 100644 index 00000000..c70eb230 --- /dev/null +++ b/src/api/wix/WixToolset.Data/IntermediateFieldExtensions.cs | |||
@@ -0,0 +1,481 @@ | |||
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 | namespace WixToolset.Data | ||
4 | { | ||
5 | using System; | ||
6 | |||
7 | public static class IntermediateFieldExtensions | ||
8 | { | ||
9 | [ThreadStatic] | ||
10 | internal static string valueContext; | ||
11 | |||
12 | public static bool IsNull(this IntermediateField field) => field?.Value?.Data == null; | ||
13 | |||
14 | public static bool AsBool(this IntermediateField field) | ||
15 | { | ||
16 | if (field == null || field.Value == null || field.Value.Data == null) | ||
17 | { | ||
18 | return false; | ||
19 | } | ||
20 | |||
21 | switch (field.Definition.Type) | ||
22 | { | ||
23 | case IntermediateFieldType.Bool: | ||
24 | return field.Value.AsBool(); | ||
25 | |||
26 | case IntermediateFieldType.LargeNumber: | ||
27 | case IntermediateFieldType.Number: | ||
28 | return field.Value.AsLargeNumber() != 0; | ||
29 | |||
30 | case IntermediateFieldType.String: | ||
31 | return !String.IsNullOrEmpty(field.Value.AsString()); | ||
32 | |||
33 | case IntermediateFieldType.Path: | ||
34 | return !String.IsNullOrEmpty(field.Value.AsPath()?.Path); | ||
35 | |||
36 | default: | ||
37 | throw new InvalidCastException($"Cannot convert field {field.Name} with type {field.Type} to boolean"); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | public static bool? AsNullableBool(this IntermediateField field) | ||
42 | { | ||
43 | if (field == null || field.Value == null || field.Value.Data == null) | ||
44 | { | ||
45 | return null; | ||
46 | } | ||
47 | |||
48 | return field.AsBool(); | ||
49 | } | ||
50 | |||
51 | public static long AsLargeNumber(this IntermediateField field) | ||
52 | { | ||
53 | if (field == null || field.Value == null || field.Value.Data == null) | ||
54 | { | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | switch (field.Definition.Type) | ||
59 | { | ||
60 | case IntermediateFieldType.Bool: | ||
61 | return field.Value.AsBool() ? 1 : 0; | ||
62 | |||
63 | case IntermediateFieldType.LargeNumber: | ||
64 | case IntermediateFieldType.Number: | ||
65 | return field.Value.AsLargeNumber(); | ||
66 | |||
67 | case IntermediateFieldType.String: | ||
68 | return Convert.ToInt64(field.Value.AsString()); | ||
69 | |||
70 | default: | ||
71 | throw new InvalidCastException($"Cannot convert field {field.Name} with type {field.Type} to large number"); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | public static long? AsNullableLargeNumber(this IntermediateField field) | ||
76 | { | ||
77 | if (field == null || field.Value == null || field.Value.Data == null) | ||
78 | { | ||
79 | return null; | ||
80 | } | ||
81 | |||
82 | return field.AsLargeNumber(); | ||
83 | } | ||
84 | |||
85 | public static int AsNumber(this IntermediateField field) | ||
86 | { | ||
87 | if (field == null || field.Value == null || field.Value.Data == null) | ||
88 | { | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | switch (field.Definition.Type) | ||
93 | { | ||
94 | case IntermediateFieldType.Bool: | ||
95 | return field.Value.AsBool() ? 1 : 0; | ||
96 | |||
97 | case IntermediateFieldType.LargeNumber: | ||
98 | case IntermediateFieldType.Number: | ||
99 | return field.Value.AsNumber(); | ||
100 | |||
101 | case IntermediateFieldType.String: | ||
102 | return Convert.ToInt32(field.Value.AsString()); | ||
103 | |||
104 | default: | ||
105 | throw new InvalidCastException($"Cannot convert field {field.Name} with type {field.Type} to number"); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | public static int? AsNullableNumber(this IntermediateField field) | ||
110 | { | ||
111 | if (field == null || field.Value == null || field.Value.Data == null) | ||
112 | { | ||
113 | return null; | ||
114 | } | ||
115 | |||
116 | return field.AsNumber(); | ||
117 | } | ||
118 | |||
119 | public static IntermediateFieldPathValue AsPath(this IntermediateField field) | ||
120 | { | ||
121 | if (field == null || field.Value == null || field.Value.Data == null) | ||
122 | { | ||
123 | return null; | ||
124 | } | ||
125 | |||
126 | switch (field.Definition.Type) | ||
127 | { | ||
128 | case IntermediateFieldType.String: | ||
129 | return new IntermediateFieldPathValue { Path = field.Value.AsString() }; | ||
130 | |||
131 | case IntermediateFieldType.Path: | ||
132 | return field.Value.AsPath(); | ||
133 | |||
134 | default: | ||
135 | throw new InvalidCastException($"Cannot convert field {field.Name} with type {field.Type} to string"); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | public static string AsString(this IntermediateField field) | ||
140 | { | ||
141 | if (field == null || field.Value == null || field.Value.Data == null) | ||
142 | { | ||
143 | return null; | ||
144 | } | ||
145 | |||
146 | switch (field.Definition.Type) | ||
147 | { | ||
148 | case IntermediateFieldType.Bool: | ||
149 | return field.Value.AsBool() ? "true" : "false"; | ||
150 | |||
151 | case IntermediateFieldType.LargeNumber: | ||
152 | case IntermediateFieldType.Number: | ||
153 | return field.Value.AsLargeNumber().ToString(); | ||
154 | |||
155 | case IntermediateFieldType.String: | ||
156 | return field.Value.AsString(); | ||
157 | |||
158 | case IntermediateFieldType.Path: | ||
159 | return field.Value.AsPath()?.Path; | ||
160 | |||
161 | default: | ||
162 | throw new InvalidCastException($"Cannot convert field {field.Name} with type {field.Type} to string"); | ||
163 | } | ||
164 | } | ||
165 | |||
166 | public static object AsObject(this IntermediateField field) | ||
167 | { | ||
168 | return field?.Value.Data; | ||
169 | } | ||
170 | |||
171 | public static IntermediateField Set(this IntermediateField field, bool value) | ||
172 | { | ||
173 | object data; | ||
174 | |||
175 | if (field == null) | ||
176 | { | ||
177 | throw new ArgumentNullException(nameof(field)); | ||
178 | } | ||
179 | |||
180 | switch (field.Type) | ||
181 | { | ||
182 | case IntermediateFieldType.Bool: | ||
183 | data = value; | ||
184 | break; | ||
185 | |||
186 | case IntermediateFieldType.LargeNumber: | ||
187 | data = value ? (long)1 : (long)0; | ||
188 | break; | ||
189 | |||
190 | case IntermediateFieldType.Number: | ||
191 | data = value ? 1 : 0; | ||
192 | break; | ||
193 | |||
194 | case IntermediateFieldType.Path: | ||
195 | throw new ArgumentException($"Cannot convert bool '{value}' to a 'Path' field type.", nameof(value)); | ||
196 | |||
197 | case IntermediateFieldType.String: | ||
198 | data = value ? "true" : "false"; | ||
199 | break; | ||
200 | |||
201 | default: | ||
202 | throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}"); | ||
203 | }; | ||
204 | |||
205 | return AssignFieldValue(field, data); | ||
206 | } | ||
207 | |||
208 | public static IntermediateField Set(this IntermediateField field, bool? value) | ||
209 | { | ||
210 | if (field == null) | ||
211 | { | ||
212 | throw new ArgumentNullException(nameof(field)); | ||
213 | } | ||
214 | |||
215 | return value.HasValue ? field.Set(value.Value) : AssignFieldValue(field, null); | ||
216 | } | ||
217 | |||
218 | public static IntermediateField Set(this IntermediateField field, long value) | ||
219 | { | ||
220 | object data; | ||
221 | |||
222 | if (field == null) | ||
223 | { | ||
224 | throw new ArgumentNullException(nameof(field)); | ||
225 | } | ||
226 | |||
227 | switch (field.Type) | ||
228 | { | ||
229 | case IntermediateFieldType.Bool: | ||
230 | data = (value != 0); | ||
231 | break; | ||
232 | |||
233 | case IntermediateFieldType.LargeNumber: | ||
234 | data = value; | ||
235 | break; | ||
236 | |||
237 | case IntermediateFieldType.Number: | ||
238 | data = (int)value; | ||
239 | break; | ||
240 | |||
241 | case IntermediateFieldType.Path: | ||
242 | throw new ArgumentException($"Cannot convert large number '{value}' to a 'Path' field type.", nameof(value)); | ||
243 | |||
244 | case IntermediateFieldType.String: | ||
245 | data = value.ToString(); | ||
246 | break; | ||
247 | |||
248 | default: | ||
249 | throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}"); | ||
250 | }; | ||
251 | |||
252 | return AssignFieldValue(field, data); | ||
253 | } | ||
254 | |||
255 | public static IntermediateField Set(this IntermediateField field, long? value) | ||
256 | { | ||
257 | if (field == null) | ||
258 | { | ||
259 | throw new ArgumentNullException(nameof(field)); | ||
260 | } | ||
261 | |||
262 | return value.HasValue ? field.Set(value.Value) : AssignFieldValue(field, null); | ||
263 | } | ||
264 | |||
265 | public static IntermediateField Set(this IntermediateField field, int value) | ||
266 | { | ||
267 | object data; | ||
268 | |||
269 | if (field == null) | ||
270 | { | ||
271 | throw new ArgumentNullException(nameof(field)); | ||
272 | } | ||
273 | |||
274 | switch (field.Type) | ||
275 | { | ||
276 | case IntermediateFieldType.Bool: | ||
277 | data = (value != 0); | ||
278 | break; | ||
279 | |||
280 | case IntermediateFieldType.LargeNumber: | ||
281 | data = (long)value; | ||
282 | break; | ||
283 | |||
284 | case IntermediateFieldType.Number: | ||
285 | data = value; | ||
286 | break; | ||
287 | |||
288 | case IntermediateFieldType.Path: | ||
289 | throw new ArgumentException($"Cannot convert number '{value}' to a 'Path' field type.", nameof(value)); | ||
290 | |||
291 | case IntermediateFieldType.String: | ||
292 | data = value.ToString(); | ||
293 | break; | ||
294 | |||
295 | default: | ||
296 | throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}"); | ||
297 | }; | ||
298 | |||
299 | return AssignFieldValue(field, data); | ||
300 | } | ||
301 | |||
302 | public static IntermediateField Set(this IntermediateField field, int? value) | ||
303 | { | ||
304 | if (field == null) | ||
305 | { | ||
306 | throw new ArgumentNullException(nameof(field)); | ||
307 | } | ||
308 | |||
309 | return value.HasValue ? field.Set(value.Value) : AssignFieldValue(field, null); | ||
310 | } | ||
311 | |||
312 | public static IntermediateField Set(this IntermediateField field, IntermediateFieldPathValue value) | ||
313 | { | ||
314 | object data; | ||
315 | |||
316 | if (field == null) | ||
317 | { | ||
318 | throw new ArgumentNullException(nameof(field)); | ||
319 | } | ||
320 | else if (value == null) // null is always allowed. | ||
321 | { | ||
322 | data = null; | ||
323 | } | ||
324 | else | ||
325 | { | ||
326 | switch (field.Type) | ||
327 | { | ||
328 | case IntermediateFieldType.Bool: | ||
329 | throw new ArgumentException($"Cannot convert path '{value.Path}' to a 'bool' field type.", nameof(value)); | ||
330 | |||
331 | case IntermediateFieldType.LargeNumber: | ||
332 | throw new ArgumentException($"Cannot convert path '{value.Path}' to a 'large number' field type.", nameof(value)); | ||
333 | |||
334 | case IntermediateFieldType.Number: | ||
335 | throw new ArgumentException($"Cannot convert path '{value.Path}' to a 'number' field type.", nameof(value)); | ||
336 | |||
337 | case IntermediateFieldType.Path: | ||
338 | data = value; | ||
339 | break; | ||
340 | |||
341 | case IntermediateFieldType.String: | ||
342 | data = value.Path; | ||
343 | break; | ||
344 | |||
345 | default: | ||
346 | throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}"); | ||
347 | } | ||
348 | } | ||
349 | |||
350 | return AssignFieldValue(field, data); | ||
351 | } | ||
352 | |||
353 | public static IntermediateField Set(this IntermediateField field, string value) | ||
354 | { | ||
355 | object data; | ||
356 | |||
357 | if (field == null) | ||
358 | { | ||
359 | throw new ArgumentNullException(nameof(field)); | ||
360 | } | ||
361 | else if (value == null) // Null is always allowed. | ||
362 | { | ||
363 | data = null; | ||
364 | } | ||
365 | else | ||
366 | { | ||
367 | switch (field.Type) | ||
368 | { | ||
369 | case IntermediateFieldType.Bool: | ||
370 | if (value.Equals("yes", StringComparison.OrdinalIgnoreCase) || value.Equals("true", StringComparison.OrdinalIgnoreCase)) | ||
371 | { | ||
372 | data = true; | ||
373 | } | ||
374 | else if (value.Equals("no", StringComparison.OrdinalIgnoreCase) || value.Equals("false", StringComparison.OrdinalIgnoreCase)) | ||
375 | { | ||
376 | data = false; | ||
377 | } | ||
378 | else | ||
379 | { | ||
380 | throw new ArgumentException($"Cannot convert string '{value}' to a 'bool' field type.", nameof(value)); | ||
381 | } | ||
382 | break; | ||
383 | |||
384 | case IntermediateFieldType.LargeNumber: | ||
385 | if (Int64.TryParse(value, out var largeNumber)) | ||
386 | { | ||
387 | data = largeNumber; | ||
388 | } | ||
389 | else | ||
390 | { | ||
391 | throw new ArgumentException($"Cannot convert string '{value}' to a 'large number' field type.", nameof(value)); | ||
392 | } | ||
393 | break; | ||
394 | |||
395 | case IntermediateFieldType.Number: | ||
396 | if (Int32.TryParse(value, out var number)) | ||
397 | { | ||
398 | data = number; | ||
399 | } | ||
400 | else | ||
401 | { | ||
402 | throw new ArgumentException($"Cannot convert string '{value}' to a 'number' field type.", field.Name); | ||
403 | } | ||
404 | break; | ||
405 | |||
406 | case IntermediateFieldType.Path: | ||
407 | data = new IntermediateFieldPathValue { Path = value }; | ||
408 | break; | ||
409 | |||
410 | case IntermediateFieldType.String: | ||
411 | data = value; | ||
412 | break; | ||
413 | |||
414 | default: | ||
415 | throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}"); | ||
416 | } | ||
417 | } | ||
418 | |||
419 | return AssignFieldValue(field, data); | ||
420 | } | ||
421 | |||
422 | public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, bool value) | ||
423 | { | ||
424 | return EnsureField(field, definition).Set(value); | ||
425 | } | ||
426 | |||
427 | public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, bool? value) | ||
428 | { | ||
429 | return EnsureField(field, definition).Set(value); | ||
430 | } | ||
431 | |||
432 | public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, long value) | ||
433 | { | ||
434 | return EnsureField(field, definition).Set(value); | ||
435 | } | ||
436 | |||
437 | public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, long? value) | ||
438 | { | ||
439 | return EnsureField(field, definition).Set(value); | ||
440 | } | ||
441 | |||
442 | public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, int value) | ||
443 | { | ||
444 | return EnsureField(field, definition).Set(value); | ||
445 | } | ||
446 | |||
447 | public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, int? value) | ||
448 | { | ||
449 | return EnsureField(field, definition).Set(value); | ||
450 | } | ||
451 | |||
452 | public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, IntermediateFieldPathValue value) | ||
453 | { | ||
454 | return EnsureField(field, definition).Set(value); | ||
455 | } | ||
456 | |||
457 | public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, string value) | ||
458 | { | ||
459 | return EnsureField(field, definition).Set(value); | ||
460 | } | ||
461 | |||
462 | public static void Overwrite(this IntermediateField field, string value) => field.Value.Data = value; | ||
463 | |||
464 | private static IntermediateField AssignFieldValue(IntermediateField field, object data) | ||
465 | { | ||
466 | field.Value = new IntermediateFieldValue | ||
467 | { | ||
468 | Context = valueContext, | ||
469 | Data = data, | ||
470 | PreviousValue = field.Value | ||
471 | }; | ||
472 | |||
473 | return field; | ||
474 | } | ||
475 | |||
476 | private static IntermediateField EnsureField(IntermediateField field, IntermediateFieldDefinition definition) | ||
477 | { | ||
478 | return field ?? new IntermediateField(definition); | ||
479 | } | ||
480 | } | ||
481 | } | ||