{
public static partial class BinaryPrimitives
{
+ public static double ReadDoubleBigEndian(System.ReadOnlySpan<byte> source) { throw null; }
+ public static double ReadDoubleLittleEndian(System.ReadOnlySpan<byte> source) { throw null; }
public static short ReadInt16BigEndian(System.ReadOnlySpan<byte> source) { throw null; }
public static short ReadInt16LittleEndian(System.ReadOnlySpan<byte> source) { throw null; }
public static int ReadInt32BigEndian(System.ReadOnlySpan<byte> source) { throw null; }
public static int ReadInt32LittleEndian(System.ReadOnlySpan<byte> source) { throw null; }
public static long ReadInt64BigEndian(System.ReadOnlySpan<byte> source) { throw null; }
public static long ReadInt64LittleEndian(System.ReadOnlySpan<byte> source) { throw null; }
+ public static float ReadSingleBigEndian(System.ReadOnlySpan<byte> source) { throw null; }
+ public static float ReadSingleLittleEndian(System.ReadOnlySpan<byte> source) { throw null; }
[System.CLSCompliantAttribute(false)]
public static ushort ReadUInt16BigEndian(System.ReadOnlySpan<byte> source) { throw null; }
[System.CLSCompliantAttribute(false)]
public static uint ReverseEndianness(uint value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static ulong ReverseEndianness(ulong value) { throw null; }
+ public static bool TryReadDoubleBigEndian(System.ReadOnlySpan<byte> source, out double value) { throw null; }
+ public static bool TryReadDoubleLittleEndian(System.ReadOnlySpan<byte> source, out double value) { throw null; }
public static bool TryReadInt16BigEndian(System.ReadOnlySpan<byte> source, out short value) { throw null; }
public static bool TryReadInt16LittleEndian(System.ReadOnlySpan<byte> source, out short value) { throw null; }
public static bool TryReadInt32BigEndian(System.ReadOnlySpan<byte> source, out int value) { throw null; }
public static bool TryReadInt32LittleEndian(System.ReadOnlySpan<byte> source, out int value) { throw null; }
public static bool TryReadInt64BigEndian(System.ReadOnlySpan<byte> source, out long value) { throw null; }
public static bool TryReadInt64LittleEndian(System.ReadOnlySpan<byte> source, out long value) { throw null; }
+ public static bool TryReadSingleBigEndian(System.ReadOnlySpan<byte> source, out float value) { throw null; }
+ public static bool TryReadSingleLittleEndian(System.ReadOnlySpan<byte> source, out float value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool TryReadUInt16BigEndian(System.ReadOnlySpan<byte> source, out ushort value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool TryReadUInt64BigEndian(System.ReadOnlySpan<byte> source, out ulong value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool TryReadUInt64LittleEndian(System.ReadOnlySpan<byte> source, out ulong value) { throw null; }
+ public static bool TryWriteDoubleBigEndian(System.Span<byte> destination, double value) { throw null; }
+ public static bool TryWriteDoubleLittleEndian(System.Span<byte> destination, double value) { throw null; }
public static bool TryWriteInt16BigEndian(System.Span<byte> destination, short value) { throw null; }
public static bool TryWriteInt16LittleEndian(System.Span<byte> destination, short value) { throw null; }
public static bool TryWriteInt32BigEndian(System.Span<byte> destination, int value) { throw null; }
public static bool TryWriteInt32LittleEndian(System.Span<byte> destination, int value) { throw null; }
public static bool TryWriteInt64BigEndian(System.Span<byte> destination, long value) { throw null; }
public static bool TryWriteInt64LittleEndian(System.Span<byte> destination, long value) { throw null; }
+ public static bool TryWriteSingleBigEndian(System.Span<byte> destination, float value) { throw null; }
+ public static bool TryWriteSingleLittleEndian(System.Span<byte> destination, float value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool TryWriteUInt16BigEndian(System.Span<byte> destination, ushort value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool TryWriteUInt64BigEndian(System.Span<byte> destination, ulong value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool TryWriteUInt64LittleEndian(System.Span<byte> destination, ulong value) { throw null; }
+ public static void WriteDoubleBigEndian(System.Span<byte> destination, double value) { }
+ public static void WriteDoubleLittleEndian(System.Span<byte> destination, double value) { }
public static void WriteInt16BigEndian(System.Span<byte> destination, short value) { }
public static void WriteInt16LittleEndian(System.Span<byte> destination, short value) { }
public static void WriteInt32BigEndian(System.Span<byte> destination, int value) { }
public static void WriteInt32LittleEndian(System.Span<byte> destination, int value) { }
public static void WriteInt64BigEndian(System.Span<byte> destination, long value) { }
public static void WriteInt64LittleEndian(System.Span<byte> destination, long value) { }
+ public static void WriteSingleBigEndian(System.Span<byte> destination, float value) { }
+ public static void WriteSingleLittleEndian(System.Span<byte> destination, float value) { }
[System.CLSCompliantAttribute(false)]
public static void WriteUInt16BigEndian(System.Span<byte> destination, ushort value) { }
[System.CLSCompliantAttribute(false)]
Assert.Equal<long>(unchecked((long)0x8877665544332211), ReadInt64LittleEndian(span));
Assert.True(TryReadInt64LittleEndian(span, out longValue));
Assert.Equal<long>(unchecked((long)0x8877665544332211), longValue);
+
+ float expectedFloat = BitConverter.Int32BitsToSingle(0x11223344);
+ Assert.Equal<float>(expectedFloat, ReadSingleBigEndian(span));
+ Assert.True(TryReadSingleBigEndian(span, out float floatValue));
+ Assert.Equal<float>(expectedFloat, floatValue);
+
+ expectedFloat = BitConverter.Int32BitsToSingle(0x44332211);
+ Assert.Equal<float>(expectedFloat, ReadSingleLittleEndian(span));
+ Assert.True(TryReadSingleLittleEndian(span, out floatValue));
+ Assert.Equal<float>(expectedFloat, floatValue);
+
+ double expectedDouble = BitConverter.Int64BitsToDouble(0x1122334455667788);
+ Assert.Equal<double>(expectedDouble, ReadDoubleBigEndian(span));
+ Assert.True(TryReadDoubleBigEndian(span, out double doubleValue));
+ Assert.Equal<double>(expectedDouble, doubleValue);
+
+ expectedDouble = BitConverter.Int64BitsToDouble(unchecked((long)0x8877665544332211));
+ Assert.Equal<double>(expectedDouble, ReadDoubleLittleEndian(span));
+ Assert.True(TryReadDoubleLittleEndian(span, out doubleValue));
+ Assert.Equal<double>(expectedDouble, doubleValue);
}
[Fact]
Assert.Equal<long>(unchecked((long)0x8877665544332211), ReadInt64LittleEndian(span));
Assert.True(TryReadInt64LittleEndian(span, out longValue));
Assert.Equal<long>(unchecked((long)0x8877665544332211), longValue);
+
+ float expectedFloat = BitConverter.Int32BitsToSingle(0x11223344);
+ Assert.Equal<float>(expectedFloat, ReadSingleBigEndian(span));
+ Assert.True(TryReadSingleBigEndian(span, out float floatValue));
+ Assert.Equal<float>(expectedFloat, floatValue);
+
+ expectedFloat = BitConverter.Int32BitsToSingle(0x44332211);
+ Assert.Equal<float>(expectedFloat, ReadSingleLittleEndian(span));
+ Assert.True(TryReadSingleLittleEndian(span, out floatValue));
+ Assert.Equal<float>(expectedFloat, floatValue);
+
+ double expectedDouble = BitConverter.Int64BitsToDouble(0x1122334455667788);
+ Assert.Equal<double>(expectedDouble, ReadDoubleBigEndian(span));
+ Assert.True(TryReadDoubleBigEndian(span, out double doubleValue));
+ Assert.Equal<double>(expectedDouble, doubleValue);
+
+ expectedDouble = BitConverter.Int64BitsToDouble(unchecked((long)0x8877665544332211));
+ Assert.Equal<double>(expectedDouble, ReadDoubleLittleEndian(span));
+ Assert.True(TryReadDoubleLittleEndian(span, out doubleValue));
+ Assert.Equal<double>(expectedDouble, doubleValue);
}
[Fact]
TestHelpers.AssertThrows<ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read<ulong>(_span));
Assert.False(MemoryMarshal.TryRead(span, out ulong ulongValue));
+ TestHelpers.AssertThrows<ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read<float>(_span));
+ Assert.False(MemoryMarshal.TryRead(span, out float floatValue));
+ TestHelpers.AssertThrows<ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read<double>(_span));
+ Assert.False(MemoryMarshal.TryRead(span, out double doubleValue));
+
Span<byte> largeSpan = new byte[100];
TestHelpers.AssertThrows<ArgumentException, byte>(largeSpan, (_span) => MemoryMarshal.Read<TestHelpers.TestValueTypeWithReference>(_span));
TestHelpers.AssertThrows<ArgumentException, byte>(largeSpan, (_span) => MemoryMarshal.TryRead(_span, out TestHelpers.TestValueTypeWithReference stringValue));
TestHelpers.AssertThrows<ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read<ulong>(_span));
Assert.False(MemoryMarshal.TryRead(span, out ulong ulongValue));
+ TestHelpers.AssertThrows<ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read<float>(_span));
+ Assert.False(MemoryMarshal.TryRead(span, out float floatValue));
+ TestHelpers.AssertThrows<ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read<double>(_span));
+ Assert.False(MemoryMarshal.TryRead(span, out double doubleValue));
+
ReadOnlySpan<byte> largeSpan = new byte[100];
TestHelpers.AssertThrows<ArgumentException, byte>(largeSpan, (_span) => MemoryMarshal.Read<TestHelpers.TestValueTypeWithReference>(_span));
TestHelpers.AssertThrows<ArgumentException, byte>(largeSpan, (_span) => MemoryMarshal.TryRead(_span, out TestHelpers.TestValueTypeWithReference stringValue));
WriteUInt16BigEndian(spanBE.Slice(14), s_testStruct.US0);
WriteUInt32BigEndian(spanBE.Slice(16), s_testStruct.UI0);
WriteUInt64BigEndian(spanBE.Slice(20), s_testStruct.UL0);
- WriteInt16BigEndian(spanBE.Slice(28), s_testStruct.S1);
- WriteInt32BigEndian(spanBE.Slice(30), s_testStruct.I1);
- WriteInt64BigEndian(spanBE.Slice(34), s_testStruct.L1);
- WriteUInt16BigEndian(spanBE.Slice(42), s_testStruct.US1);
- WriteUInt32BigEndian(spanBE.Slice(44), s_testStruct.UI1);
- WriteUInt64BigEndian(spanBE.Slice(48), s_testStruct.UL1);
+ WriteSingleBigEndian(spanBE.Slice(28), s_testStruct.F0);
+ WriteDoubleBigEndian(spanBE.Slice(32), s_testStruct.D0);
+ WriteInt16BigEndian(spanBE.Slice(40), s_testStruct.S1);
+ WriteInt32BigEndian(spanBE.Slice(42), s_testStruct.I1);
+ WriteInt64BigEndian(spanBE.Slice(46), s_testStruct.L1);
+ WriteUInt16BigEndian(spanBE.Slice(54), s_testStruct.US1);
+ WriteUInt32BigEndian(spanBE.Slice(56), s_testStruct.UI1);
+ WriteUInt64BigEndian(spanBE.Slice(60), s_testStruct.UL1);
+ WriteSingleBigEndian(spanBE.Slice(68), s_testStruct.F1);
+ WriteDoubleBigEndian(spanBE.Slice(72), s_testStruct.D1);
ReadOnlySpan<byte> readOnlySpanBE = new ReadOnlySpan<byte>(spanBE.ToArray());
US0 = ReadUInt16BigEndian(spanBE.Slice(14)),
UI0 = ReadUInt32BigEndian(spanBE.Slice(16)),
UL0 = ReadUInt64BigEndian(spanBE.Slice(20)),
- S1 = ReadInt16BigEndian(spanBE.Slice(28)),
- I1 = ReadInt32BigEndian(spanBE.Slice(30)),
- L1 = ReadInt64BigEndian(spanBE.Slice(34)),
- US1 = ReadUInt16BigEndian(spanBE.Slice(42)),
- UI1 = ReadUInt32BigEndian(spanBE.Slice(44)),
- UL1 = ReadUInt64BigEndian(spanBE.Slice(48))
+ F0 = ReadSingleBigEndian(spanBE.Slice(28)),
+ D0 = ReadDoubleBigEndian(spanBE.Slice(32)),
+ S1 = ReadInt16BigEndian(spanBE.Slice(40)),
+ I1 = ReadInt32BigEndian(spanBE.Slice(42)),
+ L1 = ReadInt64BigEndian(spanBE.Slice(46)),
+ US1 = ReadUInt16BigEndian(spanBE.Slice(54)),
+ UI1 = ReadUInt32BigEndian(spanBE.Slice(56)),
+ UL1 = ReadUInt64BigEndian(spanBE.Slice(60)),
+ F1 = ReadSingleBigEndian(spanBE.Slice(68)),
+ D1 = ReadDoubleBigEndian(spanBE.Slice(72))
};
var readStructFromReadOnlySpan = new TestStruct
US0 = ReadUInt16BigEndian(readOnlySpanBE.Slice(14)),
UI0 = ReadUInt32BigEndian(readOnlySpanBE.Slice(16)),
UL0 = ReadUInt64BigEndian(readOnlySpanBE.Slice(20)),
- S1 = ReadInt16BigEndian(readOnlySpanBE.Slice(28)),
- I1 = ReadInt32BigEndian(readOnlySpanBE.Slice(30)),
- L1 = ReadInt64BigEndian(readOnlySpanBE.Slice(34)),
- US1 = ReadUInt16BigEndian(readOnlySpanBE.Slice(42)),
- UI1 = ReadUInt32BigEndian(readOnlySpanBE.Slice(44)),
- UL1 = ReadUInt64BigEndian(readOnlySpanBE.Slice(48))
+ F0 = ReadSingleBigEndian(readOnlySpanBE.Slice(28)),
+ D0 = ReadDoubleBigEndian(readOnlySpanBE.Slice(32)),
+ S1 = ReadInt16BigEndian(readOnlySpanBE.Slice(40)),
+ I1 = ReadInt32BigEndian(readOnlySpanBE.Slice(42)),
+ L1 = ReadInt64BigEndian(readOnlySpanBE.Slice(46)),
+ US1 = ReadUInt16BigEndian(readOnlySpanBE.Slice(54)),
+ UI1 = ReadUInt32BigEndian(readOnlySpanBE.Slice(56)),
+ UL1 = ReadUInt64BigEndian(readOnlySpanBE.Slice(60)),
+ F1 = ReadSingleBigEndian(readOnlySpanBE.Slice(68)),
+ D1 = ReadDoubleBigEndian(readOnlySpanBE.Slice(72))
};
Assert.Equal(s_testStruct, readStruct);
WriteUInt16LittleEndian(spanLE.Slice(14), s_testStruct.US0);
WriteUInt32LittleEndian(spanLE.Slice(16), s_testStruct.UI0);
WriteUInt64LittleEndian(spanLE.Slice(20), s_testStruct.UL0);
- WriteInt16LittleEndian(spanLE.Slice(28), s_testStruct.S1);
- WriteInt32LittleEndian(spanLE.Slice(30), s_testStruct.I1);
- WriteInt64LittleEndian(spanLE.Slice(34), s_testStruct.L1);
- WriteUInt16LittleEndian(spanLE.Slice(42), s_testStruct.US1);
- WriteUInt32LittleEndian(spanLE.Slice(44), s_testStruct.UI1);
- WriteUInt64LittleEndian(spanLE.Slice(48), s_testStruct.UL1);
+ WriteSingleLittleEndian(spanLE.Slice(28), s_testStruct.F0);
+ WriteDoubleLittleEndian(spanLE.Slice(32), s_testStruct.D0);
+ WriteInt16LittleEndian(spanLE.Slice(40), s_testStruct.S1);
+ WriteInt32LittleEndian(spanLE.Slice(42), s_testStruct.I1);
+ WriteInt64LittleEndian(spanLE.Slice(46), s_testStruct.L1);
+ WriteUInt16LittleEndian(spanLE.Slice(54), s_testStruct.US1);
+ WriteUInt32LittleEndian(spanLE.Slice(56), s_testStruct.UI1);
+ WriteUInt64LittleEndian(spanLE.Slice(60), s_testStruct.UL1);
+ WriteSingleLittleEndian(spanLE.Slice(68), s_testStruct.F1);
+ WriteDoubleLittleEndian(spanLE.Slice(72), s_testStruct.D1);
ReadOnlySpan<byte> readOnlySpanLE = new ReadOnlySpan<byte>(spanLE.ToArray());
US0 = ReadUInt16LittleEndian(spanLE.Slice(14)),
UI0 = ReadUInt32LittleEndian(spanLE.Slice(16)),
UL0 = ReadUInt64LittleEndian(spanLE.Slice(20)),
- S1 = ReadInt16LittleEndian(spanLE.Slice(28)),
- I1 = ReadInt32LittleEndian(spanLE.Slice(30)),
- L1 = ReadInt64LittleEndian(spanLE.Slice(34)),
- US1 = ReadUInt16LittleEndian(spanLE.Slice(42)),
- UI1 = ReadUInt32LittleEndian(spanLE.Slice(44)),
- UL1 = ReadUInt64LittleEndian(spanLE.Slice(48))
+ F0 = ReadSingleLittleEndian(spanLE.Slice(28)),
+ D0 = ReadDoubleLittleEndian(spanLE.Slice(32)),
+ S1 = ReadInt16LittleEndian(spanLE.Slice(40)),
+ I1 = ReadInt32LittleEndian(spanLE.Slice(42)),
+ L1 = ReadInt64LittleEndian(spanLE.Slice(46)),
+ US1 = ReadUInt16LittleEndian(spanLE.Slice(54)),
+ UI1 = ReadUInt32LittleEndian(spanLE.Slice(56)),
+ UL1 = ReadUInt64LittleEndian(spanLE.Slice(60)),
+ F1 = ReadSingleLittleEndian(spanLE.Slice(68)),
+ D1 = ReadDoubleLittleEndian(spanLE.Slice(72))
};
var readStructFromReadOnlySpan = new TestStruct
US0 = ReadUInt16LittleEndian(readOnlySpanLE.Slice(14)),
UI0 = ReadUInt32LittleEndian(readOnlySpanLE.Slice(16)),
UL0 = ReadUInt64LittleEndian(readOnlySpanLE.Slice(20)),
- S1 = ReadInt16LittleEndian(readOnlySpanLE.Slice(28)),
- I1 = ReadInt32LittleEndian(readOnlySpanLE.Slice(30)),
- L1 = ReadInt64LittleEndian(readOnlySpanLE.Slice(34)),
- US1 = ReadUInt16LittleEndian(readOnlySpanLE.Slice(42)),
- UI1 = ReadUInt32LittleEndian(readOnlySpanLE.Slice(44)),
- UL1 = ReadUInt64LittleEndian(readOnlySpanLE.Slice(48))
+ F0 = ReadSingleLittleEndian(readOnlySpanLE.Slice(28)),
+ D0 = ReadDoubleLittleEndian(readOnlySpanLE.Slice(32)),
+ S1 = ReadInt16LittleEndian(readOnlySpanLE.Slice(40)),
+ I1 = ReadInt32LittleEndian(readOnlySpanLE.Slice(42)),
+ L1 = ReadInt64LittleEndian(readOnlySpanLE.Slice(46)),
+ US1 = ReadUInt16LittleEndian(readOnlySpanLE.Slice(54)),
+ UI1 = ReadUInt32LittleEndian(readOnlySpanLE.Slice(56)),
+ UL1 = ReadUInt64LittleEndian(readOnlySpanLE.Slice(60)),
+ F1 = ReadSingleLittleEndian(readOnlySpanLE.Slice(68)),
+ D1 = ReadDoubleLittleEndian(readOnlySpanLE.Slice(72))
};
Assert.Equal(s_testStruct, readStruct);
US0 = ushort.MaxValue,
UI0 = uint.MaxValue,
UL0 = ulong.MaxValue,
+ F0 = float.MaxValue,
+ D0 = double.MaxValue,
S1 = short.MinValue,
I1 = int.MinValue,
L1 = long.MinValue,
US1 = ushort.MinValue,
UI1 = uint.MinValue,
- UL1 = ulong.MinValue
+ UL1 = ulong.MinValue,
+ F1 = float.MinValue,
+ D1 = double.MinValue,
};
[StructLayout(LayoutKind.Sequential)]
public ushort US0;
public uint UI0;
public ulong UL0;
+ public float F0;
+ public double D0;
public short S1;
public int I1;
public long L1;
public ushort US1;
public uint UI1;
public ulong UL1;
+ public float F1;
+ public double D1;
}
}
}
TestHelpers.Validate<long>(span, longValue);
Assert.True(MemoryMarshal.TryWrite<long>(span, ref longValue));
TestHelpers.Validate<long>(span, longValue);
+
+ float floatValue = BitConverter.Int32BitsToSingle(0x11223344);
+ MemoryMarshal.Write<float>(span, ref floatValue);
+ TestHelpers.Validate<float>(span, floatValue);
+ Assert.True(MemoryMarshal.TryWrite<float>(span, ref floatValue));
+ TestHelpers.Validate<float>(span, floatValue);
+
+ double doubleValue = BitConverter.Int64BitsToDouble(0x1122334455667788);
+ MemoryMarshal.Write<double>(span, ref doubleValue);
+ TestHelpers.Validate<double>(span, doubleValue);
+ Assert.True(MemoryMarshal.TryWrite<double>(span, ref doubleValue));
+ TestHelpers.Validate<double>(span, doubleValue);
}
[Theory]
Assert.Equal(value, read);
}
+ [Theory]
+ [InlineData(float.MaxValue)]
+ [InlineData(float.MinValue)]
+ [InlineData(float.Epsilon)]
+ [InlineData(float.PositiveInfinity)]
+ [InlineData(float.NegativeInfinity)]
+ [InlineData(float.NaN)]
+ public void SpanWriteSingle(float value)
+ {
+ Assert.True(BitConverter.IsLittleEndian);
+ var span = new Span<byte>(new byte[4]);
+ WriteSingleBigEndian(span, value);
+ float read = ReadSingleBigEndian(span);
+ Assert.Equal(value, read);
+
+ span.Clear();
+ Assert.True(TryWriteSingleBigEndian(span, value));
+ read = ReadSingleBigEndian(span);
+ Assert.Equal(value, read);
+
+ span.Clear();
+ WriteSingleLittleEndian(span, value);
+ read = ReadSingleLittleEndian(span);
+ Assert.Equal(value, read);
+
+ span.Clear();
+ Assert.True(TryWriteSingleLittleEndian(span, value));
+ read = ReadSingleLittleEndian(span);
+ Assert.Equal(value, read);
+ }
+
+ [Theory]
+ [InlineData(double.MaxValue)]
+ [InlineData(double.MinValue)]
+ [InlineData(double.Epsilon)]
+ [InlineData(double.PositiveInfinity)]
+ [InlineData(double.NegativeInfinity)]
+ [InlineData(double.NaN)]
+ public void SpanWriteDouble(double value)
+ {
+ Assert.True(BitConverter.IsLittleEndian);
+ var span = new Span<byte>(new byte[8]);
+ WriteDoubleBigEndian(span, value);
+ double read = ReadDoubleBigEndian(span);
+ Assert.Equal(value, read);
+
+ span.Clear();
+ Assert.True(TryWriteDoubleBigEndian(span, value));
+ read = ReadDoubleBigEndian(span);
+ Assert.Equal(value, read);
+
+ span.Clear();
+ WriteDoubleLittleEndian(span, value);
+ read = ReadDoubleLittleEndian(span);
+ Assert.Equal(value, read);
+
+ span.Clear();
+ Assert.True(TryWriteDoubleLittleEndian(span, value));
+ read = ReadDoubleLittleEndian(span);
+ Assert.Equal(value, read);
+ }
+
[Fact]
public void SpanWriteFail()
{
uint uintValue = 1;
long longValue = 1;
ulong ulongValue = 1;
+ float floatValue = 1;
+ double doubleValue = 1;
Span<byte> span = new byte[1];
TestHelpers.AssertThrows<ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Write<ulong>(_span, ref ulongValue));
Assert.False(MemoryMarshal.TryWrite<ulong>(span, ref ulongValue));
+ TestHelpers.AssertThrows<ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Write<float>(_span, ref floatValue));
+ Assert.False(MemoryMarshal.TryWrite<float>(span, ref floatValue));
+ TestHelpers.AssertThrows<ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Write<double>(_span, ref doubleValue));
+ Assert.False(MemoryMarshal.TryWrite<double>(span, ref doubleValue));
+
var structValue = new TestHelpers.TestValueTypeWithReference { I = 1, S = "1" };
TestHelpers.AssertThrows<ArgumentException, byte>(span, (_span) => MemoryMarshal.Write<TestHelpers.TestValueTypeWithReference>(_span, ref structValue));
TestHelpers.AssertThrows<ArgumentException, byte>(span, (_span) => MemoryMarshal.TryWrite<TestHelpers.TestValueTypeWithReference>(_span, ref structValue));
/// </summary>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static sbyte ReverseEndianness(sbyte value)
- {
- return value;
- }
+ public static sbyte ReverseEndianness(sbyte value) => value;
/// <summary>
/// Reverses a primitive value - performs an endianness swap
/// rather than having to skip byte fields.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static byte ReverseEndianness(byte value)
- {
- return value;
- }
+ public static byte ReverseEndianness(byte value) => value;
/// <summary>
/// Reverses a primitive value - performs an endianness swap
public static partial class BinaryPrimitives
{
/// <summary>
+ /// Reads a <see cref="double" /> from the beginning of a read-only span of bytes, as big endian.
+ /// </summary>
+ /// <param name="source">The read-only span to read.</param>
+ /// <returns>The big endian value.</returns>
+ /// <remarks>Reads exactly 8 bytes from the beginning of the span.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="source"/> is too small to contain a <see cref="double" />.
+ /// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double ReadDoubleBigEndian(ReadOnlySpan<byte> source)
+ {
+ return BitConverter.IsLittleEndian ?
+ BitConverter.Int64BitsToDouble(ReverseEndianness(MemoryMarshal.Read<long>(source))) :
+ MemoryMarshal.Read<double>(source);
+ }
+
+ /// <summary>
/// Reads an Int16 out of a read-only span of bytes as big endian.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
}
/// <summary>
+ /// Reads a <see cref="float" /> from the beginning of a read-only span of bytes, as big endian.
+ /// </summary>
+ /// <param name="source">The read-only span to read.</param>
+ /// <returns>The big endian value.</returns>
+ /// <remarks>Reads exactly 4 bytes from the beginning of the span.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="source"/> is too small to contain a <see cref="float" />.
+ /// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float ReadSingleBigEndian(ReadOnlySpan<byte> source)
+ {
+ return BitConverter.IsLittleEndian ?
+ BitConverter.Int32BitsToSingle(ReverseEndianness(MemoryMarshal.Read<int>(source))) :
+ MemoryMarshal.Read<float>(source);
+ }
+
+ /// <summary>
/// Reads a UInt16 out of a read-only span of bytes as big endian.
/// </summary>
[CLSCompliant(false)]
}
/// <summary>
+ /// Reads a <see cref="double" /> from the beginning of a read-only span of bytes, as big endian.
+ /// </summary>
+ /// <param name="source">The read-only span of bytes to read.</param>
+ /// <param name="value">When this method returns, the value read out of the read-only span of bytes, as big endian.</param>
+ /// <returns>
+ /// <see langword="true" /> if the span is large enough to contain a <see cref="double" />; otherwise, <see langword="false" />.
+ /// </returns>
+ /// <remarks>Reads exactly 8 bytes from the beginning of the span.</remarks>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool TryReadDoubleBigEndian(ReadOnlySpan<byte> source, out double value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ bool success = MemoryMarshal.TryRead(source, out long tmp);
+ value = BitConverter.Int64BitsToDouble(ReverseEndianness(tmp));
+ return success;
+ }
+
+ return MemoryMarshal.TryRead(source, out value);
+ }
+
+ /// <summary>
/// Reads an Int16 out of a read-only span of bytes as big endian.
- /// <returns>If the span is too small to contain an Int16, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain an Int16, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt16BigEndian(ReadOnlySpan<byte> source, out short value)
{
/// <summary>
/// Reads an Int32 out of a read-only span of bytes as big endian.
- /// <returns>If the span is too small to contain an Int32, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain an Int32, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt32BigEndian(ReadOnlySpan<byte> source, out int value)
{
/// <summary>
/// Reads an Int64 out of a read-only span of bytes as big endian.
- /// <returns>If the span is too small to contain an Int64, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain an Int64, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt64BigEndian(ReadOnlySpan<byte> source, out long value)
{
}
/// <summary>
+ /// Reads a <see cref="float" /> from the beginning of a read-only span of bytes, as big endian.
+ /// </summary>
+ /// <param name="source">The read-only span of bytes to read.</param>
+ /// <param name="value">When this method returns, the value read out of the read-only span of bytes, as big endian.</param>
+ /// <returns>
+ /// <see langword="true" /> if the span is large enough to contain a <see cref="float" />; otherwise, <see langword="false" />.
+ /// </returns>
+ /// <remarks>Reads exactly 4 bytes from the beginning of the span.</remarks>
+ public static bool TryReadSingleBigEndian(ReadOnlySpan<byte> source, out float value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ bool success = MemoryMarshal.TryRead(source, out int tmp);
+ value = BitConverter.Int32BitsToSingle(ReverseEndianness(tmp));
+ return success;
+ }
+
+ return MemoryMarshal.TryRead(source, out value);
+ }
+
+ /// <summary>
/// Reads a UInt16 out of a read-only span of bytes as big endian.
- /// <returns>If the span is too small to contain a UInt16, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain a UInt16, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt16BigEndian(ReadOnlySpan<byte> source, out ushort value)
/// <summary>
/// Reads a UInt32 out of a read-only span of bytes as big endian.
- /// <returns>If the span is too small to contain a UInt32, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain a UInt32, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt32BigEndian(ReadOnlySpan<byte> source, out uint value)
/// <summary>
/// Reads a UInt64 out of a read-only span of bytes as big endian.
- /// <returns>If the span is too small to contain a UInt64, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain a UInt64, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt64BigEndian(ReadOnlySpan<byte> source, out ulong value)
public static partial class BinaryPrimitives
{
/// <summary>
+ /// Reads a <see cref="double" /> from the beginning of a read-only span of bytes, as little endian.
+ /// </summary>
+ /// <param name="source">The read-only span to read.</param>
+ /// <returns>The little endian value.</returns>
+ /// <remarks>Reads exactly 8 bytes from the beginning of the span.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="source"/> is too small to contain a <see cref="double" />.
+ /// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double ReadDoubleLittleEndian(ReadOnlySpan<byte> source)
+ {
+ return !BitConverter.IsLittleEndian ?
+ BitConverter.Int64BitsToDouble(ReverseEndianness(MemoryMarshal.Read<long>(source))) :
+ MemoryMarshal.Read<double>(source);
+ }
+
+ /// <summary>
/// Reads an Int16 out of a read-only span of bytes as little endian.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
}
/// <summary>
+ /// Reads a <see cref="float" /> from the beginning of a read-only span of bytes, as little endian.
+ /// </summary>
+ /// <param name="source">The read-only span to read.</param>
+ /// <returns>The little endian value.</returns>
+ /// <remarks>Reads exactly 4 bytes from the beginning of the span.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="source"/> is too small to contain a <see cref="float" />.
+ /// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float ReadSingleLittleEndian(ReadOnlySpan<byte> source)
+ {
+ return !BitConverter.IsLittleEndian ?
+ BitConverter.Int32BitsToSingle(ReverseEndianness(MemoryMarshal.Read<int>(source))) :
+ MemoryMarshal.Read<float>(source);
+ }
+
+ /// <summary>
/// Reads a UInt16 out of a read-only span of bytes as little endian.
/// </summary>
[CLSCompliant(false)]
}
/// <summary>
+ /// Reads a <see cref="double" /> from the beginning of a read-only span of bytes, as little endian.
+ /// </summary>
+ /// <param name="source">The read-only span of bytes to read.</param>
+ /// <param name="value">When this method returns, the value read out of the read-only span of bytes, as little endian.</param>
+ /// <returns>
+ /// <see langword="true" /> if the span is large enough to contain a <see cref="double" />; otherwise, <see langword="false" />.
+ /// </returns>
+ /// <remarks>Reads exactly 8 bytes from the beginning of the span.</remarks>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool TryReadDoubleLittleEndian(ReadOnlySpan<byte> source, out double value)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ bool success = MemoryMarshal.TryRead(source, out long tmp);
+ value = BitConverter.Int64BitsToDouble(ReverseEndianness(tmp));
+ return success;
+ }
+
+ return MemoryMarshal.TryRead(source, out value);
+ }
+
+ /// <summary>
/// Reads an Int16 out of a read-only span of bytes as little endian.
- /// <returns>If the span is too small to contain an Int16, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain an Int16, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt16LittleEndian(ReadOnlySpan<byte> source, out short value)
{
/// <summary>
/// Reads an Int32 out of a read-only span of bytes as little endian.
- /// <returns>If the span is too small to contain an Int32, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain an Int32, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt32LittleEndian(ReadOnlySpan<byte> source, out int value)
{
/// <summary>
/// Reads an Int64 out of a read-only span of bytes as little endian.
- /// <returns>If the span is too small to contain an Int64, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain an Int64, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt64LittleEndian(ReadOnlySpan<byte> source, out long value)
{
}
/// <summary>
+ /// Reads a <see cref="float" /> from the beginning of a read-only span of bytes, as little endian.
+ /// </summary>
+ /// <param name="source">The read-only span of bytes to read.</param>
+ /// <param name="value">When this method returns, the value read out of the read-only span of bytes, as little endian.</param>
+ /// <returns>
+ /// <see langword="true" /> if the span is large enough to contain a <see cref="float" />; otherwise, <see langword="false" />.
+ /// </returns>
+ /// <remarks>Reads exactly 4 bytes from the beginning of the span.</remarks>
+ public static bool TryReadSingleLittleEndian(ReadOnlySpan<byte> source, out float value)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ bool success = MemoryMarshal.TryRead(source, out int tmp);
+ value = BitConverter.Int32BitsToSingle(ReverseEndianness(tmp));
+ return success;
+ }
+
+ return MemoryMarshal.TryRead(source, out value);
+ }
+
+ /// <summary>
/// Reads a UInt16 out of a read-only span of bytes as little endian.
- /// <returns>If the span is too small to contain a UInt16, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain a UInt16, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt16LittleEndian(ReadOnlySpan<byte> source, out ushort value)
/// <summary>
/// Reads a UInt32 out of a read-only span of bytes as little endian.
- /// <returns>If the span is too small to contain a UInt32, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain a UInt32, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt32LittleEndian(ReadOnlySpan<byte> source, out uint value)
/// <summary>
/// Reads a UInt64 out of a read-only span of bytes as little endian.
- /// <returns>If the span is too small to contain a UInt64, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain a UInt64, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt64LittleEndian(ReadOnlySpan<byte> source, out ulong value)
public static partial class BinaryPrimitives
{
/// <summary>
+ /// Writes a <see cref="double" /> into a span of bytes, as big endian.
+ /// </summary>
+ /// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
+ /// <param name="value">The value to write into the span of bytes.</param>
+ /// <remarks>Writes exactly 8 bytes to the beginning of the span.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="destination" /> is too small to contain a <see cref="double" />.
+ /// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void WriteDoubleBigEndian(Span<byte> destination, double value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
+ MemoryMarshal.Write(destination, ref tmp);
+ }
+ else
+ {
+ MemoryMarshal.Write(destination, ref value);
+ }
+ }
+
+ /// <summary>
/// Writes an Int16 into a span of bytes as big endian.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
}
/// <summary>
+ /// Writes a <see cref="float" /> into a span of bytes, as big endian.
+ /// </summary>
+ /// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
+ /// <param name="value">The value to write into the span of bytes.</param>
+ /// <remarks>Writes exactly 4 bytes to the beginning of the span.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="destination" /> is too small to contain a <see cref="float" />.
+ /// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void WriteSingleBigEndian(Span<byte> destination, float value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ int tmp = ReverseEndianness(BitConverter.SingleToInt32Bits(value));
+ MemoryMarshal.Write(destination, ref tmp);
+ }
+ else
+ {
+ MemoryMarshal.Write(destination, ref value);
+ }
+ }
+
+ /// <summary>
/// Write a UInt16 into a span of bytes as big endian.
/// </summary>
[CLSCompliant(false)]
}
/// <summary>
+ /// Writes a <see cref="double" /> into a span of bytes, as big endian.
+ /// </summary>
+ /// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
+ /// <param name="value">The value to write into the span of bytes.</param>
+ /// <returns>
+ /// <see langword="true" /> if the span is large enough to contain a <see cref="double" />; otherwise, <see langword="false" />.
+ /// </returns>
+ /// <remarks>Writes exactly 8 bytes to the beginning of the span.</remarks>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool TryWriteDoubleBigEndian(Span<byte> destination, double value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
+ return MemoryMarshal.TryWrite(destination, ref tmp);
+ }
+
+ return MemoryMarshal.TryWrite(destination, ref value);
+ }
+
+ /// <summary>
/// Writes an Int16 into a span of bytes as big endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteInt16BigEndian(Span<byte> destination, short value)
{
/// <summary>
/// Writes an Int32 into a span of bytes as big endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteInt32BigEndian(Span<byte> destination, int value)
{
/// <summary>
/// Writes an Int64 into a span of bytes as big endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteInt64BigEndian(Span<byte> destination, long value)
{
}
/// <summary>
+ /// Writes a <see cref="float" /> into a span of bytes, as big endian.
+ /// </summary>
+ /// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
+ /// <param name="value">The value to write into the span of bytes.</param>
+ /// <returns>
+ /// <see langword="true" /> if the span is large enough to contain a <see cref="float" />; otherwise, <see langword="false" />.
+ /// </returns>
+ /// <remarks>Writes exactly 4 bytes to the beginning of the span.</remarks>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool TryWriteSingleBigEndian(Span<byte> destination, float value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ int tmp = ReverseEndianness(BitConverter.SingleToInt32Bits(value));
+ return MemoryMarshal.TryWrite(destination, ref tmp);
+ }
+
+ return MemoryMarshal.TryWrite(destination, ref value);
+ }
+
+ /// <summary>
/// Write a UInt16 into a span of bytes as big endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteUInt16BigEndian(Span<byte> destination, ushort value)
/// <summary>
/// Write a UInt32 into a span of bytes as big endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteUInt32BigEndian(Span<byte> destination, uint value)
/// <summary>
/// Write a UInt64 into a span of bytes as big endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteUInt64BigEndian(Span<byte> destination, ulong value)
public static partial class BinaryPrimitives
{
/// <summary>
+ /// Writes a <see cref="double" /> into a span of bytes, as little endian.
+ /// </summary>
+ /// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
+ /// <param name="value">The value to write into the span of bytes.</param>
+ /// <remarks>Writes exactly 8 bytes to the beginning of the span.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="destination" /> is too small to contain a <see cref="double" />.
+ /// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void WriteDoubleLittleEndian(Span<byte> destination, double value)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
+ MemoryMarshal.Write(destination, ref tmp);
+ }
+ else
+ {
+ MemoryMarshal.Write(destination, ref value);
+ }
+ }
+
+ /// <summary>
/// Writes an Int16 into a span of bytes as little endian.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
}
/// <summary>
+ /// Writes a <see cref="float" /> into a span of bytes, as little endian.
+ /// </summary>
+ /// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
+ /// <param name="value">The value to write into the span of bytes.</param>
+ /// <remarks>Writes exactly 4 bytes to the beginning of the span.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="destination" /> is too small to contain a <see cref="float" />.
+ /// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void WriteSingleLittleEndian(Span<byte> destination, float value)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ int tmp = ReverseEndianness(BitConverter.SingleToInt32Bits(value));
+ MemoryMarshal.Write(destination, ref tmp);
+ }
+ else
+ {
+ MemoryMarshal.Write(destination, ref value);
+ }
+ }
+
+ /// <summary>
/// Write a UInt16 into a span of bytes as little endian.
/// </summary>
[CLSCompliant(false)]
}
/// <summary>
+ /// Writes a <see cref="double" /> into a span of bytes, as little endian.
+ /// </summary>
+ /// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
+ /// <param name="value">The value to write into the span of bytes.</param>
+ /// <returns>
+ /// <see langword="true" /> if the span is large enough to contain a <see cref="double" />; otherwise, <see langword="false" />.
+ /// </returns>
+ /// <remarks>Writes exactly 8 bytes to the beginning of the span.</remarks>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool TryWriteDoubleLittleEndian(Span<byte> destination, double value)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
+ return MemoryMarshal.TryWrite(destination, ref tmp);
+ }
+
+ return MemoryMarshal.TryWrite(destination, ref value);
+ }
+
+ /// <summary>
/// Writes an Int16 into a span of bytes as little endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteInt16LittleEndian(Span<byte> destination, short value)
{
/// <summary>
/// Writes an Int32 into a span of bytes as little endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteInt32LittleEndian(Span<byte> destination, int value)
{
/// <summary>
/// Writes an Int64 into a span of bytes as little endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteInt64LittleEndian(Span<byte> destination, long value)
{
}
/// <summary>
+ /// Writes a <see cref="float" /> into a span of bytes, as little endian.
+ /// </summary>
+ /// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
+ /// <param name="value">The value to write into the span of bytes.</param>
+ /// <returns>
+ /// <see langword="true" /> if the span is large enough to contain a <see cref="float" />; otherwise, <see langword="false" />.
+ /// </returns>
+ /// <remarks>Writes exactly 4 bytes to the beginning of the span.</remarks>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool TryWriteSingleLittleEndian(Span<byte> destination, float value)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ int tmp = ReverseEndianness(BitConverter.SingleToInt32Bits(value));
+ return MemoryMarshal.TryWrite(destination, ref tmp);
+ }
+
+ return MemoryMarshal.TryWrite(destination, ref value);
+ }
+
+ /// <summary>
/// Write a UInt16 into a span of bytes as little endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteUInt16LittleEndian(Span<byte> destination, ushort value)
/// <summary>
/// Write a UInt32 into a span of bytes as little endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteUInt32LittleEndian(Span<byte> destination, uint value)
/// <summary>
/// Write a UInt64 into a span of bytes as little endian.
- /// <returns>If the span is too small to contain the value, return false.</returns>
/// </summary>
+ /// <returns>If the span is too small to contain the value, return false.</returns>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryWriteUInt64LittleEndian(Span<byte> destination, ulong value)