DecomposedGuid guidAsBytes = default;
guidAsBytes.Guid = value;
- // When a GUID is blitted, the first three components are little-endian, and the last component is big-endian.
+ // When a GUID is blitted, the first three components are native-endian, and the last component is big-endian.
// The line below forces the JIT to hoist the bounds check for the following segment.
// The JIT will optimize away the read, but it cannot optimize away the bounds check
// We use 8 instead of 7 so that we also capture the dash if we're asked to insert one.
{ _ = destination[8]; }
- HexConverter.ToBytesBuffer(guidAsBytes.Byte03, destination, 0, HexConverter.Casing.Lower);
- HexConverter.ToBytesBuffer(guidAsBytes.Byte02, destination, 2, HexConverter.Casing.Lower);
- HexConverter.ToBytesBuffer(guidAsBytes.Byte01, destination, 4, HexConverter.Casing.Lower);
- HexConverter.ToBytesBuffer(guidAsBytes.Byte00, destination, 6, HexConverter.Casing.Lower);
+ if (BitConverter.IsLittleEndian)
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte03, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte02, destination, 2, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte01, destination, 4, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte00, destination, 6, HexConverter.Casing.Lower);
+ }
+ else
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte00, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte01, destination, 2, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte02, destination, 4, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte03, destination, 6, HexConverter.Casing.Lower);
+ }
if (flags < 0 /* use dash? */)
{
}
{ _ = destination[4]; }
- HexConverter.ToBytesBuffer(guidAsBytes.Byte05, destination, 0, HexConverter.Casing.Lower);
- HexConverter.ToBytesBuffer(guidAsBytes.Byte04, destination, 2, HexConverter.Casing.Lower);
+ if (BitConverter.IsLittleEndian)
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte05, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte04, destination, 2, HexConverter.Casing.Lower);
+ }
+ else
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte04, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte05, destination, 2, HexConverter.Casing.Lower);
+ }
if (flags < 0 /* use dash? */)
{
}
{ _ = destination[4]; }
- HexConverter.ToBytesBuffer(guidAsBytes.Byte07, destination, 0, HexConverter.Casing.Lower);
- HexConverter.ToBytesBuffer(guidAsBytes.Byte06, destination, 2, HexConverter.Casing.Lower);
+ if (BitConverter.IsLittleEndian)
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte07, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte06, destination, 2, HexConverter.Casing.Lower);
+ }
+ else
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte06, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte07, destination, 2, HexConverter.Casing.Lower);
+ }
if (flags < 0 /* use dash? */)
{
return FromHash(ImmutableByteArrayInterop.DangerousGetUnderlyingArray(hashCode)!);
}
- public static unsafe BlobContentId FromHash(byte[] hashCode)
+ public static BlobContentId FromHash(byte[] hashCode)
{
const int minHashSize = 20;
throw new ArgumentException(SR.Format(SR.HashTooShort, minHashSize), nameof(hashCode));
}
- Guid guid = default(Guid);
- byte* guidPtr = (byte*)&guid;
- for (var i = 0; i < BlobUtilities.SizeOfGuid; i++)
- {
- guidPtr[i] = hashCode[i];
- }
+ // extract guid components from input data
+ uint a = ((uint)hashCode[3] << 24 | (uint)hashCode[2] << 16 | (uint)hashCode[1] << 8 | hashCode[0]);
+ ushort b = (ushort)((ushort)hashCode[5] << 8 | (ushort)hashCode[4]);
+ ushort c = (ushort)((ushort)hashCode[7] << 8 | (ushort)hashCode[6]);
+ byte d = hashCode[8];
+ byte e = hashCode[9];
+ byte f = hashCode[10];
+ byte g = hashCode[11];
+ byte h = hashCode[12];
+ byte i = hashCode[13];
+ byte j = hashCode[14];
+ byte k = hashCode[15];
// modify the guid data so it decodes to the form of a "random" guid ala rfc4122
- guidPtr[7] = (byte)((guidPtr[7] & 0x0f) | (4 << 4));
- guidPtr[8] = (byte)((guidPtr[8] & 0x3f) | (2 << 6));
+ c = (ushort)((c & 0x0fff) | (4 << 12));
+ d = (byte)((d & 0x3f) | (2 << 6));
+ Guid guid = new Guid((int)a, (short)b, (short)c, d, e, f, g, h, i, j, k);
// compute a random-looking stamp from the remaining bits, but with the upper bit set
uint stamp = 0x80000000u | ((uint)hashCode[19] << 24 | (uint)hashCode[18] << 16 | (uint)hashCode[17] << 8 | hashCode[16]);