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 #define __funknown__
00038
00039 #include <string.h>
00040 #include "ftypes.h"
00041
00042 namespace Steinberg {
00043
00044
00045 #if WINDOWS
00046 #define COM_COMPATIBLE 1
00047 #else
00048 #define COM_COMPATIBLE 0
00049 #endif
00050
00051
00052 #undef PLUGIN_API
00053 #if COM_COMPATIBLE
00054 #define PLUGIN_API __stdcall
00055 #else
00056 #define PLUGIN_API
00057 #endif
00058
00059
00060
00061
00062
00063
00064 #if COM_COMPATIBLE
00065 #define INLINE_UID(l1, l2, l3, l4) \
00066 { \
00067 (int8)((l1 & 0x000000FF) ), (int8)((l1 & 0x0000FF00) >> 8), \
00068 (int8)((l1 & 0x00FF0000) >> 16), (int8)((l1 & 0xFF000000) >> 24), \
00069 (int8)((l2 & 0x00FF0000) >> 16), (int8)((l2 & 0xFF000000) >> 24), \
00070 (int8)((l2 & 0x000000FF) ), (int8)((l2 & 0x0000FF00) >> 8), \
00071 (int8)((l3 & 0xFF000000) >> 24), (int8)((l3 & 0x00FF0000) >> 16), \
00072 (int8)((l3 & 0x0000FF00) >> 8), (int8)((l3 & 0x000000FF) ), \
00073 (int8)((l4 & 0xFF000000) >> 24), (int8)((l4 & 0x00FF0000) >> 16), \
00074 (int8)((l4 & 0x0000FF00) >> 8), (int8)((l4 & 0x000000FF) ) \
00075 }
00076 #else
00077 #define INLINE_UID(l1, l2, l3, l4) \
00078 { \
00079 (int8)((l1 & 0xFF000000) >> 24), (int8)((l1 & 0x00FF0000) >> 16), \
00080 (int8)((l1 & 0x0000FF00) >> 8), (int8)((l1 & 0x000000FF) ), \
00081 (int8)((l2 & 0xFF000000) >> 24), (int8)((l2 & 0x00FF0000) >> 16), \
00082 (int8)((l2 & 0x0000FF00) >> 8), (int8)((l2 & 0x000000FF) ), \
00083 (int8)((l3 & 0xFF000000) >> 24), (int8)((l3 & 0x00FF0000) >> 16), \
00084 (int8)((l3 & 0x0000FF00) >> 8), (int8)((l3 & 0x000000FF) ), \
00085 (int8)((l4 & 0xFF000000) >> 24), (int8)((l4 & 0x00FF0000) >> 16), \
00086 (int8)((l4 & 0x0000FF00) >> 8), (int8)((l4 & 0x000000FF) ) \
00087 }
00088 #endif
00089
00090
00091 #define DECLARE_UID(name, l1, l2, l3, l4) \
00092 const char name[16] = INLINE_UID (l1, l2, l3, l4);
00093
00094
00095 #define EXTERN_UID(name) \
00096 extern const char name[16];
00097
00098
00099 #ifdef INIT_CLASS_IID
00100 #define DECLARE_CLASS_IID(ClassName, l1, l2, l3, l4) const ::Steinberg::FUID ClassName::iid (l1, l2, l3, l4);
00101 #else
00102 #define DECLARE_CLASS_IID(ClassName, l1, l2, l3, l4)
00103 #endif
00104
00105 #define DEFINE_CLASS_IID(ClassName, l1, l2, l3, l4) const ::Steinberg::FUID ClassName::iid (l1, l2, l3, l4);
00106
00107
00108
00109
00110
00111 #define DECLARE_FUNKNOWN_METHODS \
00112 public: \
00113 virtual tresult PLUGIN_API queryInterface (const char* iid, void** obj); \
00114 virtual uint32 PLUGIN_API addRef (); \
00115 virtual uint32 PLUGIN_API release (); \
00116 protected : \
00117 uint32 __funknownRefCount; \
00118 public:
00119
00120
00121
00122 #define DELEGATE_REFCOUNT(ClassName) \
00123 public: \
00124 virtual uint32 PLUGIN_API addRef () { return ClassName::addRef (); } \
00125 virtual uint32 PLUGIN_API release () { return ClassName::release (); } \
00126
00127
00128 #define IMPLEMENT_REFCOUNT(ClassName) \
00129 uint32 PLUGIN_API ClassName::addRef () \
00130 { \
00131 return ++__funknownRefCount; \
00132 } \
00133 uint32 PLUGIN_API ClassName::release () \
00134 { \
00135 if (--__funknownRefCount == 0) \
00136 { \
00137 delete this; \
00138 return 0; \
00139 } \
00140 return __funknownRefCount; \
00141 }
00142
00143
00144 #define FUNKNOWN_CTOR { __funknownRefCount = 1; ::Steinberg::FUnknown::addObject (); }
00145 #define FUNKNOWN_DTOR { ::Steinberg::FUnknown::releaseObject (); }
00146
00147
00148 #define QUERY_INTERFACE(iid, obj, InterfaceIID, InterfaceName) \
00149 if (memcmp (iid, InterfaceIID, 16) == 0) \
00150 { \
00151 addRef (); \
00152 *obj = (InterfaceName*)this; \
00153 return kResultOk; \
00154 }
00155
00156
00157 #define IMPLEMENT_QUERYINTERFACE(ClassName, InterfaceName, ClassIID) \
00158 tresult PLUGIN_API ClassName::queryInterface (const char* iid, void** obj) \
00159 { \
00160 QUERY_INTERFACE (iid, obj, ::Steinberg::FUnknown::iid, InterfaceName) \
00161 QUERY_INTERFACE (iid, obj, ClassIID, InterfaceName) \
00162 *obj = 0; \
00163 return kNoInterface; \
00164 }
00165
00166
00167 #define IMPLEMENT_FUNKNOWN_METHODS(ClassName,InterfaceName,ClassIID) \
00168 IMPLEMENT_REFCOUNT (ClassName) \
00169 IMPLEMENT_QUERYINTERFACE (ClassName, InterfaceName, ClassIID)
00170
00171
00172
00173
00174
00175
00176
00177 #if COM_COMPATIBLE
00178 #if WINDOWS
00179 enum
00180 {
00181 kNoInterface = 0x80004002L,
00182 kResultOk = 0x00000000L,
00183 kResultTrue = kResultOk,
00184 kResultFalse = 0x00000001L,
00185 kInvalidArgument = 0x80070057L,
00186 kNotImplemented = 0x80004001L,
00187 kInternalError = 0x80004005L,
00188 kNotInitialized = 0x8000FFFFL,
00189 kOutOfMemory = 0x8007000EL
00190 };
00191 #else
00192 enum
00193 {
00194 kNoInterface = 0x80000004L,
00195 kResultOk = 0x00000000L,
00196 kResultTrue = kResultOk,
00197 kResultFalse = 0x00000001L,
00198 kInvalidArgument = 0x80000003L,
00199 kNotImplemented = 0x80000001L,
00200 kInternalError = 0x80000008L,
00201 kNotInitialized = 0x8000FFFFL,
00202 kOutOfMemory = 0x80000002L
00203 };
00204 #endif
00205 #else
00206 enum
00207 {
00208 kNoInterface = -1,
00209 kResultOk,
00210 kResultTrue = kResultOk,
00211 kResultFalse,
00212 kInvalidArgument,
00213 kNotImplemented,
00214 kInternalError,
00215 kNotInitialized,
00216 kOutOfMemory
00217 };
00218 #endif
00219
00220
00221 typedef int64 LARGE_INT;
00222
00223
00224
00225
00226 typedef char TUID[16];
00227
00231 class FUID
00232 {
00233 public:
00234
00235 FUID ();
00236 FUID (const char*);
00237 FUID (int32 l1, int32 l2, int32 l3, int32 l4);
00238 FUID (const FUID&);
00239 virtual ~FUID ();
00240
00244 bool generate ();
00245
00248 bool isValid () const;
00249
00250 FUID& operator = (const FUID& f);
00251 FUID& operator = (const char* uid);
00252
00253 bool operator == (const FUID& f) const { return memcmp (data, f.data, 16) == 0; }
00254 bool operator == (const char* uid) const { return memcmp (data, uid, 16) == 0; }
00255
00256 bool operator != (const FUID& f) const { return memcmp (data, f.data, 16) != 0; }
00257 bool operator != (const char* uid) const { return memcmp (data, uid, 16) != 0; }
00258
00259 operator const char* () const { return data; }
00260 operator char* () { return data; }
00261
00262 int32 getLong1 () const;
00263 int32 getLong2 () const;
00264 int32 getLong3 () const;
00265 int32 getLong4 () const;
00266
00270 void toString (char* string) const;
00271
00275 bool fromString (const char* string);
00276
00279 void toRegistryString (char* string) const;
00280
00282 bool fromRegistryString (const char* string);
00283
00284 enum UIDPrintStyle
00285 {
00286 kINLINE_UID,
00287 kDECLARE_UID,
00288 kFUID,
00289 kCLASS_UID
00290 };
00293 void print (char* string = 0, int32 style = kINLINE_UID) const;
00294
00295 void toTUID (TUID result) const;
00296
00297 protected:
00298 TUID data;
00299 };
00300
00301
00302
00303
00304
00316
00317 class FUnknown
00318 {
00319 public:
00320
00326 virtual tresult PLUGIN_API queryInterface (const char* iid, void** obj) = 0;
00327
00331 virtual uint32 PLUGIN_API addRef () = 0;
00332
00335 virtual uint32 PLUGIN_API release () = 0;
00336
00337
00338 static const FUID iid;
00339
00340
00341
00342 static void addObject ();
00343 static void releaseObject ();
00344 static int32 countObjects ();
00345
00346 };
00347
00348 DECLARE_CLASS_IID (FUnknown, 0x00000000, 0x00000000, 0xC0000000, 0x00000046)
00349
00350
00351
00352
00353
00366
00367 struct FReleaser
00368 {
00369 FReleaser (FUnknown* u): u (u) {}
00370 ~FReleaser () { if (u) u->release (); }
00371
00372 FUnknown* u;
00373 };
00374
00375
00376
00377
00378
00391
00392 template <class I>
00393 class FUnknownPtr
00394 {
00395 public:
00396
00397 inline FUnknownPtr (FUnknown* unknown);
00398 inline FUnknownPtr (const FUnknownPtr&);
00399 inline FUnknownPtr ();
00400 inline ~FUnknownPtr ();
00401
00402 inline I* operator=(FUnknown* unknown);
00403
00404 inline operator I* () const { return iface; }
00405 inline I* operator->() const { return iface; }
00406 inline I* getInterface () { return iface; }
00407
00408 protected:
00409 I* iface;
00410 };
00411
00412
00413 template <class I>
00414 inline FUnknownPtr<I>::FUnknownPtr (FUnknown* unknown)
00415 : iface (0)
00416 {
00417 if (unknown && unknown->queryInterface (I::iid, (void**)&iface) != kResultOk)
00418 iface = 0;
00419 }
00420
00421 template <class I>
00422 inline FUnknownPtr<I>::FUnknownPtr (const FUnknownPtr& other)
00423 : iface (other.iface)
00424 {
00425 if (iface)
00426 iface->addRef ();
00427 }
00428
00429
00430 template <class I>
00431 inline FUnknownPtr<I>::FUnknownPtr ()
00432 : iface (0)
00433 {}
00434
00435
00436 template <class I>
00437 inline FUnknownPtr<I>::~FUnknownPtr ()
00438 {
00439 if (iface)
00440 iface->release ();
00441 }
00442
00443
00444 template <class I>
00445 inline I* FUnknownPtr<I>::operator=(FUnknown* unknown)
00446 {
00447 if (iface)
00448 iface->release ();
00449 iface = 0;
00450 if (unknown && unknown->queryInterface (I::iid, (void**)&iface) != kResultOk)
00451 iface = 0;
00452 return iface;
00453 }
00454
00455
00456
00457
00458
00459
00461 class FVariant
00462 {
00463
00464 public:
00465 enum
00466 {
00467 kEmpty = 0,
00468 kInteger = 1<<0,
00469 kFloat = 1<<1,
00470 kString = 1<<2,
00471 kObject = 1<<3,
00472 kOwner = 1<<4
00473 };
00474
00475
00476
00477 FVariant () { memset (this, 0, sizeof (FVariant)); }
00478 FVariant (const FVariant& variant);
00479
00480 FVariant (int64 v) : type (kInteger), intValue (v) {}
00481 FVariant (double v) : type (kFloat), floatValue (v) {}
00482 FVariant (const char* str) : type (kString), string (str) {}
00483 FVariant (FUnknown* obj) : type (kObject), object (obj) {}
00484 ~FVariant () { empty (); }
00485
00486
00487 FVariant& operator= (const FVariant& variant);
00488
00489 inline void setInt (int64 v) { empty (); type = kInteger; intValue = v; }
00490 inline void setFloat (double v) { empty (); type = kFloat; floatValue = v; }
00491 inline void setString (const char* v) { empty (); type = kString; string = v; }
00492 inline void setObject (FUnknown* obj) { empty (); type = kObject; object = obj; }
00493
00494 inline int64 getInt () const { return (type & kInteger) ? intValue : 0; }
00495 inline double getFloat () const { return (type & kFloat) ? floatValue : 0.; }
00496 inline double getNumber () const { return (type & kInteger) ? (double)intValue : (type & kFloat) ? floatValue : 0.; }
00497 inline const char* getString () const { return (type & kString) ? string : 0; }
00498 inline FUnknown* getObject () const { return (type & kObject) ? object : 0; }
00499
00500 inline uint16 getType () const { return (type & 0x0F); }
00501 inline bool isEmpty () const { return getType () == kEmpty; }
00502 inline bool isOwner () const { return (type & kOwner) != 0; }
00503
00504 void empty ();
00505
00506 uint16 type;
00507 union
00508 {
00509 int64 intValue;
00510 double floatValue;
00511 const char* string;
00512 FUnknown* object;
00513 };
00514 };
00515
00516 }
00517
00518 #endif