[Mono-list] Buffering for StreamWriter

Nick Drochak ndrochak@gol.com
Thu, 16 May 2002 22:04:09 +0900


This is a multi-part message in MIME format.

------=_NextPart_000_000B_01C1FD25.9DDD0710
Content-Type: text/plain;
	charset="us-ascii"
Content-Transfer-Encoding: 7bit

| Please review the patches and let me know how stupid I was.
| 

Ok. Stupid thing number one.  Wrong patches.

Here's the ones that works.

Nick D.

------=_NextPart_000_000B_01C1FD25.9DDD0710
Content-Type: application/octet-stream;
	name="Console.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="Console.patch"

Index: Console.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /cvs/public/mcs/class/corlib/System/Console.cs,v=0A=
retrieving revision 1.7=0A=
diff -u -r1.7 Console.cs=0A=
--- Console.cs	1 Apr 2002 06:07:40 -0000	1.7=0A=
+++ Console.cs	16 May 2002 09:11:13 -0000=0A=
@@ -20,7 +20,9 @@=0A=
 		static Console ()=0A=
 		{=0A=
 			stderr =3D new StreamWriter (OpenStandardError ());=0A=
+			((StreamWriter)stderr).AutoFlush =3D true;=0A=
 			stdout =3D new StreamWriter (OpenStandardOutput ());=0A=
+			((StreamWriter)stdout).AutoFlush =3D true;=0A=
 			stdin  =3D new StreamReader (OpenStandardInput ());=0A=
 		}=0A=
 =0A=

------=_NextPart_000_000B_01C1FD25.9DDD0710
Content-Type: application/octet-stream;
	name="StreamWriter.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="StreamWriter.patch"

Index: StreamWriter.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /cvs/public/mcs/class/corlib/System.IO/StreamWriter.cs,v=0A=
retrieving revision 1.7=0A=
diff -u -r1.7 StreamWriter.cs=0A=
--- StreamWriter.cs	14 May 2002 11:46:20 -0000	1.7=0A=
+++ StreamWriter.cs	16 May 2002 09:11:55 -0000=0A=
@@ -8,11 +8,12 @@=0A=
 //
=20
 using System.Text;
+using System;
=20
 namespace System.IO {
 =09
 	[Serializable]
-        public class StreamWriter : TextWriter {
+	public class StreamWriter : TextWriter {
=20
 		private Encoding internalEncoding;
=20
@@ -21,17 +22,33 @@=0A=
=20
 		private bool iflush;
 	=09
-                // new public static readonly StreamWriter Null;
+		private const int DefaultBufferSize =3D 1024;
+		private const int DefaultFileBufferSize =3D 4096;
+		private const int MinimumBufferSize =3D 2;
+
+		private int pos;
+		private int BufferSize;
+		private byte[] TheBuffer;
+
+		private bool DisposedAlready =3D false;
+
+		// new public static readonly StreamWriter Null;
=20
 		public StreamWriter (Stream stream)
-			: this (stream, Encoding.UTF8, 0) {}
+			: this (stream, Encoding.UTF8, DefaultBufferSize) {}
=20
 		public StreamWriter (Stream stream, Encoding encoding)
-			: this (stream, encoding, 0) {}
+			: this (stream, encoding, DefaultBufferSize) {}
+
+		protected void Initialize(Encoding encoding, int bufferSize) {
+			internalEncoding =3D encoding;
+			pos =3D 0;
+			BufferSize =3D Math.Max(bufferSize, MinimumBufferSize);
+			TheBuffer =3D new byte[BufferSize];
+		}
=20
-		[MonoTODO("Nothing is done with bufferSize")]
-		public StreamWriter (Stream stream, Encoding encoding, int =
bufferSize)
-		{
+		//[MonoTODO("Nothing is done with bufferSize")]
+		public StreamWriter (Stream stream, Encoding encoding, int =
bufferSize) {
 			if (null =3D=3D stream)
 				throw new ArgumentNullException("stream");
 			if (null =3D=3D encoding)
@@ -42,20 +59,20 @@=0A=
 				throw new ArgumentException("bufferSize");
=20
 			internalStream =3D stream;
-			internalEncoding =3D encoding;
+
+			Initialize(encoding, bufferSize);
 		}
=20
 		public StreamWriter (string path)
-			: this (path, false, Encoding.UTF8, 0) {}
+			: this (path, false, Encoding.UTF8, DefaultFileBufferSize) {}
=20
 		public StreamWriter (string path, bool append)
-			: this (path, append, Encoding.UTF8, 0) {}
+			: this (path, append, Encoding.UTF8, DefaultFileBufferSize) {}
=20
 		public StreamWriter (string path, bool append, Encoding encoding)
-			: this (path, append, encoding, 0) {}
+			: this (path, append, encoding, DefaultFileBufferSize) {}
 	=09
-		public StreamWriter (string path, bool append, Encoding encoding, int =
bufferSize)
-		{
+		public StreamWriter (string path, bool append, Encoding encoding, int =
bufferSize) {
 			if (null =3D=3D path)
 				throw new ArgumentNullException("path");
 			if (String.Empty =3D=3D path)
@@ -86,77 +103,85 @@=0A=
 			else
 				internalStream.SetLength (0);
=20
-			internalEncoding =3D encoding;
-		=09
+			Initialize(encoding, bufferSize);
 		}
=20
-		public virtual bool AutoFlush
-		{
-
+		public virtual bool AutoFlush {
 			get {
 				return iflush;
 			}
-
 			set {
 				iflush =3D value;
 			}
 		}
=20
-		public virtual Stream BaseStream
-		{
+		public virtual Stream BaseStream {
 			get {
 				return internalStream;
 			}
 		}
=20
-		public override Encoding Encoding
-		{
+		public override Encoding Encoding {
 			get {
 				return internalEncoding;
 			}
 		}
=20
-		protected override void Dispose (bool disposing)
-		{
-			if (disposing && internalStream !=3D null) {
+		protected override void Dispose (bool disposing) {
+			if (!DisposedAlready && internalStream !=3D null) {
+				Flush();
 				internalStream.Close ();
 				internalStream =3D null;
 			}
+			DisposedAlready =3D true;
 		}
=20
-		public override void Flush ()
-		{
+		public override void Flush () {
 			if (closed)
 				throw new ObjectDisposedException("TextWriter");
=20
-			internalStream.Flush ();
+			if (pos > 0) {
+				internalStream.Write (TheBuffer, 0, pos);
+				internalStream.Flush ();
+				pos =3D 0;
+			}
 		}
 	=09
-		public override void Write (char[] buffer, int index, int count)
-		{
+		public override void Write (char[] buffer, int index, int count) {
 			byte[] res =3D new byte [internalEncoding.GetMaxByteCount =
(buffer.Length)];
 			int len;
+			int BytesToBuffer;
+			int resPos =3D 0;
=20
 			len =3D internalEncoding.GetBytes (buffer, index, count, res, 0);
=20
-			internalStream.Write (res, 0, len);
-
-			if (iflush)
-				Flush ();
-		=09
+			// if they want AutoFlush, don't bother buffering
+			if (iflush) {
+				Flush();
+				internalStream.Write (res, 0, len);
+				internalStream.Flush ();
+			} else {
+				// otherwise use the buffer.
+				// NOTE: this logic is not optimized for performance.
+				while (resPos < len) {
+					// fill the buffer if we've got more bytes than will fit
+					BytesToBuffer =3D Math.Min(BufferSize - pos, len - resPos);
+					Array.Copy(res, resPos, TheBuffer, pos, BytesToBuffer);
+					resPos +=3D BytesToBuffer;
+					pos +=3D BytesToBuffer;
+					// if the buffer is full, flush it out.
+					if (pos =3D=3D BufferSize) Flush();
+				}
+			}
 		}
=20
-		public override void Write(string value)
-		{
+		public override void Write(string value) {
 			Write (value.ToCharArray (), 0, value.Length);
 		}
=20
-		public override void Close()
-		{
+		public override void Close() {
 			Dispose(true);
 			closed =3D true;
 		}
-        }
-}
-                       =20
-                       =20
+	}
+}=0A=
\ No newline at end of file=0A=

------=_NextPart_000_000B_01C1FD25.9DDD0710--