Author: atsushi
Date: 2005-05-06 01:45:14 -0400 (Fri, 06 May 2005)
New Revision: 44109
Modified:
trunk/mcs/class/System.XML/System.Xml/ChangeLog
trunk/mcs/class/System.XML/System.Xml/XmlInputStream.cs
Log:
2005-05-06 Atsushi Enomoto <[EMAIL PROTECTED]>
* XmlInputStream.cs : Now XmlStreamReader uses non-blocking TextReader
that is mostly copied from StreamReader. It should fix bug #74161.
Modified: trunk/mcs/class/System.XML/System.Xml/ChangeLog
===================================================================
--- trunk/mcs/class/System.XML/System.Xml/ChangeLog 2005-05-06 05:01:29 UTC
(rev 44108)
+++ trunk/mcs/class/System.XML/System.Xml/ChangeLog 2005-05-06 05:45:14 UTC
(rev 44109)
@@ -1,3 +1,8 @@
+2005-05-06 Atsushi Enomoto <[EMAIL PROTECTED]>
+
+ * XmlInputStream.cs : Now XmlStreamReader uses non-blocking TextReader
+ that is mostly copied from StreamReader. It should fix bug #74161.
+
2005-05-05 Atsushi Enomoto <[EMAIL PROTECTED]>
* XmlNodeReader2.cs, XmlTextReader2.cs, XmlValidatingReader.cs,
Modified: trunk/mcs/class/System.XML/System.Xml/XmlInputStream.cs
===================================================================
--- trunk/mcs/class/System.XML/System.Xml/XmlInputStream.cs 2005-05-06
05:01:29 UTC (rev 44108)
+++ trunk/mcs/class/System.XML/System.Xml/XmlInputStream.cs 2005-05-06
05:45:14 UTC (rev 44109)
@@ -31,12 +31,12 @@
using System;
using System.IO;
using System.Text;
-using System.Xml;
+using System.Runtime.InteropServices;
namespace System.Xml
{
#region XmlStreamReader
- internal class XmlStreamReader : StreamReader
+ internal class XmlStreamReader : NonBlockingStreamReader
{
XmlInputStream input;
@@ -67,6 +67,219 @@
}
#endregion
+ #region NonBlockingStreamReader
+ // mostly copied from StreamReader.
+ internal class NonBlockingStreamReader : TextReader {
+
+ const int DefaultBufferSize = 1024;
+ const int DefaultFileBufferSize = 4096;
+ const int MinimumBufferSize = 128;
+
+ //
+ // The input buffer
+ //
+ byte [] input_buffer;
+
+ //
+ // The decoded buffer from the above input buffer
+ //
+ char [] decoded_buffer;
+
+ //
+ // Decoded bytes in decoded_buffer.
+ //
+ int decoded_count;
+
+ //
+ // Current position in the decoded_buffer
+ //
+ int pos;
+
+ //
+ // The buffer size that we are using
+ //
+ int buffer_size;
+
+ Encoding encoding;
+ Decoder decoder;
+
+ Stream base_stream;
+ bool mayBlock;
+
+ public NonBlockingStreamReader(Stream stream, Encoding encoding)
+ {
+ int buffer_size = DefaultBufferSize;
+ base_stream = stream;
+ input_buffer = new byte [buffer_size];
+ this.buffer_size = buffer_size;
+ this.encoding = encoding;
+ decoder = encoding.GetDecoder ();
+
+ decoded_buffer = new char [encoding.GetMaxCharCount
(buffer_size)];
+ decoded_count = 0;
+ pos = 0;
+ }
+
+ public override void Close ()
+ {
+ Dispose (true);
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ if (disposing && base_stream != null)
+ base_stream.Close ();
+
+ input_buffer = null;
+ decoded_buffer = null;
+ encoding = null;
+ decoder = null;
+ base_stream = null;
+ base.Dispose (disposing);
+ }
+
+ public void DiscardBufferedData ()
+ {
+ pos = decoded_count = 0;
+ mayBlock = false;
+ }
+
+ // the buffer is empty, fill it again
+ private int ReadBuffer ()
+ {
+ pos = 0;
+ int cbEncoded = 0;
+
+ // keep looping until the decoder gives us some chars
+ decoded_count = 0;
+ int parse_start = 0;
+ do
+ {
+ cbEncoded = base_stream.Read (input_buffer, 0,
buffer_size);
+
+ if (cbEncoded == 0)
+ return 0;
+
+ mayBlock = (cbEncoded < buffer_size);
+ decoded_count += decoder.GetChars
(input_buffer, parse_start, cbEncoded, decoded_buffer, 0);
+ parse_start = 0;
+ } while (decoded_count == 0);
+
+ return decoded_count;
+ }
+
+ public override int Peek ()
+ {
+ if (base_stream == null)
+ throw new ObjectDisposedException
("StreamReader", "Cannot read from a closed StreamReader");
+ if (pos >= decoded_count && (mayBlock || ReadBuffer ()
== 0))
+ return -1;
+
+ return decoded_buffer [pos];
+ }
+
+ public override int Read ()
+ {
+ if (base_stream == null)
+ throw new ObjectDisposedException
("StreamReader", "Cannot read from a closed StreamReader");
+ if (pos >= decoded_count && ReadBuffer () == 0)
+ return -1;
+
+ return decoded_buffer [pos++];
+ }
+
+ public override int Read ([In, Out] char[] dest_buffer, int
index, int count)
+ {
+ if (base_stream == null)
+ throw new ObjectDisposedException
("StreamReader", "Cannot read from a closed StreamReader");
+ if (dest_buffer == null)
+ throw new ArgumentNullException ("dest_buffer");
+ if (index < 0)
+ throw new ArgumentOutOfRangeException ("index",
"< 0");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException ("count",
"< 0");
+ // re-ordered to avoid possible integer overflow
+ if (index > dest_buffer.Length - count)
+ throw new ArgumentException ("index + count >
dest_buffer.Length");
+
+ int chars_read = 0;
+// while (count > 0)
+ {
+ if (pos >= decoded_count && ReadBuffer () == 0)
+ return chars_read > 0 ? chars_read : 0;
+
+ int cch = Math.Min (decoded_count - pos, count);
+ Array.Copy (decoded_buffer, pos, dest_buffer,
index, cch);
+ pos += cch;
+ index += cch;
+ count -= cch;
+ chars_read += cch;
+ }
+ return chars_read;
+ }
+
+ public override string ReadLine()
+ {
+ if (base_stream == null)
+ throw new ObjectDisposedException
("StreamReader", "Cannot read from a closed StreamReader");
+
+ bool foundCR = false;
+ StringBuilder text = new StringBuilder ();
+
+ while (true) {
+ int c = Read ();
+
+ if (c == -1) { // end
of stream
+ if (text.Length == 0)
+ return null;
+
+ if (foundCR)
+ text.Length--;
+
+ break;
+ }
+
+ if (c == '\n') { //
newline
+ if ((text.Length > 0) && (text
[text.Length - 1] == '\r'))
+ text.Length--;
+
+ foundCR = false;
+ break;
+ } else if (foundCR) {
+ pos--;
+ text.Length--;
+ break;
+ }
+
+ if (c == '\r')
+ foundCR = true;
+
+
+ text.Append ((char) c);
+ }
+
+ return text.ToString ();
+ }
+
+ public override string ReadToEnd()
+ {
+ if (base_stream == null)
+ throw new ObjectDisposedException
("StreamReader", "Cannot read from a closed StreamReader");
+
+ StringBuilder text = new StringBuilder ();
+
+ int size = decoded_buffer.Length;
+ char [] buffer = new char [size];
+ int len;
+
+ while ((len = Read (buffer, 0, size)) != 0)
+ text.Append (buffer, 0, len);
+
+ return text.ToString ();
+ }
+ }
+ #endregion
+
class XmlInputStream : Stream
{
public static readonly Encoding StrictUTF8;
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches