diff options
Diffstat (limited to 'src/api/wix/WixToolset.Data/IntermediateSymbolDefinition.cs')
-rw-r--r-- | src/api/wix/WixToolset.Data/IntermediateSymbolDefinition.cs | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/src/api/wix/WixToolset.Data/IntermediateSymbolDefinition.cs b/src/api/wix/WixToolset.Data/IntermediateSymbolDefinition.cs new file mode 100644 index 00000000..dc913704 --- /dev/null +++ b/src/api/wix/WixToolset.Data/IntermediateSymbolDefinition.cs | |||
@@ -0,0 +1,270 @@ | |||
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 SimpleJson; | ||
7 | |||
8 | public class IntermediateSymbolDefinition | ||
9 | { | ||
10 | private object tags; | ||
11 | |||
12 | public IntermediateSymbolDefinition(string name, IntermediateFieldDefinition[] fieldDefinitions, Type strongSymbolType) | ||
13 | : this(SymbolDefinitionType.MustBeFromAnExtension, name, 0, fieldDefinitions, strongSymbolType) | ||
14 | { | ||
15 | } | ||
16 | |||
17 | public IntermediateSymbolDefinition(string name, int revision, IntermediateFieldDefinition[] fieldDefinitions, Type strongSymbolType) | ||
18 | : this(SymbolDefinitionType.MustBeFromAnExtension, name, revision, fieldDefinitions, strongSymbolType) | ||
19 | { | ||
20 | } | ||
21 | |||
22 | internal IntermediateSymbolDefinition(SymbolDefinitionType type, IntermediateFieldDefinition[] fieldDefinitions, Type strongSymbolType) | ||
23 | : this(type, type.ToString(), 0, fieldDefinitions, strongSymbolType) | ||
24 | { | ||
25 | } | ||
26 | |||
27 | private IntermediateSymbolDefinition(SymbolDefinitionType type, string name, int revision, IntermediateFieldDefinition[] fieldDefinitions, Type strongSymbolType) | ||
28 | { | ||
29 | this.Type = type; | ||
30 | this.Name = name; | ||
31 | this.Revision = revision; | ||
32 | this.FieldDefinitions = fieldDefinitions; | ||
33 | this.StrongSymbolType = strongSymbolType ?? typeof(IntermediateSymbol); | ||
34 | #if DEBUG | ||
35 | if (this.StrongSymbolType != typeof(IntermediateSymbol) && !this.StrongSymbolType.IsSubclassOf(typeof(IntermediateSymbol))) { throw new ArgumentException(nameof(strongSymbolType)); } | ||
36 | #endif | ||
37 | } | ||
38 | |||
39 | public int Revision { get; } | ||
40 | |||
41 | public SymbolDefinitionType Type { get; } | ||
42 | |||
43 | public string Name { get; } | ||
44 | |||
45 | public IntermediateFieldDefinition[] FieldDefinitions { get; } | ||
46 | |||
47 | private Type StrongSymbolType { get; } | ||
48 | |||
49 | public IntermediateSymbol CreateSymbol(SourceLineNumber sourceLineNumber = null, Identifier id = null) | ||
50 | { | ||
51 | var symbol = (this.StrongSymbolType == typeof(IntermediateSymbol)) ? (IntermediateSymbol)Activator.CreateInstance(this.StrongSymbolType, this) : (IntermediateSymbol)Activator.CreateInstance(this.StrongSymbolType); | ||
52 | symbol.SourceLineNumbers = sourceLineNumber; | ||
53 | symbol.Id = id; | ||
54 | |||
55 | return symbol; | ||
56 | } | ||
57 | |||
58 | public bool AddTag(string add) | ||
59 | { | ||
60 | if (this.tags == null) | ||
61 | { | ||
62 | this.tags = add; | ||
63 | } | ||
64 | else if (this.tags is string tag) | ||
65 | { | ||
66 | if (tag == add) | ||
67 | { | ||
68 | return false; | ||
69 | } | ||
70 | |||
71 | this.tags = new[] { tag, add }; | ||
72 | } | ||
73 | else | ||
74 | { | ||
75 | var tagsArray = (string[])this.tags; | ||
76 | var array = new string[tagsArray.Length + 1]; | ||
77 | |||
78 | for (var i = 0; i < tagsArray.Length; ++i) | ||
79 | { | ||
80 | if (tagsArray[i] == add) | ||
81 | { | ||
82 | return false; | ||
83 | } | ||
84 | |||
85 | array[i] = tagsArray[i]; | ||
86 | } | ||
87 | |||
88 | array[tagsArray.Length] = add; | ||
89 | |||
90 | this.tags = array; | ||
91 | } | ||
92 | |||
93 | return true; | ||
94 | } | ||
95 | |||
96 | public bool HasTag(string has) | ||
97 | { | ||
98 | if (this.tags == null) | ||
99 | { | ||
100 | return false; | ||
101 | } | ||
102 | else if (this.tags is string tag) | ||
103 | { | ||
104 | return tag == has; | ||
105 | } | ||
106 | else | ||
107 | { | ||
108 | foreach (var element in (string[])this.tags) | ||
109 | { | ||
110 | if (element == has) | ||
111 | { | ||
112 | return true; | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | |||
117 | return false; | ||
118 | } | ||
119 | |||
120 | public bool RemoveTag(string remove) | ||
121 | { | ||
122 | if (this.tags is string tag) | ||
123 | { | ||
124 | if (tag == remove) | ||
125 | { | ||
126 | this.tags = null; | ||
127 | return true; | ||
128 | } | ||
129 | } | ||
130 | else if (this.tags is string[] tagsArray) | ||
131 | { | ||
132 | if (tagsArray.Length == 2) | ||
133 | { | ||
134 | if (tagsArray[0] == remove) | ||
135 | { | ||
136 | this.tags = tagsArray[1]; | ||
137 | return true; | ||
138 | } | ||
139 | else if (tagsArray[1] == remove) | ||
140 | { | ||
141 | this.tags = tagsArray[0]; | ||
142 | return true; | ||
143 | } | ||
144 | } | ||
145 | else | ||
146 | { | ||
147 | var array = new string[tagsArray.Length - 1]; | ||
148 | var arrayIndex = 0; | ||
149 | var found = false; | ||
150 | |||
151 | for (var i = 0; i < tagsArray.Length; ++i) | ||
152 | { | ||
153 | if (tagsArray[i] == remove) | ||
154 | { | ||
155 | found = true; | ||
156 | continue; | ||
157 | } | ||
158 | else if (arrayIndex == array.Length) | ||
159 | { | ||
160 | break; | ||
161 | } | ||
162 | |||
163 | array[arrayIndex++] = tagsArray[i]; | ||
164 | } | ||
165 | |||
166 | if (found) | ||
167 | { | ||
168 | this.tags = array; | ||
169 | return true; | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | |||
174 | return false; | ||
175 | } | ||
176 | |||
177 | internal static IntermediateSymbolDefinition Deserialize(JsonObject jsonObject) | ||
178 | { | ||
179 | var name = jsonObject.GetValueOrDefault<string>("name"); | ||
180 | var revision = jsonObject.GetValueOrDefault("rev", 0); | ||
181 | var definitionsJson = jsonObject.GetValueOrDefault<JsonArray>("fields"); | ||
182 | var tagsJson = jsonObject.GetValueOrDefault<JsonArray>("tags"); | ||
183 | |||
184 | var fieldDefinitions = new IntermediateFieldDefinition[definitionsJson.Count]; | ||
185 | |||
186 | for (var i = 0; i < definitionsJson.Count; ++i) | ||
187 | { | ||
188 | var definitionJson = (JsonObject)definitionsJson[i]; | ||
189 | var fieldName = definitionJson.GetValueOrDefault<string>("name"); | ||
190 | var fieldType = definitionJson.GetEnumOrDefault("type", IntermediateFieldType.String); | ||
191 | fieldDefinitions[i] = new IntermediateFieldDefinition(fieldName, fieldType); | ||
192 | } | ||
193 | |||
194 | var definition = new IntermediateSymbolDefinition(name, revision, fieldDefinitions, null); | ||
195 | |||
196 | if (tagsJson == null || tagsJson.Count == 0) | ||
197 | { | ||
198 | } | ||
199 | else if (tagsJson.Count == 1) | ||
200 | { | ||
201 | definition.tags = (string)tagsJson[0]; | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | var tags = new string[tagsJson.Count]; | ||
206 | |||
207 | for (var i = 0; i < tagsJson.Count; ++i) | ||
208 | { | ||
209 | tags[i] = (string)tagsJson[i]; | ||
210 | } | ||
211 | |||
212 | definition.tags = tags; | ||
213 | } | ||
214 | |||
215 | return definition; | ||
216 | } | ||
217 | |||
218 | internal JsonObject Serialize() | ||
219 | { | ||
220 | var jsonObject = new JsonObject | ||
221 | { | ||
222 | { "name", this.Name } | ||
223 | }; | ||
224 | |||
225 | if (this.Revision > 0) | ||
226 | { | ||
227 | jsonObject.Add("rev", this.Revision); | ||
228 | } | ||
229 | |||
230 | var fieldsJson = new JsonArray(this.FieldDefinitions.Length); | ||
231 | |||
232 | foreach (var fieldDefinition in this.FieldDefinitions) | ||
233 | { | ||
234 | var fieldJson = new JsonObject | ||
235 | { | ||
236 | { "name", fieldDefinition.Name }, | ||
237 | }; | ||
238 | |||
239 | if (fieldDefinition.Type != IntermediateFieldType.String) | ||
240 | { | ||
241 | fieldJson.Add("type", fieldDefinition.Type.ToString().ToLowerInvariant()); | ||
242 | } | ||
243 | |||
244 | fieldsJson.Add(fieldJson); | ||
245 | } | ||
246 | |||
247 | jsonObject.Add("fields", fieldsJson); | ||
248 | |||
249 | if (this.tags is string || this.tags is string[]) | ||
250 | { | ||
251 | JsonArray tagsJson; | ||
252 | |||
253 | if (this.tags is string tag) | ||
254 | { | ||
255 | tagsJson = new JsonArray(1) { tag }; | ||
256 | } | ||
257 | else | ||
258 | { | ||
259 | var array = (string[])this.tags; | ||
260 | tagsJson = new JsonArray(array.Length); | ||
261 | tagsJson.AddRange(array); | ||
262 | } | ||
263 | |||
264 | jsonObject.Add("tags", tagsJson); | ||
265 | } | ||
266 | |||
267 | return jsonObject; | ||
268 | } | ||
269 | } | ||
270 | } | ||