| 
							- //-----------------------------------------------------------------------------
 - // Project     : SDK Core
 - //
 - // Category    : SDK Core Interfaces
 - // Filename    : pluginterfaces/base/funknown.h
 - // Created by  : Steinberg, 01/2004
 - // Description : Basic Interface
 - //
 - //-----------------------------------------------------------------------------
 - // This file is part of a Steinberg SDK. It is subject to the license terms
 - // in the LICENSE file found in the top-level directory of this distribution
 - // and at www.steinberg.net/sdklicenses. 
 - // No part of the SDK, including this file, may be copied, modified, propagated,
 - // or distributed except according to the terms contained in the LICENSE file.
 - //-----------------------------------------------------------------------------
 - 
 - #pragma once
 - 
 - #include "pluginterfaces/base/fplatform.h"
 - #include "pluginterfaces/base/ftypes.h"
 - #include "pluginterfaces/base/smartpointer.h"
 - #include <string.h>
 - 
 - //------------------------------------------------------------------------
 - /*! \defgroup pluginBase Basic Interfaces
 - */
 - //------------------------------------------------------------------------
 - 
 - //------------------------------------------------------------------------
 - //  Unique Identifier macros
 - //------------------------------------------------------------------------
 - 
 - #if COM_COMPATIBLE
 - #define INLINE_UID(l1, l2, l3, l4) \
 - { \
 - 	(::Steinberg::int8)((l1 & 0x000000FF)      ), (::Steinberg::int8)((l1 & 0x0000FF00) >>  8), \
 - 	(::Steinberg::int8)((l1 & 0x00FF0000) >> 16), (::Steinberg::int8)((l1 & 0xFF000000) >> 24), \
 - 	(::Steinberg::int8)((l2 & 0x00FF0000) >> 16), (::Steinberg::int8)((l2 & 0xFF000000) >> 24), \
 - 	(::Steinberg::int8)((l2 & 0x000000FF)      ), (::Steinberg::int8)((l2 & 0x0000FF00) >>  8), \
 - 	(::Steinberg::int8)((l3 & 0xFF000000) >> 24), (::Steinberg::int8)((l3 & 0x00FF0000) >> 16), \
 - 	(::Steinberg::int8)((l3 & 0x0000FF00) >>  8), (::Steinberg::int8)((l3 & 0x000000FF)      ), \
 - 	(::Steinberg::int8)((l4 & 0xFF000000) >> 24), (::Steinberg::int8)((l4 & 0x00FF0000) >> 16), \
 - 	(::Steinberg::int8)((l4 & 0x0000FF00) >>  8), (::Steinberg::int8)((l4 & 0x000000FF)      )  \
 - }
 - #else
 - #define INLINE_UID(l1, l2, l3, l4) \
 - { \
 - 	(::Steinberg::int8)((l1 & 0xFF000000) >> 24), (::Steinberg::int8)((l1 & 0x00FF0000) >> 16), \
 - 	(::Steinberg::int8)((l1 & 0x0000FF00) >>  8), (::Steinberg::int8)((l1 & 0x000000FF)      ), \
 - 	(::Steinberg::int8)((l2 & 0xFF000000) >> 24), (::Steinberg::int8)((l2 & 0x00FF0000) >> 16), \
 - 	(::Steinberg::int8)((l2 & 0x0000FF00) >>  8), (::Steinberg::int8)((l2 & 0x000000FF)      ), \
 - 	(::Steinberg::int8)((l3 & 0xFF000000) >> 24), (::Steinberg::int8)((l3 & 0x00FF0000) >> 16), \
 - 	(::Steinberg::int8)((l3 & 0x0000FF00) >>  8), (::Steinberg::int8)((l3 & 0x000000FF)      ), \
 - 	(::Steinberg::int8)((l4 & 0xFF000000) >> 24), (::Steinberg::int8)((l4 & 0x00FF0000) >> 16), \
 - 	(::Steinberg::int8)((l4 & 0x0000FF00) >>  8), (::Steinberg::int8)((l4 & 0x000000FF)      )  \
 - }
 - #endif
 - 
 - //------------------------------------------------------------------------
 - #define DECLARE_UID(name, l1, l2, l3, l4) ::Steinberg::TUID name = INLINE_UID (l1, l2, l3, l4);
 - 
 - //------------------------------------------------------------------------
 - #define EXTERN_UID(name) extern const ::Steinberg::TUID name;
 - 
 - #ifdef INIT_CLASS_IID
 - #define DECLARE_CLASS_IID(ClassName, l1, l2, l3, l4)                              \
 - 	static const ::Steinberg::TUID ClassName##_iid = INLINE_UID (l1, l2, l3, l4); \
 - 	\
 - const ::Steinberg::FUID ClassName::iid (ClassName##_iid);
 - #else
 - #define DECLARE_CLASS_IID(ClassName, l1, l2, l3, l4) \
 - 	static const ::Steinberg::TUID ClassName##_iid = INLINE_UID (l1, l2, l3, l4);
 - #endif
 - 
 - #define DEF_CLASS_IID(ClassName) const ::Steinberg::FUID ClassName::iid (ClassName##_iid);
 - 
 - #define INLINE_UID_OF(ClassName) ClassName##_iid
 - 
 - #define INLINE_UID_FROM_FUID(x) \
 - 	INLINE_UID (x.getLong1 (), x.getLong2 (), x.getLong3 (), x.getLong4 ())
 - 
 - //------------------------------------------------------------------------
 - //  FUnknown implementation macros
 - //------------------------------------------------------------------------
 - 
 - #define DECLARE_FUNKNOWN_METHODS                                                                      \
 - public:	                                                                                              \
 - 	virtual ::Steinberg::tresult PLUGIN_API queryInterface (const ::Steinberg::TUID _iid, void** obj) SMTG_OVERRIDE; \
 - 	virtual ::Steinberg::uint32 PLUGIN_API addRef () SMTG_OVERRIDE;                                   \
 - 	virtual ::Steinberg::uint32 PLUGIN_API release () SMTG_OVERRIDE;                                  \
 - protected :                                                                                           \
 - 	::Steinberg::int32 __funknownRefCount;                                                            \
 - public:
 - 
 - //------------------------------------------------------------------------
 - 
 - #define DELEGATE_REFCOUNT(ClassName)											        \
 - public:																			        \
 - 	virtual ::Steinberg::uint32 PLUGIN_API addRef () SMTG_OVERRIDE { return ClassName::addRef ();  } \
 - 	virtual ::Steinberg::uint32 PLUGIN_API release () SMTG_OVERRIDE { return ClassName::release (); }
 - 
 - //------------------------------------------------------------------------
 - #define IMPLEMENT_REFCOUNT(ClassName)                                          \
 - ::Steinberg::uint32 PLUGIN_API ClassName::addRef ()                            \
 - {                                                                              \
 - 	return ::Steinberg::FUnknownPrivate::atomicAdd (__funknownRefCount, 1);    \
 - }                                                                              \
 - ::Steinberg::uint32 PLUGIN_API ClassName::release ()                           \
 - {                                                                              \
 - 	if (::Steinberg::FUnknownPrivate::atomicAdd (__funknownRefCount, -1) == 0) \
 - 	{                                                                          \
 - 		delete this;                                                           \
 - 		return 0;                                                              \
 - 	}                                                                          \
 - 	return __funknownRefCount;                                                 \
 - }
 - 
 - //------------------------------------------------------------------------
 - #define FUNKNOWN_CTOR	{ __funknownRefCount = 1; }
 - #define FUNKNOWN_DTOR
 - 
 - //------------------------------------------------------------------------
 - #define QUERY_INTERFACE(iid, obj, InterfaceIID, InterfaceName)  \
 - if (::Steinberg::FUnknownPrivate::iidEqual (iid, InterfaceIID)) \
 - {                                                               \
 - 	addRef ();                                                  \
 - 	*obj = static_cast< InterfaceName* >(this);                 \
 - 	return ::Steinberg::kResultOk;                              \
 - }
 - 
 - //------------------------------------------------------------------------
 - #define IMPLEMENT_QUERYINTERFACE(ClassName, InterfaceName, ClassIID)                                \
 - ::Steinberg::tresult PLUGIN_API ClassName::queryInterface (const ::Steinberg::TUID _iid, void** obj)\
 - {                                                                                                   \
 - 	QUERY_INTERFACE (_iid, obj, ::Steinberg::FUnknown::iid, InterfaceName)                          \
 - 	QUERY_INTERFACE (_iid, obj, ClassIID, InterfaceName)                                            \
 - 	*obj = nullptr;                                                                                 \
 - 	return ::Steinberg::kNoInterface;                                                               \
 - }
 - 
 - //------------------------------------------------------------------------
 - #define IMPLEMENT_FUNKNOWN_METHODS(ClassName,InterfaceName,ClassIID) \
 - 	IMPLEMENT_REFCOUNT (ClassName)                                   \
 - 	IMPLEMENT_QUERYINTERFACE (ClassName, InterfaceName, ClassIID)
 - 
 - //------------------------------------------------------------------------
 - //  Result Codes
 - //------------------------------------------------------------------------
 - 
 - namespace Steinberg {
 - 
 - //------------------------------------------------------------------------
 - #if COM_COMPATIBLE
 - #if SMTG_OS_WINDOWS
 - enum
 - {
 - 	kNoInterface		= static_cast<tresult>(0x80004002L),	// E_NOINTERFACE
 - 	kResultOk			= static_cast<tresult>(0x00000000L),	// S_OK
 - 	kResultTrue			= kResultOk,
 - 	kResultFalse		= static_cast<tresult>(0x00000001L),	// S_FALSE
 - 	kInvalidArgument	= static_cast<tresult>(0x80070057L),	// E_INVALIDARG
 - 	kNotImplemented		= static_cast<tresult>(0x80004001L),	// E_NOTIMPL
 - 	kInternalError		= static_cast<tresult>(0x80004005L),	// E_FAIL
 - 	kNotInitialized		= static_cast<tresult>(0x8000FFFFL),	// E_UNEXPECTED
 - 	kOutOfMemory		= static_cast<tresult>(0x8007000EL)		// E_OUTOFMEMORY
 - };
 - #else
 - enum
 - {
 - 	kNoInterface		= static_cast<tresult>(0x80000004L),	// E_NOINTERFACE
 - 	kResultOk			= static_cast<tresult>(0x00000000L),	// S_OK
 - 	kResultTrue			= kResultOk,
 - 	kResultFalse		= static_cast<tresult>(0x00000001L),	// S_FALSE
 - 	kInvalidArgument	= static_cast<tresult>(0x80000003L),	// E_INVALIDARG
 - 	kNotImplemented		= static_cast<tresult>(0x80000001L),	// E_NOTIMPL
 - 	kInternalError		= static_cast<tresult>(0x80000008L),	// E_FAIL
 - 	kNotInitialized		= static_cast<tresult>(0x8000FFFFL),	// E_UNEXPECTED
 - 	kOutOfMemory		= static_cast<tresult>(0x80000002L)		// E_OUTOFMEMORY
 - };
 - #endif
 - #else
 - enum
 - {
 - 	kNoInterface = -1,
 - 	kResultOk,
 - 	kResultTrue = kResultOk,
 - 	kResultFalse,
 - 	kInvalidArgument,
 - 	kNotImplemented,
 - 	kInternalError,
 - 	kNotInitialized,
 - 	kOutOfMemory
 - };
 - #endif
 - 
 - //------------------------------------------------------------------------
 - typedef int64 LARGE_INT; // obsolete
 - 
 - //------------------------------------------------------------------------
 - //	FUID class declaration
 - //------------------------------------------------------------------------
 - typedef int8 TUID[16]; ///< plain UID type
 - 
 - //------------------------------------------------------------------------
 - /* FUnknown private */
 - namespace FUnknownPrivate {
 - SMTG_ALWAYS_INLINE bool iidEqual (const void* iid1, const void* iid2)
 - {
 - 	const uint64* p1 = reinterpret_cast<const uint64*> (iid1);
 - 	const uint64* p2 = reinterpret_cast<const uint64*> (iid2);
 - 	return p1[0] == p2[0] && p1[1] == p2[1];
 - }
 - 
 - int32 PLUGIN_API atomicAdd (int32& value, int32 amount);
 - }
 - 
 - //------------------------------------------------------------------------
 - /** Handling 16 Byte Globally Unique Identifiers.
 - \ingroup pluginBase
 - 
 - Each interface declares its identifier as static member inside the interface
 - namespace (e.g. FUnknown::iid).
 - */
 - //------------------------------------------------------------------------
 - class FUID
 - {
 - public:
 - //------------------------------------------------------------------------
 - 	FUID ();
 - 	FUID (uint32 l1, uint32 l2, uint32 l3, uint32 l4);
 - 	FUID (const FUID&);
 - 	virtual ~FUID () {}
 - 
 - #if SMTG_CPP11_STDLIBSUPPORT
 - 	FUID (FUID&& other);
 - 	FUID& operator= (FUID&& other);
 - #endif
 - 
 - 	/** Generates a new Unique Identifier (UID).
 - 	    Will return true for success. If the return value is false, either no
 - 	    UID is generated or the UID is not guaranteed to be unique worldwide. */
 - 	bool generate ();
 - 
 - 	/** Checks if the UID data is valid.
 - 	    The default constructor initializes the memory with zeros. */
 - 	bool isValid () const;
 - 
 - 	FUID& operator = (const FUID& f);
 - 	bool operator == (const FUID& f) const { return ::Steinberg::FUnknownPrivate::iidEqual (data, f.data); }
 - 	bool operator < (const FUID& f) const { return memcmp (data, f.data, sizeof (TUID)) < 0; }
 - 	bool operator != (const FUID& f) const   { return !::Steinberg::FUnknownPrivate::iidEqual (data, f.data); }
 - 
 - 	uint32 getLong1 () const;
 - 	uint32 getLong2 () const;
 - 	uint32 getLong3 () const;
 - 	uint32 getLong4 () const;
 - 
 - 	void from4Int (uint32 d1, uint32 d2, uint32 d3, uint32 d4);
 - 	void to4Int (uint32& d1, uint32& d2, uint32& d3, uint32& d4) const;
 - 
 - 	typedef char8 String[64];
 - 
 - 	/** Converts UID to a string.
 - 		The string will be 32 characters long, representing the hexadecimal values
 - 		of each data byte (e.g. "9127BE30160E4BB69966670AA6087880"). 
 - 		
 - 		Typical use-case is:
 - 		\code
 - 		char8[33] strUID = {0};
 - 		FUID uid;
 - 		if (uid.generate ())
 - 			uid.toString (strUID);
 - 		\endcode
 - 		*/
 - 	void toString (char8* string) const;
 - 
 - 	/** Sets the UID data from a string.
 - 	    The string has to be 32 characters long, where each character-pair is
 - 	    the ASCII-encoded hexadecimal value of the corresponding data byte. */
 - 	bool fromString (const char8* string);
 - 
 - 	/** Converts UID to a string in Microsoft® OLE format.
 - 	(e.g. "{c200e360-38c5-11ce-ae62-08002b2b79ef}") */
 - 	void toRegistryString (char8* string) const;
 - 
 - 	/** Sets the UID data from a string in Microsoft® OLE format. */
 - 	bool fromRegistryString (const char8* string);
 - 
 - 	enum UIDPrintStyle
 - 	{
 - 		kINLINE_UID,  ///< "INLINE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
 - 		kDECLARE_UID, ///< "DECLARE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
 - 		kFUID,        ///< "FUID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
 - 		kCLASS_UID    ///< "DECLARE_CLASS_IID (Interface, 0x00000000, 0x00000000, 0x00000000, 0x00000000)"
 - 	};
 - 	/** Prints the UID to a string (or debug output if string is NULL).
 - 	    \param string is the output string if not NULL.
 - 	    \param style can be chosen from the FUID::UIDPrintStyle enumeration. */
 - 	void print (char8* string = nullptr, int32 style = kINLINE_UID) const;
 - 
 - 	template <size_t N>
 - 	inline explicit FUID (const int8 (&uid)[N])
 - 	{
 - #if SMTG_CPP11_STDLIBSUPPORT
 - 		static_assert (N == sizeof (TUID), "only TUID allowed");
 - #endif
 - 		memcpy (data, uid, sizeof (TUID));
 - 	}
 - 	inline void toTUID (TUID result) const { memcpy (result, data, sizeof (TUID)); }
 - 	inline operator const TUID& () const { return data; }
 - 	inline const TUID& toTUID () const { return data; }
 - 
 - 	static FUID fromTUID (const TUID uid)
 - 	{
 - 		FUID res;
 - 		if (uid)
 - 			memcpy (res.data, uid, sizeof (TUID));
 - 		return res;
 - 	}
 - 
 - //------------------------------------------------------------------------
 - protected:
 - 	TUID data;
 - };
 - 
 - #if SMTG_CPP11_STDLIBSUPPORT
 - template <typename T>
 - inline bool operator== (const FUID& f1, T f2)
 - {
 - 	static_assert (
 - 	    std::is_same<typename std::remove_cv<T>::type, FUID>::value,
 - 	    "Do not compare a FUID with a TUID directly. Either convert the TUID to a FUID and compare them or use FUnknownPrivate::iidEqual");
 - 	return f1.operator== (f2);
 - }
 - #endif
 - 
 - //------------------------------------------------------------------------
 - // FUnknown
 - //------------------------------------------------------------------------
 - /**	The basic interface of all interfaces.
 - \ingroup pluginBase
 - 
 - - The FUnknown::queryInterface method is used to retrieve pointers to other
 -   interfaces of the object.
 - - FUnknown::addRef and FUnknown::release manage the lifetime of the object.
 -   If no more references exist, the object is destroyed in memory.
 - 
 - Interfaces are identified by 16 byte Globally Unique Identifiers.
 - The SDK provides a class called FUID for this purpose.
 - 
 - \ref howtoClass */
 - //------------------------------------------------------------------------
 - class FUnknown
 - {
 - public:
 - 
 - //------------------------------------------------------------------------
 - 	/** Query for a pointer to the specified interface.
 - 	Returns kResultOk on success or kNoInterface if the object does not implement the interface.
 - 	The object has to call addRef when returning an interface.
 - 	\param _iid : (in) 16 Byte interface identifier (-> FUID)
 - 	\param obj : (out) On return, *obj points to the requested interface */
 - 	virtual tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) = 0;
 - 
 - 	/** Adds a reference and return the new reference count.
 - 	\par Remarks:
 - 	    The initial reference count after creating an object is 1. */
 - 	virtual uint32 PLUGIN_API addRef () = 0;
 - 
 - 	/** Releases a reference and return the new reference count.
 - 	If the reference count reaches zero, the object will be destroyed in memory. */
 - 	virtual uint32 PLUGIN_API release () = 0;
 - 
 - //------------------------------------------------------------------------
 - 	static const FUID iid;
 - //------------------------------------------------------------------------
 - };
 - 
 - 
 - DECLARE_CLASS_IID (FUnknown, 0x00000000, 0x00000000, 0xC0000000, 0x00000046)
 - 
 - //------------------------------------------------------------------------
 - // FUnknownPtr
 - //------------------------------------------------------------------------
 - /** FUnknownPtr - automatic interface conversion and smart pointer in one.
 -     This template class can be used for interface conversion like this:
 -  \code
 -     IPtr<IPath> path = owned (FHostCreate (IPath, hostClasses));
 -     FUnknownPtr<IPath2> path2 (path); // does a query interface for IPath2
 -     if (path2)
 -         ...
 -  \endcode
 - */
 - //------------------------------------------------------------------------
 - template <class I>
 - class FUnknownPtr : public IPtr<I>
 - {
 - public:
 - //------------------------------------------------------------------------
 - 	inline FUnknownPtr (FUnknown* unknown); // query interface
 - 	inline FUnknownPtr (const FUnknownPtr& p) : IPtr<I> (p) {}
 - 	inline FUnknownPtr () {}
 - 
 - 	inline FUnknownPtr& operator= (const FUnknownPtr& p)
 - 	{
 - 		IPtr<I>::operator= (p);
 - 		return *this;
 - 	}
 - 	inline I* operator= (FUnknown* unknown);
 - 	inline I* getInterface () { return this->ptr; }
 - };
 - 
 - //------------------------------------------------------------------------
 - template <class I>
 - inline FUnknownPtr<I>::FUnknownPtr (FUnknown* unknown)
 - {
 - 	if (unknown && unknown->queryInterface (I::iid, (void**)&this->ptr) != kResultOk)
 - 		this->ptr = 0;
 - }
 - 
 - //------------------------------------------------------------------------
 - template <class I>
 - inline I* FUnknownPtr<I>::operator= (FUnknown* unknown)
 - {
 - 	I* newPtr = 0;
 - 	if (unknown && unknown->queryInterface (I::iid, (void**)&newPtr) == kResultOk)
 - 	{
 - 		OPtr<I> rel (newPtr);
 - 		return IPtr<I>::operator= (newPtr);
 - 	}
 - 
 - 	return IPtr<I>::operator= (0);
 - }
 - 
 - //------------------------------------------------------------------------
 - // FReleaser (obsolete)
 - //------------------------------------------------------------------------
 - /** Release an interface using automatic object (obsolete).
 - This class is obsolete and is only kept for compatibility.
 - The replacement for FReleaser is OPtr.
 - 
 - Usage example with FReleaser:
 -  \code
 -     void someFunction ()
 -     {
 -         IPath* path = pathCreateMethod ();
 -         FReleaser releaser (path);
 -         .... do something with path...
 -         .... path not used anymore, releaser will destroy it when leaving function scope
 -     }
 -  \endcode
 - Usage example with OPtr:
 -  \code
 -     void someFunction ()
 -     {
 -         OPtr<IPath> path = pathCreateMethod ();
 -         .... do something with path...
 -         .... path not used anymore, OPtr will destroy it when leaving function scope
 -     }
 -  \endcode
 - */
 - //------------------------------------------------------------------------
 - struct FReleaser
 - {
 - 	FReleaser (FUnknown* u) : u (u) {}
 - 	~FReleaser ()
 - 	{
 - 		if (u)
 - 			u->release ();
 - 	}
 - 	FUnknown* u;
 - };
 - 
 - //------------------------------------------------------------------------
 - } // namespace Steinberg
 
 
  |