]> gitweb.ps.run Git - toc/blob - antlr4-cpp-runtime-4.9.2-source/runtime/src/support/guid.cpp
add antlr source code and ReadMe
[toc] / antlr4-cpp-runtime-4.9.2-source / runtime / src / support / guid.cpp
1 /*
2  The MIT License (MIT)
3
4  Copyright (c) 2014 Graeme Hill (http://graemehill.ca)
5
6  Permission is hereby granted, free of charge, to any person obtaining a copy
7  of this software and associated documentation files (the "Software"), to deal
8  in the Software without restriction, including without limitation the rights
9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  copies of the Software, and to permit persons to whom the Software is
11  furnished to do so, subject to the following conditions:
12
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  THE SOFTWARE.
23  */
24
25 #include "guid.h"
26
27 #ifdef GUID_LIBUUID
28 #include <uuid/uuid.h>
29 #endif
30
31 #ifdef GUID_CFUUID
32 #include <CoreFoundation/CFUUID.h>
33 #endif
34
35 #ifdef GUID_WINDOWS
36 #include <objbase.h>
37 #endif
38
39 #ifdef GUID_ANDROID
40 #include <jni.h>
41 #endif
42
43 using namespace std;
44
45 // overload << so that it's easy to convert to a string
46 ostream &operator<<(ostream &s, const Guid &guid)
47 {
48   return s << hex << setfill('0')
49   << setw(2) << (int)guid._bytes[0]
50   << setw(2) << (int)guid._bytes[1]
51   << setw(2) << (int)guid._bytes[2]
52   << setw(2) << (int)guid._bytes[3]
53   << "-"
54   << setw(2) << (int)guid._bytes[4]
55   << setw(2) << (int)guid._bytes[5]
56   << "-"
57   << setw(2) << (int)guid._bytes[6]
58   << setw(2) << (int)guid._bytes[7]
59   << "-"
60   << setw(2) << (int)guid._bytes[8]
61   << setw(2) << (int)guid._bytes[9]
62   << "-"
63   << setw(2) << (int)guid._bytes[10]
64   << setw(2) << (int)guid._bytes[11]
65   << setw(2) << (int)guid._bytes[12]
66   << setw(2) << (int)guid._bytes[13]
67   << setw(2) << (int)guid._bytes[14]
68   << setw(2) << (int)guid._bytes[15];
69 }
70
71 // create a guid from vector of bytes
72 Guid::Guid(const vector<unsigned char> &bytes)
73 {
74   _bytes = bytes;
75 }
76
77 // create a guid from array of bytes
78 Guid::Guid(const unsigned char *bytes)
79 {
80   _bytes.assign(bytes, bytes + 16);
81 }
82
83 // create a guid from array of words
84 Guid::Guid(const uint16_t *bytes, bool reverse)
85 {
86   if (reverse) {
87     for (size_t i = 8; i > 0; --i)
88     {
89       _bytes.push_back(bytes[i - 1] >> 8);
90       _bytes.push_back(bytes[i - 1] & 0xFF);
91     }
92   } else {
93     for (size_t i = 0; i < 8; ++i)
94     {
95       _bytes.push_back(bytes[i] & 0xFF);
96       _bytes.push_back(bytes[i] >> 8);
97     }
98   }
99 }
100
101 // converts a single hex char to a number (0 - 15)
102 static unsigned char hexDigitToChar(char ch)
103 {
104   if (ch > 47 && ch < 58)
105     return (unsigned char)(ch - 48);
106
107   if (ch > 96 && ch < 103)
108     return (unsigned char)(ch - 87);
109
110   if (ch > 64 && ch < 71)
111     return (unsigned char)(ch - 55);
112
113   return 0;
114 }
115
116 // converts the two hexadecimal characters to an unsigned char (a byte)
117 static unsigned char hexPairToChar(char a, char b)
118 {
119   return hexDigitToChar(a) * 16 + hexDigitToChar(b);
120 }
121
122 // create a guid from string
123 Guid::Guid(const string &fromString)
124 {
125   _bytes.clear();
126
127   char charOne = 0, charTwo;
128   bool lookingForFirstChar = true;
129
130   for (const char &ch : fromString)
131   {
132     if (ch == '-')
133       continue;
134
135     if (lookingForFirstChar)
136     {
137       charOne = ch;
138       lookingForFirstChar = false;
139     }
140     else
141     {
142       charTwo = ch;
143       auto byte = hexPairToChar(charOne, charTwo);
144       _bytes.push_back(byte);
145       lookingForFirstChar = true;
146     }
147   }
148
149 }
150
151 // create empty guid
152 Guid::Guid()
153 {
154   _bytes = vector<unsigned char>(16, 0);
155 }
156
157 // copy constructor
158 Guid::Guid(const Guid &other)
159 {
160   _bytes = other._bytes;
161 }
162
163 // overload assignment operator
164 Guid &Guid::operator=(const Guid &other)
165 {
166   _bytes = other._bytes;
167   return *this;
168 }
169
170 // overload equality operator
171 bool Guid::operator==(const Guid &other) const
172 {
173   return _bytes == other._bytes;
174 }
175
176 // overload inequality operator
177 bool Guid::operator!=(const Guid &other) const
178 {
179   return !((*this) == other);
180 }
181
182 const std::string Guid::toString() const
183 {
184   std::stringstream os;
185   os << *this;
186   return os.str();
187 }
188
189 // This is the linux friendly implementation, but it could work on other
190 // systems that have libuuid available
191 #ifdef GUID_LIBUUID
192 Guid GuidGenerator::newGuid()
193 {
194   uuid_t id;
195   uuid_generate(id);
196   return id;
197 }
198 #endif
199
200 // this is the mac and ios version
201 #ifdef GUID_CFUUID
202 Guid GuidGenerator::newGuid()
203 {
204   auto newId = CFUUIDCreate(NULL);
205   auto bytes = CFUUIDGetUUIDBytes(newId);
206   CFRelease(newId);
207
208   const unsigned char byteArray[16] =
209   {
210     bytes.byte0,
211     bytes.byte1,
212     bytes.byte2,
213     bytes.byte3,
214     bytes.byte4,
215     bytes.byte5,
216     bytes.byte6,
217     bytes.byte7,
218     bytes.byte8,
219     bytes.byte9,
220     bytes.byte10,
221     bytes.byte11,
222     bytes.byte12,
223     bytes.byte13,
224     bytes.byte14,
225     bytes.byte15
226   };
227   return byteArray;
228 }
229 #endif
230
231 // obviously this is the windows version
232 #ifdef GUID_WINDOWS
233 Guid GuidGenerator::newGuid()
234 {
235   GUID newId;
236   CoCreateGuid(&newId);
237
238   const unsigned char bytes[16] =
239   {
240     (newId.Data1 >> 24) & 0xFF,
241     (newId.Data1 >> 16) & 0xFF,
242     (newId.Data1 >> 8) & 0xFF,
243     (newId.Data1) & 0xff,
244
245     (newId.Data2 >> 8) & 0xFF,
246     (newId.Data2) & 0xff,
247
248     (newId.Data3 >> 8) & 0xFF,
249     (newId.Data3) & 0xFF,
250
251     newId.Data4[0],
252     newId.Data4[1],
253     newId.Data4[2],
254     newId.Data4[3],
255     newId.Data4[4],
256     newId.Data4[5],
257     newId.Data4[6],
258     newId.Data4[7]
259   };
260
261   return bytes;
262 }
263 #endif
264
265 // android version that uses a call to a java api
266 #ifdef GUID_ANDROID
267 GuidGenerator::GuidGenerator(JNIEnv *env)
268 {
269   _env = env;
270   _uuidClass = env->FindClass("java/util/UUID");
271   _newGuidMethod = env->GetStaticMethodID(_uuidClass, "randomUUID", "()Ljava/util/UUID;");
272   _mostSignificantBitsMethod = env->GetMethodID(_uuidClass, "getMostSignificantBits", "()J");
273   _leastSignificantBitsMethod = env->GetMethodID(_uuidClass, "getLeastSignificantBits", "()J");
274 }
275
276 Guid GuidGenerator::newGuid()
277 {
278   jobject javaUuid = _env->CallStaticObjectMethod(_uuidClass, _newGuidMethod);
279   jlong mostSignificant = _env->CallLongMethod(javaUuid, _mostSignificantBitsMethod);
280   jlong leastSignificant = _env->CallLongMethod(javaUuid, _leastSignificantBitsMethod);
281
282   unsigned char bytes[16] =
283   {
284     (mostSignificant >> 56) & 0xFF,
285     (mostSignificant >> 48) & 0xFF,
286     (mostSignificant >> 40) & 0xFF,
287     (mostSignificant >> 32) & 0xFF,
288     (mostSignificant >> 24) & 0xFF,
289     (mostSignificant >> 16) & 0xFF,
290     (mostSignificant >> 8) & 0xFF,
291     (mostSignificant) & 0xFF,
292     (leastSignificant >> 56) & 0xFF,
293     (leastSignificant >> 48) & 0xFF,
294     (leastSignificant >> 40) & 0xFF,
295     (leastSignificant >> 32) & 0xFF,
296     (leastSignificant >> 24) & 0xFF,
297     (leastSignificant >> 16) & 0xFF,
298     (leastSignificant >> 8) & 0xFF,
299     (leastSignificant) & 0xFF,
300   };
301   return bytes;
302 }
303 #endif