2010-04-07 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.Data / System.Data.SqlClient.jvm / SqlXmlTextReader.cs
blob38d935dd5edf692e0f8b4f641f2992bd6501b780
1 //
2 // System.Data.SqlClient.SqlXmlTextReader.cs
3 //
4 // Author:
5 // Konstantin Triger (kostat@mainsoft.com)
6 //
7 // Copyright (C) 2006 Mainsoft, corp. (http://www.mainsoft.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System;
30 using System.IO;
31 using System.Text;
32 using System.Xml;
34 namespace System.Data.SqlClient {
35 internal sealed class SqlXmlTextReader : TextReader {
37 #region FragmentXmlTextReader
39 sealed class FragmentXmlTextReader : XmlTextReader {
40 public FragmentXmlTextReader(System.IO.TextReader reader) : base(reader) {}
42 public override bool Read() {
43 do {
44 if (!base.Read())
45 return false;
46 }while(base.Depth == 0);
48 return true;
51 public override int Depth {
52 get {
53 int depth = base.Depth;
54 if (depth >= 1)
55 depth --;
57 return depth;
62 #endregion
64 #region Fields
66 bool _hasPeekedChar;
67 readonly char[] _peekedChar = new char[1];
68 readonly SqlDataReader _reader;
70 string _data;
71 int _rootPosition;
72 int _position = -1;
73 bool _eof;
75 static readonly char[] OpenRoot = new char[] {'<', 'X', '>'};
76 const int OpenRootLength = 3;
77 static readonly char[] CloseRoot = new char[] {'<', '/', 'X', '>'};
78 const int CloseRootLength = 4;
80 #endregion // Fields
82 #region Constructors
84 private SqlXmlTextReader (SqlDataReader reader) {
85 _reader = reader;
88 #endregion
90 #region Methods
92 public static XmlReader Create(SqlDataReader dataReader) {
93 return new FragmentXmlTextReader(new SqlXmlTextReader(dataReader));
96 public override void Close() {
97 _reader.Close ();
100 public override int Peek () {
101 if (!_hasPeekedChar) {
103 int consumed = Read(_peekedChar, 0, 1);
104 if (consumed < 0)
105 return -1;
107 _hasPeekedChar = true;
110 return _peekedChar[0];
113 public override int Read () {
114 int c = Peek();
115 _hasPeekedChar = false;
116 return c;
119 public override int Read (char[] buffer, int index, int count) {
120 if (buffer == null)
121 throw new ArgumentNullException("buffer");
123 if (index < 0)
124 throw new ArgumentOutOfRangeException("index");
126 if (count < 0)
127 throw new ArgumentOutOfRangeException("count");
129 if (count == 0)
130 return 0;
132 int got = 0;
134 if (_hasPeekedChar) {
135 buffer[index++] = _peekedChar[0];
136 count--;
137 _hasPeekedChar = false;
138 got ++;
141 if (!_eof) {
142 while (count > 0) {
144 if (_rootPosition < OpenRootLength) {
145 buffer[index++] = OpenRoot[_rootPosition++];
146 count --;
147 got ++;
148 continue;
151 if (_position < 0) {
152 if (_reader.Read()) {
153 _position = 0;
154 _data = _reader.GetString(0);
156 else {
157 if(_reader.NextResult())
158 continue;
159 else {
160 _rootPosition = 0;
161 _eof = true;
162 break;
167 int consumed = ((_position + count) > _data.Length) ? (_data.Length - (int)_position) : count;
168 _data.CopyTo(_position, buffer, index, consumed);
170 if (consumed > 0) {
171 _position += consumed;
172 got += consumed;
173 index += consumed;
174 count -= consumed;
176 else
177 _position = -1;
181 while (count > 0 && _rootPosition < CloseRootLength) {
182 buffer[index++] = CloseRoot[_rootPosition++];
183 count --;
184 got ++;
188 return got;
191 #endregion // Methods