Przeglądaj źródła

major cleanup

svn path=/trunk/mcs/; revision=3642
Piers Haken 24 lat temu
rodzic
commit
042b6ba652
1 zmienionych plików z 85 dodań i 90 usunięć
  1. 85 90
      mcs/class/corlib/System.IO/StreamReader.cs

+ 85 - 90
mcs/class/corlib/System.IO/StreamReader.cs

@@ -14,61 +14,67 @@ namespace System.IO {
 	[Serializable]
 	public class StreamReader : TextReader {
 
+		private const int DefaultBufferSize = 1024;
+		private const int DefaultFileBufferSize = 4096;
+		private const int MinimumBufferSize = 128;
+
 		// buffering members
-		private char[] buffer;
+		private byte [] rgbEncoded;
+//		private int cbEncoded;
+		private char [] rgchDecoded;
+		private int cchDecoded;
+
 		private int pos;
 
+
 		private Encoding internalEncoding;
 		private Decoder decoder;
 
 		private Stream internalStream;
 
-                public new static readonly StreamReader Null = new StreamReader((Stream)null);
+		public new static readonly StreamReader Null = new StreamReader((Stream)null);
 
 		public StreamReader(Stream stream)
-			: this (stream, null, false, 0) { }
+			: this (stream, null, false, DefaultBufferSize) { }
 
 		public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
-			: this (stream, null, detectEncodingFromByteOrderMarks, 0) { }
+			: this (stream, null, detectEncodingFromByteOrderMarks, DefaultBufferSize) { }
 
 		public StreamReader(Stream stream, Encoding encoding)
-			: this (stream, encoding, false, 0) { }
+			: this (stream, encoding, false, DefaultBufferSize) { }
 
 		public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks)
-			: this (stream, encoding, detectEncodingFromByteOrderMarks, 0) { }
+			: this (stream, encoding, detectEncodingFromByteOrderMarks, DefaultBufferSize) { }
 		
-		[MonoTODO]
 		public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
 		{
-			internalStream = stream;
-
-			// use detect encoding flag
-			if (encoding == null) {
-				internalEncoding = Encoding.UTF8;
-				decoder = Encoding.UTF8.GetDecoder ();
-			} else {
-				internalEncoding = encoding;
-				decoder = encoding.GetDecoder ();
- 			}
-
-			buffer = null;
+			Initialize (stream, encoding, detectEncodingFromByteOrderMarks, bufferSize);
 		}
 
 		public StreamReader(string path)
-			: this (path, null, false, 0) { }
+			: this (path, null, false, DefaultFileBufferSize) { }
 
 		public StreamReader(string path, bool detectEncodingFromByteOrderMarks)
-			: this (path, null, detectEncodingFromByteOrderMarks, 0) { }
+			: this (path, null, detectEncodingFromByteOrderMarks, DefaultFileBufferSize) { }
 
 		public StreamReader(string path, Encoding encoding)
-			: this (path, encoding, false, 0) { }
+			: this (path, encoding, false, DefaultFileBufferSize) { }
 
 		public StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks)
-			: this (path, encoding, detectEncodingFromByteOrderMarks, 0) { }
+			: this (path, encoding, detectEncodingFromByteOrderMarks, DefaultFileBufferSize) { }
 		
 		[MonoTODO]
 		public StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
 		{
+			Stream stream = (Stream) File.OpenRead (path);
+			Initialize (stream, encoding, detectEncodingFromByteOrderMarks, bufferSize);
+		}
+
+		[MonoTODO]
+		protected void Initialize (Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
+		{
+			internalStream = stream;
+
 			// use detect encoding flag
 			if (encoding == null) {
 				internalEncoding = Encoding.UTF8;
@@ -76,11 +82,15 @@ namespace System.IO {
 			} else {
 				internalEncoding = encoding;
 				decoder = encoding.GetDecoder ();
- 			}
+			}
 
-			internalStream = (Stream) File.OpenRead (path);
+			if (bufferSize < MinimumBufferSize)
+				bufferSize = MinimumBufferSize;
 
-			buffer = null;
+			rgbEncoded = new byte [bufferSize];
+			rgchDecoded = new char [internalEncoding.GetMaxCharCount (bufferSize)];
+			pos = 0;
+			cchDecoded = 0;
 		}
 
 		public virtual Stream BaseStream
@@ -104,56 +114,42 @@ namespace System.IO {
 
 		public void DiscardBufferedData ()
 		{
-			if ((buffer == null) || (pos == buffer.Length))
+			pos = 0;
+			cchDecoded = 0;
+
+/* I'm sure there's no need to do all this
+			if ((cchDecoded == null) || (pos == cchDecoded.Length))
 				return;
 
 			if (!internalStream.CanSeek)
 				return;
 
-			int seek_back = pos - buffer.Length;
+			int seek_back = pos - cchDecoded.Length;
 			internalStream.Seek (seek_back, SeekOrigin.Current);
+*/
 		}
 
-		private int GetRemaining ()
-		{
-			return (buffer != null) ? buffer.Length - pos : 0;
-		}
-
-		private int RoundUpTo (int number, int roundto)
-		{
-			if ((number % roundto) == 0)
-				return number;
-			else
-				return ((number / roundto) + 1) * roundto;
-		}
 
-		private bool ReadBuffer (int count)
+		// the buffer is empty, fill it again
+		[MonoTODO ("handle byte order marks here")]
+		private int ReadBuffer ()
 		{
-			// There are still enough bytes in the buffer.
-			if ((buffer != null) && (pos + count <= buffer.Length))
-				return true;
-
-			// Number of bytes remaining in the buffer.
-			int remaining = GetRemaining ();
-
-			// Round up to block size
-			int size = RoundUpTo (count, 4096);
-			byte[] bytes = new byte [size];
-			int cnt = internalStream.Read (bytes, 0, size);
-
-			if (cnt <= 0) 
-				return false;
-
-			int bufcnt = decoder.GetCharCount (bytes, 0, cnt);
-			char[] newbuffer = new char [remaining + bufcnt];
-			if (remaining > 0)
-				Array.Copy (buffer, pos, newbuffer, 0, remaining);
-			buffer = newbuffer;
-
-			bufcnt = decoder.GetChars (bytes, 0, cnt, buffer, remaining);
 			pos = 0;
-
-			return true;
+			int cbEncoded = 0;
+			cchDecoded = 0;
+			do	// keep looping until the decoder gives us some chars
+			{
+				cbEncoded = internalStream.Read (rgbEncoded, 0, rgbEncoded.Length);
+				// TODO: remove this line when iconv is fixed
+				int bufcnt = decoder.GetCharCount (rgbEncoded, 0, cbEncoded);
+
+				if (cbEncoded == 0)
+					return 0;
+				// TODO: remove byte order marks here
+				cchDecoded += decoder.GetChars (rgbEncoded, 0, cbEncoded, rgchDecoded, 0);
+			} while (cchDecoded == 0);
+
+			return cchDecoded;
 		}
 
 		public override int Peek ()
@@ -161,18 +157,18 @@ namespace System.IO {
 			if (!internalStream.CanSeek)
 				return -1;
 
-			if (!ReadBuffer (1))
+			if (pos >= cchDecoded && ReadBuffer () == 0)
 				return -1;
 
-			return buffer [pos];
+			return rgchDecoded [pos];
 		}
 
 		public override int Read ()
 		{
-			if (!ReadBuffer (1))
+			if (pos >= cchDecoded && ReadBuffer () == 0)
 				return -1;
 
-			return buffer[pos++];
+			return rgchDecoded [pos++];
 		}
 
 		public override int Read (char[] dest_buffer, int index, int count)
@@ -186,15 +182,20 @@ namespace System.IO {
 			if ((index < 0) || (count < 0))
 				throw new ArgumentOutOfRangeException ();
 
-			if (!ReadBuffer (count))
-				return -1;
-
-			int remaining = buffer.Length - pos;
-			int size = Math.Min (remaining, count);
-
-			Array.Copy (buffer, pos, dest_buffer, index, size);
-
-			return size;
+			int cchRead = 0;
+			while (count > 0)
+			{
+				if (pos >= cchDecoded && ReadBuffer () == 0)
+					return -1;
+
+				int cch = Math.Min (cchDecoded - pos, count);
+				Array.Copy (rgchDecoded, pos, dest_buffer, index, cch);
+				pos += cch;
+				index += cch;
+				count -= cch;
+				cchRead += cch;
+			}
+			return cchRead;
 		}
 
 		public override string ReadLine()
@@ -225,24 +226,18 @@ namespace System.IO {
 			return text.ToString ();
 		}
 
-                public override string ReadToEnd()
+		public override string ReadToEnd()
 		{
 			StringBuilder text = new StringBuilder ();
 
-			while (true) {
-				int c = Read ();
-
-				if (c == -1) {
-					if (text.Length == 0)
-						return null;
-
-					break;
-				}
-
+			int c;
+			while ((c = Read ()) != -1) {
 				text.Append ((char) c);
 			}
 
+			if (text.Length == 0)
+				return null;
 			return text.ToString ();
-                }
+		}
 	}
 }