aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Data/IntermediateSection.cs
blob: 86aa0c898e69ad4b43b0bfe0771f44e8fadc9c5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// 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.

namespace WixToolset.Data
{
    using System;
    using System.Collections.Generic;
    using SimpleJson;

    /// <summary>
    /// Section in an intermediate file.
    /// </summary>
    public class IntermediateSection
    {
        private readonly List<IntermediateSymbol> symbols;

        /// <summary>
        /// Creates a new section as part of an intermediate.
        /// </summary>
        /// <param name="id">Identifier for section.</param>
        /// <param name="type">Type of section.</param>
        /// <param name="codepage">Codepage for resulting database.</param>
        /// <param name="compilationId">Optional compilation identifier</param>
        public IntermediateSection(string id, SectionType type, int codepage, string compilationId = null)
        {
            this.Id = id;
            this.Type = type;
            this.Codepage = codepage;
            this.CompilationId = compilationId;
            this.symbols = new List<IntermediateSymbol>();
        }

        /// <summary>
        /// Gets the identifier for the section.
        /// </summary>
        /// <value>Section identifier.</value>
        public string Id { get; }

        /// <summary>
        /// Gets the type of the section.
        /// </summary>
        /// <value>Type of section.</value>
        public SectionType Type { get; }

        /// <summary>
        /// Gets the codepage for the section.
        /// </summary>
        /// <value>Codepage for the section.</value>
        public int Codepage { get; }

        /// <summary>
        /// Gets and sets the identifier of the compilation of the source file containing the section.
        /// </summary>
        public string CompilationId { get; }

        /// <summary>
        /// Gets and sets the identifier of the library that combined the section.
        /// </summary>
        public string LibraryId { get; private set; }

        /// <summary>
        /// Symbols in the section.
        /// </summary>
        public IReadOnlyCollection<IntermediateSymbol> Symbols => this.symbols;

        /// <summary>
        /// Adds a symbol to the section.
        /// </summary>
        /// <typeparam name="T">Type of IntermediateSymbol to add to the section.</typeparam>
        /// <param name="symbol">Symbol to add to the section.</param>
        /// <returns>Symbol added to the section.</returns>
        public T AddSymbol<T>(T symbol) where T : IntermediateSymbol
        {
            this.symbols.Add(symbol);
            return symbol;
        }

        /// <summary>
        /// Assigns the section to a library.
        /// </summary>
        /// <param name="libraryId">Identifier of the library.</param>
        public void AssignToLibrary(string libraryId)
        {
            this.LibraryId = libraryId;
        }

        /// <summary>
        /// Removes a symbol from the section.
        /// </summary>
        /// <param name="symbol">Symbol to remove.</param>
        /// <returns>True if the symbol was removed; otherwise false.</returns>
        public bool RemoveSymbol(IntermediateSymbol symbol)
        {
            return this.symbols.Remove(symbol);
        }

        /// <summary>
        /// Parse a section from the JSON data.
        /// </summary>
        internal static IntermediateSection Deserialize(ISymbolDefinitionCreator creator, Uri baseUri, JsonObject jsonObject)
        {
            var codepage = jsonObject.GetValueOrDefault("codepage", 0);
            var id = jsonObject.GetValueOrDefault<string>("id");
            var type = jsonObject.GetEnumOrDefault("type", SectionType.Unknown);

            if (SectionType.Unknown == type)
            {
                throw new ArgumentException("JSON object is not a valid section, unknown section type", nameof(type));
            }

            var section = new IntermediateSection(id, type, codepage);

            var symbolsJson = jsonObject.GetValueOrDefault<JsonArray>("symbols");

            foreach (JsonObject symbolJson in symbolsJson)
            {
                var symbol = IntermediateSymbol.Deserialize(creator, baseUri, symbolJson);
                section.symbols.Add(symbol);
            }

            return section;
        }

        internal JsonObject Serialize()
        {
            var jsonObject = new JsonObject
            {
                { "type", this.Type.ToString().ToLowerInvariant() },
                { "codepage", this.Codepage }
            };

            if (!String.IsNullOrEmpty(this.Id))
            {
                jsonObject.Add("id", this.Id);
            }

            var symbolsJson = new JsonArray(this.Symbols.Count);

            foreach (var symbol in this.Symbols)
            {
                var symbolJson = symbol.Serialize();
                symbolsJson.Add(symbolJson);
            }

            jsonObject.Add("symbols", symbolsJson);

            return jsonObject;
        }
    }
}