File: StaticDataManager.cs

package info (click to toggle)
mono 6.14.1%2Bds2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,282,732 kB
  • sloc: cs: 11,182,461; xml: 2,850,281; ansic: 699,123; cpp: 122,919; perl: 58,604; javascript: 30,841; asm: 21,845; makefile: 19,602; sh: 10,973; python: 4,772; pascal: 925; sql: 859; sed: 16; php: 1
file content (221 lines) | stat: -rw-r--r-- 8,651 bytes parent folder | download | duplicates (6)
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
//------------------------------------------------------------------------------
// <copyright file="StaticDataManager.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
// <owner current="true" primary="true">Microsoft</owner>
// <owner current="false">Microsoft</owner>
//------------------------------------------------------------------------------

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Xml.Xsl.Qil;
using System.Xml.Xsl.Runtime;

namespace System.Xml.Xsl.IlGen {

    /// <summary>
    /// This internal class maintains a list of unique values.  Each unique value is assigned a unique ID, which can
    /// be used to quickly access the value, since it corresponds to the value's position in the list.
    /// </summary>
    internal class UniqueList<T> {
        private Dictionary<T, int> lookup = new Dictionary<T, int>();
        private List<T> list = new List<T>();

        /// <summary>
        /// If "value" is already in the list, do not add it.  Return the unique ID of the value in the list.
        /// </summary>
        public int Add(T value) {
            int id;

            if (!this.lookup.ContainsKey(value)) {
                // The value does not yet exist, so add it to the list
                id = list.Count;
                this.lookup.Add(value, id);
                this.list.Add(value);
            }
            else {
                id = this.lookup[value];
            }

            return id;
        }

        /// <summary>
        /// Return an array of the unique values.
        /// </summary>
        public T[] ToArray() {
            return list.ToArray();
        }
    }


    /// <summary>
    /// Manages all static data that is used by the runtime.  This includes:
    ///   1. All NCName and QName atoms that will be used at run-time
    ///   2. All QName filters that will be used at run-time
    ///   3. All Xml types that will be used at run-time
    ///   4. All global variables and parameters
    /// </summary>
    internal class StaticDataManager {
        private UniqueList<string> uniqueNames;
        private UniqueList<Int32Pair> uniqueFilters;
        private List<StringPair[]> prefixMappingsList;
        private List<string> globalNames;
        private UniqueList<EarlyBoundInfo> earlyInfo;
        private UniqueList<XmlQueryType> uniqueXmlTypes;
        private UniqueList<XmlCollation> uniqueCollations;

        /// <summary>
        /// Add "name" to the list of unique names that are used by this query.  Return the index of
        /// the unique name in the list.
        /// </summary>
        public int DeclareName(string name) {
            if (this.uniqueNames == null)
                this.uniqueNames = new UniqueList<string>();

            return this.uniqueNames.Add(name);
        }

        /// <summary>
        /// Return an array of all names that are used by the query (null if no names).
        /// </summary>
        public string[] Names {
            get { return (this.uniqueNames != null) ? this.uniqueNames.ToArray() : null; }
        }

        /// <summary>
        /// Add a name filter to the list of unique filters that are used by this query.  Return the index of
        /// the unique filter in the list.
        /// </summary>
        public int DeclareNameFilter(string locName, string nsUri) {
            if (this.uniqueFilters == null)
                this.uniqueFilters = new UniqueList<Int32Pair>();

            return this.uniqueFilters.Add(new Int32Pair(DeclareName(locName), DeclareName(nsUri)));
        }

        /// <summary>
        /// Return an array of all name filters, where each name filter is represented as a pair of integer offsets (localName, namespaceUri)
        /// into the Names array (null if no name filters).
        /// </summary>
        public Int32Pair[] NameFilters {
            get { return (this.uniqueFilters != null) ? this.uniqueFilters.ToArray() : null; }
        }

        /// <summary>
        /// Add a list of QilExpression NamespaceDeclarations to an array of strings (prefix followed by namespace URI).
        /// Return index of the prefix mappings within this array.
        /// </summary>
        public int DeclarePrefixMappings(IList<QilNode> list) {
            StringPair[] prefixMappings;

            // Fill mappings array
            prefixMappings = new StringPair[list.Count];
            for (int i = 0; i < list.Count; i++) {
                // Each entry in mappings array must be a constant NamespaceDeclaration
                QilBinary ndNmspDecl = (QilBinary) list[i];
                Debug.Assert(ndNmspDecl != null);
                Debug.Assert(ndNmspDecl.Left is QilLiteral && ndNmspDecl.Right is QilLiteral);

                prefixMappings[i] = new StringPair((string) (QilLiteral) ndNmspDecl.Left, (string) (QilLiteral) ndNmspDecl.Right);
            }

            // Add mappings to list and return index
            if (this.prefixMappingsList == null)
                this.prefixMappingsList = new List<StringPair[]>();

            this.prefixMappingsList.Add(prefixMappings);
            return this.prefixMappingsList.Count - 1;
        }

        /// <summary>
        /// Return an array of all prefix mappings that are used by the query to compute names (null if no mappings).
        /// </summary>
        public StringPair[][] PrefixMappingsList {
            get { return (this.prefixMappingsList != null) ? this.prefixMappingsList.ToArray() : null; }
        }

        /// <summary>
        /// Declare a new global variable or parameter.
        /// </summary>
        public int DeclareGlobalValue(string name) {
            int idx;

            if (this.globalNames == null)
                this.globalNames = new List<string>();

            idx = this.globalNames.Count;
            this.globalNames.Add(name);
            return idx;
        }

        /// <summary>
        /// Return an array containing the names of all global variables and parameters.
        /// </summary>
        public string[] GlobalNames {
            get { return (this.globalNames != null) ? this.globalNames.ToArray() : null; }
        }

        /// <summary>
        /// Add early bound information to a list that is used by this query.  Return the index of
        /// the early bound information in the list.
        /// </summary>
        public int DeclareEarlyBound(string namespaceUri, Type ebType) {
            if (this.earlyInfo == null)
                this.earlyInfo = new UniqueList<EarlyBoundInfo>();

            return this.earlyInfo.Add(new EarlyBoundInfo(namespaceUri, ebType));
        }

        /// <summary>
        /// Return an array of all early bound information that is used by the query (null if none is used).
        /// </summary>
        public EarlyBoundInfo[] EarlyBound {
            get {
                if (this.earlyInfo != null)
                    return this.earlyInfo.ToArray();

                return null;
            }
        }

        /// <summary>
        /// Add "type" to the list of unique types that are used by this query.  Return the index of
        /// the unique type in the list.
        /// </summary>
        public int DeclareXmlType(XmlQueryType type) {
            if (this.uniqueXmlTypes == null)
                this.uniqueXmlTypes = new UniqueList<XmlQueryType>();

            XmlQueryTypeFactory.CheckSerializability(type);
            return this.uniqueXmlTypes.Add(type);
        }

        /// <summary>
        /// Return an array of all types that are used by the query (null if no names).
        /// </summary>
        public XmlQueryType[] XmlTypes {
            get { return (this.uniqueXmlTypes != null) ? this.uniqueXmlTypes.ToArray() : null; }
        }

        /// <summary>
        /// Add "collation" to the list of unique collations that are used by this query.  Return the index of
        /// the unique collation in the list.
        /// </summary>
        public int DeclareCollation(string collation) {
            if (this.uniqueCollations == null)
                this.uniqueCollations = new UniqueList<XmlCollation>();

            return this.uniqueCollations.Add(XmlCollation.Create(collation));
        }

        /// <summary>
        /// Return an array of all collations that are used by the query (null if no names).
        /// </summary>
        public XmlCollation[] Collations {
            get { return (this.uniqueCollations != null) ? this.uniqueCollations.ToArray() : null; }
        }
    }
}