diff --git a/Settings.StyleCop b/Settings.StyleCop
index 30c78e19f..b4cc1655f 100644
--- a/Settings.StyleCop
+++ b/Settings.StyleCop
@@ -38,6 +38,7 @@
bools
desensitivity
premultiplied
+ endianness
diff --git a/src/ImageSharp/IO/EndianBinaryReader.cs b/src/ImageSharp/IO/EndianBinaryReader.cs
index 105647675..c0753e765 100644
--- a/src/ImageSharp/IO/EndianBinaryReader.cs
+++ b/src/ImageSharp/IO/EndianBinaryReader.cs
@@ -10,9 +10,8 @@ namespace ImageSharp.IO
using System.Text;
///
- /// Equivalent of , but with either endianness, depending on
- /// the EndianBitConverter it is constructed with. No data is buffered in the
- /// reader; the client may seek within the stream at will.
+ /// Equivalent of , but with either endianness, depending on the it is constructed with.
+ /// No data is buffered in the reader; the client may seek within the stream at will.
///
internal class EndianBinaryReader : IDisposable
{
@@ -24,7 +23,7 @@ namespace ImageSharp.IO
///
/// Buffer used for temporary storage before conversion into primitives
///
- private readonly byte[] buffer = new byte[16];
+ private readonly byte[] storageBuffer = new byte[16];
///
/// Buffer used for temporary storage when reading a single character
@@ -67,26 +66,10 @@ namespace ImageSharp.IO
/// Encoding to use when reading character data
public EndianBinaryReader(EndianBitConverter bitConverter, Stream stream, Encoding encoding)
{
- // TODO: Use Guard
- if (bitConverter == null)
- {
- throw new ArgumentNullException("bitConverter");
- }
-
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- if (encoding == null)
- {
- throw new ArgumentNullException("encoding");
- }
-
- if (!stream.CanRead)
- {
- throw new ArgumentException("Stream isn't writable", "stream");
- }
+ Guard.NotNull(bitConverter, nameof(bitConverter));
+ Guard.NotNull(stream, nameof(stream));
+ Guard.NotNull(encoding, nameof(encoding));
+ Guard.IsTrue(stream.CanRead, nameof(stream), "Stream isn't readable.");
this.BaseStream = stream;
this.BitConverter = bitConverter;
@@ -140,8 +123,8 @@ namespace ImageSharp.IO
/// The byte read
public byte ReadByte()
{
- this.ReadInternal(this.buffer, 1);
- return this.buffer[0];
+ this.ReadInternal(this.storageBuffer, 1);
+ return this.storageBuffer[0];
}
///
@@ -150,8 +133,8 @@ namespace ImageSharp.IO
/// The byte read
public sbyte ReadSByte()
{
- this.ReadInternal(this.buffer, 1);
- return unchecked((sbyte)this.buffer[0]);
+ this.ReadInternal(this.storageBuffer, 1);
+ return unchecked((sbyte)this.storageBuffer[0]);
}
///
@@ -160,8 +143,8 @@ namespace ImageSharp.IO
/// The boolean read
public bool ReadBoolean()
{
- this.ReadInternal(this.buffer, 1);
- return this.BitConverter.ToBoolean(this.buffer, 0);
+ this.ReadInternal(this.storageBuffer, 1);
+ return this.BitConverter.ToBoolean(this.storageBuffer, 0);
}
///
@@ -171,8 +154,8 @@ namespace ImageSharp.IO
/// The 16-bit integer read
public short ReadInt16()
{
- this.ReadInternal(this.buffer, 2);
- return this.BitConverter.ToInt16(this.buffer, 0);
+ this.ReadInternal(this.storageBuffer, 2);
+ return this.BitConverter.ToInt16(this.storageBuffer, 0);
}
///
@@ -182,8 +165,8 @@ namespace ImageSharp.IO
/// The 32-bit integer read
public int ReadInt32()
{
- this.ReadInternal(this.buffer, 4);
- return this.BitConverter.ToInt32(this.buffer, 0);
+ this.ReadInternal(this.storageBuffer, 4);
+ return this.BitConverter.ToInt32(this.storageBuffer, 0);
}
///
@@ -193,8 +176,8 @@ namespace ImageSharp.IO
/// The 64-bit integer read
public long ReadInt64()
{
- this.ReadInternal(this.buffer, 8);
- return this.BitConverter.ToInt64(this.buffer, 0);
+ this.ReadInternal(this.storageBuffer, 8);
+ return this.BitConverter.ToInt64(this.storageBuffer, 0);
}
///
@@ -204,8 +187,8 @@ namespace ImageSharp.IO
/// The 16-bit unsigned integer read
public ushort ReadUInt16()
{
- this.ReadInternal(this.buffer, 2);
- return this.BitConverter.ToUInt16(this.buffer, 0);
+ this.ReadInternal(this.storageBuffer, 2);
+ return this.BitConverter.ToUInt16(this.storageBuffer, 0);
}
///
@@ -215,8 +198,8 @@ namespace ImageSharp.IO
/// The 32-bit unsigned integer read
public uint ReadUInt32()
{
- this.ReadInternal(this.buffer, 4);
- return this.BitConverter.ToUInt32(this.buffer, 0);
+ this.ReadInternal(this.storageBuffer, 4);
+ return this.BitConverter.ToUInt32(this.storageBuffer, 0);
}
///
@@ -226,8 +209,8 @@ namespace ImageSharp.IO
/// The 64-bit unsigned integer read
public ulong ReadUInt64()
{
- this.ReadInternal(this.buffer, 8);
- return this.BitConverter.ToUInt64(this.buffer, 0);
+ this.ReadInternal(this.storageBuffer, 8);
+ return this.BitConverter.ToUInt64(this.storageBuffer, 0);
}
///
@@ -237,8 +220,8 @@ namespace ImageSharp.IO
/// The floating point value read
public float ReadSingle()
{
- this.ReadInternal(this.buffer, 4);
- return this.BitConverter.ToSingle(this.buffer, 0);
+ this.ReadInternal(this.storageBuffer, 4);
+ return this.BitConverter.ToSingle(this.storageBuffer, 0);
}
///
@@ -248,8 +231,8 @@ namespace ImageSharp.IO
/// The floating point value read
public double ReadDouble()
{
- this.ReadInternal(this.buffer, 8);
- return this.BitConverter.ToDouble(this.buffer, 0);
+ this.ReadInternal(this.storageBuffer, 8);
+ return this.BitConverter.ToDouble(this.storageBuffer, 0);
}
///
@@ -259,8 +242,8 @@ namespace ImageSharp.IO
/// The decimal value read
public decimal ReadDecimal()
{
- this.ReadInternal(this.buffer, 16);
- return this.BitConverter.ToDecimal(this.buffer, 0);
+ this.ReadInternal(this.storageBuffer, 16);
+ return this.BitConverter.ToDecimal(this.storageBuffer, 0);
}
///
@@ -296,33 +279,17 @@ namespace ImageSharp.IO
{
this.CheckDisposed();
- // TODO: Use Guard
- if (this.buffer == null)
- {
- throw new ArgumentNullException("buffer");
- }
-
- if (index < 0)
- {
- throw new ArgumentOutOfRangeException("index");
- }
-
- if (count < 0)
- {
- throw new ArgumentOutOfRangeException("index");
- }
-
- if (count + index > data.Length)
- {
- throw new ArgumentException("Not enough space in buffer for specified number of characters starting at specified index");
- }
+ Guard.NotNull(this.storageBuffer, nameof(this.storageBuffer));
+ Guard.MustBeGreaterThanOrEqualTo(index, 0, nameof(index));
+ Guard.MustBeGreaterThanOrEqualTo(count, 0, nameof(count));
+ Guard.IsFalse(count + index > data.Length, nameof(data.Length), "Not enough space in buffer for specified number of characters starting at specified index.");
int read = 0;
bool firstTime = true;
// Use the normal buffer if we're only reading a small amount, otherwise
// use at most 4K at a time.
- byte[] byteBuffer = this.buffer;
+ byte[] byteBuffer = this.storageBuffer;
if (byteBuffer.Length < count * this.minBytesPerChar)
{
@@ -339,11 +306,10 @@ namespace ImageSharp.IO
amountToRead = count * this.minBytesPerChar;
firstTime = false;
}
-
- // After that we can only assume we need to fully read 'chars left -1' characters
- // and a single byte of the character we may be in the middle of
else
{
+ // After that we can only assume we need to fully read 'chars left -1' characters
+ // and a single byte of the character we may be in the middle of
amountToRead = ((count - read - 1) * this.minBytesPerChar) + 1;
}
@@ -379,25 +345,11 @@ namespace ImageSharp.IO
public int Read(byte[] buffer, int index, int count)
{
this.CheckDisposed();
- if (buffer == null)
- {
- throw new ArgumentNullException("buffer");
- }
- if (index < 0)
- {
- throw new ArgumentOutOfRangeException("index");
- }
-
- if (count < 0)
- {
- throw new ArgumentOutOfRangeException("index");
- }
-
- if (count + index > buffer.Length)
- {
- throw new ArgumentException("Not enough space in buffer for specified number of bytes starting at specified index");
- }
+ Guard.NotNull(this.storageBuffer, nameof(this.storageBuffer));
+ Guard.MustBeGreaterThanOrEqualTo(index, 0, nameof(index));
+ Guard.MustBeGreaterThanOrEqualTo(count, 0, nameof(count));
+ Guard.IsFalse(count + index > buffer.Length, nameof(buffer.Length), "Not enough space in buffer for specified number of bytes starting at specified index.");
int read = 0;
while (count > 0)
@@ -426,10 +378,7 @@ namespace ImageSharp.IO
public byte[] ReadBytes(int count)
{
this.CheckDisposed();
- if (count < 0)
- {
- throw new ArgumentOutOfRangeException("count");
- }
+ Guard.MustBeGreaterThanOrEqualTo(count, 0, nameof(count));
byte[] ret = new byte[count];
int index = 0;
@@ -581,11 +530,7 @@ namespace ImageSharp.IO
int read = this.BaseStream.Read(data, index, size - index);
if (read == 0)
{
- throw new EndOfStreamException(
- string.Format(
- "End of stream reached with {0} byte{1} left to read.",
- size - index,
- size - index == 1 ? "s" : string.Empty));
+ throw new EndOfStreamException($"End of stream reached with {size - index} byte{(size - index == 1 ? "s" : string.Empty)} left to read.");
}
index += read;
@@ -618,4 +563,4 @@ namespace ImageSharp.IO
return index;
}
}
-}
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/IO/EndianBinaryReaderTests.cs b/tests/ImageSharp.Tests/IO/EndianBinaryReaderTests.cs
new file mode 100644
index 000000000..3eed88c87
--- /dev/null
+++ b/tests/ImageSharp.Tests/IO/EndianBinaryReaderTests.cs
@@ -0,0 +1,66 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Tests.IO
+{
+ using System;
+ using System.IO;
+ using System.Text;
+
+ using ImageSharp.IO;
+
+ using Xunit;
+
+ ///
+ /// The endian binary reader tests.
+ ///
+ public class EndianBinaryReaderTests
+ {
+ ///
+ /// The test string.
+ ///
+ private const string TestString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmopqrstuvwxyz";
+
+ ///
+ /// The test bytes.
+ ///
+ private static readonly byte[] TestBytes = Encoding.ASCII.GetBytes(TestString);
+
+ ///
+ /// Tests to ensure that the reader can read beyond internal buffer size.
+ ///
+ [Fact]
+ public void ReadCharsBeyondInternalBufferSize()
+ {
+ MemoryStream stream = new MemoryStream(TestBytes);
+ using (EndianBinaryReader subject = new EndianBinaryReader(EndianBitConverter.Little, stream))
+ {
+ char[] chars = new char[TestString.Length];
+ subject.Read(chars, 0, chars.Length);
+ Assert.Equal(TestString, new string(chars));
+ }
+ }
+
+ ///
+ /// Tests to ensure that the reader cannot read beyond the provided buffer size.
+ ///
+ [Fact]
+ public void ReadCharsBeyondProvidedBufferSize()
+ {
+ Assert.Throws(
+ typeof(ArgumentException),
+ () =>
+ {
+ MemoryStream stream = new MemoryStream(TestBytes);
+ using (EndianBinaryReader subject = new EndianBinaryReader(EndianBitConverter.Little, stream))
+ {
+ char[] chars = new char[TestString.Length - 1];
+
+ subject.Read(chars, 0, TestString.Length);
+ }
+ });
+ }
+ }
+}