* BinaryReader.cs: internal buffer fix. Little-endian conversions.
authorSergey Chaban <serge@mono-cvs.ximian.com>
Tue, 30 Apr 2002 14:32:21 +0000 (14:32 -0000)
committerSergey Chaban <serge@mono-cvs.ximian.com>
Tue, 30 Apr 2002 14:32:21 +0000 (14:32 -0000)
 * BinaryWriter.cs: little-endian conversions.

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

mcs/class/corlib/System.IO/BinaryReader.cs
mcs/class/corlib/System.IO/BinaryWriter.cs
mcs/class/corlib/System.IO/ChangeLog

index 7090a6b5f8732cace94e00671359506b79533ed3..573ab00c416f08b35e37f38ba1be45a54f40ce68 100644 (file)
@@ -7,6 +7,7 @@
 
 using System;
 using System.Text;
+using System.Globalization;
 
 namespace System.IO {
        public class BinaryReader : IDisposable {
@@ -24,13 +25,14 @@ namespace System.IO {
 
                public BinaryReader(Stream input, Encoding encoding) {
                        if (input == null || encoding == null) 
-                               throw new ArgumentNullException();
+                               throw new ArgumentNullException(Locale.GetText ("Input or Encoding is a null reference."));
                        if (!input.CanRead)
-                               throw new ArgumentException();
+                               throw new ArgumentException(Locale.GetText ("The stream doesn't support reading."));
 
                        m_stream = input;
                        m_encoding = encoding;
                        m_encoding_max_byte = m_encoding.GetMaxByteCount(1);
+                       m_buffer = new byte [32];
                }
 
                public virtual Stream BaseStream {
@@ -153,7 +155,9 @@ namespace System.IO {
                                throw new EndOfStreamException();
                        }
 
-                       bool ret = BitConverter.ToBoolean(m_buffer, m_buffer_pos);
+                       // Return value:
+                       //  true if the byte is non-zero; otherwise false.
+                       bool ret = (m_buffer[m_buffer_pos] != 0);
                        ConsumeBuffered(1);
                        return ret;
                }
@@ -240,18 +244,22 @@ namespace System.IO {
                                throw new EndOfStreamException();
                        }
 
-                       short ret = BitConverter.ToInt16(m_buffer, m_buffer_pos);
+                       short ret = (short) (m_buffer[m_buffer_pos] | (m_buffer[m_buffer_pos + 1] << 8));
                        ConsumeBuffered(2);
                        return ret;
                }
 
                public virtual int ReadInt32() {
-                       if (!EnsureBuffered(1)) {
+                       if (!EnsureBuffered(4)) {
                                throw new EndOfStreamException();
                        }
 
-                       int ret = BitConverter.ToInt32(m_buffer, m_buffer_pos);
-                       ConsumeBuffered(1);
+                       int ret = (m_buffer[m_buffer_pos]             |
+                                  (m_buffer[m_buffer_pos + 1] << 8)  |
+                                  (m_buffer[m_buffer_pos + 2] << 16) |
+                                  (m_buffer[m_buffer_pos + 3] << 24)
+                                 );
+                       ConsumeBuffered(4);
                        return ret;
                }
 
@@ -260,9 +268,18 @@ namespace System.IO {
                                throw new EndOfStreamException();
                        }
 
-                       long ret = BitConverter.ToInt64(m_buffer, m_buffer_pos);
+                       uint ret_low  = (uint) (m_buffer[m_buffer_pos]            |
+                                              (m_buffer[m_buffer_pos + 1] << 8)  |
+                                              (m_buffer[m_buffer_pos + 2] << 16) |
+                                              (m_buffer[m_buffer_pos + 3] << 24)
+                                              );
+                       uint ret_high = (uint) (m_buffer[m_buffer_pos + 4]        |
+                                              (m_buffer[m_buffer_pos + 5] << 8)  |
+                                              (m_buffer[m_buffer_pos + 6] << 16) |
+                                              (m_buffer[m_buffer_pos + 7] << 24)
+                                              );
                        ConsumeBuffered(8);
-                       return ret;
+                       return (long) ((((ulong) ret_high) << 32) | ret_low);
                }
 
                [CLSCompliant(false)]
@@ -307,7 +324,7 @@ namespace System.IO {
                                throw new EndOfStreamException();
                        }
 
-                       ushort ret = BitConverter.ToUInt16(m_buffer, m_buffer_pos);
+                       ushort ret = (ushort) (m_buffer[m_buffer_pos] | (m_buffer[m_buffer_pos + 1] << 8));
                        ConsumeBuffered(2);
                        return ret;
                }
@@ -318,7 +335,11 @@ namespace System.IO {
                                throw new EndOfStreamException();
                        }
 
-                       uint ret = BitConverter.ToUInt32(m_buffer, m_buffer_pos);
+                       uint ret = (uint) (m_buffer[m_buffer_pos]            |
+                                         (m_buffer[m_buffer_pos + 1] << 8)  |
+                                         (m_buffer[m_buffer_pos + 2] << 16) |
+                                         (m_buffer[m_buffer_pos + 3] << 24)
+                                         );
                        ConsumeBuffered(4);
                        return ret;
                }
@@ -329,24 +350,37 @@ namespace System.IO {
                                throw new EndOfStreamException();
                        }
 
-                       ulong ret = BitConverter.ToUInt64(m_buffer, m_buffer_pos);
+                       uint ret_low  = (uint) (m_buffer[m_buffer_pos]            |
+                                              (m_buffer[m_buffer_pos + 1] << 8)  |
+                                              (m_buffer[m_buffer_pos + 2] << 16) |
+                                              (m_buffer[m_buffer_pos + 3] << 24)
+                                              );
+                       uint ret_high = (uint) (m_buffer[m_buffer_pos + 4]        |
+                                              (m_buffer[m_buffer_pos + 5] << 8)  |
+                                              (m_buffer[m_buffer_pos + 6] << 16) |
+                                              (m_buffer[m_buffer_pos + 7] << 24)
+                                              );
                        ConsumeBuffered(8);
-                       return ret;
+                       return (((ulong) ret_high) << 32) | ret_low;
                }
 
                
                bool EnsureBuffered(int bytes) {
                        int needed = bytes - (m_buffer_used - m_buffer_pos);
-                       if (needed <= 0)
+                       if (needed < 0)
                                return true;
 
                        if (m_buffer_used + needed > m_buffer.Length) {
                                byte[] old_buffer = m_buffer;
                                m_buffer = new byte[m_buffer_used + needed];
                                Array.Copy(old_buffer, 0, m_buffer, 0, m_buffer_used);
+                               m_buffer_pos = m_buffer_used;
                        }
 
-                       m_buffer_used += m_stream.Read(m_buffer, m_buffer_used, needed);
+                       int n = m_stream.Read(m_buffer, m_buffer_used, needed);
+                       if (n == 0) return false;
+
+                       m_buffer_used += n;
 
                        return (m_buffer_used >= m_buffer_pos + bytes);
                }
@@ -354,9 +388,6 @@ namespace System.IO {
 
                void ConsumeBuffered(int bytes) {
                        m_buffer_pos += bytes;
-                       if (m_buffer_pos == m_buffer_used) {
-                               m_buffer_pos = 0;
-                       }
                }
        }
 }
index d96a59ab6b8277eb10503d2687a18ac7140dfced..539eb6ab9c0d403380e3d274658421e502781d6a 100755 (executable)
@@ -7,17 +7,24 @@
 
 using System;
 using System.Text;
+using System.Globalization;
 
 namespace System.IO {
        [Serializable]
        public class BinaryWriter : IDisposable {
+
+               // Null is a BinaryWriter with no backing store.
                public static readonly BinaryWriter Null;
 
                protected Stream OutStream;
-               Encoding m_encoding;
-               
-               protected BinaryWriter() {
-                       m_encoding = Encoding.UTF8;
+               private Encoding m_encoding;
+               private byte [] buffer;
+
+               static BinaryWriter() {
+                       Null = new BinaryWriter();
+               }
+
+               protected BinaryWriter() : this (Stream.Null, Encoding.UTF8) {
                }
 
                public BinaryWriter(Stream output) : this(output, Encoding.UTF8) {
@@ -25,12 +32,13 @@ namespace System.IO {
 
                public BinaryWriter(Stream output, Encoding encoding) {
                        if (output == null || encoding == null) 
-                               throw new ArgumentNullException();
+                               throw new ArgumentNullException(Locale.GetText ("Output or Encoding is a null reference."));
                        if (!output.CanWrite)
-                               throw new ArgumentException();
+                               throw new ArgumentException(Locale.GetText ("Stream does not support writing or already closed."));
 
                        OutStream = output;
                        m_encoding = encoding;
+                       buffer = new byte [16];
                }
 
                public virtual Stream BaseStream {
@@ -57,7 +65,8 @@ namespace System.IO {
                }
 
                public virtual void Write(bool value) {
-                       OutStream.Write(BitConverter.GetBytes(value), 0, 1);
+                       buffer [0] = (byte) (value ? 1 : 0);
+                       OutStream.Write(buffer, 0, 1);
                }
 
                public virtual void Write(byte value) {
@@ -65,10 +74,14 @@ namespace System.IO {
                }
 
                public virtual void Write(byte[] value) {
+                       if (value == null)
+                               throw new ArgumentNullException(Locale.GetText ("Byte buffer is a null reference."));
                        OutStream.Write(value, 0, value.Length);
                }
 
                public virtual void Write(byte[] value, int offset, int length) {
+                       if (value == null)
+                               throw new ArgumentNullException(Locale.GetText ("Byte buffer is a null reference."));
                        OutStream.Write(value, offset, length);
                }
 
@@ -80,23 +93,26 @@ namespace System.IO {
                }
                
                public virtual void Write(char[] value) {
+                       if (value == null)
+                               throw new ArgumentNullException(Locale.GetText ("Chars is a null reference."));
                        byte[] enc = m_encoding.GetBytes(value, 0, value.Length);
                        OutStream.Write(enc, 0, enc.Length);
                }
 
                public virtual void Write(char[] value, int offset, int length) {
+                       if (value == null)
+                               throw new ArgumentNullException(Locale.GetText ("Chars is a null reference."));
                        byte[] enc = m_encoding.GetBytes(value, offset, length);
                        OutStream.Write(enc, 0, enc.Length);
                }
 
                unsafe public virtual void Write(decimal value) {
-                       byte[] to_write = new byte[16];
                        byte* value_ptr = (byte *)&value;
                        for (int i = 0; i < 16; i++) {
-                               to_write[i] = value_ptr[i];
+                               buffer [i] = value_ptr [i];
                        }
 
-                       OutStream.Write(to_write, 0, 16);
+                       OutStream.Write(buffer, 0, 16);
                }
 
                public virtual void Write(double value) {
@@ -104,23 +120,29 @@ namespace System.IO {
                }
                
                public virtual void Write(short value) {
-                       OutStream.Write(BitConverter.GetBytes(value), 0, 2);
+                       buffer [0] = (byte) value;
+                       buffer [1] = (byte) (value >> 8);
+                       OutStream.Write(buffer, 0, 2);
                }
                
                public virtual void Write(int value) {
-                       OutStream.Write(BitConverter.GetBytes(value), 0, 4);
+                       buffer [0] = (byte) value;
+                       buffer [1] = (byte) (value >> 8);
+                       buffer [2] = (byte) (value >> 16);
+                       buffer [3] = (byte) (value >> 24);
+                       OutStream.Write(buffer, 0, 4);
                }
 
                public virtual void Write(long value) {
-                       OutStream.Write(BitConverter.GetBytes(value), 0, 8);
+                       for (int i = 0, sh = 0; i < 8; i++, sh += 8)
+                               buffer [i] = (byte) (value >> sh);
+                       OutStream.Write(buffer, 0, 8);
                }
 
                [CLSCompliant(false)]
-               unsafe public virtual void Write(sbyte value) {
-                       byte[] to_write = new byte[1];
-
-                       to_write[0] = *(byte *)&value;
-                       OutStream.Write(to_write, 0, 1);
+               public virtual void Write(sbyte value) {
+                       buffer [0] = (byte) value;
+                       OutStream.Write(buffer, 0, 1);
                }
 
                public virtual void Write(float value) {
@@ -135,17 +157,25 @@ namespace System.IO {
 
                [CLSCompliant(false)]
                public virtual void Write(ushort value) {
-                       OutStream.Write(BitConverter.GetBytes(value), 0, 2);
+                       buffer [0] = (byte) value;
+                       buffer [1] = (byte) (value >> 8);
+                       OutStream.Write(buffer, 0, 2);
                }
 
                [CLSCompliant(false)]
                public virtual void Write(uint value) {
-                       OutStream.Write(BitConverter.GetBytes(value), 0, 4);
+                       buffer [0] = (byte) value;
+                       buffer [1] = (byte) (value >> 8);
+                       buffer [2] = (byte) (value >> 16);
+                       buffer [3] = (byte) (value >> 24);
+                       OutStream.Write(buffer, 0, 4);
                }
 
                [CLSCompliant(false)]
                public virtual void Write(ulong value) {
-                       OutStream.Write(BitConverter.GetBytes(value), 0, 8);
+                       for (int i = 0, sh = 0; i < 8; i++, sh += 8)
+                               buffer [i] = (byte) (value >> sh);
+                       OutStream.Write(buffer, 0, 8);
                }
 
                protected void Write7BitEncodedInt(int value) {
index 7830fe71a009d2118f5b62043fed59aaa076046b..a56b499cd5a4c8b16d11484d801bb378356e685e 100644 (file)
@@ -1,3 +1,12 @@
+2002-04-30  Sergey Chaban  <serge@wildwestsoftware.com>
+
+       * BinaryReader.cs: Allocate buffer before its first use.
+       Handle end of stream properly. Methods to read native types
+       (ReadInt* etc.) are little-endian (see Compact Framework docs).
+
+       * BinaryWriter.cs: Store data in little-endian format.
+       Use internal buffer for conversions.
+
 2002-03-31  Dick Porter  <dick@ximian.com>
 
        * Directory.cs: Strip out "." and ".." from returned list