**** Merged from MCS ****
[mono-project.git] / mcs / class / System.XML / System.Xml / XmlParserInput.cs
blob6bb0bb1d166510d035576d459870bb6b87467c08
1 //
2 // System.Xml.XmlParserInput
3 //
4 // Author:
5 // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
6 //
7 // (C)2003 Atsushi Enomoto
8 //
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.
30 using System;
31 using System.IO;
32 using System.Text;
33 using System.Xml;
34 using System.Globalization;
36 namespace System.Xml
38 internal class XmlParserInput
40 #region ctor
41 public XmlParserInput (TextReader reader, string baseURI)
42 : this (reader, baseURI, 1, 1)
46 public XmlParserInput (TextReader reader, string baseURI, int line, int column)
48 this.reader = reader;
50 StreamReader sr = reader as StreamReader;
51 if (sr != null)
52 can_seek = sr.BaseStream.CanSeek;
54 this.line = line;
55 this.column = column;
56 this.baseURI = baseURI;
58 #endregion
60 #region Public Methods
61 // Read the next character and compare it against the
62 // specified character.
63 public void Close ()
65 this.reader.Close ();
68 public void Expect (int expected)
70 int ch = ReadChar ();
72 if (ch != expected) {
73 throw ReaderError (
74 String.Format (CultureInfo.InvariantCulture,
75 "expected '{0}' ({1:X}) but found '{2}' ({3:X})",
76 (char)expected,
77 expected,
78 (char)ch,
79 ch));
83 public void Expect (string expected)
85 int len = expected.Length;
86 for(int i=0; i< len; i++)
87 Expect (expected[i]);
90 public void InsertParameterEntityBuffer (string value)
92 this.peBuffer.Insert (peBufferIndex, ' ');
93 this.peBuffer.Insert (peBufferIndex + 1, value);
94 this.peBuffer.Insert (peBufferIndex + value.Length + 1, ' ');
95 peStored = true;
98 public int PeekChar ()
100 if (peStored)
101 return peBuffer [peBufferIndex];
103 if (has_peek)
104 return peek_char;
106 peek_char = reader.Read ();
107 if (peek_char >= 0xD800 && peek_char <= 0xDBFF) {
108 int i = reader.Read ();
109 if (i >= 0xDC00 && i <= 0xDFFF)
110 peek_char += i;
112 has_peek = true;
113 return peek_char;
116 public int ReadChar ()
118 int ch;
120 if (peStored) {
121 ch = peBuffer [peBufferIndex];
122 peBufferIndex++;
123 if (peBufferIndex == peBuffer.Length) {
124 peStored = false;
125 peBuffer.Length = 0;
126 peBufferIndex = 0;
128 // I decided not to add character to currentTag with respect to PERef value
129 return ch;
132 if (has_peek) {
133 ch = peek_char;
134 has_peek = false;
135 } else {
136 ch = reader.Read ();
137 if (ch >= 0xD800 && ch <= 0xDBFF) {
138 int i = reader.Read ();
139 if (i > 0xDC00 && i <= 0xDFFF)
140 ch += i;
144 if (ch == '\n') {
145 line++;
146 column = 1;
147 } else {
148 column++;
150 return ch;
153 #endregion
155 #region Public Properties
156 public string BaseURI {
157 get { return baseURI; }
160 public bool HasPEBuffer {
161 get { return peStored; }
164 public int LineNumber {
165 get { return line; }
168 public int LinePosition {
169 get { return column; }
172 public bool InitialState {
173 get { return initialState; }
174 set { initialState = value; }
177 #endregion
179 #region Privates
180 TextReader reader;
181 bool can_seek;
182 bool has_peek;
183 int peek_char;
184 int line;
185 int column;
186 StringBuilder peBuffer = new StringBuilder ();
187 string baseURI;
188 bool peStored = false;
189 bool initialState = true;
190 int peBufferIndex;
192 private int ParseCharReference (string name)
194 int ret = -1;
195 if (name.Length > 0 && name [0] == '#') {
196 if (name [1] == 'x')
197 ret = int.Parse (name.Substring (2, name.Length - 2), NumberStyles.None & NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
198 else
199 ret = int.Parse (name.Substring (1, name.Length - 1), CultureInfo.InvariantCulture);
201 return ret;
204 private int ParseKnownEntityReference (string name)
206 switch (name) {
207 case "quot": return '"';
208 case "lt": return '<';
209 case "gt": return '>';
210 case "amp": return '&';
211 case "apos": return '\'';
213 return -1;
216 private XmlException ReaderError (string message)
218 return new XmlException (message, null, line, column);
220 #endregion