29 #include <uuid/uuid.h>
33 #include <CoreFoundation/CFUUID.h>
48 AndroidGuidInfo androidInfo;
50 AndroidGuidInfo AndroidGuidInfo::fromJniEnv(JNIEnv *env)
54 auto localUuidClass = env->FindClass(
"java/util/UUID");
55 info.uuidClass = (jclass)env->NewGlobalRef(localUuidClass);
56 env->DeleteLocalRef(localUuidClass);
57 info.newGuidMethod = env->GetStaticMethodID(
58 info.uuidClass,
"randomUUID",
"()Ljava/util/UUID;");
59 info.mostSignificantBitsMethod = env->GetMethodID(
60 info.uuidClass,
"getMostSignificantBits",
"()J");
61 info.leastSignificantBitsMethod = env->GetMethodID(
62 info.uuidClass,
"getLeastSignificantBits",
"()J");
63 info.initThreadId = std::this_thread::get_id();
67 void initJni(JNIEnv *env)
69 androidInfo = AndroidGuidInfo::fromJniEnv(env);
76 std::ios_base::fmtflags f(s.flags());
77 s << std::hex << std::setfill(
'0')
78 << std::setw(2) << (int)
guid._bytes[0]
79 << std::setw(2) << (int)
guid._bytes[1]
80 << std::setw(2) << (int)
guid._bytes[2]
81 << std::setw(2) << (int)
guid._bytes[3]
83 << std::setw(2) << (int)
guid._bytes[4]
84 << std::setw(2) << (int)
guid._bytes[5]
86 << std::setw(2) << (int)
guid._bytes[6]
87 << std::setw(2) << (int)
guid._bytes[7]
89 << std::setw(2) << (int)
guid._bytes[8]
90 << std::setw(2) << (int)
guid._bytes[9]
92 << std::setw(2) << (int)
guid._bytes[10]
93 << std::setw(2) << (int)
guid._bytes[11]
94 << std::setw(2) << (int)
guid._bytes[12]
95 << std::setw(2) << (int)
guid._bytes[13]
96 << std::setw(2) << (int)
guid._bytes[14]
97 << std::setw(2) << (int)
guid._bytes[15];
102 bool operator<(
const xg::Guid &lhs,
const xg::Guid &rhs)
104 return lhs.bytes() < rhs.bytes();
107 bool Guid::isValid()
const
110 return *
this != empty;
114 std::string Guid::str()
const
116 char one[10], two[6], three[6], four[6], five[14];
118 snprintf(one, 10,
"%02x%02x%02x%02x",
119 _bytes[0], _bytes[1], _bytes[2], _bytes[3]);
120 snprintf(two, 6,
"%02x%02x",
121 _bytes[4], _bytes[5]);
122 snprintf(three, 6,
"%02x%02x",
123 _bytes[6], _bytes[7]);
124 snprintf(four, 6,
"%02x%02x",
125 _bytes[8], _bytes[9]);
126 snprintf(five, 14,
"%02x%02x%02x%02x%02x%02x",
127 _bytes[10], _bytes[11], _bytes[12], _bytes[13], _bytes[14], _bytes[15]);
128 const std::string sep(
"-");
129 std::string out(one);
140 Guid::operator std::string()
const
146 const std::array<unsigned char, 16>& Guid::bytes()
const
152 Guid::Guid(
const std::array<unsigned char, 16> &bytes) : _bytes(bytes)
156 Guid::Guid(std::array<unsigned char, 16> &&bytes) : _bytes(
std::move(bytes))
163 if (ch > 47 && ch < 58)
167 if (ch > 96 && ch < 103)
171 if (ch > 64 && ch < 71)
180 if (ch > 47 && ch < 58)
184 if (ch > 96 && ch < 103)
188 if (ch > 64 && ch < 71)
201 Guid::Guid(std::string_view fromString)
205 bool lookingForFirstChar =
true;
206 unsigned nextByte = 0;
208 for (
const char &ch : fromString)
220 if (lookingForFirstChar)
223 lookingForFirstChar =
false;
229 _bytes[nextByte++] = byte;
230 lookingForFirstChar =
true;
243 Guid::Guid() : _bytes{ {0} }
249 std::fill(_bytes.begin(), _bytes.end(),
static_cast<unsigned char>(0));
253 bool Guid::operator==(
const Guid &other)
const
255 return _bytes == other._bytes;
259 bool Guid::operator!=(
const Guid &other)
const
261 return !((*this) == other);
267 _bytes.swap(other._bytes);
275 std::array<unsigned char, 16> data;
276 static_assert(std::is_same<
unsigned char[16], uuid_t>::value,
"Wrong type!");
277 uuid_generate(data.data());
278 return Guid{std::move(data)};
286 auto newId = CFUUIDCreate(NULL);
287 auto bytes = CFUUIDGetUUIDBytes(newId);
290 std::array<unsigned char, 16> byteArray =
309 return Guid{std::move(byteArray)};
318 CoCreateGuid(&newId);
320 std::array<unsigned char, 16> bytes =
322 (
unsigned char)((newId.Data1 >> 24) & 0xFF),
323 (
unsigned char)((newId.Data1 >> 16) & 0xFF),
324 (
unsigned char)((newId.Data1 >> 8) & 0xFF),
325 (
unsigned char)((newId.Data1) & 0xff),
327 (
unsigned char)((newId.Data2 >> 8) & 0xFF),
328 (
unsigned char)((newId.Data2) & 0xff),
330 (
unsigned char)((newId.Data3 >> 8) & 0xFF),
331 (
unsigned char)((newId.Data3) & 0xFF),
333 (
unsigned char)newId.Data4[0],
334 (
unsigned char)newId.Data4[1],
335 (
unsigned char)newId.Data4[2],
336 (
unsigned char)newId.Data4[3],
337 (
unsigned char)newId.Data4[4],
338 (
unsigned char)newId.Data4[5],
339 (
unsigned char)newId.Data4[6],
340 (
unsigned char)newId.Data4[7]
343 return Guid{std::move(bytes)};
351 assert(env != androidInfo.env || std::this_thread::get_id() == androidInfo.initThreadId);
353 jobject javaUuid = env->CallStaticObjectMethod(
354 androidInfo.uuidClass, androidInfo.newGuidMethod);
355 jlong mostSignificant = env->CallLongMethod(javaUuid,
356 androidInfo.mostSignificantBitsMethod);
357 jlong leastSignificant = env->CallLongMethod(javaUuid,
358 androidInfo.leastSignificantBitsMethod);
360 std::array<unsigned char, 16> bytes =
362 (
unsigned char)((mostSignificant >> 56) & 0xFF),
363 (
unsigned char)((mostSignificant >> 48) & 0xFF),
364 (
unsigned char)((mostSignificant >> 40) & 0xFF),
365 (
unsigned char)((mostSignificant >> 32) & 0xFF),
366 (
unsigned char)((mostSignificant >> 24) & 0xFF),
367 (
unsigned char)((mostSignificant >> 16) & 0xFF),
368 (
unsigned char)((mostSignificant >> 8) & 0xFF),
369 (
unsigned char)((mostSignificant) & 0xFF),
370 (
unsigned char)((leastSignificant >> 56) & 0xFF),
371 (
unsigned char)((leastSignificant >> 48) & 0xFF),
372 (
unsigned char)((leastSignificant >> 40) & 0xFF),
373 (
unsigned char)((leastSignificant >> 32) & 0xFF),
374 (
unsigned char)((leastSignificant >> 24) & 0xFF),
375 (
unsigned char)((leastSignificant >> 16) & 0xFF),
376 (
unsigned char)((leastSignificant >> 8) & 0xFF),
377 (
unsigned char)((leastSignificant) & 0xFF)
380 env->DeleteLocalRef(javaUuid);
382 return Guid{std::move(bytes)};
387 return newGuid(androidInfo.env);
399 void swap(xg::Guid &lhs, xg::Guid &rhs) noexcept
BEGIN_XG_NAMESPACE std::ostream & operator<<(std::ostream &s, const Guid &guid)
bool operator<(const xg::Guid &lhs, const xg::Guid &rhs)
bool isValidHexChar(char ch)
unsigned char hexPairToChar(char a, char b)
unsigned char hexDigitToChar(char ch)
auto newGuid() -> std::string
Generate new GUID string value.
const Wt::WFormModel::Field guid
void swap(xg::Guid &lhs, xg::Guid &rhs) noexcept