Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve float serialization, add .NET 5 Half support. #77

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions NetSerializer.UnitTests/HalfTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#if NET5_0
using System;
using System.IO;
using NUnit.Framework;

namespace NetSerializer.UnitTests
{
[TestFixture]
[TestOf(typeof(Primitives))]
[Parallelizable(ParallelScope.All)]
public class HalfTest
{
[Test]
public void Test()
{
var serializer = new Serializer(new[] {typeof(SerializationType)});

var stream = new MemoryStream();
var obj = new SerializationType
{
R = (Half) 0,
G = (Half) 12.34,
B = (Half) 0.1,
A = Half.PositiveInfinity,
};

serializer.Serialize(stream, obj);

stream.Position = 0;

var read = (SerializationType) serializer.Deserialize(stream);

Assert.That(read.R, Is.EqualTo(obj.R));
Assert.That(read.G, Is.EqualTo(obj.G));
Assert.That(read.B, Is.EqualTo(obj.B));
Assert.That(read.A, Is.EqualTo(obj.A));
}

[Serializable]
private class SerializationType
{
public Half R;
public Half G;
public Half B;
public Half A;
}
}
}
#endif
27 changes: 27 additions & 0 deletions NetSerializer.UnitTests/PrimitivesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,33 @@ namespace NetSerializer.UnitTests
[Parallelizable(ParallelScope.All)]
public class PrimitivesTest
{
#if NET5_0
#if NO_UNSAFE
[Ignore("Float and half tests are inacurrate due to rounding when NO_UNSAFE is enabled.")]
#endif
[Test]
[TestCase(0)]
[TestCase(1)]
[TestCase(123.4)]
[TestCase(0.01)]
[TestCase(double.PositiveInfinity)]
[TestCase(double.NegativeInfinity)]
[TestCase(double.NaN)]
public void TestHalf(double val)
{
// Can't stick Half values in attributes so have to do this.
var half = (Half) val;

var stream = new MemoryStream();
Primitives.WritePrimitive(stream, half);

stream.Position = 0;

Primitives.ReadPrimitive(new ByteStream(stream), out Half read);
Assert.That(read, Is.EqualTo(half));
}
PJB3005 marked this conversation as resolved.
Show resolved Hide resolved
#endif

#if NO_UNSAFE
[Ignore("Float tests are inacurrate due to rounding when NO_UNSAFE is enabled.")]
#endif
Expand Down
31 changes: 31 additions & 0 deletions NetSerializer/Primitives.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using System.Text;
using System.Diagnostics;
#if NETCOREAPP
using System.Runtime.CompilerServices;
using System.Text.Unicode;
using System.Buffers.Binary;
using System.Buffers;
Expand Down Expand Up @@ -240,6 +241,21 @@ public static unsafe void ReadPrimitive(Stream stream, out double value)
ulong v = ReadUInt64(stream);
value = *(double*)(&v);
}

#if NET5_0
public static void WritePrimitive(Stream stream, Half value)
{
ushort v = Unsafe.As<Half, ushort>(ref value);
WriteUInt16(stream, v);
}

public static void ReadPrimitive(Stream stream, out Half value)
{
var v = ReadUInt16(stream);
value = Unsafe.As<ushort, Half>(ref v);
}
#endif

#else
public static void WritePrimitive(Stream stream, float value)
{
Expand All @@ -264,6 +280,21 @@ public static void ReadPrimitive(Stream stream, out double value)
ulong v = ReadUInt64(stream);
value = BitConverter.Int64BitsToDouble((long)v);
}

#if NET5_0
public static void WritePrimitive(Stream stream, Half value)
{
WritePrimitive(stream, (double)value);
}

public static void ReadPrimitive(Stream stream, out Half value)
{
double v;
ReadPrimitive(stream, out v);
value = (Half)v;
}
#endif

#endif

private static void WriteUInt16(Stream stream, ushort value)
Expand Down
5 changes: 4 additions & 1 deletion NetSerializer/TypeSerializers/PrimitivesSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright 2015 Tomi Valkeinen
*
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
Expand Down Expand Up @@ -29,6 +29,9 @@ sealed class PrimitivesSerializer : IStaticTypeSerializer
typeof(DateTime),
typeof(byte[]),
typeof(Decimal),
#if NET5_0
typeof(Half),
#endif
};

public bool Handles(Type type)
Expand Down