funknown.cpp

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 // Project     : SDK Core
00003 // Version     : 1.0
00004 //
00005 // Category    : SDK Core Interfaces
00006 // Filename    : funknown.cpp
00007 // Created by  : Steinberg, 01/2004
00008 // Modified    : $Date: 2008/01/09 12:51:43 $
00009 // Description : Basic Interface
00010 //
00011 //-----------------------------------------------------------------------------
00012 // LICENSE
00013 // © 2008, Steinberg Media Technologies GmbH, All Rights Reserved
00014 //-----------------------------------------------------------------------------
00015 // This Software Development Kit may not be distributed in parts or its entirety  
00016 // without prior written agreement by Steinberg Media Technologies GmbH. 
00017 // This SDK must not be used to re-engineer or manipulate any technology used  
00018 // in any Steinberg or Third-party application or software module, 
00019 // unless permitted by law.
00020 // Neither the name of the Steinberg Media Technologies nor the names of its
00021 // contributors may be used to endorse or promote products derived from this 
00022 // software without specific prior written permission.
00023 // 
00024 // THIS SDK IS PROVIDED BY STEINBERG MEDIA TECHNOLOGIES GMBH "AS IS" AND
00025 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
00027 // IN NO EVENT SHALL STEINBERG MEDIA TECHNOLOGIES GMBH BE LIABLE FOR ANY DIRECT, 
00028 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
00029 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
00030 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
00031 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00032 // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00033 // OF THE POSSIBILITY OF SUCH DAMAGE.
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 //  FUnknown static members
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 //      FUID implementation
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         // implement me!
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         // e.g. {c200e360-38c5-11ce-ae62-08002b2b79ef}
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         // e.g. {c200e360-38c5-11ce-ae62-08002b2b79ef}
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) // no string: debug output
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 //  helpers
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 //      FVariant class
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; // copy memory
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; // copy memory
00519 
00520         return *this;
00521 }
00522 
00523 }
Empty

Copyright ©2008 Steinberg Media Technologies. All Rights Reserved.