1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 namespace System
  7 {
  8     public class Uuid
  9     {
 10         public const long size = 16;
 11 
 12         public typedef byte[size].Iterator Iterator;
 13         public typedef byte[size].ConstIterator ConstIterator;
 14 
 15         public inline nothrow Iterator Begin()
 16         {
 17             return data.Begin();
 18         }
 19         public inline nothrow ConstIterator Begin() const
 20         {
 21             return data.CBegin();
 22         }
 23         public inline nothrow ConstIterator CBegin() const
 24         {
 25             return data.CBegin();
 26         }
 27         public inline nothrow Iterator End()
 28         {
 29             return data.End();
 30         }
 31         public inline nothrow ConstIterator End() const
 32         {
 33             return data.CEnd();
 34         }
 35         public inline nothrow ConstIterator CEnd() const
 36         {
 37             return data.CEnd();
 38         }
 39 
 40         public nothrow Uuid() : data()
 41         {
 42         }
 43         public nothrow Uuid(ulong leftHalfulong rightHalf) : data()
 44         {
 45             data[0] = cast<byte>(leftHalf >> 56u);
 46             data[1] = cast<byte>(leftHalf >> 48u);
 47             data[2] = cast<byte>(leftHalf >> 40u);
 48             data[3] = cast<byte>(leftHalf >> 32u);
 49             data[4] = cast<byte>(leftHalf >> 24u);
 50             data[5] = cast<byte>(leftHalf >> 16u);
 51             data[6] = cast<byte>(leftHalf >> 8u);
 52             data[7] = cast<byte>(leftHalf);
 53             data[8] = cast<byte>(rightHalf >> 56u);
 54             data[9] = cast<byte>(rightHalf >> 48u);
 55             data[10] = cast<byte>(rightHalf >> 40u);
 56             data[11] = cast<byte>(rightHalf >> 32u);
 57             data[12] = cast<byte>(rightHalf >> 24u);
 58             data[13] = cast<byte>(rightHalf >> 16u);
 59             data[14] = cast<byte>(rightHalf >> 8u);
 60             data[15] = cast<byte>(rightHalf);
 61         }
 62         public nothrow ulong LeftHalf() const
 63         {
 64             ulong leftHalf;
 65             leftHalf = data[0];
 66             leftHalf = (leftHalf << 8u) | data[1];
 67             leftHalf = (leftHalf << 8u) | data[2];
 68             leftHalf = (leftHalf << 8u) | data[3];
 69             leftHalf = (leftHalf << 8u) | data[4];
 70             leftHalf = (leftHalf << 8u) | data[5];
 71             leftHalf = (leftHalf << 8u) | data[6];
 72             leftHalf = (leftHalf << 8u) | data[7];
 73             return leftHalf;
 74         }
 75         public nothrow ulong RightHalf() const
 76         {
 77             ulong rightHalf;
 78             rightHalf = data[8];
 79             rightHalf = (rightHalf << 8u) | data[9];
 80             rightHalf = (rightHalf << 8u) | data[10];
 81             rightHalf = (rightHalf << 8u) | data[11];
 82             rightHalf = (rightHalf << 8u) | data[12];
 83             rightHalf = (rightHalf << 8u) | data[13];
 84             rightHalf = (rightHalf << 8u) | data[14];
 85             rightHalf = (rightHalf << 8u) | data[15];
 86             return rightHalf;
 87         }
 88         public static nothrow Uuid Random()
 89         {
 90             return Uuid(Random64()Random64());
 91         }
 92         public byte[size] data;
 93     }
 94 
 95     public inline nothrow bool operator==(const Uuid& leftconst Uuid& right)
 96     {
 97         for (long i = 0; i < Uuid.size; ++i;)
 98         {
 99             if (left.data[i] != right.data[i]) return false;
100         }
101         return true;
102     }
103 
104     public nothrow string ToString(const Uuid& uuid)
105     {
106         string s;
107         int index = 0;
108         for (byte x : uuid)
109         {
110             s.Append(ToLower(ToHexString(x)));
111             if (index == 3 || index == 5 || index == 7 || index == 9)
112             {
113                 s.Append('-');
114             }
115             ++index;
116         }
117         return s;
118     }
119 
120     public Uuid ParseUuid(const string& uuidHexString)
121     {
122         if (uuidHexString.Length() != 2 * Uuid.size + 4)
123         {
124             ThrowConversionException("wrong number of hex bytes in uuid string '" + uuidHexString + "'." + ToString(Uuid.size) + " hex bytes + 4 hyphens expected.");
125         }
126         Uuid uuid;
127         int index = 0;
128         for (long i = 0; i < Uuid.size; ++i;)
129         {
130             string hexByteStr = uuidHexString.Substring(index2);
131             byte hexByte = ParseHexByte(hexByteStr);
132             uuid.data[i] = hexByte;
133             ++index;
134             ++index;
135             if (i == 3 || i == 5 || i == 7 || i == 9)
136             {
137                 ++index;
138             }
139         }
140         return uuid;
141     }
142 }