summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/IO/BinaryReader.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/IO/BinaryReader.cs')
-rw-r--r--src/mscorlib/src/System/IO/BinaryReader.cs347
1 files changed, 208 insertions, 139 deletions
diff --git a/src/mscorlib/src/System/IO/BinaryReader.cs b/src/mscorlib/src/System/IO/BinaryReader.cs
index d973860472..54358d601d 100644
--- a/src/mscorlib/src/System/IO/BinaryReader.cs
+++ b/src/mscorlib/src/System/IO/BinaryReader.cs
@@ -13,54 +13,60 @@
**
**
============================================================*/
-namespace System.IO {
- using System;
- using System.Runtime;
- using System.Text;
- using System.Globalization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Security;
+using System;
+using System.Runtime;
+using System.Text;
+using System.Globalization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Security;
+namespace System.IO
+{
public class BinaryReader : IDisposable
{
private const int MaxCharBytesSize = 128;
- private Stream m_stream;
- private byte[] m_buffer;
- private Decoder m_decoder;
- private byte[] m_charBytes;
- private char[] m_singleChar;
- private char[] m_charBuffer;
- private int m_maxCharsSize; // From MaxCharBytesSize & Encoding
+ private Stream m_stream;
+ private byte[] m_buffer;
+ private Decoder m_decoder;
+ private byte[] m_charBytes;
+ private char[] m_singleChar;
+ private char[] m_charBuffer;
+ private int m_maxCharsSize; // From MaxCharBytesSize & Encoding
// Performance optimization for Read() w/ Unicode. Speeds us up by ~40%
- private bool m_2BytesPerChar;
- private bool m_isMemoryStream; // "do we sit on MemoryStream?" for Read/ReadInt32 perf
- private bool m_leaveOpen;
+ private bool m_2BytesPerChar;
+ private bool m_isMemoryStream; // "do we sit on MemoryStream?" for Read/ReadInt32 perf
+ private bool m_leaveOpen;
- public BinaryReader(Stream input) : this(input, Encoding.UTF8, false) {
+ public BinaryReader(Stream input) : this(input, Encoding.UTF8, false)
+ {
}
- public BinaryReader(Stream input, Encoding encoding) : this(input, encoding, false) {
+ public BinaryReader(Stream input, Encoding encoding) : this(input, encoding, false)
+ {
}
- public BinaryReader(Stream input, Encoding encoding, bool leaveOpen) {
- if (input==null) {
+ public BinaryReader(Stream input, Encoding encoding, bool leaveOpen)
+ {
+ if (input == null)
+ {
throw new ArgumentNullException(nameof(input));
}
- if (encoding==null) {
+ if (encoding == null)
+ {
throw new ArgumentNullException(nameof(encoding));
}
if (!input.CanRead)
- throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
+ throw new ArgumentException(SR.Argument_StreamNotReadable);
Contract.EndContractBlock();
m_stream = input;
m_decoder = encoding.GetDecoder();
m_maxCharsSize = encoding.GetMaxCharCount(MaxCharBytesSize);
int minBufferSize = encoding.GetMaxByteCount(1); // max bytes per one char
- if (minBufferSize < 16)
+ if (minBufferSize < 16)
minBufferSize = 16;
m_buffer = new byte[minBufferSize];
// m_charBuffer and m_charBytes will be left null.
@@ -73,21 +79,26 @@ namespace System.IO {
m_isMemoryStream = (m_stream.GetType() == typeof(MemoryStream));
m_leaveOpen = leaveOpen;
- Debug.Assert(m_decoder!=null, "[BinaryReader.ctor]m_decoder!=null");
+ Debug.Assert(m_decoder != null, "[BinaryReader.ctor]m_decoder!=null");
}
- public virtual Stream BaseStream {
- get {
+ public virtual Stream BaseStream
+ {
+ get
+ {
return m_stream;
}
}
- public virtual void Close() {
+ public virtual void Close()
+ {
Dispose(true);
}
- protected virtual void Dispose(bool disposing) {
- if (disposing) {
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
Stream copyOfStream = m_stream;
m_stream = null;
if (copyOfStream != null && !m_leaveOpen)
@@ -106,10 +117,11 @@ namespace System.IO {
Dispose(true);
}
- public virtual int PeekChar() {
+ public virtual int PeekChar()
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
- if (m_stream==null) __Error.FileNotOpen();
+ if (m_stream == null) __Error.FileNotOpen();
if (!m_stream.CanSeek)
return -1;
@@ -118,59 +130,70 @@ namespace System.IO {
m_stream.Position = origPos;
return ch;
}
-
- public virtual int Read() {
+
+ public virtual int Read()
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
- if (m_stream==null) {
+ if (m_stream == null)
+ {
__Error.FileNotOpen();
}
return InternalReadOneChar();
}
- public virtual bool ReadBoolean(){
+ public virtual bool ReadBoolean()
+ {
FillBuffer(1);
- return (m_buffer[0]!=0);
+ return (m_buffer[0] != 0);
}
- public virtual byte ReadByte() {
+ public virtual byte ReadByte()
+ {
// Inlined to avoid some method call overhead with FillBuffer.
- if (m_stream==null) __Error.FileNotOpen();
+ if (m_stream == null) __Error.FileNotOpen();
int b = m_stream.ReadByte();
if (b == -1)
__Error.EndOfFile();
- return (byte) b;
+ return (byte)b;
}
[CLSCompliant(false)]
- public virtual sbyte ReadSByte() {
+ public virtual sbyte ReadSByte()
+ {
FillBuffer(1);
return (sbyte)(m_buffer[0]);
}
- public virtual char ReadChar() {
+ public virtual char ReadChar()
+ {
int value = Read();
- if (value==-1) {
+ if (value == -1)
+ {
__Error.EndOfFile();
}
return (char)value;
}
- public virtual short ReadInt16() {
+ public virtual short ReadInt16()
+ {
FillBuffer(2);
return (short)(m_buffer[0] | m_buffer[1] << 8);
}
[CLSCompliant(false)]
- public virtual ushort ReadUInt16(){
+ public virtual ushort ReadUInt16()
+ {
FillBuffer(2);
return (ushort)(m_buffer[0] | m_buffer[1] << 8);
}
- public virtual int ReadInt32() {
- if (m_isMemoryStream) {
- if (m_stream==null) __Error.FileNotOpen();
+ public virtual int ReadInt32()
+ {
+ if (m_isMemoryStream)
+ {
+ if (m_stream == null) __Error.FileNotOpen();
// read directly from MemoryStream buffer
MemoryStream mStream = m_stream as MemoryStream;
Debug.Assert(mStream != null, "m_stream as MemoryStream != null");
@@ -185,22 +208,25 @@ namespace System.IO {
}
[CLSCompliant(false)]
- public virtual uint ReadUInt32() {
+ public virtual uint ReadUInt32()
+ {
FillBuffer(4);
return (uint)(m_buffer[0] | m_buffer[1] << 8 | m_buffer[2] << 16 | m_buffer[3] << 24);
}
- public virtual long ReadInt64() {
+ public virtual long ReadInt64()
+ {
FillBuffer(8);
uint lo = (uint)(m_buffer[0] | m_buffer[1] << 8 |
m_buffer[2] << 16 | m_buffer[3] << 24);
uint hi = (uint)(m_buffer[4] | m_buffer[5] << 8 |
m_buffer[6] << 16 | m_buffer[7] << 24);
- return (long) ((ulong)hi) << 32 | lo;
+ return (long)((ulong)hi) << 32 | lo;
}
[CLSCompliant(false)]
- public virtual ulong ReadUInt64() {
+ public virtual ulong ReadUInt64()
+ {
FillBuffer(8);
uint lo = (uint)(m_buffer[0] | m_buffer[1] << 8 |
m_buffer[2] << 16 | m_buffer[3] << 24);
@@ -209,13 +235,15 @@ namespace System.IO {
return ((ulong)hi) << 32 | lo;
}
- public virtual unsafe float ReadSingle() {
+ public virtual unsafe float ReadSingle()
+ {
FillBuffer(4);
uint tmpBuffer = (uint)(m_buffer[0] | m_buffer[1] << 8 | m_buffer[2] << 16 | m_buffer[3] << 24);
return *((float*)&tmpBuffer);
}
- public virtual unsafe double ReadDouble() {
+ public virtual unsafe double ReadDouble()
+ {
FillBuffer(8);
uint lo = (uint)(m_buffer[0] | m_buffer[1] << 8 |
m_buffer[2] << 16 | m_buffer[3] << 24);
@@ -226,18 +254,22 @@ namespace System.IO {
return *((double*)&tmpBuffer);
}
- public virtual decimal ReadDecimal() {
+ public virtual decimal ReadDecimal()
+ {
FillBuffer(16);
- try {
+ try
+ {
return Decimal.ToDecimal(m_buffer);
}
- catch (ArgumentException e) {
+ catch (ArgumentException e)
+ {
// ReadDecimal cannot leak out ArgumentException
- throw new IOException(Environment.GetResourceString("Arg_DecBitCtor"), e);
+ throw new IOException(SR.Arg_DecBitCtor, e);
}
}
- public virtual String ReadString() {
+ public virtual String ReadString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
if (m_stream == null)
@@ -251,29 +283,34 @@ namespace System.IO {
// Length of the string in bytes, not chars
stringLength = Read7BitEncodedInt();
- if (stringLength<0) {
- throw new IOException(Environment.GetResourceString("IO.IO_InvalidStringLen_Len", stringLength));
+ if (stringLength < 0)
+ {
+ throw new IOException(SR.Format(SR.IO_InvalidStringLen_Len, stringLength));
}
- if (stringLength==0) {
+ if (stringLength == 0)
+ {
return String.Empty;
}
- if (m_charBytes==null) {
- m_charBytes = new byte[MaxCharBytesSize];
+ if (m_charBytes == null)
+ {
+ m_charBytes = new byte[MaxCharBytesSize];
}
-
- if (m_charBuffer == null) {
+
+ if (m_charBuffer == null)
+ {
m_charBuffer = new char[m_maxCharsSize];
}
-
- StringBuilder sb = null;
+
+ StringBuilder sb = null;
do
{
- readLength = ((stringLength - currPos)>MaxCharBytesSize)?MaxCharBytesSize:(stringLength - currPos);
+ readLength = ((stringLength - currPos) > MaxCharBytesSize) ? MaxCharBytesSize : (stringLength - currPos);
n = m_stream.Read(m_charBytes, 0, readLength);
- if (n==0) {
+ if (n == 0)
+ {
__Error.EndOfFile();
}
@@ -285,38 +322,43 @@ namespace System.IO {
if (sb == null)
sb = StringBuilderCache.Acquire(stringLength); // Actual string length in chars may be smaller.
sb.Append(m_charBuffer, 0, charsRead);
- currPos +=n;
-
- } while (currPos<stringLength);
+ currPos += n;
+ } while (currPos < stringLength);
return StringBuilderCache.GetStringAndRelease(sb);
}
- public virtual int Read(char[] buffer, int index, int count) {
- if (buffer==null) {
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ public virtual int Read(char[] buffer, int index, int count)
+ {
+ if (buffer == null)
+ {
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
}
- if (index < 0) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (index < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (count < 0) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (buffer.Length - index < count) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ if (buffer.Length - index < count)
+ {
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
}
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.Ensures(Contract.Result<int>() <= count);
Contract.EndContractBlock();
- if (m_stream==null)
+ if (m_stream == null)
__Error.FileNotOpen();
// SafeCritical: index and count have already been verified to be a valid range for the buffer
return InternalReadChars(buffer, index, count);
}
- private int InternalReadChars(char[] buffer, int index, int count) {
+ private int InternalReadChars(char[] buffer, int index, int count)
+ {
Contract.Requires(buffer != null);
Contract.Requires(index >= 0 && count >= 0);
Debug.Assert(m_stream != null);
@@ -324,11 +366,13 @@ namespace System.IO {
int numBytes = 0;
int charsRemaining = count;
- if (m_charBytes==null) {
+ if (m_charBytes == null)
+ {
m_charBytes = new byte[MaxCharBytesSize];
}
- while (charsRemaining > 0) {
+ while (charsRemaining > 0)
+ {
int charsRead = 0;
// We really want to know what the minimum number of bytes per char
// is for our encoding. Otherwise for UnicodeEncoding we'd have to
@@ -337,7 +381,8 @@ namespace System.IO {
// special case for DecoderNLS subclasses when there is a hanging byte from the previous loop
DecoderNLS decoder = m_decoder as DecoderNLS;
- if (decoder != null && decoder.HasState && numBytes > 1) {
+ if (decoder != null && decoder.HasState && numBytes > 1)
+ {
numBytes -= 1;
}
@@ -360,10 +405,11 @@ namespace System.IO {
else
{
numBytes = m_stream.Read(m_charBytes, 0, numBytes);
- byteBuffer = m_charBytes;
+ byteBuffer = m_charBytes;
}
- if (numBytes == 0) {
+ if (numBytes == 0)
+ {
return (count - charsRemaining);
}
@@ -390,7 +436,7 @@ namespace System.IO {
}
charsRemaining -= charsRead;
- index+=charsRead;
+ index += charsRead;
}
// this should never fail
@@ -401,7 +447,8 @@ namespace System.IO {
return (count - charsRemaining);
}
- private int InternalReadOneChar() {
+ private int InternalReadOneChar()
+ {
// I know having a separate InternalReadOneChar method seems a little
// redundant, but this makes a scenario like the security parser code
// 20% faster, in addition to the optimizations for UnicodeEncoding I
@@ -409,18 +456,21 @@ namespace System.IO {
int charsRead = 0;
int numBytes = 0;
long posSav = posSav = 0;
-
+
if (m_stream.CanSeek)
posSav = m_stream.Position;
- if (m_charBytes==null) {
+ if (m_charBytes == null)
+ {
m_charBytes = new byte[MaxCharBytesSize];
}
- if (m_singleChar==null) {
+ if (m_singleChar == null)
+ {
m_singleChar = new char[1];
}
- while (charsRead == 0) {
+ while (charsRead == 0)
+ {
// We really want to know what the minimum number of bytes per char
// is for our encoding. Otherwise for UnicodeEncoding we'd have to
// do ~1+log(n) reads to read n characters.
@@ -428,25 +478,27 @@ namespace System.IO {
numBytes = m_2BytesPerChar ? 2 : 1;
int r = m_stream.ReadByte();
- m_charBytes[0] = (byte) r;
+ m_charBytes[0] = (byte)r;
if (r == -1)
numBytes = 0;
- if (numBytes == 2) {
+ if (numBytes == 2)
+ {
r = m_stream.ReadByte();
- m_charBytes[1] = (byte) r;
+ m_charBytes[1] = (byte)r;
if (r == -1)
numBytes = 1;
}
- if (numBytes==0) {
+ if (numBytes == 0)
+ {
// Console.WriteLine("Found no bytes. We're outta here.");
return -1;
}
Debug.Assert(numBytes == 1 || numBytes == 2, "BinaryReader::InternalReadOneChar assumes it's reading one or 2 bytes only.");
- try {
-
+ try
+ {
charsRead = m_decoder.GetChars(m_charBytes, 0, numBytes, m_singleChar, 0);
}
catch
@@ -468,65 +520,74 @@ namespace System.IO {
return m_singleChar[0];
}
- public virtual char[] ReadChars(int count) {
- if (count<0) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ public virtual char[] ReadChars(int count)
+ {
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.Ensures(Contract.Result<char[]>() != null);
Contract.Ensures(Contract.Result<char[]>().Length <= count);
Contract.EndContractBlock();
- if (m_stream == null) {
+ if (m_stream == null)
+ {
__Error.FileNotOpen();
}
- if (count == 0) {
- return EmptyArray<Char>.Value;
+ if (count == 0)
+ {
+ return Array.Empty<Char>();
}
// SafeCritical: we own the chars buffer, and therefore can guarantee that the index and count are valid
char[] chars = new char[count];
int n = InternalReadChars(chars, 0, count);
- if (n!=count) {
+ if (n != count)
+ {
char[] copy = new char[n];
- Buffer.InternalBlockCopy(chars, 0, copy, 0, 2*n); // sizeof(char)
+ Buffer.InternalBlockCopy(chars, 0, copy, 0, 2 * n); // sizeof(char)
chars = copy;
}
return chars;
}
- public virtual int Read(byte[] buffer, int index, int count) {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ public virtual int Read(byte[] buffer, int index, int count)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.Ensures(Contract.Result<int>() <= count);
Contract.EndContractBlock();
- if (m_stream==null) __Error.FileNotOpen();
+ if (m_stream == null) __Error.FileNotOpen();
return m_stream.Read(buffer, index, count);
}
- public virtual byte[] ReadBytes(int count) {
- if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ public virtual byte[] ReadBytes(int count)
+ {
+ if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.Ensures(Contract.Result<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().Length <= Contract.OldValue(count));
Contract.EndContractBlock();
- if (m_stream==null) __Error.FileNotOpen();
+ if (m_stream == null) __Error.FileNotOpen();
- if (count == 0) {
- return EmptyArray<Byte>.Value;
+ if (count == 0)
+ {
+ return Array.Empty<Byte>();
}
byte[] result = new byte[count];
int numRead = 0;
- do {
+ do
+ {
int n = m_stream.Read(result, numRead, count);
if (n == 0)
break;
@@ -534,7 +595,8 @@ namespace System.IO {
count -= n;
} while (count > 0);
- if (numRead != result.Length) {
+ if (numRead != result.Length)
+ {
// Trim array. This should happen on EOF & possibly net streams.
byte[] copy = new byte[numRead];
Buffer.InternalBlockCopy(result, 0, copy, 0, numRead);
@@ -544,46 +606,53 @@ namespace System.IO {
return result;
}
- protected virtual void FillBuffer(int numBytes) {
- if (m_buffer != null && (numBytes < 0 || numBytes > m_buffer.Length)) {
- throw new ArgumentOutOfRangeException(nameof(numBytes), Environment.GetResourceString("ArgumentOutOfRange_BinaryReaderFillBuffer"));
+ protected virtual void FillBuffer(int numBytes)
+ {
+ if (m_buffer != null && (numBytes < 0 || numBytes > m_buffer.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(numBytes), SR.ArgumentOutOfRange_BinaryReaderFillBuffer);
}
- int bytesRead=0;
+ int bytesRead = 0;
int n = 0;
- if (m_stream==null) __Error.FileNotOpen();
+ if (m_stream == null) __Error.FileNotOpen();
// Need to find a good threshold for calling ReadByte() repeatedly
// vs. calling Read(byte[], int, int) for both buffered & unbuffered
// streams.
- if (numBytes==1) {
+ if (numBytes == 1)
+ {
n = m_stream.ReadByte();
- if (n==-1)
+ if (n == -1)
__Error.EndOfFile();
m_buffer[0] = (byte)n;
return;
}
- do {
- n = m_stream.Read(m_buffer, bytesRead, numBytes-bytesRead);
- if (n==0) {
+ do
+ {
+ n = m_stream.Read(m_buffer, bytesRead, numBytes - bytesRead);
+ if (n == 0)
+ {
__Error.EndOfFile();
}
- bytesRead+=n;
- } while (bytesRead<numBytes);
+ bytesRead += n;
+ } while (bytesRead < numBytes);
}
- internal protected int Read7BitEncodedInt() {
+ internal protected int Read7BitEncodedInt()
+ {
// Read out an Int32 7 bits at a time. The high bit
// of the byte when on means to continue reading more bytes.
int count = 0;
int shift = 0;
byte b;
- do {
+ do
+ {
// Check for a corrupted stream. Read a max of 5 bytes.
// In a future version, add a DataFormatException.
if (shift == 5 * 7) // 5 bytes max per Int32, shift += 7
- throw new FormatException(Environment.GetResourceString("Format_Bad7BitInt32"));
+ throw new FormatException(SR.Format_Bad7BitInt32);
// ReadByte handles end of stream cases for us.
b = ReadByte();