2002-03-23 Martin Baulig <martin@gnome.org>
authorMartin Baulig <martin@novell.com>
Sat, 23 Mar 2002 17:02:45 +0000 (17:02 -0000)
committerMartin Baulig <martin@novell.com>
Sat, 23 Mar 2002 17:02:45 +0000 (17:02 -0000)
* StreamReader.cs: Always do buffered reading, use 4k blocks.
(Read (char[], int, int)): Implemented.
(DiscardBufferedData): Implemented.

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

mcs/class/corlib/System.IO/ChangeLog
mcs/class/corlib/System.IO/StreamReader.cs

index 83c84b3d0493c4526902acd8a5f549ee8d44c502..eeaac2b28942df3d1e85146809e25223a75b15a6 100644 (file)
@@ -1,3 +1,9 @@
+2002-03-23  Martin Baulig  <martin@gnome.org>
+
+       * StreamReader.cs: Always do buffered reading, use 4k blocks.
+       (Read (char[], int, int)): Implemented.
+       (DiscardBufferedData): Implemented.
+
 2002-03-21  Mike Kestner <mkestner@speakeasy.net>
 
        * StreamReader.cs : Fill out, add buffering, and use encoding.
index fd31d58b1dbcfeec1f29084f37fee14a64fdedab..3ad64759a3173c6d69e33ffbf01df0733dccfd21 100644 (file)
@@ -97,15 +97,63 @@ namespace System.IO {
                        }\r
                }\r
 \r
-               [MonoTODO]\r
                public override void Close ()\r
                {\r
                        Dispose (true);\r
                }\r
 \r
-               [MonoTODO]\r
                public void DiscardBufferedData ()\r
                {\r
+                       if ((buffer == null) || (pos == buffer.Length))\r
+                               return;\r
+\r
+                       if (!internalStream.CanSeek)\r
+                               return;\r
+\r
+                       int seek_back = pos - buffer.Length;\r
+                       internalStream.Seek (seek_back, SeekOrigin.Current);\r
+               }\r
+\r
+               private int GetRemaining ()\r
+               {\r
+                       return (buffer != null) ? buffer.Length - pos : 0;\r
+               }\r
+\r
+               private int RoundUpTo (int number, int roundto)\r
+               {\r
+                       if ((number % roundto) == 0)\r
+                               return number;\r
+                       else\r
+                               return ((number / roundto) + 1) * roundto;\r
+               }\r
+\r
+               private bool ReadBuffer (int count)\r
+               {\r
+                       // There are still enough bytes in the buffer.\r
+                       if ((buffer != null) && (pos + count < buffer.Length))\r
+                               return true;\r
+\r
+                       // Number of bytes remaining in the buffer.\r
+                       int remaining = GetRemaining ();\r
+\r
+                       // Round up to block size\r
+                       int size = RoundUpTo (count, 4096);\r
+                       byte[] bytes = new byte [size];\r
+                       int cnt = internalStream.Read (bytes, 0, size);\r
+\r
+                       if (cnt <= 0) \r
+                               return false;\r
+\r
+                       int bufcnt = decoder.GetCharCount (bytes, 0, cnt);\r
+                       char[] newbuffer = new char [remaining + bufcnt];\r
+                       if (remaining > 0)\r
+                               Array.Copy (buffer, newbuffer, remaining);\r
+                       buffer = newbuffer;\r
+\r
+                       bufcnt = decoder.GetChars (bytes, 0, cnt, buffer, remaining);\r
+                       pos = remaining;\r
+\r
+                       return true;\r
                }\r
 \r
                public override int Peek ()\r
@@ -113,46 +161,40 @@ namespace System.IO {
                        if (!internalStream.CanSeek)\r
                                return -1;\r
 \r
-                       if ((buffer == null) || ((pos + 1) == buffer.Length)) {\r
-                               int cnt = internalEncoding.GetMaxByteCount (1);\r
-                               byte[] bytes = new byte[cnt];\r
-                               int actcnt = internalStream.Read (bytes, 0, cnt);\r
-                               internalStream.Seek (-actcnt, SeekOrigin.Current);\r
+                       if (!ReadBuffer (1))\r
+                               return -1;\r
 \r
-                               if (actcnt <= 0) \r
-                                       return -1;\r
+                       return buffer [pos];\r
+               }\r
 \r
-                               int bufcnt = decoder.GetCharCount (bytes, 0, cnt);\r
-                               char[] chars = new char [bufcnt];\r
-                               bufcnt = decoder.GetChars (bytes, 0, cnt, chars, 0);\r
-                               return chars [0];\r
-                       }\r
+               public override int Read ()\r
+               {\r
+                       if (!ReadBuffer (1))\r
+                               return -1;\r
 \r
-                       return buffer [pos + 1];\r
+                       return buffer[pos++];\r
                }\r
 \r
-               public override int Read ()\r
+               public override int Read (char[] dest_buffer, int index, int count)\r
                {\r
-                       if ((buffer == null) || (++pos == buffer.Length)) {\r
-                               byte[] bytes =  new byte [8192];\r
-                               int cnt = internalStream.Read (bytes, 0, 8192);\r
+                       if (dest_buffer == null)\r
+                               throw new ArgumentException ();\r
 \r
-                               if (cnt <= 0) \r
-                                       return -1;\r
+                       if (index + count >= dest_buffer.Length)\r
+                               throw new ArgumentException ();\r
 \r
-                               int bufcnt = decoder.GetCharCount (bytes, 0, cnt);\r
-                               buffer = new char [bufcnt];\r
-                               bufcnt = decoder.GetChars (bytes, 0, cnt, buffer, 0);\r
-                               pos = 0;\r
-                       }\r
+                       if ((index < 0) || (count < 0))\r
+                               throw new ArgumentOutOfRangeException ();\r
 \r
-                       return buffer[pos];\r
-               }\r
+                       if (!ReadBuffer (count))\r
+                               return -1;\r
 \r
-               [MonoTODO]\r
-               public override int Read (char[] buffer, int index, int count)\r
-               {\r
-                       return 0;\r
+                       int remaining = buffer.Length - pos;\r
+                       int size = Math.Min (remaining, count);\r
+\r
+                       Array.Copy (buffer, pos, dest_buffer, index, size);\r
+\r
+                       return size;\r
                }\r
 \r
                [MonoTODO]\r