(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / corlib / Mono.Xml / MiniParser.cs
blobc155737bcd9c126e91a05e16ed4b6514c72dc01f
1 //
2 // System.Security.Cryptography.MiniParser: Internal XML parser implementation
3 //
4 // Authors:
5 // Sergey Chaban
6 //
7 // Copyright (c) 2001, 2002 Wild West Software
8 // Copyright (c) 2002 Sergey Chaban
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System;
32 using System.Text;
33 using System.Collections;
34 using System.Globalization;
36 namespace Mono.Xml {
38 #if INSIDE_CORLIB
39 internal
40 #else
41 [CLSCompliant(false)]
42 public
43 #endif
44 class MiniParser {
46 public interface IReader {
47 int Read();
50 public interface IAttrList {
51 int Length {get;}
52 bool IsEmpty {get;}
53 string GetName(int i);
54 string GetValue(int i);
55 string GetValue(string name);
56 void ChangeValue(string name, string newValue);
57 string[] Names {get;}
58 string[] Values {get;}
61 public interface IMutableAttrList : IAttrList {
62 void Clear();
63 void Add(string name, string value);
64 void CopyFrom(IAttrList attrs);
65 void Remove(int i);
66 void Remove(string name);
69 public interface IHandler {
70 void OnStartParsing(MiniParser parser);
71 void OnStartElement(string name, IAttrList attrs);
72 void OnEndElement(string name);
73 void OnChars(string ch);
74 void OnEndParsing(MiniParser parser);
77 public class HandlerAdapter : IHandler {
78 public HandlerAdapter() {}
79 public void OnStartParsing(MiniParser parser) {}
80 public void OnStartElement(string name, IAttrList attrs) {}
81 public void OnEndElement(string name) {}
82 public void OnChars(string ch) {}
83 public void OnEndParsing(MiniParser parser) {}
86 private enum CharKind : byte {
87 LEFT_BR = 0,
88 RIGHT_BR = 1,
89 SLASH = 2,
90 PI_MARK = 3,
91 EQ = 4,
92 AMP = 5,
93 SQUOTE = 6,
94 DQUOTE = 7,
95 BANG = 8,
96 LEFT_SQBR = 9,
97 SPACE = 0xA,
98 RIGHT_SQBR = 0xB,
99 TAB = 0xC,
100 CR = 0xD,
101 EOL = 0xE,
102 CHARS = 0xF,
103 UNKNOWN = 0x1F
106 private enum ActionCode : byte {
107 START_ELEM = 0,
108 END_ELEM = 1,
109 END_NAME = 2,
110 SET_ATTR_NAME = 3,
111 SET_ATTR_VAL = 4,
112 SEND_CHARS = 5,
113 START_CDATA = 6,
114 END_CDATA = 7,
115 ERROR = 8,
116 STATE_CHANGE = 9,
117 FLUSH_CHARS_STATE_CHANGE = 0xA,
118 ACC_CHARS_STATE_CHANGE = 0xB,
119 ACC_CDATA = 0xC,
120 PROC_CHAR_REF = 0xD,
121 UNKNOWN = 0xF
124 public class AttrListImpl : IMutableAttrList {
125 protected ArrayList names;
126 protected ArrayList values;
128 public AttrListImpl() : this(0) {}
130 public AttrListImpl(int initialCapacity) {
131 if (initialCapacity <= 0) {
132 names = new ArrayList();
133 values = new ArrayList();
134 } else {
135 names = new ArrayList(initialCapacity);
136 values = new ArrayList(initialCapacity);
140 public AttrListImpl(IAttrList attrs)
141 : this(attrs != null ? attrs.Length : 0) {
142 if (attrs != null) this.CopyFrom(attrs);
145 public int Length {
146 get {return names.Count;}
149 public bool IsEmpty {
150 get {return this.Length != 0;}
153 public string GetName(int i) {
154 string res = null;
155 if (i >= 0 && i < this.Length) {
156 res = names[i] as string;
158 return res;
161 public string GetValue(int i) {
162 string res = null;
163 if (i >= 0 && i < this.Length) {
164 res = values[i] as string;
166 return res;
169 public string GetValue(string name) {
170 return this.GetValue(names.IndexOf(name));
173 public void ChangeValue(string name, string newValue) {
174 int i = names.IndexOf(name);
175 if (i >= 0 && i < this.Length) {
176 values[i] = newValue;
180 public string[] Names {
181 get {return names.ToArray(typeof(string)) as string[];}
184 public string[] Values {
185 get {return values.ToArray(typeof(string)) as string[];}
188 public void Clear() {
189 names.Clear();
190 values.Clear();
193 public void Add(string name, string value) {
194 names.Add(name);
195 values.Add(value);
198 public void Remove(int i) {
199 if (i >= 0) {
200 names.RemoveAt(i);
201 values.RemoveAt(i);
205 public void Remove(string name) {
206 this.Remove(names.IndexOf(name));
209 public void CopyFrom(IAttrList attrs) {
210 if (attrs != null && ((object)this == (object)attrs)) {
211 this.Clear();
212 int n = attrs.Length;
213 for (int i = 0; i < n; i++) {
214 this.Add(attrs.GetName(i), attrs.GetValue(i));
220 public class XMLError : Exception {
221 protected string descr;
222 protected int line, column;
223 public XMLError() : this("Unknown") {}
224 public XMLError(string descr) : this(descr, -1, -1) {}
225 public XMLError(string descr, int line, int column)
226 : base(descr) {
227 this.descr = descr;
228 this.line = line;
229 this.column = column;
231 public int Line {get {return line;}}
232 public int Column {get {return column;}}
233 public override string ToString() {
234 return (String.Format("{0} @ (line = {1}, col = {2})", descr, line, column));
238 private static readonly int INPUT_RANGE = 13;
239 private static readonly ushort[] tbl = {
240 (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 1), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 0), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ERROR << 8) | 128), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 128), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 128), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 128), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 128), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 128), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 128), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 128), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 128), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 128), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 128),
241 (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 2), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 133), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 16), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.FLUSH_CHARS_STATE_CHANGE << 8) | 4),
242 (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.END_ELEM << 8) | 0), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 2), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 2), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129),
243 (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 5), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3),
244 (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 4), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.END_NAME << 8) | 6), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.END_NAME << 8) | 7), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.END_NAME << 8) | 8), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129),
245 (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 0), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 3),
246 (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 0), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ERROR << 8) | 129),
247 (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.FLUSH_CHARS_STATE_CHANGE << 8) | 1), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.PROC_CHAR_REF << 8) | 10), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 7), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10),
248 (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 9), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.START_ELEM << 8) | 6), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.START_ELEM << 8) | 7), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 8), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129),
249 (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 9), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.SET_ATTR_NAME << 8) | 11), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 12), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 130),
250 (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 13), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.PROC_CHAR_REF << 8) | 10), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 10),
251 (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 14), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 15), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 11), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 132), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 132), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 132), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 132), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 132), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 132), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 132), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 132), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 132), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ERROR << 8) | 132),
252 (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.SET_ATTR_NAME << 8) | 11), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 12), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 130), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ERROR << 8) | 130),
253 (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.SEND_CHARS << 8) | 2), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 16), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 134), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 134), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 134), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 134), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 134), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 134), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 134), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ERROR << 8) | 134), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 134), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 134), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ERROR << 8) | 134),
254 (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.SET_ATTR_VAL << 8) | 17), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.PROC_CHAR_REF << 8) | 14), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 14),
255 (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.SET_ATTR_VAL << 8) | 17), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.PROC_CHAR_REF << 8) | 15), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 15),
256 (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.START_CDATA << 8) | 18), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 0), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.START_CDATA << 8) | 19),
257 (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.START_ELEM << 8) | 6), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.START_ELEM << 8) | 7), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.STATE_CHANGE << 8) | 17), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CHARS_STATE_CHANGE << 8) | 9), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ERROR << 8) | 129), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ERROR << 8) | 129),
258 (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.END_CDATA << 8) | 10), (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 18),
259 (ushort)(((ushort)CharKind.LEFT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.SLASH << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.RIGHT_BR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.PI_MARK << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.EQ << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.AMP << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.SQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.BANG << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.LEFT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.SPACE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.RIGHT_SQBR << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.DQUOTE << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19), (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.ACC_CDATA << 8) | 19),
260 (ushort)(((ushort)CharKind.CHARS << 12) | ((ushort)ActionCode.UNKNOWN << 8) | 255),
261 0xFFFF
264 protected static string[] errors = {
265 /* 0 */ "Expected element",
266 /* 1 */ "Invalid character in tag",
267 /* 2 */ "No '='",
268 /* 3 */ "Invalid character entity",
269 /* 4 */ "Invalid attr value",
270 /* 5 */ "Empty tag",
271 /* 6 */ "No end tag",
272 /* 7 */ "Bad entity ref"
275 protected int line;
276 protected int col;
277 protected int[] twoCharBuff;
278 protected bool splitCData;
280 public MiniParser() {
281 twoCharBuff = new int[2];
282 splitCData = false;
283 Reset();
286 public void Reset() {
287 line = 0;
288 col = 0;
291 protected static bool StrEquals(string str, StringBuilder sb, int sbStart, int len) {
292 if (len != str.Length) return false;
293 for (int i = 0; i < len; i++) {
294 if (str[i] != sb[sbStart + i]) return false;
296 return true;
299 protected void FatalErr(string descr) {
300 throw new XMLError(descr, this.line, this.col);
303 protected static int Xlat(int charCode, int state) {
304 int p = state * INPUT_RANGE;
305 int n = System.Math.Min(tbl.Length - p, INPUT_RANGE);
306 for (;--n >= 0;) {
307 ushort code = tbl[p];
308 if (charCode == (code >> 12)) return (code & 0xFFF);
309 p++;
311 return 0xFFF;
314 public void Parse(IReader reader, IHandler handler) {
315 if (reader == null) throw new ArgumentNullException("reader");
316 if (handler == null) handler = new HandlerAdapter();
318 AttrListImpl attrList = new AttrListImpl();
319 string lastAttrName = null;
320 Stack tagStack = new Stack();
321 string elementName = null;
322 line = 1;
323 col = 0;
324 int currCh = 0;
325 int stateCode = 0;
326 StringBuilder sbChars = new StringBuilder();
327 bool seenCData = false;
328 bool isComment = false;
329 bool isDTD = false;
330 int bracketSwitch = 0;
332 handler.OnStartParsing(this);
334 while (true) {
335 ++this.col;
337 currCh = reader.Read();
339 if (currCh == -1) {
340 if (stateCode != 0) {
341 FatalErr("Unexpected EOF");
343 break;
346 int charCode = "<>/?=&'\"![ ]\t\r\n".IndexOf((char)currCh) & 0xF;
347 if (charCode == (int)CharKind.CR) continue; // ignore
348 // whitepace ::= (#x20 | #x9 | #xd | #xa)+
349 if (charCode == (int)CharKind.TAB) charCode = (int)CharKind.SPACE; // tab == space
350 if (charCode == (int)CharKind.EOL) {
351 this.col = 0;
352 this.line++;
353 charCode = (int)CharKind.SPACE;
356 int actionCode = MiniParser.Xlat(charCode, stateCode);
357 stateCode = actionCode & 0xFF;
358 // Ignore newline inside attribute value.
359 if (currCh == '\n' && (stateCode == 0xE || stateCode == 0xF)) continue;
360 actionCode >>= 8;
362 if (stateCode >= 0x80) {
363 if (stateCode == 0xFF) {
364 FatalErr("State dispatch error.");
365 } else {
366 FatalErr(errors[stateCode ^ 0x80]);
370 switch (actionCode) {
371 case (int)ActionCode.START_ELEM:
372 handler.OnStartElement(elementName, attrList);
373 if (currCh != '/') {
374 tagStack.Push(elementName);
375 } else {
376 handler.OnEndElement(elementName);
378 attrList.Clear();
379 break;
381 case (int)ActionCode.END_ELEM:
382 elementName = sbChars.ToString();
383 sbChars = new StringBuilder();
384 string endName = null;
385 if (tagStack.Count == 0 ||
386 elementName != (endName = tagStack.Pop() as string)) {
387 if (endName == null) {
388 FatalErr("Tag stack underflow");
389 } else {
390 FatalErr(String.Format("Expected end tag '{0}' but found '{1}'", elementName, endName));
393 handler.OnEndElement(elementName);
394 break;
396 case (int)ActionCode.END_NAME:
397 elementName = sbChars.ToString();
398 sbChars = new StringBuilder();
399 if (currCh != '/' && currCh != '>') break;
400 goto case (int)ActionCode.START_ELEM;
402 case (int)ActionCode.SET_ATTR_NAME:
403 lastAttrName = sbChars.ToString();
404 sbChars = new StringBuilder();
405 break;
407 case (int)ActionCode.SET_ATTR_VAL:
408 if (lastAttrName == null) FatalErr("Internal error.");
409 attrList.Add(lastAttrName, sbChars.ToString());
410 sbChars = new StringBuilder();
411 lastAttrName = null;
412 break;
414 case (int)ActionCode.SEND_CHARS:
415 handler.OnChars(sbChars.ToString());
416 sbChars = new StringBuilder();
417 break;
419 case (int)ActionCode.START_CDATA:
420 string cdata = "CDATA[";
421 isComment = false;
422 isDTD = false;
424 if (currCh == '-') {
425 currCh = reader.Read();
427 if (currCh != '-') FatalErr("Invalid comment");
429 this.col++;
430 isComment = true;
431 twoCharBuff[0] = -1;
432 twoCharBuff[1] = -1;
433 } else {
434 if (currCh != '[') {
435 isDTD = true;
436 bracketSwitch = 0;
437 break;
440 for (int i = 0; i < cdata.Length; i++) {
441 if (reader.Read() != cdata[i]) {
442 this.col += i+1;
443 break;
446 this.col += cdata.Length;
447 seenCData = true;
449 break;
451 case (int)ActionCode.END_CDATA:
452 int n = 0;
453 currCh = ']';
455 while (currCh == ']') {
456 currCh = reader.Read();
457 n++;
460 if (currCh != '>') {
461 for (int i = 0; i < n; i++) sbChars.Append(']');
462 sbChars.Append((char)currCh);
463 stateCode = 0x12;
464 } else {
465 for (int i = 0; i < n-2; i++) sbChars.Append(']');
466 seenCData = false;
469 this.col += n;
470 break;
472 case (int)ActionCode.ERROR:
473 FatalErr(String.Format("Error {0}", stateCode));
474 break;
476 case (int)ActionCode.STATE_CHANGE:
477 break;
479 case (int)ActionCode.FLUSH_CHARS_STATE_CHANGE:
480 sbChars = new StringBuilder();
481 if (currCh != '<') goto case (int)ActionCode.ACC_CHARS_STATE_CHANGE;
482 break;
484 case (int)ActionCode.ACC_CHARS_STATE_CHANGE:
485 sbChars.Append((char)currCh);
486 break;
488 case (int)ActionCode.ACC_CDATA:
489 if (isComment) {
490 if (currCh == '>'
491 && twoCharBuff[0] == '-'
492 && twoCharBuff[1] == '-') {
493 isComment = false;
494 stateCode = 0;
495 } else {
496 twoCharBuff[0] = twoCharBuff[1];
497 twoCharBuff[1] = currCh;
499 } else if (isDTD) {
500 if (currCh == '<' || currCh == '>') bracketSwitch ^= 1;
501 if (currCh == '>' && bracketSwitch != 0) {
502 isDTD = false;
503 stateCode = 0;
505 } else {
506 if (this.splitCData
507 && sbChars.Length > 0
508 && seenCData) {
509 handler.OnChars(sbChars.ToString());
510 sbChars = new StringBuilder();
512 seenCData = false;
513 sbChars.Append((char)currCh);
515 break;
517 case (int)ActionCode.PROC_CHAR_REF:
518 currCh = reader.Read();
519 int cl = this.col + 1;
520 if (currCh == '#') { // character reference
521 int r = 10;
522 int chCode = 0;
523 int nDigits = 0;
524 currCh = reader.Read();
525 cl++;
527 if (currCh == 'x') {
528 currCh = reader.Read();
529 cl++;
530 r=16;
533 NumberStyles style = r == 16 ? NumberStyles.HexNumber : NumberStyles.Integer;
535 while (true) {
536 int x = -1;
537 if (Char.IsNumber((char)currCh) || "abcdef".IndexOf(Char.ToLower((char)currCh)) != -1) {
538 try {
539 x = Int32.Parse(new string((char)currCh, 1), style);
540 } catch (FormatException) {x = -1;}
542 if (x == -1) break;
543 chCode *= r;
544 chCode += x;
545 nDigits++;
546 currCh = reader.Read();
547 cl++;
550 if (currCh == ';' && nDigits > 0) {
551 sbChars.Append((char)chCode);
552 } else {
553 FatalErr("Bad char ref");
555 } else {
556 // entity reference
557 string entityRefChars = "aglmopqstu"; // amp | apos | quot | gt | lt
558 string entities = "&'\"><";
560 int pos = 0;
561 int entIdx = 0xF;
562 int predShift = 0;
564 int sbLen = sbChars.Length;
566 while (true) {
567 if (pos != 0xF) pos = entityRefChars.IndexOf((char)currCh) & 0xF;
568 if (pos == 0xF) FatalErr(errors[7]);
569 sbChars.Append((char)currCh);
571 int path = "\uFF35\u3F8F\u4F8F\u0F5F\uFF78\uE1F4\u2299\uEEFF\uEEFF\uFF4F"[pos];
572 int lBr = (path >> 4) & 0xF;
573 int rBr = path & 0xF;
574 int lPred = path >> 12;
575 int rPred = (path >> 8) & 0xF;
576 currCh = reader.Read();
577 cl++;
578 pos = 0xF;
579 if (lBr != 0xF && currCh == entityRefChars[lBr]) {
580 if (lPred < 0xE) entIdx = lPred;
581 // pred = lPred;
582 predShift = 12; // left
583 } else if (rBr != 0xF && currCh == entityRefChars[rBr]) {
584 if (rPred < 0xE) entIdx = rPred;
585 // pred = rPred;
586 predShift = 8; // right
587 } else if (currCh == ';') {
588 if (entIdx != 0xF
589 && predShift != 0
590 && ((path >> predShift) & 0xF) == 0xE) break;
591 continue; // pos == 0xF
594 pos=0;
598 int l = cl - this.col - 1;
600 if ((l > 0 && l < 5)
601 &&(StrEquals("amp", sbChars, sbLen, l)
602 || StrEquals("apos", sbChars, sbLen, l)
603 || StrEquals("quot", sbChars, sbLen, l)
604 || StrEquals("lt", sbChars, sbLen, l)
605 || StrEquals("gt", sbChars, sbLen, l))
607 sbChars.Length = sbLen;
608 sbChars.Append(entities[entIdx]);
609 } else FatalErr(errors[7]);
612 this.col = cl;
613 break;
615 default:
616 FatalErr(String.Format("Unexpected action code - {0}.", actionCode));
617 break;
619 } // while (true)
621 handler.OnEndParsing(this);
623 } // Parse