2 // System.Security.Cryptography.MiniParser: Internal XML parser implementation
9 * Copyright (c) 2001, 2002 Wild West Software
10 * Copyright (c) 2002 Sergey Chaban
12 * Permission is hereby granted, free of charge, to any person
13 * obtaining a copy of this software and associated documentation
14 * files (the "Software"), to deal in the Software without restriction,
15 * including without limitation the rights to use, copy, modify, merge,
16 * publish, distribute, sublicense, and/or sell copies of the Software,
17 * and to permit persons to whom the Software is furnished to do so,
18 * subject to the following conditions:
20 * The above copyright notice and this permission notice shall be included
21 * in all copies or substantial portions of the Software.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
25 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
27 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
29 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
35 using System.Globalization;
37 namespace System.Security.Cryptography {
39 internal class MiniParser {
41 public interface IReader {
45 public interface IAttrList {
48 string GetName(int i);
49 string GetValue(int i);
50 string GetValue(string name);
51 void ChangeValue(string name, string newValue);
53 string[] Values {get;}
56 public interface IMutableAttrList : IAttrList {
58 void Add(string name, string value);
59 void CopyFrom(IAttrList attrs);
61 void Remove(string name);
64 public interface IHandler {
65 void OnStartParsing(MiniParser parser);
66 void OnStartElement(string name, IAttrList attrs);
67 void OnEndElement(string name);
68 void OnChars(string ch);
69 void OnEndParsing(MiniParser parser);
72 public class HandlerAdapter : IHandler {
73 public HandlerAdapter() {}
74 public void OnStartParsing(MiniParser parser) {}
75 public void OnStartElement(string name, IAttrList attrs) {}
76 public void OnEndElement(string name) {}
77 public void OnChars(string ch) {}
78 public void OnEndParsing(MiniParser parser) {}
81 private enum CharKind : byte {
101 private enum ActionCode : byte {
112 FLUSH_CHARS_STATE_CHANGE = 0xA,
113 ACC_CHARS_STATE_CHANGE = 0xB,
119 public class AttrListImpl : IMutableAttrList {
120 protected ArrayList names;
121 protected ArrayList values;
123 public AttrListImpl() : this(0) {}
125 public AttrListImpl(int initialCapacity) {
126 if (initialCapacity <= 0) {
127 names = new ArrayList();
128 values = new ArrayList();
130 names = new ArrayList(initialCapacity);
131 values = new ArrayList(initialCapacity);
135 public AttrListImpl(IAttrList attrs)
136 : this(attrs != null ? attrs.Length : 0) {
137 if (attrs != null) this.CopyFrom(attrs);
141 get {return names.Count;}
144 public bool IsEmpty {
145 get {return this.Length != 0;}
148 public string GetName(int i) {
150 if (i >= 0 && i < this.Length) {
151 res = names[i] as string;
156 public string GetValue(int i) {
158 if (i >= 0 && i < this.Length) {
159 res = values[i] as string;
164 public string GetValue(string name) {
165 return this.GetValue(names.IndexOf(name));
168 public void ChangeValue(string name, string newValue) {
169 int i = names.IndexOf(name);
170 if (i >= 0 && i < this.Length) {
171 values[i] = newValue;
175 public string[] Names {
176 get {return names.ToArray(typeof(string)) as string[];}
179 public string[] Values {
180 get {return values.ToArray(typeof(string)) as string[];}
183 public void Clear() {
188 public void Add(string name, string value) {
193 public void Remove(int i) {
200 public void Remove(string name) {
201 this.Remove(names.IndexOf(name));
204 public void CopyFrom(IAttrList attrs) {
205 if (attrs != null && ((object)this == (object)attrs)) {
207 int n = attrs.Length;
208 for (int i = 0; i < n; i++) {
209 this.Add(attrs.GetName(i), attrs.GetValue(i));
215 public class XMLError : Exception {
216 protected string descr;
217 protected int line, column;
218 public XMLError() : this("Unknown") {}
219 public XMLError(string descr) : this(descr, -1, -1) {}
220 public XMLError(string descr, int line, int column)
224 this.column = column;
226 public int Line {get {return line;}}
227 public int Column {get {return column;}}
228 public override string ToString() {
229 return (String.Format("{0} @ (line = {1}, col = {2})", descr, line, column));
233 private static readonly int INPUT_RANGE = 13;
234 private static readonly ushort[] tbl = {
235 ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 1, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 0, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ERROR << 8) | 128, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 128, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 128, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 128, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 128, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 128, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 128, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 128, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 128, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 128, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 128,
236 ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 2, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 133, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 16, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.FLUSH_CHARS_STATE_CHANGE << 8) | 4,
237 ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.END_ELEM << 8) | 0, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 2, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 2, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129,
238 ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 5, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3,
239 ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 4, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.END_NAME << 8) | 6, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.END_NAME << 8) | 7, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.END_NAME << 8) | 8, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129,
240 ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 0, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3,
241 ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 0, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ERROR << 8) | 129,
242 ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.FLUSH_CHARS_STATE_CHANGE << 8) | 1, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.PROC_CHAR_REF << 8) | 10, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 7, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10,
243 ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 9, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.START_ELEM << 8) | 6, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.START_ELEM << 8) | 7, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 8, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129,
244 ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 9, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.SET_ATTR_NAME << 8) | 11, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 12, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 130,
245 ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 13, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.PROC_CHAR_REF << 8) | 10, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10,
246 ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 14, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 15, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 11, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 132, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 132, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 132, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 132, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 132, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 132, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 132, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 132, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 132, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ERROR << 8) | 132,
247 ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.SET_ATTR_NAME << 8) | 11, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 12, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 130, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ERROR << 8) | 130,
248 ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.SEND_CHARS << 8) | 2, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 16, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 134, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 134, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 134, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 134, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 134, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 134, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 134, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ERROR << 8) | 134, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 134, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 134, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ERROR << 8) | 134,
249 ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.SET_ATTR_VAL << 8) | 17, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.PROC_CHAR_REF << 8) | 14, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14,
250 ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.SET_ATTR_VAL << 8) | 17, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.PROC_CHAR_REF << 8) | 15, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15,
251 ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.START_CDATA << 8) | 18, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 0, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19,
252 ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.START_ELEM << 8) | 6, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.START_ELEM << 8) | 7, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 17, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 9, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129,
253 ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.END_CDATA << 8) | 10, ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18,
254 ((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19, ((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19,
258 protected static string[] errors = {
259 /* 0 */ "Expected element",
260 /* 1 */ "Invalid character in tag",
262 /* 3 */ "Invalid character entity",
263 /* 4 */ "Invalid attr value",
265 /* 6 */ "No end tag",
266 /* 7 */ "Bad entity ref"
271 protected int[] twoCharBuff;
272 protected bool splitCData;
274 public MiniParser() {
275 twoCharBuff = new int[2];
280 public void Reset() {
285 protected static bool StrEquals(string str, StringBuilder sb, int sbStart, int len) {
286 if (len != str.Length) return false;
287 for (int i = 0; i < len; i++) {
288 if (str[i] != sb[sbStart + i]) return false;
293 protected void FatalErr(string descr) {
294 throw new XMLError(descr, this.line, this.col);
297 protected static int Xlat(int charCode, int state) {
298 int p = state * INPUT_RANGE;
299 int n = Math.Min(tbl.Length - p, INPUT_RANGE);
301 ushort code = tbl[p];
302 if (charCode == (code >> 12)) return (code & 0xFFF);
308 public void Parse(IReader reader, IHandler handler) {
309 if (reader == null) throw new ArgumentNullException("reader");
310 if (handler == null) handler = new HandlerAdapter();
312 AttrListImpl attrList = new AttrListImpl();
313 string lastAttrName = null;
314 Stack tagStack = new Stack();
315 string elementName = null;
320 StringBuilder sbChars = new StringBuilder();
321 bool seenCData = false;
322 bool isComment = false;
324 int bracketSwitch = 0;
326 handler.OnStartParsing(this);
332 currCh = reader.Read();
335 if (stateCode != 0) {
336 FatalErr("Unexpected EOF");
341 int charCode = "<>/?=&'\"![ ]\t\r\n".IndexOf((char)currCh) & 0xF;
342 if (charCode == (int)CharKind.CR) continue; // ignore
343 // whitepace ::= (#x20 | #x9 | #xd | #xa)+
344 if (charCode == (int)CharKind.TAB) charCode = (int)CharKind.SPACE; // tab == space
345 if (charCode == (int)CharKind.EOL) {
348 charCode = (int)CharKind.SPACE;
351 int actionCode = MiniParser.Xlat(charCode, stateCode);
352 stateCode = actionCode & 0xFF;
353 // Ignore newline inside attribute value.
354 if (currCh == '\n' && (stateCode == 0xE || stateCode == 0xF)) continue;
357 if (stateCode >= 0x80) {
358 if (stateCode == 0xFF) {
359 FatalErr("State dispatch error.");
361 FatalErr(errors[stateCode ^ 0x80]);
365 switch (actionCode) {
366 case (int)ActionCode.START_ELEM:
367 handler.OnStartElement(elementName, attrList);
369 tagStack.Push(elementName);
371 handler.OnEndElement(elementName);
376 case (int)ActionCode.END_ELEM:
377 elementName = sbChars.ToString();
378 sbChars = new StringBuilder();
379 string endName = null;
380 if (tagStack.Count == 0 ||
381 elementName != (endName = tagStack.Pop() as string)) {
382 if (endName == null) {
383 FatalErr("Tag stack underflow");
385 FatalErr(String.Format("Expected end tag '{0}' but found '{1}'", elementName, endName));
388 handler.OnEndElement(elementName);
391 case (int)ActionCode.END_NAME:
392 elementName = sbChars.ToString();
393 sbChars = new StringBuilder();
394 if (currCh != '/' && currCh != '>') break;
395 goto case (int)ActionCode.START_ELEM;
397 case (int)ActionCode.SET_ATTR_NAME:
398 lastAttrName = sbChars.ToString();
399 sbChars = new StringBuilder();
402 case (int)ActionCode.SET_ATTR_VAL:
403 if (lastAttrName == null) FatalErr("Internal error.");
404 attrList.Add(lastAttrName, sbChars.ToString());
405 sbChars = new StringBuilder();
409 case (int)ActionCode.SEND_CHARS:
410 handler.OnChars(sbChars.ToString());
411 sbChars = new StringBuilder();
414 case (int)ActionCode.START_CDATA:
415 string cdata = "CDATA[";
420 currCh = reader.Read();
422 if (currCh != '-') FatalErr("Invalid comment");
435 for (int i = 0; i < cdata.Length; i++) {
436 if (reader.Read() != cdata[i]) {
441 this.col += cdata.Length;
446 case (int)ActionCode.END_CDATA:
450 while (currCh == ']') {
451 currCh = reader.Read();
456 for (int i = 0; i < n; i++) sbChars.Append(']');
457 sbChars.Append((char)currCh);
460 for (int i = 0; i < n-2; i++) sbChars.Append(']');
467 case (int)ActionCode.ERROR:
468 FatalErr(String.Format("Error {0}", stateCode));
471 case (int)ActionCode.STATE_CHANGE:
474 case (int)ActionCode.FLUSH_CHARS_STATE_CHANGE:
475 sbChars = new StringBuilder();
476 if (currCh != '<') goto case (int)ActionCode.ACC_CHARS_STATE_CHANGE;
479 case (int)ActionCode.ACC_CHARS_STATE_CHANGE:
480 sbChars.Append((char)currCh);
483 case (int)ActionCode.ACC_CDATA:
486 && twoCharBuff[0] == '-'
487 && twoCharBuff[1] == '-') {
491 twoCharBuff[0] = twoCharBuff[1];
492 twoCharBuff[1] = currCh;
495 if (currCh == '<' || currCh == '>') bracketSwitch ^= 1;
496 if (currCh == '>' && bracketSwitch != 0) {
502 && sbChars.Length > 0
504 handler.OnChars(sbChars.ToString());
505 sbChars = new StringBuilder();
508 sbChars.Append((char)currCh);
512 case (int)ActionCode.PROC_CHAR_REF:
513 currCh = reader.Read();
514 int cl = this.col + 1;
515 if (currCh == '#') { // character reference
519 currCh = reader.Read();
523 currCh = reader.Read();
528 NumberStyles style = r == 16 ? NumberStyles.HexNumber : NumberStyles.Integer;
532 if (Char.IsNumber((char)currCh) || "abcdef".IndexOf(Char.ToLower((char)currCh)) != -1) {
534 x = Int32.Parse(new string((char)currCh, 1), style);
535 } catch (FormatException) {x = -1;}
541 currCh = reader.Read();
545 if (currCh == ';' && nDigits > 0) {
546 sbChars.Append((char)chCode);
548 FatalErr("Bad char ref");
552 string entityRefChars = "aglmopqstu"; // amp | apos | quot | gt | lt
553 string entities = "&'\"><";
560 int sbLen = sbChars.Length;
563 if (pos != 0xF) pos = entityRefChars.IndexOf((char)currCh) & 0xF;
564 if (pos == 0xF) FatalErr(errors[7]);
565 sbChars.Append((char)currCh);
567 int path = "\uFF35\u3F8F\u4F8F\u0F5F\uFF78\uE1F4\u2299\uEEFF\uEEFF\uFF4F"[pos];
568 int lBr = (path >> 4) & 0xF;
569 int rBr = path & 0xF;
570 int lPred = path >> 12;
571 int rPred = (path >> 8) & 0xF;
572 currCh = reader.Read();
575 if (lBr != 0xF && currCh == entityRefChars[lBr]) {
576 if (lPred < 0xE) entIdx = lPred;
578 predShift = 12; // left
579 } else if (rBr != 0xF && currCh == entityRefChars[rBr]) {
580 if (rPred < 0xE) entIdx = rPred;
582 predShift = 8; // right
583 } else if (currCh == ';') {
586 && ((path >> predShift) & 0xF) == 0xE) break;
587 continue; // pos == 0xF
594 int l = cl - this.col - 1;
597 &&(StrEquals("amp", sbChars, sbLen, l)
598 || StrEquals("apos", sbChars, sbLen, l)
599 || StrEquals("quot", sbChars, sbLen, l)
600 || StrEquals("lt", sbChars, sbLen, l)
601 || StrEquals("gt", sbChars, sbLen, l))
603 sbChars.Length = sbLen;
604 sbChars.Append(entities[entIdx]);
605 } else FatalErr(errors[7]);
612 FatalErr(String.Format("Unexpected action code - {0}.", actionCode));
617 handler.OnEndParsing(this);