28#include <CoreFoundation/CoreFoundation.h>
30#if !defined (SMTG_USE_STDATOMIC_H)
31#if defined(MAC_OS_X_VERSION_10_11) && defined(MAC_OS_X_VERSION_MIN_REQUIRED)
32#define SMTG_USE_STDATOMIC_H (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_11)
34#define SMTG_USE_STDATOMIC_H 0
38#if !SMTG_USE_STDATOMIC_H
39#include <libkern/OSAtomic.h>
40#if defined(__GNUC__) && (__GNUC__ >= 4) && !__LP64__
42#pragma GCC diagnostic ignored "-Wformat"
48#if !defined (SMTG_USE_STDATOMIC_H)
49#if defined (__ANDROID__) || defined(_LIBCPP_VERSION)
50#define SMTG_USE_STDATOMIC_H 1
52#include <ext/atomicity.h>
58#if defined (SMTG_USE_STDATOMIC_H) && SMTG_USE_STDATOMIC_H
67#define GuidStruct GUID
79static void toString8 (char8*
string,
const char* data, int32 i1, int32 i2);
80static void fromString8 (
const char8*
string,
char* data, int32 i1, int32 i2);
81static uint32 makeLong (uint8 b1, uint8 b2, uint8 b3, uint8 b4);
86namespace FUnknownPrivate {
88int32 PLUGIN_API atomicAdd (int32& var, int32 d)
90#if SMTG_USE_STDATOMIC_H
91 return atomic_fetch_add (
reinterpret_cast<atomic_int_least32_t*
> (&var), d) + d;
95 return InterlockedExchangeAdd (
reinterpret_cast<long volatile*
>(&var), d) + d;
97 return InterlockedExchangeAdd ((LONG*)&var, d) + d;
100 return OSAtomicAdd32Barrier (d, (int32_t*)&var);
101#elif defined(__ANDROID__)
104 __gnu_cxx::__atomic_add (&var, d);
107#warning implement me!
121 memset (data, 0,
sizeof (TUID));
125FUID::FUID (uint32 l1, uint32 l2, uint32 l3, uint32 l4)
127 from4Int (l1, l2, l3, l4);
131FUID::FUID (
const FUID& f)
133 memcpy (data, f.data, sizeof (TUID));
137#if SMTG_CPP11_STDLIBSUPPORT
138FUID::FUID (FUID&& other)
140 memcpy (data, other.data, sizeof (TUID));
143FUID& FUID::operator= (FUID&& other)
145 memcpy (data, other.data, sizeof (TUID));
154#if defined(_M_ARM64) || defined(_M_ARM)
159 HRESULT hr = CoCreateGuid (&guid);
162 case RPC_S_OK:
memcpy (data, (
char*)&guid,
sizeof (
TUID));
return true;
164 case (HRESULT)RPC_S_UUID_LOCAL_ONLY:
165 default:
return false;
170 CFUUIDRef uuid = CFUUIDCreate (kCFAllocatorDefault);
173 CFUUIDBytes bytes = CFUUIDGetUUIDBytes (uuid);
181 srand ((
size_t)
this);
182 for (int32 i = 0; i < 16; i++)
183 data[i] =
static_cast<unsigned char>(
rand ());
186#warning implement me!
196 return memcmp (data, nulluid,
sizeof (
TUID)) != 0;
200FUID& FUID::operator= (
const FUID& f)
202 memcpy (data, f.data, sizeof (TUID));
207void FUID::from4Int (uint32 l1, uint32 l2, uint32 l3, uint32 l4)
210 data [0] = (
char)((l1 & 0x000000FF) );
211 data [1] = (
char)((l1 & 0x0000FF00) >> 8);
212 data [2] = (
char)((l1 & 0x00FF0000) >> 16);
213 data [3] = (
char)((l1 & 0xFF000000) >> 24);
214 data [4] = (
char)((l2 & 0x00FF0000) >> 16);
215 data [5] = (
char)((l2 & 0xFF000000) >> 24);
216 data [6] = (
char)((l2 & 0x000000FF) );
217 data [7] = (
char)((l2 & 0x0000FF00) >> 8);
218 data [8] = (
char)((l3 & 0xFF000000) >> 24);
219 data [9] = (
char)((l3 & 0x00FF0000) >> 16);
220 data [10] = (
char)((l3 & 0x0000FF00) >> 8);
221 data [11] = (
char)((l3 & 0x000000FF) );
222 data [12] = (
char)((l4 & 0xFF000000) >> 24);
223 data [13] = (
char)((l4 & 0x00FF0000) >> 16);
224 data [14] = (
char)((l4 & 0x0000FF00) >> 8);
225 data [15] = (
char)((l4 & 0x000000FF) );
227 data [0] = (
char)((l1 & 0xFF000000) >> 24);
228 data [1] = (
char)((l1 & 0x00FF0000) >> 16);
229 data [2] = (
char)((l1 & 0x0000FF00) >> 8);
230 data [3] = (
char)((l1 & 0x000000FF) );
231 data [4] = (
char)((l2 & 0xFF000000) >> 24);
232 data [5] = (
char)((l2 & 0x00FF0000) >> 16);
233 data [6] = (
char)((l2 & 0x0000FF00) >> 8);
234 data [7] = (
char)((l2 & 0x000000FF) );
235 data [8] = (
char)((l3 & 0xFF000000) >> 24);
236 data [9] = (
char)((l3 & 0x00FF0000) >> 16);
237 data [10] = (
char)((l3 & 0x0000FF00) >> 8);
238 data [11] = (
char)((l3 & 0x000000FF) );
239 data [12] = (
char)((l4 & 0xFF000000) >> 24);
240 data [13] = (
char)((l4 & 0x00FF0000) >> 16);
241 data [14] = (
char)((l4 & 0x0000FF00) >> 8);
242 data [15] = (
char)((l4 & 0x000000FF) );
247void FUID::to4Int (uint32& d1, uint32& d2, uint32& d3, uint32& d4)
const
256uint32 FUID::getLong1 ()
const
259 return makeLong (data[3], data[2], data[1], data[0]);
261 return makeLong (data[0], data[1], data[2], data[3]);
266uint32 FUID::getLong2 ()
const
269 return makeLong (data[5], data[4], data[7], data[6]);
271 return makeLong (data[4], data[5], data[6], data[7]);
276uint32 FUID::getLong3 ()
const
279 return makeLong (data[8], data[9], data[10], data[11]);
281 return makeLong (data[8], data[9], data[10], data[11]);
286uint32 FUID::getLong4 ()
const
289 return makeLong (data[12], data[13], data[14], data[15]);
291 return makeLong (data[12], data[13], data[14], data[15]);
302 auto* g = (GuidStruct*)data;
305 Steinberg::toString8 (s, data, 8, 16);
307 sprintf (
string,
"%08X%04X%04X%s", g->Data1, g->Data2, g->Data3, s);
309 Steinberg::toString8 (
string, data, 0, 16);
316 if (!
string || !*
string)
318 if (
strlen (
string) != 32)
327 sscanf (s,
"%x", &g.Data1);
330 sscanf (s,
"%hx", &g.Data2);
333 sscanf (s,
"%hx", &g.Data3);
336 Steinberg::fromString8 (
string + 16, data, 8, 16);
338 Steinberg::fromString8 (
string, data, 0, 16);
347 if (!
string || !*
string)
349 if (
strlen (
string) != 38)
360 sscanf (s,
"%x", &g.Data1);
363 sscanf (s,
"%hx", &g.Data2);
366 sscanf (s,
"%hx", &g.Data3);
369 Steinberg::fromString8 (
string + 20, data, 8, 10);
370 Steinberg::fromString8 (
string + 25, data, 10, 16);
372 Steinberg::fromString8 (
string + 1, data, 0, 4);
373 Steinberg::fromString8 (
string + 10, data, 4, 6);
374 Steinberg::fromString8 (
string + 15, data, 6, 8);
375 Steinberg::fromString8 (
string + 20, data, 8, 10);
376 Steinberg::fromString8 (
string + 25, data, 10, 16);
388 auto* g = (GuidStruct*)data;
391 Steinberg::toString8 (s1, data, 8, 10);
394 Steinberg::toString8 (s2, data, 10, 16);
396 sprintf (
string,
"{%08X-%04X-%04X-%s-%s}", g->Data1, g->Data2, g->Data3, s1, s2);
399 Steinberg::toString8 (s1, data, 0, 4);
401 Steinberg::toString8 (s2, data, 4, 6);
403 Steinberg::toString8 (s3, data, 6, 8);
405 Steinberg::toString8 (s4, data, 8, 10);
407 Steinberg::toString8 (s5, data, 10, 16);
409 snprintf (
string, 40,
"{%s-%s-%s-%s-%s}", s1, s2, s3, s4, s5);
416 print (style,
string, 62);
420void FUID::print (int32 style, char8*
string,
size_t stringBufferSize)
const
422 if (!
string || stringBufferSize == 0)
425 print (style, str, 128);
428 OutputDebugStringA (str);
429 OutputDebugStringA (
"\n");
436 uint32 l1, l2, l3, l4;
437 to4Int (l1, l2, l3, l4);
442 snprintf (
string, stringBufferSize,
"INLINE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1,
447 snprintf (
string, stringBufferSize,
"DECLARE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1,
452 snprintf (
string, stringBufferSize,
"FUID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3,
459 "DECLARE_CLASS_IID (Interface, 0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3,
468static uint32 makeLong (uint8 b1, uint8 b2, uint8 b3, uint8 b4)
470 return (uint32 (b1) << 24) | (uint32 (b2) << 16) | (uint32 (b3) << 8) | uint32 (b4);
474static void toString8 (char8*
string,
const char* data, int32 i1, int32 i2)
477 for (int32 i = i1; i < i2; i++)
480 snprintf (s, 3,
"%02X", (uint8)data[i]);
486static void fromString8 (
const char8*
string,
char* data, int32 i1, int32 i2)
488 for (int32 i = i1; i < i2; i++)
T atomic_fetch_add(T... args)
Handling 16 Byte Globally Unique Identifiers.
void toString(char8 *string) const
Converts UID to a string.
bool fromRegistryString(const char8 *string)
Sets the UID data from a string in Microsoft(R) OLE format.
bool fromString(const char8 *string)
Sets the UID data from a string.
bool isValid() const
Checks if the UID data is valid.
void toRegistryString(char8 *string) const
Converts UID to a string in Microsoft(R) OLE format.
void print(int32 style, char8 *string=nullptr, size_t stringBufferSize=0) const
Prints the UID to a string (or debug output if string is NULL).
@ kCLASS_UID
"DECLARE_CLASS_IID (Interface, 0x00000000, 0x00000000, 0x00000000, 0x00000000)"
@ kDECLARE_UID
"DECLARE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
@ kINLINE_UID
"INLINE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
@ kFUID
"FUID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
bool generate()
Generates a new Unique Identifier (UID).
char TUID[16]
plain UID type