[Mono-list] A NUnit test with System.IO.BinaryReader

Eduardo Garcia kiwnix@yahoo.es
17 Aug 2002 17:17:17 +0200


--=-hSS78xzDczA9LbU8UHVy
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

I sent it to the author of the class but no answer recived, here is the
test case:

I wish it is fine, and this is usefull.

It pass all the tests fine.

--=-hSS78xzDczA9LbU8UHVy
Content-Disposition: attachment; filename=BinaryReader.cs
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; name=BinaryReader.cs; charset=UTF-8

//
// System.IO.BinaryReader
//
// Author:
//   Matt Kimball (matt@kimball.net)
//

using System;
using System.Text;
using System.Globalization;

namespace System.IO {
	public class BinaryReader : IDisposable {
		Stream m_stream;
		Encoding m_encoding;
		int m_encoding_max_byte;

		byte[] m_buffer;
		int m_buffer_used;
		int m_buffer_pos;


		public BinaryReader(Stream input) : this(input, Encoding.UTF8) {
		}

		public BinaryReader(Stream input, Encoding encoding) {
			if (input =3D=3D null || encoding =3D=3D null)=20
				throw new ArgumentNullException(Locale.GetText ("Input or Encoding is a=
 null reference."));
			if (!input.CanRead)
				throw new ArgumentException(Locale.GetText ("The stream doesn't support=
 reading."));

			m_stream =3D input;
			m_encoding =3D encoding;
			m_encoding_max_byte =3D m_encoding.GetMaxByteCount(1);
			m_buffer =3D new byte [32];
		}

		public virtual Stream BaseStream {
			get {
				return m_stream;
			}
		}

		public virtual void Close() {
			Dispose (true);
			m_stream.Close();
		}
	=09
		protected virtual void Dispose (bool disposing)
		{
			if (disposing)
				m_stream.Close ();

			m_buffer =3D null;
			m_buffer_used =3D 0;
		}

		void IDisposable.Dispose()=20
		{
			Dispose (true);
		}

		protected virtual void FillBuffer(int bytes) {
			if (!EnsureBuffered(m_buffer_used - m_buffer_pos + bytes)) {
				throw new EndOfStreamException();
			}
		}

		public virtual int PeekChar() {
			EnsureBuffered(m_encoding_max_byte);
		=09
			int i;
			for (i =3D 1; m_encoding.GetCharCount(m_buffer, m_buffer_pos, i) =3D=3D =
0; i++) {
				if (m_buffer_pos + i >=3D m_buffer_used) {
					return -1;
				}
			}

			char[] decode =3D m_encoding.GetChars(m_buffer, m_buffer_pos, i);
			return decode[0];
		}

		public virtual int Read() {
			char[] decode =3D new char[1];

			Read(decode, 0, 1);
			return decode[0];
		}

		public virtual int Read(byte[] buffer, int index, int count) {
			if (buffer =3D=3D null) {
				throw new ArgumentNullException();
			}
			if (buffer.Length - index < count) {
				throw new ArgumentException();
			}
			if (index < 0 || count < 0) {
				throw new ArgumentOutOfRangeException();
			}

			EnsureBuffered(count);
		=09
			if (m_buffer_used - m_buffer_pos < count) {
				count =3D m_buffer_used - m_buffer_pos;
			}

			Array.Copy(m_buffer, m_buffer_pos, buffer, index, count);

			ConsumeBuffered(count);
			return count;
		}

		public virtual int Read(char[] buffer, int index, int count) {
			if (buffer =3D=3D null) {
				throw new ArgumentNullException();
			}
			if (buffer.Length - index < count) {
				throw new ArgumentException();
			}
			if (index < 0 || count < 0) {
				throw new ArgumentOutOfRangeException();
			}

			EnsureBuffered(m_encoding_max_byte * count);

			int i;	=09
			for (i =3D 1; m_encoding.GetCharCount(m_buffer, m_buffer_pos, i) < count=
; i++) {
				if (m_buffer_pos + i >=3D m_buffer_used) {
					break;
				}
			}
		=09
			count =3D m_encoding.GetCharCount(m_buffer, m_buffer_pos, i);

			char[] dec =3D m_encoding.GetChars(m_buffer, m_buffer_pos, i);
			Array.Copy(dec, 0, buffer, index, count);

			ConsumeBuffered(i);
			return count;
		}

		protected int Read7BitEncodedInt() {
			int ret =3D 0;
			int shift =3D 0;
			int count =3D 0;
			byte b;

			do {
				if (!EnsureBuffered(++count)) {
					throw new EndOfStreamException();
				}
				b =3D m_buffer[m_buffer_pos + count - 1];
			=09
				ret =3D ret | ((b & 0x7f) << shift);
				shift +=3D 7;
			} while ((b & 0x80) =3D=3D 0x80);

			ConsumeBuffered(count);
			return ret;
		}

		public virtual bool ReadBoolean() {
			if (!EnsureBuffered(1)) {
				throw new EndOfStreamException();
			}

			// Return value:
			//  true if the byte is non-zero; otherwise false.
			bool ret =3D (m_buffer[m_buffer_pos] !=3D 0);
			ConsumeBuffered(1);
			return ret;
		}

		public virtual byte ReadByte() {
			if (!EnsureBuffered(1)) {
				throw new EndOfStreamException();
			}

			byte ret =3D m_buffer[m_buffer_pos];
			ConsumeBuffered(1);
			return ret;
		}

		public virtual byte[] ReadBytes(int count) {
			if (count < 0) {
				throw new ArgumentOutOfRangeException();
			}

			EnsureBuffered(count);

			if (count > m_buffer_used - m_buffer_pos) {
				count =3D m_buffer_used - m_buffer_pos;
			}

			if (count =3D=3D 0) {
				throw new EndOfStreamException();
			}

			byte[] buf =3D new byte[count];
			Read(buf, 0, count);
			return buf;
		}

		public virtual char ReadChar() {
			char[] buf =3D ReadChars(1);
			return buf[0];
		}

		public virtual char[] ReadChars(int count) {
			if (count < 0) {
				throw new ArgumentOutOfRangeException();
			}

			char[] full =3D new char[count];
			count =3D Read(full, 0, count);
		=09
			if (count !=3D full.Length) {
				char[] ret =3D new char[count];
				Array.Copy(full, 0, ret, 0, count);
				return ret;
			} else {
				return full;
			}
		}

		unsafe public virtual decimal ReadDecimal() {
			if (!EnsureBuffered(16)) {
				throw new EndOfStreamException();
			}

			decimal ret;
			byte* ret_ptr =3D (byte *)&ret;
			for (int i =3D 0; i < 16; i++) {
				ret_ptr[i] =3D m_buffer[m_buffer_pos + i];
			}

			ConsumeBuffered(16);
			return ret;
		}

		public virtual double ReadDouble() {
			if (!EnsureBuffered(8)) {
				throw new EndOfStreamException();
			}

			double ret =3D BitConverter.ToDouble(m_buffer, m_buffer_pos);
			ConsumeBuffered(8);
			return ret;
		}

		public virtual short ReadInt16() {
			if (!EnsureBuffered(2)) {
				throw new EndOfStreamException();
			}

			short ret =3D (short) (m_buffer[m_buffer_pos] | (m_buffer[m_buffer_pos +=
 1] << 8));
			ConsumeBuffered(2);
			return ret;
		}

		public virtual int ReadInt32() {
			if (!EnsureBuffered(4)) {
				throw new EndOfStreamException();
			}

			int ret =3D (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;
		}

		public virtual long ReadInt64() {
			if (!EnsureBuffered(8)) {
				throw new EndOfStreamException();
			}

			uint ret_low  =3D (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 =3D (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 (long) ((((ulong) ret_high) << 32) | ret_low);
		}

		[CLSCompliant(false)]
		unsafe public virtual sbyte ReadSByte() {
			if (!EnsureBuffered(1)) {
				throw new EndOfStreamException();
			}

			sbyte ret;
			byte* ret_ptr =3D (byte *)&ret;
			ret_ptr[0] =3D m_buffer[m_buffer_pos];

			ConsumeBuffered(1);
			return ret;
		}

		public virtual string ReadString() {
			int len =3D Read7BitEncodedInt();

			char[] str =3D ReadChars(len);
			string ret =3D "";
			for (int i =3D 0; i < str.Length; i++) {
				ret =3D ret + str[i];
			}

			return ret;
		}

		public virtual float ReadSingle() {
			if (!EnsureBuffered(4)) {
				throw new EndOfStreamException();
			}

			float ret =3D BitConverter.ToSingle(m_buffer, m_buffer_pos);
			ConsumeBuffered(4);
			return ret;
		}

		[CLSCompliant(false)]
		public virtual ushort ReadUInt16() {
			if (!EnsureBuffered(2)) {
				throw new EndOfStreamException();
			}

			ushort ret =3D (ushort) (m_buffer[m_buffer_pos] | (m_buffer[m_buffer_pos=
 + 1] << 8));
			ConsumeBuffered(2);
			return ret;
		}

		[CLSCompliant(false)]
		public virtual uint ReadUInt32() {
			if (!EnsureBuffered(4)) {
				throw new EndOfStreamException();
			}

			uint ret =3D (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;
		}

		[CLSCompliant(false)]
		public virtual ulong ReadUInt64() {
			if (!EnsureBuffered(8)) {
				throw new EndOfStreamException();
			}

			uint ret_low  =3D (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 =3D (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 (((ulong) ret_high) << 32) | ret_low;
		}

	=09
		bool EnsureBuffered(int bytes) {
			int needed =3D bytes - (m_buffer_used - m_buffer_pos);
			if (needed < 0)
				return true;

			if (m_buffer_used + needed > m_buffer.Length) {
				byte[] old_buffer =3D m_buffer;
				m_buffer =3D new byte[m_buffer_used + needed];
				Array.Copy(old_buffer, 0, m_buffer, 0, m_buffer_used);
				m_buffer_pos =3D m_buffer_used;
			}

			int n =3D m_stream.Read(m_buffer, m_buffer_used, needed);
			if (n =3D=3D 0) return false;

			m_buffer_used +=3D n;

			return (m_buffer_used >=3D m_buffer_pos + bytes);
		}


		void ConsumeBuffered(int bytes) {
			m_buffer_pos +=3D bytes;
		}
	}
}

--=-hSS78xzDczA9LbU8UHVy--