{
if (b.Length != 16)
{
- ThrowArgumentException();
+ ThrowGuidArrayCtorArgumentException();
}
- if (BitConverter.IsLittleEndian)
+ this = MemoryMarshal.Read<Guid>(b);
+
+ if (!BitConverter.IsLittleEndian)
{
- this = MemoryMarshal.Read<Guid>(b);
- return;
+ _a = BinaryPrimitives.ReverseEndianness(_a);
+ _b = BinaryPrimitives.ReverseEndianness(_b);
+ _c = BinaryPrimitives.ReverseEndianness(_c);
}
+ }
- // slower path for BigEndian:
- _k = b[15]; // hoist bounds checks
- _a = BinaryPrimitives.ReadInt32LittleEndian(b);
- _b = BinaryPrimitives.ReadInt16LittleEndian(b.Slice(4));
- _c = BinaryPrimitives.ReadInt16LittleEndian(b.Slice(6));
- _d = b[8];
- _e = b[9];
- _f = b[10];
- _g = b[11];
- _h = b[12];
- _i = b[13];
- _j = b[14];
+ public Guid(ReadOnlySpan<byte> b, bool bigEndian)
+ {
+ if (b.Length != 16)
+ {
+ ThrowGuidArrayCtorArgumentException();
+ }
- [StackTraceHidden]
- static void ThrowArgumentException()
+ this = MemoryMarshal.Read<Guid>(b);
+
+ if (BitConverter.IsLittleEndian == bigEndian)
{
- throw new ArgumentException(SR.Format(SR.Arg_GuidArrayCtor, "16"), nameof(b));
+ _a = BinaryPrimitives.ReverseEndianness(_a);
+ _b = BinaryPrimitives.ReverseEndianness(_b);
+ _c = BinaryPrimitives.ReverseEndianness(_c);
}
}
+ [DoesNotReturn]
+ [StackTraceHidden]
+ private static void ThrowGuidArrayCtorArgumentException()
+ {
+ throw new ArgumentException(SR.Format(SR.Arg_GuidArrayCtor, "16"), "b");
+ }
+
[CLSCompliant(false)]
public Guid(uint a, ushort b, ushort c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
{
str[i] == '0' &&
(str[i + 1] | 0x20) == 'x';
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static unsafe ReadOnlySpan<byte> AsBytes(in Guid source) =>
+ new ReadOnlySpan<byte>(Unsafe.AsPointer(ref Unsafe.AsRef(in source)), sizeof(Guid));
+
// Returns an unsigned byte array containing the GUID.
public byte[] ToByteArray()
{
}
else
{
- TryWriteBytes(g);
+ // slower path for BigEndian
+ Guid guid = new Guid(AsBytes(this), false);
+ MemoryMarshal.TryWrite(g, ref Unsafe.AsRef(in guid));
+ }
+ return g;
+ }
+
+
+ // Returns an unsigned byte array containing the GUID.
+ public byte[] ToByteArray(bool bigEndian)
+ {
+ var g = new byte[16];
+ if (BitConverter.IsLittleEndian != bigEndian)
+ {
+ MemoryMarshal.TryWrite(g, ref Unsafe.AsRef(in this));
+ }
+ else
+ {
+ // slower path for Reverse
+ Guid guid = new Guid(AsBytes(this), bigEndian);
+ MemoryMarshal.TryWrite(g, ref Unsafe.AsRef(in guid));
}
return g;
}
// Returns whether bytes are successfully written to given span.
public bool TryWriteBytes(Span<byte> destination)
{
+ if (destination.Length < 16)
+ return false;
+
if (BitConverter.IsLittleEndian)
{
- return MemoryMarshal.TryWrite(destination, ref Unsafe.AsRef(in this));
+ MemoryMarshal.TryWrite(destination, ref Unsafe.AsRef(in this));
}
+ else
+ {
+ // slower path for BigEndian
+ Guid guid = new Guid(AsBytes(this), false);
+ MemoryMarshal.TryWrite(destination, ref Unsafe.AsRef(in guid));
+ }
+ return true;
+ }
- // slower path for BigEndian
+ // Returns whether bytes are successfully written to given span.
+ public bool TryWriteBytes(Span<byte> destination, bool bigEndian, out int bytesWritten)
+ {
if (destination.Length < 16)
+ {
+ bytesWritten = 0;
return false;
+ }
- destination[15] = _k; // hoist bounds checks
- BinaryPrimitives.WriteInt32LittleEndian(destination, _a);
- BinaryPrimitives.WriteInt16LittleEndian(destination.Slice(4), _b);
- BinaryPrimitives.WriteInt16LittleEndian(destination.Slice(6), _c);
- destination[8] = _d;
- destination[9] = _e;
- destination[10] = _f;
- destination[11] = _g;
- destination[12] = _h;
- destination[13] = _i;
- destination[14] = _j;
+ if (BitConverter.IsLittleEndian != bigEndian)
+ {
+ MemoryMarshal.TryWrite(destination, ref Unsafe.AsRef(in this));
+ }
+ else
+ {
+ // slower path for Reverse
+ Guid guid = new Guid(AsBytes(this), bigEndian);
+ MemoryMarshal.TryWrite(destination, ref Unsafe.AsRef(in guid));
+ }
+ bytesWritten = 16;
return true;
}
public Guid(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k) { throw null; }
public Guid(int a, short b, short c, byte[] d) { throw null; }
public Guid(System.ReadOnlySpan<byte> b) { throw null; }
+ public Guid(System.ReadOnlySpan<byte> b, bool bigEndian) { throw null; }
public Guid(string g) { throw null; }
[System.CLSCompliantAttribute(false)]
public Guid(uint a, ushort b, ushort c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k) { throw null; }
bool System.ISpanFormattable.TryFormat(System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("GuidFormat")] System.ReadOnlySpan<char> format, System.IFormatProvider? provider) { throw null; }
bool System.IUtf8SpanFormattable.TryFormat(System.Span<byte> utf8Destination, out int bytesWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("GuidFormat")] System.ReadOnlySpan<char> format, System.IFormatProvider? provider) { throw null; }
public byte[] ToByteArray() { throw null; }
+ public byte[] ToByteArray(bool bigEndian) { throw null; }
public override string ToString() { throw null; }
public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("GuidFormat")] string? format) { throw null; }
public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("GuidFormat")] string? format, System.IFormatProvider? provider) { throw null; }
public static bool TryParseExact(System.ReadOnlySpan<char> input, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("GuidFormat")] System.ReadOnlySpan<char> format, out System.Guid result) { throw null; }
public static bool TryParseExact([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true), System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("GuidFormat")] string? format, out System.Guid result) { throw null; }
public bool TryWriteBytes(System.Span<byte> destination) { throw null; }
+ public bool TryWriteBytes(Span<byte> destination, bool bigEndian, out int bytesWritten) { throw null; }
+
}
public readonly partial struct Half : System.IComparable, System.IComparable<System.Half>, System.IEquatable<System.Half>, System.IFormattable, System.IParsable<System.Half>, System.ISpanFormattable, System.ISpanParsable<System.Half>, System.Numerics.IAdditionOperators<System.Half, System.Half, System.Half>, System.Numerics.IAdditiveIdentity<System.Half, System.Half>, System.Numerics.IBinaryFloatingPointIeee754<System.Half>, System.Numerics.IBinaryNumber<System.Half>, System.Numerics.IBitwiseOperators<System.Half, System.Half, System.Half>, System.Numerics.IComparisonOperators<System.Half, System.Half, bool>, System.Numerics.IDecrementOperators<System.Half>, System.Numerics.IDivisionOperators<System.Half, System.Half, System.Half>, System.Numerics.IEqualityOperators<System.Half, System.Half, bool>, System.Numerics.IExponentialFunctions<System.Half>, System.Numerics.IFloatingPoint<System.Half>, System.Numerics.IFloatingPointConstants<System.Half>, System.Numerics.IFloatingPointIeee754<System.Half>, System.Numerics.IHyperbolicFunctions<System.Half>, System.Numerics.IIncrementOperators<System.Half>, System.Numerics.ILogarithmicFunctions<System.Half>, System.Numerics.IMinMaxValue<System.Half>, System.Numerics.IModulusOperators<System.Half, System.Half, System.Half>, System.Numerics.IMultiplicativeIdentity<System.Half, System.Half>, System.Numerics.IMultiplyOperators<System.Half, System.Half, System.Half>, System.Numerics.INumber<System.Half>, System.Numerics.INumberBase<System.Half>, System.Numerics.IPowerFunctions<System.Half>, System.Numerics.IRootFunctions<System.Half>, System.Numerics.ISignedNumber<System.Half>, System.Numerics.ISubtractionOperators<System.Half, System.Half, System.Half>, System.Numerics.ITrigonometricFunctions<System.Half>, System.Numerics.IUnaryNegationOperators<System.Half, System.Half>, System.Numerics.IUnaryPlusOperators<System.Half, System.Half>, System.IUtf8SpanFormattable
{
Assert.Equal(expected, new Guid(b));
}
+ public static IEnumerable<object[]> Ctor_ByteArray_BigEndian_TestData()
+ {
+ yield return new object[] { new byte[16], true, Guid.Empty };
+ yield return new object[] { new byte[16], false, Guid.Empty };
+ yield return new object[] { new byte[] { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, true, new Guid("11223344-5566-7788-9900-aabbccddeeff") };
+ yield return new object[] { new byte[] { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, false, new Guid("44332211-6655-8877-9900-aabbccddeeff") };
+ yield return new object[] { new byte[] { 0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, true, new Guid("44332211-6655-8877-9900-aabbccddeeff") };
+ yield return new object[] { new byte[] { 0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, false, new Guid("11223344-5566-7788-9900-aabbccddeeff") };
+ yield return new object[] { s_testGuid.ToByteArray(true), true, s_testGuid };
+ yield return new object[] { s_testGuid.ToByteArray(), false, s_testGuid };
+ }
+
+ [Theory]
+ [MemberData(nameof(Ctor_ByteArray_BigEndian_TestData))]
+ public static void Ctor_ByteArray_BigEndian(byte[] b, bool bigEndian, Guid expected)
+ {
+ Assert.Equal(expected, new Guid(b, bigEndian));
+ }
+
[Fact]
public static void Ctor_NullByteArray_ThrowsArgumentNullException()
{
public static void ToByteArray()
{
Assert.Equal(new byte[] { 0xd5, 0x10, 0xa1, 0xa8, 0x49, 0xfc, 0xc5, 0x43, 0xbf, 0x46, 0x80, 0x2d, 0xb8, 0xf8, 0x43, 0xff }, s_testGuid.ToByteArray());
+ Assert.Equal(new byte[] { 0xd5, 0x10, 0xa1, 0xa8, 0x49, 0xfc, 0xc5, 0x43, 0xbf, 0x46, 0x80, 0x2d, 0xb8, 0xf8, 0x43, 0xff }, s_testGuid.ToByteArray(false));
+ Assert.Equal(new byte[] { 0xa8, 0xa1, 0x10, 0xd5, 0xfc, 0x49, 0x43, 0xc5, 0xbf, 0x46, 0x80, 0x2d, 0xb8, 0xf8, 0x43, 0xff }, s_testGuid.ToByteArray(true));
}
public static IEnumerable<object[]> ToString_TestData()
}
[Theory]
+ [MemberData(nameof(Ctor_ByteArray_BigEndian_TestData))]
+ public static void TryWriteBytes_BigEndian_ValidLength_ReturnsTrue(byte[] b, bool bigEndian, Guid guid)
+ {
+ var bytes = new byte[16];
+ Assert.True(guid.TryWriteBytes(new Span<byte>(bytes), bigEndian, out int bytesWritten));
+ Assert.Equal(b, bytes);
+ Assert.Equal(16, bytesWritten);
+ }
+
+ [Theory]
[InlineData(0)]
[InlineData(15)]
public static void TryWriteBytes_LengthTooShort_ReturnsFalse(int length)
{
Assert.False(s_testGuid.TryWriteBytes(new Span<byte>(new byte[length])));
+ Assert.False(s_testGuid.TryWriteBytes(new Span<byte>(new byte[length]), true, out int bytesWritten));
+ Assert.Equal(0, bytesWritten);
+ Assert.False(s_testGuid.TryWriteBytes(new Span<byte>(new byte[length]), false, out bytesWritten));
+ Assert.Equal(0, bytesWritten);
}
[Theory]