From db77dc65362d83df2df92d872bca1ea4a56e72ac Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 21 Mar 2018 09:24:59 -0700 Subject: [PATCH] Remove BitConverter from EndianBinaryReader Also eliminate unnessary offset arithmetic. --- src/ImageSharp/IO/EndianBinaryReader.cs | 68 ++++++++++++++++--------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/src/ImageSharp/IO/EndianBinaryReader.cs b/src/ImageSharp/IO/EndianBinaryReader.cs index 2b2a79c7e..43bb59682 100644 --- a/src/ImageSharp/IO/EndianBinaryReader.cs +++ b/src/ImageSharp/IO/EndianBinaryReader.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Buffers.Binary; using System.IO; using System.Text; @@ -41,7 +42,7 @@ namespace SixLabors.ImageSharp.IO /// /// The endianness used to read data /// - private Endianness endianness; + private readonly Endianness endianness; /// /// Initializes a new instance of the class. @@ -74,7 +75,6 @@ namespace SixLabors.ImageSharp.IO Guard.IsTrue(stream.CanRead, nameof(stream), "Stream isn't readable"); this.BaseStream = stream; - this.BitConverter = EndianBitConverter.GetConverter(endianness); this.Encoding = encoding; this.decoder = encoding.GetDecoder(); this.endianness = endianness; @@ -96,11 +96,6 @@ namespace SixLabors.ImageSharp.IO /// public Stream BaseStream { get; } - /// - /// Gets the bit converter used to read values from the stream. - /// - internal EndianBitConverter BitConverter { get; } - /// /// Closes the reader, including the underlying stream. /// @@ -149,7 +144,6 @@ namespace SixLabors.ImageSharp.IO this.ReadInternal(this.storageBuffer, 1); return this.storageBuffer[0] != 0; - } /// @@ -160,7 +154,10 @@ namespace SixLabors.ImageSharp.IO public short ReadInt16() { this.ReadInternal(this.storageBuffer, 2); - return this.BitConverter.ToInt16(this.storageBuffer, 0); + + return (this.endianness == Endianness.BigEndian) + ? BinaryPrimitives.ReadInt16BigEndian(this.storageBuffer) + : BinaryPrimitives.ReadInt16LittleEndian(this.storageBuffer); } /// @@ -171,7 +168,10 @@ namespace SixLabors.ImageSharp.IO public int ReadInt32() { this.ReadInternal(this.storageBuffer, 4); - return this.BitConverter.ToInt32(this.storageBuffer, 0); + + return (this.endianness == Endianness.BigEndian) + ? BinaryPrimitives.ReadInt32BigEndian(this.storageBuffer) + : BinaryPrimitives.ReadInt32LittleEndian(this.storageBuffer); } /// @@ -182,7 +182,10 @@ namespace SixLabors.ImageSharp.IO public long ReadInt64() { this.ReadInternal(this.storageBuffer, 8); - return this.BitConverter.ToInt64(this.storageBuffer, 0); + + return (this.endianness == Endianness.BigEndian) + ? BinaryPrimitives.ReadInt64BigEndian(this.storageBuffer) + : BinaryPrimitives.ReadInt64LittleEndian(this.storageBuffer); } /// @@ -193,7 +196,10 @@ namespace SixLabors.ImageSharp.IO public ushort ReadUInt16() { this.ReadInternal(this.storageBuffer, 2); - return this.BitConverter.ToUInt16(this.storageBuffer, 0); + + return (this.endianness == Endianness.BigEndian) + ? BinaryPrimitives.ReadUInt16BigEndian(this.storageBuffer) + : BinaryPrimitives.ReadUInt16LittleEndian(this.storageBuffer); } /// @@ -204,7 +210,10 @@ namespace SixLabors.ImageSharp.IO public uint ReadUInt32() { this.ReadInternal(this.storageBuffer, 4); - return this.BitConverter.ToUInt32(this.storageBuffer, 0); + + return (this.endianness == Endianness.BigEndian) + ? BinaryPrimitives.ReadUInt32BigEndian(this.storageBuffer) + : BinaryPrimitives.ReadUInt32LittleEndian(this.storageBuffer); } /// @@ -215,7 +224,11 @@ namespace SixLabors.ImageSharp.IO public ulong ReadUInt64() { this.ReadInternal(this.storageBuffer, 8); - return this.BitConverter.ToUInt64(this.storageBuffer, 0); + + return (this.endianness == Endianness.BigEndian) + ? BinaryPrimitives.ReadUInt64BigEndian(this.storageBuffer) + : BinaryPrimitives.ReadUInt64LittleEndian(this.storageBuffer); + } /// @@ -223,10 +236,11 @@ namespace SixLabors.ImageSharp.IO /// for this reader. 4 bytes are read. /// /// The floating point value read - public float ReadSingle() + public unsafe float ReadSingle() { - this.ReadInternal(this.storageBuffer, 4); - return this.BitConverter.ToSingle(this.storageBuffer, 0); + int intValue = ReadInt32(); + + return *((float*)&intValue); } /// @@ -234,10 +248,11 @@ namespace SixLabors.ImageSharp.IO /// for this reader. 8 bytes are read. /// /// The floating point value read - public double ReadDouble() + public unsafe double ReadDouble() { - this.ReadInternal(this.storageBuffer, 8); - return this.BitConverter.ToDouble(this.storageBuffer, 0); + long value = this.ReadInt64(); + + return *((double*)&value); } /// @@ -245,10 +260,17 @@ namespace SixLabors.ImageSharp.IO /// for this reader. 16 bytes are read. /// /// The decimal value read - public decimal ReadDecimal() + public unsafe decimal ReadDecimal() { - this.ReadInternal(this.storageBuffer, 16); - return this.BitConverter.ToDecimal(this.storageBuffer, 0); + decimal result = 0m; + int* presult = (int*)&result; + + presult[0] = this.ReadInt32(); + presult[1] = this.ReadInt32(); + presult[2] = this.ReadInt32(); + presult[3] = this.ReadInt32(); + + return result; } ///