You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
372 lines
15 KiB
372 lines
15 KiB
using System; |
|
using System.Runtime.InteropServices; |
|
|
|
namespace MessagePack.Internal |
|
{ |
|
[StructLayout(LayoutKind.Explicit, Pack = 1)] |
|
internal struct GuidBits |
|
{ |
|
[FieldOffset(0)] |
|
public readonly Guid Value; |
|
|
|
[FieldOffset(0)] |
|
public readonly byte Byte0; |
|
[FieldOffset(1)] |
|
public readonly byte Byte1; |
|
[FieldOffset(2)] |
|
public readonly byte Byte2; |
|
[FieldOffset(3)] |
|
public readonly byte Byte3; |
|
[FieldOffset(4)] |
|
public readonly byte Byte4; |
|
[FieldOffset(5)] |
|
public readonly byte Byte5; |
|
[FieldOffset(6)] |
|
public readonly byte Byte6; |
|
[FieldOffset(7)] |
|
public readonly byte Byte7; |
|
[FieldOffset(8)] |
|
public readonly byte Byte8; |
|
[FieldOffset(9)] |
|
public readonly byte Byte9; |
|
[FieldOffset(10)] |
|
public readonly byte Byte10; |
|
[FieldOffset(11)] |
|
public readonly byte Byte11; |
|
[FieldOffset(12)] |
|
public readonly byte Byte12; |
|
[FieldOffset(13)] |
|
public readonly byte Byte13; |
|
[FieldOffset(14)] |
|
public readonly byte Byte14; |
|
[FieldOffset(15)] |
|
public readonly byte Byte15; |
|
|
|
// string.Join(", ", Enumerable.Range(0, 256).Select(x => (int)BitConverter.ToString(new byte[] { (byte)x }).ToLower()[0])) |
|
static byte[] byteToHexStringHigh = new byte[256] { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102 }; |
|
|
|
// string.Join(", ", Enumerable.Range(0, 256).Select(x => (int)BitConverter.ToString(new byte[] { (byte)x }).ToLower()[1])) |
|
static byte[] byteToHexStringLow = new byte[256] { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102 }; |
|
|
|
public GuidBits(ref Guid value) |
|
{ |
|
this = default(GuidBits); |
|
this.Value = value; |
|
} |
|
|
|
// 4-pattern, lower/upper and '-' or no |
|
public GuidBits(ArraySegment<byte> utf8string) |
|
{ |
|
this = default(GuidBits); |
|
|
|
var array = utf8string.Array; |
|
var offset = utf8string.Offset; |
|
|
|
// 32 |
|
if (utf8string.Count == 32) |
|
{ |
|
if (BitConverter.IsLittleEndian) |
|
{ |
|
this.Byte0 = Parse(array, offset + 6); |
|
this.Byte1 = Parse(array, offset + 4); |
|
this.Byte2 = Parse(array, offset + 2); |
|
this.Byte3 = Parse(array, offset + 0); |
|
|
|
this.Byte4 = Parse(array, offset + 10); |
|
this.Byte5 = Parse(array, offset + 8); |
|
|
|
this.Byte6 = Parse(array, offset + 14); |
|
this.Byte7 = Parse(array, offset + 12); |
|
} |
|
else |
|
{ |
|
this.Byte0 = Parse(array, offset + 0); |
|
this.Byte1 = Parse(array, offset + 2); |
|
this.Byte2 = Parse(array, offset + 4); |
|
this.Byte3 = Parse(array, offset + 6); |
|
|
|
this.Byte4 = Parse(array, offset + 8); |
|
this.Byte5 = Parse(array, offset + 10); |
|
|
|
this.Byte6 = Parse(array, offset + 12); |
|
this.Byte7 = Parse(array, offset + 14); |
|
} |
|
this.Byte8 = Parse(array, offset + 16); |
|
this.Byte9 = Parse(array, offset + 18); |
|
|
|
this.Byte10 = Parse(array, offset + 20); |
|
this.Byte11 = Parse(array, offset + 22); |
|
this.Byte12 = Parse(array, offset + 24); |
|
this.Byte13 = Parse(array, offset + 26); |
|
this.Byte14 = Parse(array, offset + 28); |
|
this.Byte15 = Parse(array, offset + 30); |
|
return; |
|
} |
|
else if (utf8string.Count == 36) |
|
{ |
|
// '-' => 45 |
|
if (BitConverter.IsLittleEndian) |
|
{ |
|
this.Byte0 = Parse(array, offset + 6); |
|
this.Byte1 = Parse(array, offset + 4); |
|
this.Byte2 = Parse(array, offset + 2); |
|
this.Byte3 = Parse(array, offset + 0); |
|
|
|
if (array[offset + 8] != '-') goto ERROR; |
|
|
|
this.Byte4 = Parse(array, offset + 11); |
|
this.Byte5 = Parse(array, offset + 9); |
|
|
|
if (array[offset + 13] != '-') goto ERROR; |
|
|
|
this.Byte6 = Parse(array, offset + 16); |
|
this.Byte7 = Parse(array, offset + 14); |
|
} |
|
else |
|
{ |
|
this.Byte0 = Parse(array, offset + 0); |
|
this.Byte1 = Parse(array, offset + 2); |
|
this.Byte2 = Parse(array, offset + 4); |
|
this.Byte3 = Parse(array, offset + 6); |
|
|
|
if (array[offset + 8] != '-') goto ERROR; |
|
|
|
this.Byte4 = Parse(array, offset + 9); |
|
this.Byte5 = Parse(array, offset + 11); |
|
|
|
if (array[offset + 13] != '-') goto ERROR; |
|
|
|
this.Byte6 = Parse(array, offset + 14); |
|
this.Byte7 = Parse(array, offset + 16); |
|
} |
|
|
|
if (array[offset + 18] != '-') goto ERROR; |
|
|
|
this.Byte8 = Parse(array, offset + 19); |
|
this.Byte9 = Parse(array, offset + 21); |
|
|
|
if (array[offset + 23] != '-') goto ERROR; |
|
|
|
this.Byte10 = Parse(array, offset + 24); |
|
this.Byte11 = Parse(array, offset + 26); |
|
this.Byte12 = Parse(array, offset + 28); |
|
this.Byte13 = Parse(array, offset + 30); |
|
this.Byte14 = Parse(array, offset + 32); |
|
this.Byte15 = Parse(array, offset + 34); |
|
return; |
|
} |
|
|
|
ERROR: |
|
throw new ArgumentException("Invalid Guid Pattern."); |
|
} |
|
|
|
#if NETSTANDARD |
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] |
|
#endif |
|
static byte Parse(byte[] bytes, int highOffset) |
|
{ |
|
return unchecked((byte)(SwitchParse(bytes[highOffset]) * 16 + SwitchParse(bytes[highOffset + 1]))); |
|
} |
|
|
|
#if NETSTANDARD |
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] |
|
#endif |
|
static byte SwitchParse(byte b) |
|
{ |
|
// '0'(48) ~ '9'(57) => -48 |
|
// 'A'(65) ~ 'F'(70) => -55 |
|
// 'a'(97) ~ 'f'(102) => -87 |
|
switch (b) |
|
{ |
|
case 48: |
|
case 49: |
|
case 50: |
|
case 51: |
|
case 52: |
|
case 53: |
|
case 54: |
|
case 55: |
|
case 56: |
|
case 57: |
|
return unchecked((byte)((b - 48))); |
|
case 65: |
|
case 66: |
|
case 67: |
|
case 68: |
|
case 69: |
|
case 70: |
|
return unchecked((byte)((b - 55))); |
|
case 97: |
|
case 98: |
|
case 99: |
|
case 100: |
|
case 101: |
|
case 102: |
|
return unchecked((byte)((b - 87))); |
|
case 0: |
|
case 1: |
|
case 2: |
|
case 3: |
|
case 4: |
|
case 5: |
|
case 6: |
|
case 7: |
|
case 8: |
|
case 9: |
|
case 10: |
|
case 11: |
|
case 12: |
|
case 13: |
|
case 14: |
|
case 15: |
|
case 16: |
|
case 17: |
|
case 18: |
|
case 19: |
|
case 20: |
|
case 21: |
|
case 22: |
|
case 23: |
|
case 24: |
|
case 25: |
|
case 26: |
|
case 27: |
|
case 28: |
|
case 29: |
|
case 30: |
|
case 31: |
|
case 32: |
|
case 33: |
|
case 34: |
|
case 35: |
|
case 36: |
|
case 37: |
|
case 38: |
|
case 39: |
|
case 40: |
|
case 41: |
|
case 42: |
|
case 43: |
|
case 44: |
|
case 45: |
|
case 46: |
|
case 47: |
|
case 58: |
|
case 59: |
|
case 60: |
|
case 61: |
|
case 62: |
|
case 63: |
|
case 64: |
|
case 71: |
|
case 72: |
|
case 73: |
|
case 74: |
|
case 75: |
|
case 76: |
|
case 77: |
|
case 78: |
|
case 79: |
|
case 80: |
|
case 81: |
|
case 82: |
|
case 83: |
|
case 84: |
|
case 85: |
|
case 86: |
|
case 87: |
|
case 88: |
|
case 89: |
|
case 90: |
|
case 91: |
|
case 92: |
|
case 93: |
|
case 94: |
|
case 95: |
|
case 96: |
|
default: |
|
throw new ArgumentException("Invalid Guid Pattern."); |
|
} |
|
} |
|
|
|
// 4(x2) - 2(x2) - 2(x2) - 2(x2) - 6(x2) |
|
public void Write(byte[] buffer, int offset) |
|
{ |
|
if (BitConverter.IsLittleEndian) |
|
{ |
|
// int(_a) |
|
buffer[offset + 6] = byteToHexStringHigh[Byte0]; |
|
buffer[offset + 7] = byteToHexStringLow[Byte0]; |
|
buffer[offset + 4] = byteToHexStringHigh[Byte1]; |
|
buffer[offset + 5] = byteToHexStringLow[Byte1]; |
|
buffer[offset + 2] = byteToHexStringHigh[Byte2]; |
|
buffer[offset + 3] = byteToHexStringLow[Byte2]; |
|
buffer[offset + 0] = byteToHexStringHigh[Byte3]; |
|
buffer[offset + 1] = byteToHexStringLow[Byte3]; |
|
|
|
buffer[offset + 8] = (byte)'-'; |
|
|
|
// short(_b) |
|
buffer[offset + 11] = byteToHexStringHigh[Byte4]; |
|
buffer[offset + 12] = byteToHexStringLow[Byte4]; |
|
buffer[offset + 9] = byteToHexStringHigh[Byte5]; |
|
buffer[offset + 10] = byteToHexStringLow[Byte5]; |
|
|
|
buffer[offset + 13] = (byte)'-'; |
|
|
|
// short(_c) |
|
buffer[offset + 16] = byteToHexStringHigh[Byte6]; |
|
buffer[offset + 17] = byteToHexStringLow[Byte6]; |
|
buffer[offset + 14] = byteToHexStringHigh[Byte7]; |
|
buffer[offset + 15] = byteToHexStringLow[Byte7]; |
|
} |
|
else |
|
{ |
|
buffer[offset + 0] = byteToHexStringHigh[Byte0]; |
|
buffer[offset + 1] = byteToHexStringLow[Byte0]; |
|
buffer[offset + 2] = byteToHexStringHigh[Byte1]; |
|
buffer[offset + 3] = byteToHexStringLow[Byte1]; |
|
buffer[offset + 4] = byteToHexStringHigh[Byte2]; |
|
buffer[offset + 5] = byteToHexStringLow[Byte2]; |
|
buffer[offset + 6] = byteToHexStringHigh[Byte3]; |
|
buffer[offset + 7] = byteToHexStringLow[Byte3]; |
|
|
|
buffer[offset + 8] = (byte)'-'; |
|
|
|
buffer[offset + 9] = byteToHexStringHigh[Byte4]; |
|
buffer[offset + 10] = byteToHexStringLow[Byte4]; |
|
buffer[offset + 11] = byteToHexStringHigh[Byte5]; |
|
buffer[offset + 12] = byteToHexStringLow[Byte5]; |
|
|
|
buffer[offset + 13] = (byte)'-'; |
|
|
|
buffer[offset + 14] = byteToHexStringHigh[Byte6]; |
|
buffer[offset + 15] = byteToHexStringLow[Byte6]; |
|
buffer[offset + 16] = byteToHexStringHigh[Byte7]; |
|
buffer[offset + 17] = byteToHexStringLow[Byte7]; |
|
} |
|
|
|
buffer[offset + 18] = (byte)'-'; |
|
|
|
buffer[offset + 19] = byteToHexStringHigh[Byte8]; |
|
buffer[offset + 20] = byteToHexStringLow[Byte8]; |
|
buffer[offset + 21] = byteToHexStringHigh[Byte9]; |
|
buffer[offset + 22] = byteToHexStringLow[Byte9]; |
|
|
|
buffer[offset + 23] = (byte)'-'; |
|
|
|
buffer[offset + 24] = byteToHexStringHigh[Byte10]; |
|
buffer[offset + 25] = byteToHexStringLow[Byte10]; |
|
buffer[offset + 26] = byteToHexStringHigh[Byte11]; |
|
buffer[offset + 27] = byteToHexStringLow[Byte11]; |
|
buffer[offset + 28] = byteToHexStringHigh[Byte12]; |
|
buffer[offset + 29] = byteToHexStringLow[Byte12]; |
|
buffer[offset + 30] = byteToHexStringHigh[Byte13]; |
|
buffer[offset + 31] = byteToHexStringLow[Byte13]; |
|
buffer[offset + 32] = byteToHexStringHigh[Byte14]; |
|
buffer[offset + 33] = byteToHexStringLow[Byte14]; |
|
buffer[offset + 34] = byteToHexStringHigh[Byte15]; |
|
buffer[offset + 35] = byteToHexStringLow[Byte15]; |
|
} |
|
} |
|
} |