Skip to content

Commit

Permalink
Add more extension methods and bump version (#150)
Browse files Browse the repository at this point in the history
* Adding single and double precision extension methods for encoding and decoding

* Bumping version to v0.3.4
  • Loading branch information
hoakbuilds authored Jul 12, 2021
1 parent 540890b commit 61376e9
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 12 deletions.
2 changes: 1 addition & 1 deletion SharedBuildProperties.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Product>Solnet</Product>
<Version>0.3.3</Version>
<Version>0.3.4</Version>
<Copyright>Copyright 2021 &#169; Solnet</Copyright>
<Authors>blockmountain</Authors>
<PublisherName>blockmountain</PublisherName>
Expand Down
30 changes: 30 additions & 0 deletions src/Solnet.Programs/Utilities/Deserialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,5 +172,35 @@ public static BigInteger GetBigInt(this ReadOnlySpan<byte> data, int offset, int
throw new ArgumentOutOfRangeException(nameof(offset));
return new BigInteger(data.Slice(offset, length), isSigned, isBigEndian);
}

/// <summary>
/// Get a double-precision floating-point number from the span at the given offset.
/// </summary>
/// <param name="data">The span to get data from.</param>
/// <param name="offset">The offset at which the double-precision floating-point number begins.</param>
/// <returns>The <see cref="double"/> instance that represents the value.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the span.</exception>
public static double GetDouble(this ReadOnlySpan<byte> data, int offset)
{
if (offset + 8 > data.Length)
throw new ArgumentOutOfRangeException(nameof(offset));

return BinaryPrimitives.ReadDoubleLittleEndian(data.Slice(offset, 8));
}

/// <summary>
/// Get a single-precision floating-point number from the span at the given offset.
/// </summary>
/// <param name="data">The span to get data from.</param>
/// <param name="offset">The offset at which the single-precision floating-point number begins.</param>
/// <returns>The <see cref="float"/> instance that represents the value.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the span.</exception>
public static float GetSingle(this ReadOnlySpan<byte> data, int offset)
{
if (offset + 4 > data.Length)
throw new ArgumentOutOfRangeException(nameof(offset));

return BinaryPrimitives.ReadSingleLittleEndian(data.Slice(offset, 4));
}
}
}
42 changes: 31 additions & 11 deletions src/Solnet.Programs/Utilities/Serialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public static class Serialization
/// <param name="data">The span to get data from.</param>
/// <param name="value">The 8-bit unsigned integer value to write.</param>
/// <param name="offset">The offset at which to write the 8-bit unsigned integer.</param>
/// <returns>The 8-bit unsigned integer.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WriteU8(this byte[] data, byte value, int offset)
{
Expand All @@ -32,7 +31,6 @@ public static void WriteU8(this byte[] data, byte value, int offset)
/// <param name="data">The span to get data from.</param>
/// <param name="value">The 16-bit unsigned integer value to write.</param>
/// <param name="offset">The offset at which to write the 16-bit unsigned integer.</param>
/// <returns>The 16-bit unsigned integer.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WriteU16(this byte[] data, ushort value, int offset)
{
Expand All @@ -47,7 +45,6 @@ public static void WriteU16(this byte[] data, ushort value, int offset)
/// <param name="data">The span to get data from.</param>
/// <param name="value">The 32-bit unsigned integer value to write.</param>
/// <param name="offset">The offset at which to write the 32-bit unsigned integer.</param>
/// <returns>The 32-bit unsigned integer.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WriteU32(this byte[] data, uint value, int offset)
{
Expand All @@ -62,7 +59,6 @@ public static void WriteU32(this byte[] data, uint value, int offset)
/// <param name="data">The span to get data from.</param>
/// <param name="value">The 64-bit unsigned integer value to write.</param>
/// <param name="offset">The offset at which to write the 64-bit unsigned integer.</param>
/// <returns>The 64-bit unsigned integer.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WriteU64(this byte[] data, ulong value, int offset)
{
Expand All @@ -77,7 +73,6 @@ public static void WriteU64(this byte[] data, ulong value, int offset)
/// <param name="data">The span to get data from.</param>
/// <param name="value">The 8-bit signed integer value to write.</param>
/// <param name="offset">The offset at which to write the 8-bit signed integer.</param>
/// <returns>The 8-bit signed integer.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WriteS8(this byte[] data, sbyte value, int offset)
{
Expand All @@ -92,7 +87,6 @@ public static void WriteS8(this byte[] data, sbyte value, int offset)
/// <param name="data">The span to get data from.</param>
/// <param name="value">The 16-bit signed integer value to write.</param>
/// <param name="offset">The offset at which to write the 16-bit signed integer.</param>
/// <returns>The 16-bit signed integer.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WriteS16(this byte[] data, short value, int offset)
{
Expand All @@ -107,7 +101,6 @@ public static void WriteS16(this byte[] data, short value, int offset)
/// <param name="data">The span to get data from.</param>
/// <param name="value">The 32-bit signed integer value to write.</param>
/// <param name="offset">The offset at which to write the 32-bit signed integer.</param>
/// <returns>The 32-bit signed integer.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WriteS32(this byte[] data, int value, int offset)
{
Expand All @@ -122,7 +115,6 @@ public static void WriteS32(this byte[] data, int value, int offset)
/// <param name="data">The span to get data from.</param>
/// <param name="value">The 64-bit signed integer value to write.</param>
/// <param name="offset">The offset at which to write the 64-bit signed integer.</param>
/// <returns>The 64-bit signed integer.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WriteS64(this byte[] data, long value, int offset)
{
Expand All @@ -137,7 +129,6 @@ public static void WriteS64(this byte[] data, long value, int offset)
/// <param name="data">The span to get data from.</param>
/// <param name="span">The <see cref="ReadOnlySpan{T}"/> to write.</param>
/// <param name="offset">The offset at which to write the <see cref="ReadOnlySpan{T}"/>.</param>
/// <returns>The <see cref="PublicKey"/> instance.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WriteSpan(this byte[] data, ReadOnlySpan<byte> span, int offset)
{
Expand All @@ -152,7 +143,6 @@ public static void WriteSpan(this byte[] data, ReadOnlySpan<byte> span, int offs
/// <param name="data">The span to get data from.</param>
/// <param name="publicKey">The <see cref="PublicKey"/> to write.</param>
/// <param name="offset">The offset at which to write the <see cref="PublicKey"/>.</param>
/// <returns>The <see cref="PublicKey"/> instance.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WritePubKey(this byte[] data, PublicKey publicKey, int offset)
{
Expand All @@ -170,7 +160,7 @@ public static void WritePubKey(this byte[] data, PublicKey publicKey, int offset
/// <param name="offset">The offset at which to write the <see cref="BigInteger"/>.</param>
/// <param name="isSigned">Whether the value uses signed encoding.</param>
/// <param name="isBigEndian">Whether the value is in big-endian byte order.</param>
/// <returns>The <see cref="BigInteger"/> instance that represents the value.</returns>
/// <returns>An integer representing the number of bytes written to the byte array.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static int WriteBigInt(this byte[] data, BigInteger bigInteger, int offset,
bool isSigned = false, bool isBigEndian = false)
Expand All @@ -186,5 +176,35 @@ public static int WriteBigInt(this byte[] data, BigInteger bigInteger, int offse
isBigEndian);
return written;
}

/// <summary>
/// Write a double-precision floating-point value to the byte array at the given offset.
/// </summary>
/// <param name="data">The byte array to get data from.</param>
/// <param name="value">The <see cref="double"/> to write.</param>
/// <param name="offset">The offset at which to write the <see cref="double"/>.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WriteDouble(this byte[] data, double value, int offset)
{
if (offset + 8 > data.Length)
throw new ArgumentOutOfRangeException(nameof(offset));

BinaryPrimitives.WriteDoubleLittleEndian(data.AsSpan(offset, 8), value);
}

/// <summary>
/// Write a single-precision floating-point value to the byte array at the given offset.
/// </summary>
/// <param name="data">The byte array to get data from.</param>
/// <param name="value">The <see cref="float"/> to write.</param>
/// <param name="offset">The offset at which to write the <see cref="float"/>.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset is too big for the data array.</exception>
public static void WriteSingle(this byte[] data, float value, int offset)
{
if (offset + 4 > data.Length)
throw new ArgumentOutOfRangeException(nameof(offset));

BinaryPrimitives.WriteSingleLittleEndian(data.AsSpan(offset, 4), value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ public class DeserializationUtilitiesTest
153, 153, 153, 153, 153, 153, 153, 25,
};

private static readonly byte[] DoubleBytes =
{
108, 251, 85, 215, 136, 134, 245, 63
};

private static readonly byte[] SingleBytes =
{
71, 52, 172, 63,
};

[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestReadU8Exception()
Expand Down Expand Up @@ -208,5 +218,39 @@ public void TestReadBigInteger()
BigInteger bi = span.GetBigInt(0, 16);
Assert.AreEqual(actual, bi);
}

[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestReadDoubleException()
{
ReadOnlySpan<byte> span = DoubleBytes.AsSpan();
double bi = span.GetDouble(1);
}

[TestMethod]
public void TestReadDouble()
{
const double actual = 1.34534534564565;
ReadOnlySpan<byte> span = DoubleBytes.AsSpan();
double bi = span.GetDouble(0);
Assert.AreEqual(actual, bi);
}

[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestReadSingleException()
{
ReadOnlySpan<byte> span = SingleBytes.AsSpan();
float bi = span.GetSingle(1);
}

[TestMethod]
public void TestReadSingle()
{
const float actual = 1.34534534f;
ReadOnlySpan<byte> span = SingleBytes.AsSpan();
float bi = span.GetSingle(0);
Assert.AreEqual(actual, bi);
}
}
}
46 changes: 46 additions & 0 deletions test/Solnet.Programs.Test/Utilities/SerializationUtilitiesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ public class SerializationUtilitiesTest
225, 70, 206, 235, 121, 172, 28, 180, 133, 237,
95, 91, 55, 145, 58, 140, 245, 133, 126, 255, 0, 169
};

private static readonly byte[] DoubleBytes =
{
108, 251, 85, 215, 136, 134, 245, 63
};

private static readonly byte[] SingleBytes =
{
71, 52, 172, 63,
};

[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
Expand Down Expand Up @@ -198,5 +208,41 @@ public void TestWriteBigInteger()
153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 25,
}, sut);
}

[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestWriteDoubleException()
{
const double value = 1.34534534564565;
byte[] bytes = new byte[8];
bytes.WriteDouble(value, 1);
}

[TestMethod]
public void TestWriteDouble()
{
const double value = 1.34534534564565;
byte[] bytes = new byte[8];
bytes.WriteDouble(value, 0);
CollectionAssert.AreEqual(DoubleBytes, bytes);
}

[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestWriteSingleException()
{
const float value = 1.34534534f;
byte[] bytes = new byte[4];
bytes.WriteSingle(value, 1);
}

[TestMethod]
public void TestWriteSingle()
{
const float value = 1.34534534f;
byte[] bytes = new byte[4];
bytes.WriteSingle(value, 0);
CollectionAssert.AreEqual(SingleBytes, bytes);
}
}
}

0 comments on commit 61376e9

Please sign in to comment.