瀏覽代碼

2010-01-19 Alan McGovern <[email protected]>
* BufferedStream.cs: Patch by Tom Philpot to optimise ReadByte
* and
WriteByte significantly by making them fulfill their request by
directly reading from the buffer.


svn path=/trunk/mcs/; revision=149799

Alan McGovern 16 年之前
父節點
當前提交
dd3b6549b4

+ 42 - 10
mcs/class/corlib/System.IO/BufferedStream.cs

@@ -169,22 +169,54 @@ namespace System.IO {
 		{
 			CheckObjectDisposedException ();
 			
-			byte[] b = new byte[1];
+			if (!m_stream.CanRead) {
+				throw new NotSupportedException (
+					Locale.GetText ("Cannot read from stream"));
+			}
 
-			if (Read(b, 0, 1) == 1) {
-				return b[0];
-			} else {
-				return -1;
+			if (!m_buffer_reading) {
+				Flush ();
+				m_buffer_reading = true;
+			}
+
+			if (1 <= m_buffer_read_ahead - m_buffer_pos) {
+				return m_buffer [m_buffer_pos++];
+			}
+			else
+			{
+				if (m_buffer_pos >= m_buffer_read_ahead) {
+					m_buffer_pos = 0;
+					m_buffer_read_ahead = 0;
+				}
+
+				m_buffer_read_ahead = m_stream.Read (m_buffer, 0, m_buffer.Length);
+				if (1 <= m_buffer_read_ahead) {
+					return m_buffer [m_buffer_pos++];
+				} else {
+					return -1;
+				}
 			}
 		}
 
 		public override void WriteByte (byte value) 
 		{
 			CheckObjectDisposedException ();
-			byte[] b = new byte[1];
+			if (!m_stream.CanWrite) {
+				throw new NotSupportedException (
+					Locale.GetText ("Cannot write to stream"));
+			}
+
+			if (m_buffer_reading) {
+				Flush ();
+				m_buffer_reading = false;
+			} 
+			else
+			// reordered to avoid possible integer overflow
+			if (m_buffer_pos >= m_buffer.Length - 1) {
+				Flush ();
+			} 
 
-			b[0] = value;
-			Write(b, 0, 1);
+			m_buffer [m_buffer_pos++] = value;
 		}
 
 		public override int Read ([In,Out] byte[] array, int offset, int count) 
@@ -229,9 +261,9 @@ namespace System.IO {
 			count -= ret;
 
 			if (count >= m_buffer.Length) {
-				ret += m_stream.Read(array, offset, count);
+				ret += m_stream.Read (array, offset, count);
 			} else {
-				m_buffer_read_ahead = m_stream.Read(m_buffer, 0, m_buffer.Length);
+				m_buffer_read_ahead = m_stream.Read (m_buffer, 0, m_buffer.Length);
 				
 				if (count < m_buffer_read_ahead) {
 					Buffer.BlockCopyInternal (m_buffer, 0, array, offset, count);

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

@@ -1,3 +1,8 @@
+2010-01-19  Alan McGovern  <[email protected]>
+	* BufferedStream.cs: Patch by Tom Philpot to optimise ReadByte and
+	WriteByte significantly by making them fulfill their request by
+	directly reading from the buffer.
+
 2010-01-14  Rolf Bjarne Kvinge  <[email protected]>
 
 	* UnmanagedMemoryStream.cs: Read: don't read bytes one-by-one, read all

+ 18 - 0
mcs/class/corlib/Test/System.IO/BufferedStreamTest.cs

@@ -242,6 +242,15 @@ public class BufferedStreamTest {
 		stream.Read (new byte [1], 0, 1);
 	}
 
+	[Test]
+	[ExpectedException(typeof(NotSupportedException))]
+	public void ReadByte_CantRead () 
+	{
+		WriteOnlyStream wo = new WriteOnlyStream ();
+		BufferedStream stream = new BufferedStream (wo);
+		stream.ReadByte ();
+	}
+
 	[Test]
 	[ExpectedException(typeof(ArgumentOutOfRangeException))]
 	public void Read_OffsetNegative () 
@@ -344,6 +353,15 @@ public class BufferedStreamTest {
 		stream.Write (new byte [1], 0, 1);
 	}
 
+	[Test]
+	[ExpectedException(typeof(NotSupportedException))]
+	public void WriteByte_CantWrite () 
+	{
+		ReadOnlyStream ro = new ReadOnlyStream ();
+		BufferedStream stream = new BufferedStream (ro);
+		stream.WriteByte (0);
+	}
+
 	[Test]
 	[ExpectedException(typeof(ArgumentOutOfRangeException))]
 	public void Write_OffsetNegative ()