2004-12-03 Lluis Sanchez Gual <lluis@novell.com>
[mono.git] / mcs / class / corlib / System.IO / BinaryReader.cs
index d89c5e7587e61a5ad5d3a0bfabc0a60c530eea15..7958b70efb0a40521488a6e03209415214e26922 100644 (file)
@@ -6,6 +6,29 @@
 //   Dick Porter (dick@ximian.com)
 //
 
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 using System;
 using System.Text;
 using System.Globalization;
@@ -17,9 +40,6 @@ namespace System.IO {
                int m_encoding_max_byte;
 
                byte[] m_buffer;
-               byte[] m_peekBuffer;
-               int m_peekIndex = 0;
-               int m_peekLimit = 0;
                
                private bool m_disposed = false;
 
@@ -65,19 +85,18 @@ namespace System.IO {
                        Dispose (true);
                }
 
-               protected virtual void FillBuffer(int bytes) {
-                       if(m_stream==null) {
+               protected virtual void FillBuffer (int bytes)
+               {
+                       if (m_disposed)
+                               throw new ObjectDisposedException ("BinaryReader", "Cannot read from a closed BinaryReader.");
+                       if (m_stream==null)
                                throw new IOException("Stream is invalid");
-                       }
                        
                        CheckBuffer(bytes);
 
                        /* Cope with partial reads */
                        int pos=0;
 
-                       while (m_peekIndex < m_peekLimit)
-                               m_buffer[pos++] = m_peekBuffer[m_peekIndex++];
-
                        while(pos<bytes) {
                                int n=m_stream.Read(m_buffer, pos, bytes-pos);
                                if(n==0) {
@@ -97,21 +116,28 @@ namespace System.IO {
                                throw new IOException("Stream is invalid");
                        }
 
+                       if ( !m_stream.CanSeek )
+                       {
+                               return -1;
+                       }
+
                        char[] result = new char[1];
                        byte[] bytes;
                        int bcount;
 
                        int ccount = ReadCharBytes (result, 0, 1, out bytes, out bcount);
 
-                       if (m_peekBuffer == null || m_peekBuffer.Length < bcount)
-                               m_peekBuffer = new byte[bcount];
+                       // Reposition the stream
+                       m_stream.Position -= bcount;
 
-                       Array.Copy (bytes, m_peekBuffer, bcount);
-                       m_peekIndex = 0;
-                       m_peekLimit = bcount;
-
-                       if (ccount == 0) return -1;
-                       else return result[0];
+                       // If we read 0 characters then return -1
+                       if (ccount == 0) 
+                       {
+                               return -1;
+                       }
+                       
+                       // Return the single character we read
+                       return result[0];
                }
 
                public virtual int Read() {
@@ -138,18 +164,14 @@ namespace System.IO {
                        if (buffer == null) {
                                throw new ArgumentNullException("buffer is null");
                        }
-                       if (buffer.Length - index < count) {
-                               throw new ArgumentException("buffer is too small");
-                       }
                        if (index < 0) {
                                throw new ArgumentOutOfRangeException("index is less than 0");
                        }
                        if (count < 0) {
                                throw new ArgumentOutOfRangeException("count is less than 0");
                        }
-
-                       while (m_peekIndex < m_peekLimit) {
-                               buffer[index++] = m_peekBuffer[m_peekIndex++]; count--; 
+                       if (buffer.Length - index < count) {
+                               throw new ArgumentException("buffer is too small");
                        }
 
                        int bytes_read=m_stream.Read(buffer, index, count);
@@ -170,15 +192,15 @@ namespace System.IO {
                        if (buffer == null) {
                                throw new ArgumentNullException("buffer is null");
                        }
-                       if (buffer.Length - index < count) {
-                               throw new ArgumentException("buffer is too small");
-                       }
                        if (index < 0) {
                                throw new ArgumentOutOfRangeException("index is less than 0");
                        }
                        if (count < 0) {
                                throw new ArgumentOutOfRangeException("count is less than 0");
                        }
+                       if (buffer.Length - index < count) {
+                               throw new ArgumentException("buffer is too small");
+                       }
 
                        int bytes_read;
                        byte[] bytes;
@@ -190,11 +212,14 @@ namespace System.IO {
                        int chars_read=0;
                        bytes_read=0;
                        
-                       while(chars_read < count) {
+                       while(chars_read < count) 
+                       {
                                CheckBuffer(bytes_read + 1);
 
-                               int read_byte = (m_peekIndex < m_peekLimit) ? m_peekBuffer[m_peekIndex++] : m_stream.ReadByte();
-                               if(read_byte==-1) {
+                               int read_byte = m_stream.ReadByte();
+
+                               if(read_byte==-1) 
+                               {
                                        /* EOF */
                                        bytes = m_buffer;
                                        return(chars_read);
@@ -229,17 +254,17 @@ namespace System.IO {
                }
 
                public virtual bool ReadBoolean() {
-                       FillBuffer(1);
-
                        // Return value:
                        //  true if the byte is non-zero; otherwise false.
-                       return(m_buffer[0] != 0);
+                       return ReadByte() != 0;
                }
 
                public virtual byte ReadByte() {
-                       FillBuffer(1);
-
-                       return(m_buffer[0]);
+                       int val = m_stream.ReadByte ();
+                       if (val != -1)
+                               return (byte) val;
+                       
+                       throw new EndOfStreamException ();
                }
 
                public virtual byte[] ReadBytes(int count) {
@@ -262,9 +287,6 @@ namespace System.IO {
                        byte[] buf = new byte[count];
                        int pos=0;
                        
-                       while (m_peekIndex < m_peekLimit)
-                               buf[pos++] = m_peekBuffer[m_peekIndex++];
-\r
                        while(pos < count) \r
                        {
                                int n=m_stream.Read(buf, pos, count-pos);
@@ -384,9 +406,7 @@ namespace System.IO {
 
                [CLSCompliant(false)]
                public virtual sbyte ReadSByte() {
-                       FillBuffer(1);
-
-                       return((sbyte)m_buffer[0]);
+                       return (sbyte) ReadByte ();
                }
 
                public virtual string ReadString() {