Forráskód Böngészése

2002-03-23 Martin Baulig <[email protected]>

	* StreamReader.cs: Always do buffered reading, use 4k blocks.
	(Read (char[], int, int)): Implemented.
	(DiscardBufferedData): Implemented.

svn path=/trunk/mcs/; revision=3289
Martin Baulig 24 éve
szülő
commit
552bb40a61

+ 6 - 0
mcs/class/corlib/System.IO/ChangeLog

@@ -1,3 +1,9 @@
+2002-03-23  Martin Baulig  <[email protected]>
+
+	* StreamReader.cs: Always do buffered reading, use 4k blocks.
+	(Read (char[], int, int)): Implemented.
+	(DiscardBufferedData): Implemented.
+
 2002-03-21  Mike Kestner <[email protected]>
 
 	* StreamReader.cs : Fill out, add buffering, and use encoding.

+ 74 - 32
mcs/class/corlib/System.IO/StreamReader.cs

@@ -97,15 +97,63 @@ namespace System.IO {
 			}
 		}
 
-		[MonoTODO]
 		public override void Close ()
 		{
 			Dispose (true);
 		}
 
-		[MonoTODO]
 		public void DiscardBufferedData ()
 		{
+			if ((buffer == null) || (pos == buffer.Length))
+				return;
+
+			if (!internalStream.CanSeek)
+				return;
+
+			int seek_back = pos - buffer.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)
+		{
+			// 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, newbuffer, remaining);
+			buffer = newbuffer;
+
+			bufcnt = decoder.GetChars (bytes, 0, cnt, buffer, remaining);
+			pos = remaining;
+
+			return true;
 		}
 
 		public override int Peek ()
@@ -113,46 +161,40 @@ namespace System.IO {
 			if (!internalStream.CanSeek)
 				return -1;
 
-			if ((buffer == null) || ((pos + 1) == buffer.Length)) {
-				int cnt = internalEncoding.GetMaxByteCount (1);
-				byte[] bytes = new byte[cnt];
-				int actcnt = internalStream.Read (bytes, 0, cnt);
-				internalStream.Seek (-actcnt, SeekOrigin.Current);
+			if (!ReadBuffer (1))
+				return -1;
 
-				if (actcnt <= 0) 
-					return -1;
+			return buffer [pos];
+		}
 
-				int bufcnt = decoder.GetCharCount (bytes, 0, cnt);
-				char[] chars = new char [bufcnt];
-				bufcnt = decoder.GetChars (bytes, 0, cnt, chars, 0);
-				return chars [0];
-			}
+		public override int Read ()
+		{
+			if (!ReadBuffer (1))
+				return -1;
 
-			return buffer [pos + 1];
+			return buffer[pos++];
 		}
 
-		public override int Read ()
+		public override int Read (char[] dest_buffer, int index, int count)
 		{
-			if ((buffer == null) || (++pos == buffer.Length)) {
-				byte[] bytes =  new byte [8192];
-				int cnt = internalStream.Read (bytes, 0, 8192);
+			if (dest_buffer == null)
+				throw new ArgumentException ();
 
-				if (cnt <= 0) 
-					return -1;
+			if (index + count >= dest_buffer.Length)
+				throw new ArgumentException ();
 
-				int bufcnt = decoder.GetCharCount (bytes, 0, cnt);
-				buffer = new char [bufcnt];
-				bufcnt = decoder.GetChars (bytes, 0, cnt, buffer, 0);
-				pos = 0;
-			}
+			if ((index < 0) || (count < 0))
+				throw new ArgumentOutOfRangeException ();
 
-			return buffer[pos];
-		}
+			if (!ReadBuffer (count))
+				return -1;
 
-		[MonoTODO]
-		public override int Read (char[] buffer, int index, int count)
-		{
-			return 0;
+			int remaining = buffer.Length - pos;
+			int size = Math.Min (remaining, count);
+
+			Array.Copy (buffer, pos, dest_buffer, index, size);
+
+			return size;
 		}
 
 		[MonoTODO]