Browse Source

Remove BitConverter from EndianBinaryWriter & add Floating point tests

af/merge-core
Jason Nelson 8 years ago
parent
commit
6c1ed4d2c1
  1. 86
      src/ImageSharp/IO/EndianBinaryWriter.cs
  2. 12
      src/ImageSharp/IO/EndianBitConverter.GetBytes.cs
  3. 41
      tests/ImageSharp.Tests/IO/EndianBinaryReaderWriterTests.cs

86
src/ImageSharp/IO/EndianBinaryWriter.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;
@ -23,6 +24,11 @@ namespace SixLabors.ImageSharp.IO
/// </summary>
private readonly char[] charBuffer = new char[1];
/// <summary>
/// The endianness used to write the data
/// </summary>
private readonly Endianness endianness;
/// <summary>
/// Whether or not this writer has been disposed yet.
/// </summary>
@ -55,8 +61,8 @@ namespace SixLabors.ImageSharp.IO
Guard.IsTrue(stream.CanWrite, nameof(stream), "Stream isn't writable");
this.BaseStream = stream;
this.BitConverter = EndianBitConverter.GetConverter(endianness);
this.Encoding = encoding;
this.endianness = endianness;
}
/// <summary>
@ -69,11 +75,6 @@ namespace SixLabors.ImageSharp.IO
/// </summary>
public Stream BaseStream { get; }
/// <summary>
/// Gets the bit converter used to write values to the stream
/// </summary>
internal EndianBitConverter BitConverter { get; }
/// <summary>
/// Closes the writer, including the underlying stream.
/// </summary>
@ -108,7 +109,8 @@ namespace SixLabors.ImageSharp.IO
/// <param name="value">The value to write</param>
public void Write(bool value)
{
this.BitConverter.CopyBytes(value, this.buffer, 0);
this.buffer[0] = value ? (byte)1 : (byte)0;
this.WriteInternal(this.buffer, 1);
}
@ -119,7 +121,15 @@ namespace SixLabors.ImageSharp.IO
/// <param name="value">The value to write</param>
public void Write(short value)
{
this.BitConverter.CopyBytes(value, this.buffer, 0);
if (this.endianness == Endianness.BigEndian)
{
BinaryPrimitives.WriteInt16BigEndian(this.buffer, value);
}
else
{
BinaryPrimitives.WriteInt16LittleEndian(this.buffer, value);
}
this.WriteInternal(this.buffer, 2);
}
@ -130,7 +140,15 @@ namespace SixLabors.ImageSharp.IO
/// <param name="value">The value to write</param>
public void Write(int value)
{
this.BitConverter.CopyBytes(value, this.buffer, 0);
if (this.endianness == Endianness.BigEndian)
{
BinaryPrimitives.WriteInt32BigEndian(this.buffer, value);
}
else
{
BinaryPrimitives.WriteInt32LittleEndian(this.buffer, value);
}
this.WriteInternal(this.buffer, 4);
}
@ -141,7 +159,15 @@ namespace SixLabors.ImageSharp.IO
/// <param name="value">The value to write</param>
public void Write(long value)
{
this.BitConverter.CopyBytes(value, this.buffer, 0);
if (this.endianness == Endianness.BigEndian)
{
BinaryPrimitives.WriteInt64BigEndian(this.buffer, value);
}
else
{
BinaryPrimitives.WriteInt64LittleEndian(this.buffer, value);
}
this.WriteInternal(this.buffer, 8);
}
@ -152,7 +178,15 @@ namespace SixLabors.ImageSharp.IO
/// <param name="value">The value to write</param>
public void Write(ushort value)
{
this.BitConverter.CopyBytes(value, this.buffer, 0);
if (this.endianness == Endianness.BigEndian)
{
BinaryPrimitives.WriteUInt16BigEndian(this.buffer, value);
}
else
{
BinaryPrimitives.WriteUInt16LittleEndian(this.buffer, value);
}
this.WriteInternal(this.buffer, 2);
}
@ -163,7 +197,15 @@ namespace SixLabors.ImageSharp.IO
/// <param name="value">The value to write</param>
public void Write(uint value)
{
this.BitConverter.CopyBytes(value, this.buffer, 0);
if (this.endianness == Endianness.BigEndian)
{
BinaryPrimitives.WriteUInt32BigEndian(this.buffer, value);
}
else
{
BinaryPrimitives.WriteUInt32LittleEndian(this.buffer, value);
}
this.WriteInternal(this.buffer, 4);
}
@ -174,7 +216,15 @@ namespace SixLabors.ImageSharp.IO
/// <param name="value">The value to write</param>
public void Write(ulong value)
{
this.BitConverter.CopyBytes(value, this.buffer, 0);
if (this.endianness == Endianness.BigEndian)
{
BinaryPrimitives.WriteUInt64BigEndian(this.buffer, value);
}
else
{
BinaryPrimitives.WriteUInt64LittleEndian(this.buffer, value);
}
this.WriteInternal(this.buffer, 8);
}
@ -183,10 +233,9 @@ namespace SixLabors.ImageSharp.IO
/// for this writer. 4 bytes are written.
/// </summary>
/// <param name="value">The value to write</param>
public void Write(float value)
public unsafe void Write(float value)
{
this.BitConverter.CopyBytes(value, this.buffer, 0);
this.WriteInternal(this.buffer, 4);
this.Write(*((int*)&value));
}
/// <summary>
@ -194,10 +243,9 @@ namespace SixLabors.ImageSharp.IO
/// for this writer. 8 bytes are written.
/// </summary>
/// <param name="value">The value to write</param>
public void Write(double value)
public unsafe void Write(double value)
{
this.BitConverter.CopyBytes(value, this.buffer, 0);
this.WriteInternal(this.buffer, 8);
this.Write(*((long*)&value));
}
/// <summary>

12
src/ImageSharp/IO/EndianBitConverter.GetBytes.cs

@ -121,17 +121,5 @@ namespace SixLabors.ImageSharp.IO
{
return this.GetBytes(*((int*)&value));
}
/// <summary>
/// Returns the specified decimal value as an array of bytes.
/// </summary>
/// <param name="value">The number to convert.</param>
/// <returns>An array of bytes with length 16.</returns>
public byte[] GetBytes(decimal value)
{
byte[] result = new byte[16];
this.CopyBytes(value, result, 0);
return result;
}
}
}

41
tests/ImageSharp.Tests/IO/EndianBinaryReaderWriterTests.cs

@ -1,6 +1,7 @@
// 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;
@ -9,6 +10,44 @@ 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());
}
}
}
/// <summary>
/// Ensures that the data written through a binary writer can be read back through the reader
/// </summary>
@ -55,4 +94,4 @@ namespace SixLabors.ImageSharp.Tests.IO
}
}
}
}
}
Loading…
Cancel
Save