00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef __funknown__
00037 #include "funknown.h"
00038 #endif
00039
00040 #include <stdio.h>
00041
00042 #if WINDOWS
00043 #include <objbase.h>
00044 #endif
00045
00046 #if TARGET_API_MAC_CARBON
00047 #include <CoreFoundation/CoreFoundation.h>
00048 #endif
00049
00050 namespace Steinberg {
00051
00052
00053 #if COM_COMPATIBLE
00054 #if WINDOWS
00055 #define GuidStruct GUID
00056 #else
00057 struct GuidStruct
00058 {
00059 uint32 Data1;
00060 uint16 Data2;
00061 uint16 Data3;
00062 uint8 Data4[8];
00063 };
00064 #endif
00065 #endif
00066
00067 static void toString (char* string, const char* data, int32 i1, int32 i2);
00068 static void fromString (const char* string, char* data, int32 i1, int32 i2);
00069 static int32 makeLong (uint8 b1, uint8 b2, uint8 b3, uint8 b4);
00070
00071
00072
00073
00074
00075 static int32 gNumObjects = 0;
00076
00077
00078 void FUnknown::addObject ()
00079 {
00080 gNumObjects++;
00081 }
00082
00083
00084 void FUnknown::releaseObject ()
00085 {
00086 gNumObjects--;
00087 }
00088
00089
00090 int32 FUnknown::countObjects ()
00091 {
00092 return gNumObjects;
00093 }
00094
00095
00096
00097
00098
00099 FUID::FUID ()
00100 {
00101 memset (data, 0, 16);
00102 }
00103
00104
00105 FUID::FUID (const char* uid)
00106 {
00107 memset (data, 0, 16);
00108 if (uid)
00109 memcpy (data, uid, 16);
00110 }
00111
00112
00113 FUID::FUID (int32 l1, int32 l2, int32 l3, int32 l4)
00114 {
00115 #if COM_COMPATIBLE
00116 data [0] = (char)((l1 & 0x000000FF) );
00117 data [1] = (char)((l1 & 0x0000FF00) >> 8);
00118 data [2] = (char)((l1 & 0x00FF0000) >> 16);
00119 data [3] = (char)((l1 & 0xFF000000) >> 24);
00120 data [4] = (char)((l2 & 0x00FF0000) >> 16);
00121 data [5] = (char)((l2 & 0xFF000000) >> 24);
00122 data [6] = (char)((l2 & 0x000000FF) );
00123 data [7] = (char)((l2 & 0x0000FF00) >> 8);
00124 data [8] = (char)((l3 & 0xFF000000) >> 24);
00125 data [9] = (char)((l3 & 0x00FF0000) >> 16);
00126 data [10] = (char)((l3 & 0x0000FF00) >> 8);
00127 data [11] = (char)((l3 & 0x000000FF) );
00128 data [12] = (char)((l4 & 0xFF000000) >> 24);
00129 data [13] = (char)((l4 & 0x00FF0000) >> 16);
00130 data [14] = (char)((l4 & 0x0000FF00) >> 8);
00131 data [15] = (char)((l4 & 0x000000FF) );
00132 #else
00133 data [0] = (char)((l1 & 0xFF000000) >> 24);
00134 data [1] = (char)((l1 & 0x00FF0000) >> 16);
00135 data [2] = (char)((l1 & 0x0000FF00) >> 8);
00136 data [3] = (char)((l1 & 0x000000FF) );
00137 data [4] = (char)((l2 & 0xFF000000) >> 24);
00138 data [5] = (char)((l2 & 0x00FF0000) >> 16);
00139 data [6] = (char)((l2 & 0x0000FF00) >> 8);
00140 data [7] = (char)((l2 & 0x000000FF) );
00141 data [8] = (char)((l3 & 0xFF000000) >> 24);
00142 data [9] = (char)((l3 & 0x00FF0000) >> 16);
00143 data [10] = (char)((l3 & 0x0000FF00) >> 8);
00144 data [11] = (char)((l3 & 0x000000FF) );
00145 data [12] = (char)((l4 & 0xFF000000) >> 24);
00146 data [13] = (char)((l4 & 0x00FF0000) >> 16);
00147 data [14] = (char)((l4 & 0x0000FF00) >> 8);
00148 data [15] = (char)((l4 & 0x000000FF) );
00149 #endif
00150 }
00151
00152
00153 FUID::FUID (const FUID& f)
00154 {
00155 memcpy (data, f.data, 16);
00156 }
00157
00158
00159 FUID::~FUID ()
00160 {}
00161
00162
00163 bool FUID::generate ()
00164 {
00165 #if WINDOWS
00166 GUID guid;
00167 HRESULT hr = CoCreateGuid (&guid);
00168 switch (hr)
00169 {
00170 case RPC_S_OK:
00171 memcpy (data, (char*)&guid, 16);
00172 return true;
00173
00174 case RPC_S_UUID_LOCAL_ONLY:
00175 default:
00176 return false;
00177 }
00178
00179 #elif TARGET_API_MAC_CARBON
00180 CFUUIDRef uuid = CFUUIDCreate (kCFAllocatorDefault);
00181 if (uuid)
00182 {
00183 CFUUIDBytes bytes = CFUUIDGetUUIDBytes (uuid);
00184 memcpy (data, (char*)&bytes, 16);
00185 CFRelease (uuid);
00186 return true;
00187 }
00188 return false;
00189
00190 #else
00191
00192 return false;
00193 #endif
00194 }
00195
00196
00197 bool FUID::isValid () const
00198 {
00199 char nulluid[16];
00200 memset (nulluid, 0, 16);
00201
00202 return memcmp (data, nulluid, 16) != 0;
00203 }
00204
00205
00206 FUID& FUID::operator = (const FUID& f)
00207 {
00208 memcpy (data, f.data, 16);
00209 return *this;
00210 }
00211
00212
00213 FUID& FUID::operator = (const char* uid)
00214 {
00215 memcpy (data, uid, 16);
00216 return *this;
00217 }
00218
00219
00220 int32 FUID::getLong1 () const
00221 {
00222 #if COM_COMPATIBLE
00223 return makeLong (data[3], data[2], data [1], data [0]);
00224 #else
00225 return makeLong (data[0], data[1], data [2], data [3]);
00226 #endif
00227 }
00228
00229
00230 int32 FUID::getLong2 () const
00231 {
00232 #if COM_COMPATIBLE
00233 return makeLong (data[5], data[4], data [7], data [6]);
00234 #else
00235 return makeLong (data[4], data[5], data [6], data [7]);
00236 #endif
00237 }
00238
00239
00240 int32 FUID::getLong3 () const
00241 {
00242 #if COM_COMPATIBLE
00243 return makeLong (data[8], data[9], data [10], data [11]);
00244 #else
00245 return makeLong (data[8], data[9], data [10], data [11]);
00246 #endif
00247 }
00248
00249
00250 int32 FUID::getLong4 () const
00251 {
00252 #if COM_COMPATIBLE
00253 return makeLong (data[12], data[13], data [14], data [15]);
00254 #else
00255 return makeLong (data[12], data[13], data [14], data [15]);
00256 #endif
00257 }
00258
00259
00260 void FUID::toString (char* string) const
00261 {
00262 if (!string)
00263 return;
00264
00265 #if COM_COMPATIBLE
00266 GuidStruct* g = (GuidStruct*)data;
00267
00268 char s[17];
00269 Steinberg::toString (s, data, 8, 16);
00270
00271 sprintf (string, "%08X%04X%04X%s", g->Data1, g->Data2, g->Data3, s);
00272 #else
00273 Steinberg::toString (string, data, 0, 16);
00274 #endif
00275 }
00276
00277
00278 bool FUID::fromRegistryString (const char* string)
00279 {
00280 if (!string || !*string)
00281 return false;
00282 if (strlen (string) != 38)
00283 return false;
00284
00285
00286
00287 #if COM_COMPATIBLE
00288 GuidStruct g;
00289 char s[10];
00290
00291 strncpy (s, string + 1, 8);
00292 s[8] = 0;
00293 sscanf (s, "%x", &g.Data1);
00294 strncpy (s, string + 10, 4);
00295 s[4] = 0;
00296 sscanf (s, "%x", &g.Data2);
00297 strncpy (s, string + 15, 4);
00298 s[4] = 0;
00299 sscanf (s, "%x", &g.Data3);
00300 memcpy (data, &g, 8);
00301
00302 Steinberg::fromString (string + 20, data, 8, 10);
00303 Steinberg::fromString (string + 25, data, 10, 16);
00304 #else
00305 Steinberg::fromString (string + 1, data, 0, 4);
00306 Steinberg::fromString (string + 10, data, 4, 6);
00307 Steinberg::fromString (string + 15, data, 6, 8);
00308 Steinberg::fromString (string + 20, data, 8, 10);
00309 Steinberg::fromString (string + 25, data, 10, 16);
00310 #endif
00311
00312 return true;
00313 }
00314
00315
00316 void FUID::toRegistryString (char* string) const
00317 {
00318
00319
00320 #if COM_COMPATIBLE
00321 GuidStruct* g = (GuidStruct*)data;
00322
00323 char s1[5];
00324 Steinberg::toString (s1, data, 8, 10);
00325
00326 char s2[13];
00327 Steinberg::toString (s2, data, 10, 16);
00328
00329 sprintf (string, "{%08X-%04X-%04X-%s-%s}", g->Data1, g->Data2, g->Data3, s1, s2);
00330 #else
00331 char s1[9];
00332 Steinberg::toString (s1, data, 0, 4);
00333 char s2[5];
00334 Steinberg::toString (s2, data, 4, 6);
00335 char s3[5];
00336 Steinberg::toString (s3, data, 6, 8);
00337 char s4[5];
00338 Steinberg::toString (s4, data, 8, 10);
00339 char s5[13];
00340 Steinberg::toString (s5, data, 10, 16);
00341
00342 sprintf (string, "{%s-%s-%s-%s-%s}", s1, s2, s3, s4, s5);
00343 #endif
00344 }
00345
00346
00347 bool FUID::fromString (const char* string)
00348 {
00349 if (!string || !*string)
00350 return false;
00351 if (strlen (string) != 32)
00352 return false;
00353
00354 #if COM_COMPATIBLE
00355 GuidStruct g;
00356 char s[33];
00357
00358 strcpy (s, string);
00359 s[8] = 0;
00360 sscanf (s, "%x", &g.Data1);
00361 strcpy (s, string + 8);
00362 s[4] = 0;
00363 sscanf (s, "%x", &g.Data2);
00364 strcpy (s, string + 12);
00365 s[4] = 0;
00366 sscanf (s, "%x", &g.Data3);
00367
00368 memcpy (data, &g, 8);
00369 Steinberg::fromString (string + 16, data, 8, 16);
00370 #else
00371 Steinberg::fromString (string, data, 0, 16);
00372 #endif
00373
00374 return true;
00375 }
00376
00377
00378 void FUID::print (char* string, int32 style) const
00379 {
00380 if (!string)
00381 {
00382 char str [128];
00383 print (str, style);
00384
00385 #if WINDOWS
00386 OutputDebugString (str);
00387 OutputDebugString ("\n");
00388 #endif
00389 return;
00390 }
00391
00392 int32 l1 = getLong1 ();
00393 int32 l2 = getLong2 ();
00394 int32 l3 = getLong3 ();
00395 int32 l4 = getLong4 ();
00396
00397 switch (style)
00398 {
00399 case kINLINE_UID:
00400 sprintf (string, "INLINE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4);
00401 break;
00402
00403 case kDECLARE_UID:
00404 sprintf (string, "DECLARE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4);
00405 break;
00406
00407 case kFUID:
00408 sprintf (string, "FUID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4);
00409 break;
00410
00411 case kCLASS_UID:
00412 default:
00413 sprintf (string, "DECLARE_CLASS_IID (Interface, 0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4);
00414 break;
00415 }
00416 }
00417
00418
00419 void FUID::toTUID (TUID result) const
00420 {
00421 memcpy (result, data, 16);
00422 }
00423
00424
00425
00426
00427
00428 static int32 makeLong (uint8 b1, uint8 b2, uint8 b3, uint8 b4)
00429 {
00430 return (int32(b1) << 24) | (int32(b2) << 16) | (int32(b3) << 8) | int32(b4);
00431 }
00432
00433
00434 static void toString (char* string, const char* data, int32 i1, int32 i2)
00435 {
00436 *string = 0;
00437 for (int32 i = i1; i < i2; i++)
00438 {
00439 char s[3];
00440 sprintf (s, "%02X", (uint8)data[i]);
00441 strcat (string, s);
00442 }
00443 }
00444
00445
00446 static void fromString (const char* string, char* data, int32 i1, int32 i2)
00447 {
00448 for (int32 i = i1; i < i2; i++)
00449 {
00450 char s[3];
00451 s[0] = *string++;
00452 s[1] = *string++;
00453 s[2] = 0;
00454
00455 int32 d = 0;
00456 sscanf (s, "%2x", &d);
00457 data[i] = (char)d;
00458 }
00459 }
00460
00461
00462
00463
00464
00465 FVariant::FVariant (const FVariant& variant)
00466 : type (variant.type)
00467 {
00468 if ((type & kString) && variant.string)
00469 {
00470 string = new char[strlen (variant.string) + 1];
00471 strcpy ((char*)string, variant.string);
00472 type |= kOwner;
00473 }
00474 else if ((type & kObject) && variant.object)
00475 {
00476 object = variant.object;
00477 object->addRef ();
00478 type |= kOwner;
00479 }
00480 else
00481 intValue = variant.intValue;
00482 }
00483
00484
00485 void FVariant::empty ()
00486 {
00487 if (type & kOwner)
00488 {
00489 if ((type & kString) && string)
00490 delete [] (char *)string;
00491
00492 else if ((type & kObject) && object)
00493 object->release ();
00494 }
00495 memset (this, 0, sizeof (FVariant));
00496 }
00497
00498
00499 FVariant& FVariant::operator= (const FVariant& variant)
00500 {
00501 empty ();
00502
00503 type = variant.type;
00504
00505 if ((type & kString) && variant.string)
00506 {
00507 string = new char[strlen (variant.string) + 1];
00508 strcpy ((char*)string, variant.string);
00509 type |= kOwner;
00510 }
00511 else if ((type & kObject) && variant.object)
00512 {
00513 object = variant.object;
00514 object->addRef ();
00515 type |= kOwner;
00516 }
00517 else
00518 intValue = variant.intValue;
00519
00520 return *this;
00521 }
00522
00523 }