1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#include "Prerequisites/BsPrerequisitesUtil.h"
4#include "Utility/BsUUID.h"
5#include "Utility/BsPlatformUtility.h"
6
7namespace
8{
9 constexpr const char HEX_TO_LITERAL[16] =
10 { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11
12 constexpr const bs::UINT8 LITERAL_TO_HEX[256] =
13 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
14 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
15 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
16 // 0 through 9 translate to 0 though 9
17 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
18 // A through F translate to 10 though 15
19 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
20 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
21 // a through f translate to 10 though 15
22 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
23 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
24 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
25 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
26 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
27 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
28 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
29 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
30 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
31 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
32 };
33}
34
35namespace bs
36{
37 UUID UUID::EMPTY;
38
39 UUID::UUID(const String& uuid)
40 {
41 memset(mData, 0, sizeof(mData));
42
43 if (uuid.size() < 36)
44 return;
45
46 UINT32 idx = 0;
47
48 // First group: 8 digits
49 for(INT32 i = 7; i >= 0; --i)
50 {
51 char charVal = uuid[idx++];
52 UINT8 hexVal = LITERAL_TO_HEX[(int)charVal];
53
54 mData[0] |= hexVal << (i * 4);
55 }
56
57 idx++;
58
59 // Second group: 4 digits
60 for(INT32 i = 7; i >= 4; --i)
61 {
62 char charVal = uuid[idx++];
63 UINT8 hexVal = LITERAL_TO_HEX[(int)charVal];
64
65 mData[1] |= hexVal << (i * 4);
66 }
67
68 idx++;
69
70 // Third group: 4 digits
71 for(INT32 i = 3; i >= 0; --i)
72 {
73 char charVal = uuid[idx++];
74 UINT8 hexVal = LITERAL_TO_HEX[(int)charVal];
75
76 mData[1] |= hexVal << (i * 4);
77 }
78
79 idx++;
80
81 // Fourth group: 4 digits
82 for(INT32 i = 7; i >= 4; --i)
83 {
84 char charVal = uuid[idx++];
85 UINT8 hexVal = LITERAL_TO_HEX[(int)charVal];
86
87 mData[2] |= hexVal << (i * 4);
88 }
89
90 idx++;
91
92 // Fifth group: 12 digits
93 for(INT32 i = 3; i >= 0; --i)
94 {
95 char charVal = uuid[idx++];
96 UINT8 hexVal = LITERAL_TO_HEX[(int)charVal];
97
98 mData[2] |= hexVal << (i * 4);
99 }
100
101 for(INT32 i = 7; i >= 0; --i)
102 {
103 char charVal = uuid[idx++];
104 UINT8 hexVal = LITERAL_TO_HEX[(int)charVal];
105
106 mData[3] |= hexVal << (i * 4);
107 }
108 }
109
110 String UUID::toString() const
111 {
112 UINT8 output[36];
113 UINT32 idx = 0;
114
115 // First group: 8 digits
116 for(INT32 i = 7; i >= 0; --i)
117 {
118 UINT32 hexVal = (mData[0] >> (i * 4)) & 0xF;
119 output[idx++] = HEX_TO_LITERAL[hexVal];
120 }
121
122 output[idx++] = '-';
123
124 // Second group: 4 digits
125 for(INT32 i = 7; i >= 4; --i)
126 {
127 UINT32 hexVal = (mData[1] >> (i * 4)) & 0xF;
128 output[idx++] = HEX_TO_LITERAL[hexVal];
129 }
130
131 output[idx++] = '-';
132
133 // Third group: 4 digits
134 for(INT32 i = 3; i >= 0; --i)
135 {
136 UINT32 hexVal = (mData[1] >> (i * 4)) & 0xF;
137 output[idx++] = HEX_TO_LITERAL[hexVal];
138 }
139
140 output[idx++] = '-';
141
142 // Fourth group: 4 digits
143 for(INT32 i = 7; i >= 4; --i)
144 {
145 UINT32 hexVal = (mData[2] >> (i * 4)) & 0xF;
146 output[idx++] = HEX_TO_LITERAL[hexVal];
147 }
148
149 output[idx++] = '-';
150
151 // Fifth group: 12 digits
152 for(INT32 i = 3; i >= 0; --i)
153 {
154 UINT32 hexVal = (mData[2] >> (i * 4)) & 0xF;
155 output[idx++] = HEX_TO_LITERAL[hexVal];
156 }
157
158 for(INT32 i = 7; i >= 0; --i)
159 {
160 UINT32 hexVal = (mData[3] >> (i * 4)) & 0xF;
161 output[idx++] = HEX_TO_LITERAL[hexVal];
162 }
163
164 return String((const char*)output, 36);
165 }
166
167 UUID UUIDGenerator::generateRandom()
168 {
169 return PlatformUtility::generateUUID();
170 }
171}
172