main
cs 146 lines 4.66 KB
Raw
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 using System.Diagnostics;
7 using SimpleJson;
8
9 [DebuggerDisplay("{Data}")]
10 public class IntermediateFieldValue
11 {
12 public string Context { get; internal set; }
13
14 internal object Data { get; set; }
15
16 public IntermediateFieldValue PreviousValue { get; internal set; }
17
18 public static explicit operator bool(IntermediateFieldValue value) => value.AsBool();
19
20 public static explicit operator bool?(IntermediateFieldValue value) => value.AsNullableBool();
21
22 public static explicit operator int(IntermediateFieldValue value) => value.AsNumber();
23
24 public static explicit operator int?(IntermediateFieldValue value) => value.AsNullableNumber();
25
26 public static explicit operator IntermediateFieldPathValue(IntermediateFieldValue value) => value.AsPath();
27
28 public static explicit operator string(IntermediateFieldValue value) => value.AsString();
29
30 internal static IntermediateFieldValue Deserialize(JsonObject jsonObject, Uri baseUri, IntermediateFieldType type)
31 {
32 var context = jsonObject.GetValueOrDefault<string>("context");
33 if (!jsonObject.TryGetValue("data", out var data))
34 {
35 throw new ArgumentException();
36 }
37
38 var value = data;
39
40 switch (value)
41 {
42 case int intData:
43 switch (type)
44 {
45 case IntermediateFieldType.Bool:
46 value = intData != 0;
47 break;
48
49 case IntermediateFieldType.LargeNumber:
50 value = Convert.ToInt64(data);
51 break;
52
53 case IntermediateFieldType.Path:
54 case IntermediateFieldType.String:
55 value = intData.ToString();
56 break;
57 }
58 break;
59
60 case long longData:
61 switch (type)
62 {
63 case IntermediateFieldType.Bool:
64 value = longData != 0;
65 break;
66
67 case IntermediateFieldType.Number:
68 value = Convert.ToInt32(longData);
69 break;
70
71 case IntermediateFieldType.Path:
72 case IntermediateFieldType.String:
73 value = longData.ToString();
74 break;
75 }
76 break;
77
78 case JsonObject jsonData:
79 jsonData.TryGetValue("embed", out var embed);
80
81 value = new IntermediateFieldPathValue
82 {
83 BaseUri = (embed != null) ? baseUri : null,
84 Embed = embed != null,
85 Path = jsonData.GetValueOrDefault<string>("path"),
86 };
87 break;
88
89 // Nothing to do for this case, so leave it out.
90 // case string stringData:
91 // break;
92 }
93
94 var previousValueJson = jsonObject.GetValueOrDefault<JsonObject>("prev");
95 var previousValue = (previousValueJson == null) ? null : IntermediateFieldValue.Deserialize(previousValueJson, baseUri, type);
96
97 return new IntermediateFieldValue
98 {
99 Context = context,
100 Data = value,
101 PreviousValue = previousValue
102 };
103 }
104
105 internal JsonObject Serialize()
106 {
107 var jsonObject = new JsonObject();
108
109 if (!String.IsNullOrEmpty(this.Context))
110 {
111 jsonObject.Add("context", this.Context);
112 }
113
114 if (this.Data is IntermediateFieldPathValue pathField)
115 {
116 var jsonData = new JsonObject();
117
118 // pathField.BaseUri is set during load, not saved.
119
120 if (pathField.Embed)
121 {
122 jsonData.Add("embed", "true");
123 }
124
125 if (!String.IsNullOrEmpty(pathField.Path))
126 {
127 jsonData.Add("path", pathField.Path);
128 }
129
130 jsonObject.Add("data", jsonData);
131 }
132 else
133 {
134 jsonObject.Add("data", this.Data);
135 }
136
137 if (this.PreviousValue != null)
138 {
139 var previousValueJson = this.PreviousValue.Serialize();
140 jsonObject.Add("prev", previousValueJson);
141 }
142
143 return jsonObject;
144 }
145 }
146 }