aboutsummaryrefslogtreecommitdiff
path: root/src/api/wix/WixToolset.Data/IntermediateFieldExtensions.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/wix/WixToolset.Data/IntermediateFieldExtensions.cs')
-rw-r--r--src/api/wix/WixToolset.Data/IntermediateFieldExtensions.cs481
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
3namespace 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}