| 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.Collections.Generic; |
| 7 | using SimpleJson; |
| 8 | |
| 9 | /// <summary> |
| 10 | /// Section in an intermediate file. |
| 11 | /// </summary> |
| 12 | public class IntermediateSection |
| 13 | { |
| 14 | private readonly List<IntermediateSymbol> symbols; |
| 15 | |
| 16 | /// <summary> |
| 17 | /// Creates a new section as part of an intermediate. |
| 18 | /// </summary> |
| 19 | /// <param name="id">Identifier for section.</param> |
| 20 | /// <param name="type">Type of section.</param> |
| 21 | /// <param name="compilationId">Optional compilation identifier</param> |
| 22 | public IntermediateSection(string id, SectionType type, string compilationId = null) |
| 23 | { |
| 24 | this.Id = id; |
| 25 | this.Type = type; |
| 26 | this.CompilationId = compilationId; |
| 27 | this.symbols = new List<IntermediateSymbol>(); |
| 28 | } |
| 29 | |
| 30 | /// <summary> |
| 31 | /// Gets the identifier for the section. |
| 32 | /// </summary> |
| 33 | /// <value>Section identifier.</value> |
| 34 | public string Id { get; } |
| 35 | |
| 36 | /// <summary> |
| 37 | /// Gets the type of the section. |
| 38 | /// </summary> |
| 39 | /// <value>Type of section.</value> |
| 40 | public SectionType Type { get; } |
| 41 | |
| 42 | /// <summary> |
| 43 | /// Gets and sets the identifier of the compilation of the source file containing the section. |
| 44 | /// </summary> |
| 45 | public string CompilationId { get; } |
| 46 | |
| 47 | /// <summary> |
| 48 | /// Gets and sets the identifier of the library that combined the section. |
| 49 | /// </summary> |
| 50 | public string LibraryId { get; private set; } |
| 51 | |
| 52 | /// <summary> |
| 53 | /// Symbols in the section. |
| 54 | /// </summary> |
| 55 | public IReadOnlyCollection<IntermediateSymbol> Symbols => this.symbols; |
| 56 | |
| 57 | /// <summary> |
| 58 | /// Adds a symbol to the section. |
| 59 | /// </summary> |
| 60 | /// <typeparam name="T">Type of IntermediateSymbol to add to the section.</typeparam> |
| 61 | /// <param name="symbol">Symbol to add to the section.</param> |
| 62 | /// <returns>Symbol added to the section.</returns> |
| 63 | public T AddSymbol<T>(T symbol) where T : IntermediateSymbol |
| 64 | { |
| 65 | this.symbols.Add(symbol); |
| 66 | return symbol; |
| 67 | } |
| 68 | |
| 69 | /// <summary> |
| 70 | /// Assigns the section to a library. |
| 71 | /// </summary> |
| 72 | /// <param name="libraryId">Identifier of the library.</param> |
| 73 | public IntermediateSection AssignToLibrary(string libraryId) |
| 74 | { |
| 75 | this.LibraryId = libraryId; |
| 76 | |
| 77 | return this; |
| 78 | } |
| 79 | |
| 80 | /// <summary> |
| 81 | /// Removes a symbol from the section. |
| 82 | /// </summary> |
| 83 | /// <param name="symbol">Symbol to remove.</param> |
| 84 | /// <returns>True if the symbol was removed; otherwise false.</returns> |
| 85 | public bool RemoveSymbol(IntermediateSymbol symbol) |
| 86 | { |
| 87 | return this.symbols.Remove(symbol); |
| 88 | } |
| 89 | |
| 90 | /// <summary> |
| 91 | /// Parse a section from the JSON data. |
| 92 | /// </summary> |
| 93 | internal static IntermediateSection Deserialize(ISymbolDefinitionCreator creator, Uri baseUri, JsonObject jsonObject) |
| 94 | { |
| 95 | var id = jsonObject.GetValueOrDefault<string>("id"); |
| 96 | var type = jsonObject.GetEnumOrDefault("type", SectionType.Unknown); |
| 97 | |
| 98 | if (SectionType.Unknown == type) |
| 99 | { |
| 100 | throw new ArgumentException("JSON object is not a valid section, unknown section type", nameof(type)); |
| 101 | } |
| 102 | |
| 103 | var section = new IntermediateSection(id, type); |
| 104 | |
| 105 | var symbolsJson = jsonObject.GetValueOrDefault<JsonArray>("symbols"); |
| 106 | |
| 107 | foreach (JsonObject symbolJson in symbolsJson) |
| 108 | { |
| 109 | var symbol = IntermediateSymbol.Deserialize(creator, baseUri, symbolJson); |
| 110 | section.symbols.Add(symbol); |
| 111 | } |
| 112 | |
| 113 | return section; |
| 114 | } |
| 115 | |
| 116 | internal JsonObject Serialize() |
| 117 | { |
| 118 | var jsonObject = new JsonObject |
| 119 | { |
| 120 | { "type", this.Type.ToString().ToLowerInvariant() } |
| 121 | }; |
| 122 | |
| 123 | if (!String.IsNullOrEmpty(this.Id)) |
| 124 | { |
| 125 | jsonObject.Add("id", this.Id); |
| 126 | } |
| 127 | |
| 128 | var symbolsJson = new JsonArray(this.Symbols.Count); |
| 129 | |
| 130 | foreach (var symbol in this.Symbols) |
| 131 | { |
| 132 | var symbolJson = symbol.Serialize(); |
| 133 | symbolsJson.Add(symbolJson); |
| 134 | } |
| 135 | |
| 136 | jsonObject.Add("symbols", symbolsJson); |
| 137 | |
| 138 | return jsonObject; |
| 139 | } |
| 140 | } |
| 141 | } |