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

[CBOR] Make Half Read/Write methods public and add unit tests #38946

Merged
merged 2 commits into from
Jul 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions src/libraries/System.Formats.Cbor/ref/System.Formats.Cbor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public void ReadEndArray() { }
public void ReadEndIndefiniteLengthByteString() { }
public void ReadEndIndefiniteLengthTextString() { }
public void ReadEndMap() { }
public System.Half ReadHalf() { throw null; }
public int ReadInt32() { throw null; }
public long ReadInt64() { throw null; }
public void ReadNull() { }
Expand Down Expand Up @@ -144,6 +145,7 @@ public void WriteEndArray() { }
public void WriteEndIndefiniteLengthByteString() { }
public void WriteEndIndefiniteLengthTextString() { }
public void WriteEndMap() { }
public void WriteHalf(System.Half value) { }
public void WriteInt32(int value) { }
public void WriteInt64(long value) { }
public void WriteNull() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public partial class CborReader
/// there was an unexpected end of CBOR encoding data. -or-
/// the next value uses a CBOR encoding that is not valid under the current conformance mode.
/// </exception>
internal Half ReadHalf()
public Half ReadHalf()
{
CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Simple);
ReadOnlySpan<byte> buffer = GetRemainingBytes();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public partial class CborWriter
/// The major type of the encoded value is not permitted in the parent data item. -or-
/// The written data is not accepted under the current conformance mode
/// </exception>
internal void WriteHalf(Half value)
public void WriteHalf(Half value)
{
EnsureWriteCapacity(1 + HalfHelpers.SizeOfHalf);
WriteInitialByte(new CborInitialByte(CborMajorType.Simple, CborAdditionalInfo.Additional16BitData));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,28 @@ public partial class CborReaderTests
// Data points taken from https://tools.ietf.org/html/rfc7049#appendix-A
// Additional pairs generated using http://cbor.me/

[Theory]
[InlineData(0.0, "f90000")]
[InlineData(-0.0, "f98000")]
[InlineData(1.0, "f93c00")]
[InlineData(1.5, "f93e00")]
[InlineData(65504.0, "f97bff")]
[InlineData(5.960464477539063e-8, "f90001")]
[InlineData(0.00006103515625, "f90400")]
[InlineData(-4.0, "f9c400")]
[InlineData(double.PositiveInfinity, "f97c00")]
[InlineData(double.NaN, "f97e00")]
[InlineData(double.NegativeInfinity, "f9fc00")]
public static void ReadHalf_SingleValue_HappyPath(float expectedResult, string hexEncoding)
{
byte[] encoding = hexEncoding.HexToByteArray();
var reader = new CborReader(encoding);
Assert.Equal(CborReaderState.HalfPrecisionFloat, reader.PeekState());
Half actualResult = reader.ReadHalf();
AssertHelpers.Equal((Half)expectedResult, actualResult);
Assert.Equal(CborReaderState.Finished, reader.PeekState());
}

[Theory]
[InlineData(100000.0, "fa47c35000")]
[InlineData(3.4028234663852886e+38, "fa7f7fffff")]
Expand Down Expand Up @@ -225,6 +247,25 @@ public static void ReadNull_InvalidTypes_ShouldThrowInvalidOperationException(st
Assert.Equal(encoding.Length, reader.BytesRemaining);
}

[Theory]
[InlineData("01")] // integer
[InlineData("40")] // empty text string
[InlineData("60")] // empty byte string
[InlineData("80")] // []
[InlineData("a0")] // {}
[InlineData("f6")] // null
[InlineData("f4")] // false
[InlineData("c202")] // tagged value
[InlineData("fa47c35000")] // single-precision float encoding
[InlineData("fb7ff0000000000000")] // double-precision float encoding
public static void ReadHalf_InvalidTypes_ShouldThrowInvalidOperationException(string hexEncoding)
{
byte[] encoding = hexEncoding.HexToByteArray();
var reader = new CborReader(encoding);
Assert.Throws<InvalidOperationException>(() => reader.ReadHalf());
Assert.Equal(encoding.Length, reader.BytesRemaining);
}

[Theory]
[InlineData("01")] // integer
[InlineData("40")] // empty text string
Expand Down Expand Up @@ -259,5 +300,21 @@ public static void ReadDouble_InvalidTypes_ShouldThrowInvalidOperationException(
Assert.Throws<InvalidOperationException>(() => reader.ReadDouble());
Assert.Equal(encoding.Length, reader.BytesRemaining);
}

public static class AssertHelpers
{
// temporary workaround for xunit's lack of support for Half equality assertions
public static void Equal(Half expected, Half actual)
{
if (Half.IsNaN(expected))
{
Assert.True(Half.IsNaN(actual), $"Expected: {expected}\nActual: {actual}");
}
else
{
Assert.Equal(expected, actual);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@ public partial class CborWriterTests
// Data points taken from https://tools.ietf.org/html/rfc7049#appendix-A
// Additional pairs generated using http://cbor.me/

[Theory]
[InlineData(0.0, "f90000")]
[InlineData(-0.0, "f98000")]
[InlineData(1.0, "f93c00")]
[InlineData(1.5, "f93e00")]
[InlineData(65504.0, "f97bff")]
[InlineData(5.960464477539063e-8, "f90001")]
[InlineData(0.00006103515625, "f90400")]
[InlineData(-4.0, "f9c400")]
[InlineData(float.PositiveInfinity, "f97c00")]
[InlineData(float.NaN, "f9fe00")]
[InlineData(float.NegativeInfinity, "f9fc00")]
public static void WriteHalf_SingleValue_HappyPath(float input, string hexExpectedEncoding)
{
byte[] expectedEncoding = hexExpectedEncoding.HexToByteArray();
var writer = new CborWriter();
writer.WriteHalf((Half)input);
AssertHelper.HexEqual(expectedEncoding, writer.Encode());
}

[Theory]
[InlineData(100000.0, "fa47c35000")]
[InlineData(3.4028234663852886e+38, "fa7f7fffff")]
Expand Down