DotNetReplacements.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. namespace Pathfinding.Util {
  2. /// <summary>
  3. /// Simple implementation of a GUID.
  4. /// Version: Since 3.6.4 this struct works properly on platforms with different endianness such as Wii U.
  5. /// </summary>
  6. public struct Guid {
  7. const string hex = "0123456789ABCDEF";
  8. public static readonly Guid zero = new Guid(new byte[16]);
  9. public static readonly string zeroString = new Guid(new byte[16]).ToString();
  10. readonly ulong _a, _b;
  11. public Guid (byte[] bytes) {
  12. // Pack 128 bits into 2 longs
  13. ulong a = ((ulong)bytes[0] << 8*0) |
  14. ((ulong)bytes[1] << 8*1) |
  15. ((ulong)bytes[2] << 8*2) |
  16. ((ulong)bytes[3] << 8*3) |
  17. ((ulong)bytes[4] << 8*4) |
  18. ((ulong)bytes[5] << 8*5) |
  19. ((ulong)bytes[6] << 8*6) |
  20. ((ulong)bytes[7] << 8*7);
  21. ulong b = ((ulong)bytes[8] << 8*0) |
  22. ((ulong)bytes[9] << 8*1) |
  23. ((ulong)bytes[10] << 8*2) |
  24. ((ulong)bytes[11] << 8*3) |
  25. ((ulong)bytes[12] << 8*4) |
  26. ((ulong)bytes[13] << 8*5) |
  27. ((ulong)bytes[14] << 8*6) |
  28. ((ulong)bytes[15] << 8*7);
  29. // Need to swap endianness on e.g Wii U
  30. _a = System.BitConverter.IsLittleEndian ? a : SwapEndianness(a);
  31. _b = System.BitConverter.IsLittleEndian ? b : SwapEndianness(b);
  32. }
  33. public Guid (string str) {
  34. _a = 0;
  35. _b = 0;
  36. if (str.Length < 32)
  37. throw new System.FormatException("Invalid Guid format");
  38. int counter = 0;
  39. int i = 0;
  40. int offset = 15*4;
  41. for (; counter < 16; i++) {
  42. if (i >= str.Length)
  43. throw new System.FormatException("Invalid Guid format. String too short");
  44. char c = str[i];
  45. if (c == '-') continue;
  46. //Neat trick, perhaps a bit slow, but one will probably not use Guid parsing that much
  47. int value = hex.IndexOf(char.ToUpperInvariant(c));
  48. if (value == -1)
  49. throw new System.FormatException("Invalid Guid format : "+c+" is not a hexadecimal character");
  50. _a |= (ulong)value << offset;
  51. //SetByte (counter,(byte)value);
  52. offset -= 4;
  53. counter++;
  54. }
  55. offset = 15*4;
  56. for (; counter < 32; i++) {
  57. if (i >= str.Length)
  58. throw new System.FormatException("Invalid Guid format. String too short");
  59. char c = str[i];
  60. if (c == '-') continue;
  61. //Neat trick, perhaps a bit slow, but one will probably not use Guid parsing that much
  62. int value = hex.IndexOf(char.ToUpperInvariant(c));
  63. if (value == -1)
  64. throw new System.FormatException("Invalid Guid format : "+c+" is not a hexadecimal character");
  65. _b |= (ulong)value << offset;
  66. //SetByte (counter,(byte)value);
  67. offset -= 4;
  68. counter++;
  69. }
  70. }
  71. public static Guid Parse (string input) {
  72. return new Guid(input);
  73. }
  74. /// <summary>Swaps between little and big endian</summary>
  75. static ulong SwapEndianness (ulong value) {
  76. var b1 = (value >> 0) & 0xff;
  77. var b2 = (value >> 8) & 0xff;
  78. var b3 = (value >> 16) & 0xff;
  79. var b4 = (value >> 24) & 0xff;
  80. var b5 = (value >> 32) & 0xff;
  81. var b6 = (value >> 40) & 0xff;
  82. var b7 = (value >> 48) & 0xff;
  83. var b8 = (value >> 56) & 0xff;
  84. return b1 << 56 | b2 << 48 | b3 << 40 | b4 << 32 | b5 << 24 | b6 << 16 | b7 << 8 | b8 << 0;
  85. }
  86. public byte[] ToByteArray () {
  87. var bytes = new byte[16];
  88. byte[] ba = System.BitConverter.GetBytes(!System.BitConverter.IsLittleEndian ? SwapEndianness(_a) : _a);
  89. byte[] bb = System.BitConverter.GetBytes(!System.BitConverter.IsLittleEndian ? SwapEndianness(_b) : _b);
  90. for (int i = 0; i < 8; i++) {
  91. bytes[i] = ba[i];
  92. bytes[i+8] = bb[i];
  93. }
  94. return bytes;
  95. }
  96. private static System.Random random = new System.Random();
  97. public static Guid NewGuid () {
  98. var bytes = new byte[16];
  99. random.NextBytes(bytes);
  100. return new Guid(bytes);
  101. }
  102. public static bool operator == (Guid lhs, Guid rhs) {
  103. return lhs._a == rhs._a && lhs._b == rhs._b;
  104. }
  105. public static bool operator != (Guid lhs, Guid rhs) {
  106. return lhs._a != rhs._a || lhs._b != rhs._b;
  107. }
  108. public override bool Equals (System.Object _rhs) {
  109. if (!(_rhs is Guid)) return false;
  110. var rhs = (Guid)_rhs;
  111. return _a == rhs._a && _b == rhs._b;
  112. }
  113. public override int GetHashCode () {
  114. ulong ab = _a ^ _b;
  115. return (int)(ab >> 32) ^ (int)ab;
  116. }
  117. private static System.Text.StringBuilder text;
  118. public override string ToString () {
  119. if (text == null) {
  120. text = new System.Text.StringBuilder();
  121. }
  122. lock (text) {
  123. text.Length = 0;
  124. text.Append(_a.ToString("x16")).Append('-').Append(_b.ToString("x16"));
  125. return text.ToString();
  126. }
  127. }
  128. }
  129. }