From 6d8bc96304f494f981b61466e285a6fe27286bf3 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 18 Apr 2018 12:07:54 -0700 Subject: [PATCH] Remove EndianBinaryReader & Writer It was factored out over the last few PRs --- src/ImageSharp/IO/EndianBinaryReader.cs | 364 ------------------ src/ImageSharp/IO/EndianBinaryWriter.cs | 303 --------------- .../IO/EndianBinaryReaderWriterTests.cs | 97 ----- 3 files changed, 764 deletions(-) delete mode 100644 src/ImageSharp/IO/EndianBinaryReader.cs delete mode 100644 src/ImageSharp/IO/EndianBinaryWriter.cs delete mode 100644 tests/ImageSharp.Tests/IO/EndianBinaryReaderWriterTests.cs diff --git a/src/ImageSharp/IO/EndianBinaryReader.cs b/src/ImageSharp/IO/EndianBinaryReader.cs deleted file mode 100644 index 6454ff2506..0000000000 --- a/src/ImageSharp/IO/EndianBinaryReader.cs +++ /dev/null @@ -1,364 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Buffers.Binary; -using System.IO; -using System.Text; - -namespace SixLabors.ImageSharp.IO -{ - /// - /// Equivalent of , but with either endianness. - /// No data is buffered in the reader; the client may seek within the stream at will. - /// - internal class EndianBinaryReader : IDisposable - { - /// - /// Buffer used for temporary storage before conversion into primitives - /// - private readonly byte[] storageBuffer = new byte[16]; - - /// - /// Whether or not this reader has been disposed yet. - /// - private bool disposed; - - /// - /// The endianness used to read data - /// - private readonly Endianness endianness; - - /// - /// Initializes a new instance of the class. - /// Constructs a new binary reader with the given bit converter, reading - /// to the given stream, using the given encoding. - /// - /// Endianness to use when reading data - /// Stream to read data from - public EndianBinaryReader(Endianness endianness, Stream stream) - { - Guard.NotNull(stream, nameof(stream)); - Guard.IsTrue(stream.CanRead, nameof(stream), "Stream isn't readable"); - - this.BaseStream = stream; - this.endianness = endianness; - } - - /// - /// Gets the underlying stream of the EndianBinaryReader. - /// - public Stream BaseStream { get; } - - /// - /// Closes the reader, including the underlying stream. - /// - public void Close() - { - this.Dispose(); - } - - /// - /// Seeks within the stream. - /// - /// Offset to seek to. - /// Origin of seek operation. - public void Seek(int offset, SeekOrigin origin) - { - this.CheckDisposed(); - this.BaseStream.Seek(offset, origin); - } - - /// - /// Reads a single byte from the stream. - /// - /// The byte read - public byte ReadByte() - { - this.ReadInternal(this.storageBuffer, 1); - return this.storageBuffer[0]; - } - - /// - /// Reads a single signed byte from the stream. - /// - /// The byte read - public sbyte ReadSByte() - { - this.ReadInternal(this.storageBuffer, 1); - return unchecked((sbyte)this.storageBuffer[0]); - } - - /// - /// Reads a boolean from the stream. 1 byte is read. - /// - /// The boolean read - public bool ReadBoolean() - { - this.ReadInternal(this.storageBuffer, 1); - - return this.storageBuffer[0] != 0; - } - - /// - /// Reads a 16-bit signed integer from the stream, using the bit converter - /// for this reader. 2 bytes are read. - /// - /// The 16-bit integer read - public short ReadInt16() - { - this.ReadInternal(this.storageBuffer, 2); - - return (this.endianness == Endianness.BigEndian) - ? BinaryPrimitives.ReadInt16BigEndian(this.storageBuffer) - : BinaryPrimitives.ReadInt16LittleEndian(this.storageBuffer); - } - - /// - /// Reads a 32-bit signed integer from the stream, using the bit converter - /// for this reader. 4 bytes are read. - /// - /// The 32-bit integer read - public int ReadInt32() - { - this.ReadInternal(this.storageBuffer, 4); - - return (this.endianness == Endianness.BigEndian) - ? BinaryPrimitives.ReadInt32BigEndian(this.storageBuffer) - : BinaryPrimitives.ReadInt32LittleEndian(this.storageBuffer); - } - - /// - /// Reads a 64-bit signed integer from the stream, using the bit converter - /// for this reader. 8 bytes are read. - /// - /// The 64-bit integer read - public long ReadInt64() - { - this.ReadInternal(this.storageBuffer, 8); - - return (this.endianness == Endianness.BigEndian) - ? BinaryPrimitives.ReadInt64BigEndian(this.storageBuffer) - : BinaryPrimitives.ReadInt64LittleEndian(this.storageBuffer); - } - - /// - /// Reads a 16-bit unsigned integer from the stream, using the bit converter - /// for this reader. 2 bytes are read. - /// - /// The 16-bit unsigned integer read - public ushort ReadUInt16() - { - this.ReadInternal(this.storageBuffer, 2); - - return (this.endianness == Endianness.BigEndian) - ? BinaryPrimitives.ReadUInt16BigEndian(this.storageBuffer) - : BinaryPrimitives.ReadUInt16LittleEndian(this.storageBuffer); - } - - /// - /// Reads a 32-bit unsigned integer from the stream, using the bit converter - /// for this reader. 4 bytes are read. - /// - /// The 32-bit unsigned integer read - public uint ReadUInt32() - { - this.ReadInternal(this.storageBuffer, 4); - - return (this.endianness == Endianness.BigEndian) - ? BinaryPrimitives.ReadUInt32BigEndian(this.storageBuffer) - : BinaryPrimitives.ReadUInt32LittleEndian(this.storageBuffer); - } - - /// - /// Reads a 64-bit unsigned integer from the stream, using the bit converter - /// for this reader. 8 bytes are read. - /// - /// The 64-bit unsigned integer read - public ulong ReadUInt64() - { - this.ReadInternal(this.storageBuffer, 8); - - return (this.endianness == Endianness.BigEndian) - ? BinaryPrimitives.ReadUInt64BigEndian(this.storageBuffer) - : BinaryPrimitives.ReadUInt64LittleEndian(this.storageBuffer); - } - - /// - /// Reads a single-precision floating-point value from the stream, using the bit converter - /// for this reader. 4 bytes are read. - /// - /// The floating point value read - public unsafe float ReadSingle() - { - int intValue = this.ReadInt32(); - - return *((float*)&intValue); - } - - /// - /// Reads a double-precision floating-point value from the stream, using the bit converter - /// for this reader. 8 bytes are read. - /// - /// The floating point value read - public unsafe double ReadDouble() - { - long value = this.ReadInt64(); - - return *((double*)&value); - } - - /// - /// Reads the specified number of bytes into the given buffer, starting at - /// the given index. - /// - /// The buffer to copy data into - /// The first index to copy data into - /// The number of bytes to read - /// The number of bytes actually read. This will only be less than - /// the requested number of bytes if the end of the stream is reached. - /// - public int Read(byte[] buffer, int index, int count) - { - this.CheckDisposed(); - - 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) - { - int block = this.BaseStream.Read(buffer, index, count); - if (block == 0) - { - return read; - } - - index += block; - read += block; - count -= block; - } - - return read; - } - - /// - /// Reads the specified number of bytes, returning them in a new byte array. - /// If not enough bytes are available before the end of the stream, this - /// method will return what is available. - /// - /// The number of bytes to read - /// The bytes read - public byte[] ReadBytes(int count) - { - this.CheckDisposed(); - Guard.MustBeGreaterThanOrEqualTo(count, 0, nameof(count)); - - byte[] ret = new byte[count]; - int index = 0; - while (index < count) - { - int read = this.BaseStream.Read(ret, index, count - index); - - // Stream has finished half way through. That's fine, return what we've got. - if (read == 0) - { - byte[] copy = new byte[index]; - Buffer.BlockCopy(ret, 0, copy, 0, index); - return copy; - } - - index += read; - } - - return ret; - } - - /// - /// Reads the specified number of bytes, returning them in a new byte array. - /// If not enough bytes are available before the end of the stream, this - /// method will throw an IOException. - /// - /// The number of bytes to read - /// The bytes read - public byte[] ReadBytesOrThrow(int count) - { - byte[] ret = new byte[count]; - this.ReadInternal(ret, count); - return ret; - } - - /// - /// Disposes of the underlying stream. - /// - public void Dispose() - { - if (!this.disposed) - { - this.disposed = true; - ((IDisposable)this.BaseStream).Dispose(); - } - } - - /// - /// Checks whether or not the reader has been disposed, throwing an exception if so. - /// - private void CheckDisposed() - { - if (this.disposed) - { - throw new ObjectDisposedException(nameof(EndianBinaryReader)); - } - } - - /// - /// Reads the given number of bytes from the stream, throwing an exception - /// if they can't all be read. - /// - /// Buffer to read into - /// Number of bytes to read - private void ReadInternal(byte[] data, int size) - { - this.CheckDisposed(); - int index = 0; - while (index < size) - { - int read = this.BaseStream.Read(data, index, size - index); - if (read == 0) - { - throw new EndOfStreamException($"End of stream reached with {size - index} byte{(size - index == 1 ? "s" : string.Empty)} left to read."); - } - - index += read; - } - } - - /// - /// Reads the given number of bytes from the stream if possible, returning - /// the number of bytes actually read, which may be less than requested if - /// (and only if) the end of the stream is reached. - /// - /// Buffer to read into - /// Number of bytes to read - /// Number of bytes actually read - private int TryReadInternal(byte[] data, int size) - { - this.CheckDisposed(); - int index = 0; - while (index < size) - { - int read = this.BaseStream.Read(data, index, size - index); - if (read == 0) - { - return index; - } - - index += read; - } - - return index; - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/IO/EndianBinaryWriter.cs b/src/ImageSharp/IO/EndianBinaryWriter.cs deleted file mode 100644 index 9c42f0b694..0000000000 --- a/src/ImageSharp/IO/EndianBinaryWriter.cs +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Buffers.Binary; -using System.IO; - -namespace SixLabors.ImageSharp.IO -{ - /// - /// Equivalent of , but with either endianness - /// - internal class EndianBinaryWriter : IDisposable - { - /// - /// Buffer used for temporary storage during conversion from primitives - /// - private readonly byte[] buffer = new byte[16]; - - /// - /// The endianness used to write the data - /// - private readonly Endianness endianness; - - /// - /// Whether or not this writer has been disposed yet. - /// - private bool disposed; - - /// - /// Initializes a new instance of the class - /// with the given bit converter, writing to the given stream, using the given encoding. - /// - /// Endianness to use when writing data - /// Stream to write data to - public EndianBinaryWriter(Endianness endianness, Stream stream) - { - Guard.NotNull(stream, nameof(stream)); - Guard.IsTrue(stream.CanWrite, nameof(stream), "Stream isn't writable"); - - this.BaseStream = stream; - this.endianness = endianness; - } - - /// - /// Gets the underlying stream of the EndianBinaryWriter. - /// - public Stream BaseStream { get; } - - /// - /// Closes the writer, including the underlying stream. - /// - public void Close() - { - this.Dispose(); - } - - /// - /// Flushes the underlying stream. - /// - public void Flush() - { - this.CheckDisposed(); - this.BaseStream.Flush(); - } - - /// - /// Seeks within the stream. - /// - /// Offset to seek to. - /// Origin of seek operation. - public void Seek(int offset, SeekOrigin origin) - { - this.CheckDisposed(); - this.BaseStream.Seek(offset, origin); - } - - /// - /// Writes a boolean value to the stream. 1 byte is written. - /// - /// The value to write - public void Write(bool value) - { - this.buffer[0] = value ? (byte)1 : (byte)0; - - this.WriteInternal(this.buffer, 1); - } - - /// - /// Writes a 16-bit signed integer to the stream, using the bit converter - /// for this writer. 2 bytes are written. - /// - /// The value to write - public void Write(short value) - { - if (this.endianness == Endianness.BigEndian) - { - BinaryPrimitives.WriteInt16BigEndian(this.buffer, value); - } - else - { - BinaryPrimitives.WriteInt16LittleEndian(this.buffer, value); - } - - this.WriteInternal(this.buffer, 2); - } - - /// - /// Writes a 32-bit signed integer to the stream, using the bit converter - /// for this writer. 4 bytes are written. - /// - /// The value to write - public void Write(int value) - { - if (this.endianness == Endianness.BigEndian) - { - BinaryPrimitives.WriteInt32BigEndian(this.buffer, value); - } - else - { - BinaryPrimitives.WriteInt32LittleEndian(this.buffer, value); - } - - this.WriteInternal(this.buffer, 4); - } - - /// - /// Writes a 64-bit signed integer to the stream, using the bit converter - /// for this writer. 8 bytes are written. - /// - /// The value to write - public void Write(long value) - { - if (this.endianness == Endianness.BigEndian) - { - BinaryPrimitives.WriteInt64BigEndian(this.buffer, value); - } - else - { - BinaryPrimitives.WriteInt64LittleEndian(this.buffer, value); - } - - this.WriteInternal(this.buffer, 8); - } - - /// - /// Writes a 16-bit unsigned integer to the stream, using the bit converter - /// for this writer. 2 bytes are written. - /// - /// The value to write - public void Write(ushort value) - { - if (this.endianness == Endianness.BigEndian) - { - BinaryPrimitives.WriteUInt16BigEndian(this.buffer, value); - } - else - { - BinaryPrimitives.WriteUInt16LittleEndian(this.buffer, value); - } - - this.WriteInternal(this.buffer, 2); - } - - /// - /// Writes a 32-bit unsigned integer to the stream, using the bit converter - /// for this writer. 4 bytes are written. - /// - /// The value to write - public void Write(uint value) - { - if (this.endianness == Endianness.BigEndian) - { - BinaryPrimitives.WriteUInt32BigEndian(this.buffer, value); - } - else - { - BinaryPrimitives.WriteUInt32LittleEndian(this.buffer, value); - } - - this.WriteInternal(this.buffer, 4); - } - - /// - /// Writes a 64-bit unsigned integer to the stream, using the bit converter - /// for this writer. 8 bytes are written. - /// - /// The value to write - public void Write(ulong value) - { - if (this.endianness == Endianness.BigEndian) - { - BinaryPrimitives.WriteUInt64BigEndian(this.buffer, value); - } - else - { - BinaryPrimitives.WriteUInt64LittleEndian(this.buffer, value); - } - - this.WriteInternal(this.buffer, 8); - } - - /// - /// Writes a single-precision floating-point value to the stream, using the bit converter - /// for this writer. 4 bytes are written. - /// - /// The value to write - public unsafe void Write(float value) - { - this.Write(*((int*)&value)); - } - - /// - /// Writes a double-precision floating-point value to the stream, using the bit converter - /// for this writer. 8 bytes are written. - /// - /// The value to write - public unsafe void Write(double value) - { - this.Write(*((long*)&value)); - } - - /// - /// Writes a signed byte to the stream. - /// - /// The value to write - public void Write(byte value) - { - this.buffer[0] = value; - this.WriteInternal(this.buffer, 1); - } - - /// - /// Writes an unsigned byte to the stream. - /// - /// The value to write - public void Write(sbyte value) - { - this.buffer[0] = unchecked((byte)value); - this.WriteInternal(this.buffer, 1); - } - - /// - /// Writes an array of bytes to the stream. - /// - /// The values to write - /// value is null - public void Write(byte[] value) - { - Guard.NotNull(value, nameof(value)); - this.WriteInternal(value, value.Length); - } - - /// - /// Writes a portion of an array of bytes to the stream. - /// - /// An array containing the bytes to write - /// The index of the first byte to write within the array - /// The number of bytes to write - /// value is null - public void Write(byte[] value, int offset, int count) - { - this.CheckDisposed(); - this.BaseStream.Write(value, offset, count); - } - - /// - /// Disposes of the underlying stream. - /// - public void Dispose() - { - if (!this.disposed) - { - this.Flush(); - this.disposed = true; - ((IDisposable)this.BaseStream).Dispose(); - } - } - - /// - /// Checks whether or not the writer has been disposed, throwing an exception if so. - /// - private void CheckDisposed() - { - if (this.disposed) - { - throw new ObjectDisposedException(nameof(EndianBinaryWriter)); - } - } - - /// - /// Writes the specified number of bytes from the start of the given byte array, - /// after checking whether or not the writer has been disposed. - /// - /// The array of bytes to write from - /// The number of bytes to write - private void WriteInternal(byte[] bytes, int length) - { - this.CheckDisposed(); - this.BaseStream.Write(bytes, 0, length); - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/IO/EndianBinaryReaderWriterTests.cs b/tests/ImageSharp.Tests/IO/EndianBinaryReaderWriterTests.cs deleted file mode 100644 index 6e22b16891..0000000000 --- a/tests/ImageSharp.Tests/IO/EndianBinaryReaderWriterTests.cs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.IO; -using SixLabors.ImageSharp.IO; -using Xunit; - -namespace SixLabors.ImageSharp.Tests.IO -{ - public class EndianBinaryReaderWriterTests - { - [Fact] - public void RoundtripSingles() - { - foreach ((Endianness endianness, byte[] bytes) in new[] { - (Endianness.BigEndian, new byte[] { 64, 73, 15, 219 }), - (Endianness.LittleEndian, new byte[] { 219, 15, 73, 64 }) - }) - { - var stream = new MemoryStream(); - - using (var writer = new EndianBinaryWriter(endianness, stream)) - { - writer.Write((float)Math.PI); - - Assert.Equal(bytes, stream.ToArray()); - } - } - } - - [Fact] - public void RoundtripDoubles() - { - foreach ((Endianness endianness, byte[] bytes) in new[] { - (Endianness.BigEndian, new byte[] { 64, 9, 33, 251, 84, 68, 45, 24 }), - (Endianness.LittleEndian, new byte[] { 24, 45, 68, 84, 251, 33, 9, 64 }) - }) - { - var stream = new MemoryStream(); - - using (var writer = new EndianBinaryWriter(endianness, stream)) - { - writer.Write(Math.PI); - - Assert.Equal(bytes, stream.ToArray()); - } - } - } - - /// - /// Ensures that the data written through a binary writer can be read back through the reader - /// - [Fact] - public void RoundtripValues() - { - foreach (Endianness endianness in new[] { Endianness.BigEndian, Endianness.LittleEndian }) - { - var stream = new MemoryStream(); - - var writer = new EndianBinaryWriter(endianness, stream); - - writer.Write(true); // Bool - writer.Write((byte)1); // Byte - writer.Write((short)1); // Int16 - writer.Write(1); // Int32 - writer.Write(1L); // Int64 - writer.Write(1f); // Single - writer.Write(1d); // Double - writer.Write((sbyte)1); // SByte - writer.Write((ushort)1); // UInt16 - writer.Write((uint)1); // UInt32 - writer.Write(1UL); // ULong - - Assert.Equal(43, stream.Length); - - stream.Position = 0; - - var reader = new EndianBinaryReader(endianness, stream); - - Assert.True(reader.ReadBoolean()); // Bool - Assert.Equal((byte)1, reader.ReadByte()); // Byte - Assert.Equal((short)1, reader.ReadInt16()); // Int16 - Assert.Equal(1, reader.ReadInt32()); // Int32 - Assert.Equal(1L, reader.ReadInt64()); // Int64 - Assert.Equal(1f, reader.ReadSingle()); // Single - Assert.Equal(1d, reader.ReadDouble()); // Double - Assert.Equal((sbyte)1, reader.ReadSByte()); // SByte - Assert.Equal((ushort)1, reader.ReadUInt16()); // UInt16 - Assert.Equal((uint)1, reader.ReadUInt32()); // UInt32 - Assert.Equal(1UL, reader.ReadUInt64()); // ULong - - stream.Dispose(); - } - } - } -} \ No newline at end of file