text:
//-----------------------------------------------------------------------------
// 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 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 Globaly Unique Identifiers.
\ingroup pluginBase

Each interface declares its identifier as static member inside the interface
namespace (e.g. FUnknown::iid).
*/
//------------------------------------------------------------------------
class FUID
{
public:
//------------------------------------------------------------------------
	FUID ();
	inline FUID (const TUID uid);
	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);
	FUID& operator = (FIDString uid);
	FUID& operator = (TUID uid);

	bool operator == (const FUID& f) const { return ::Steinberg::FUnknownPrivate::iidEqual (data, f.data); }
	bool operator == (FIDString uid) const { return ::Steinberg::FUnknownPrivate::iidEqual (data, uid); }
	bool operator == (TUID uid) const { return ::Steinberg::FUnknownPrivate::iidEqual (data, uid); }

	bool operator < (const FUID& f) const { return memcmp (data, f.data, sizeof (TUID)) < 0; }
	bool operator < (FIDString uid) const { return memcmp (data, uid, sizeof (TUID)) < 0; }
	bool operator < (TUID uid) const { return memcmp (data, uid, sizeof (TUID)) < 0; }

	bool operator != (const FUID& f) const   { return !::Steinberg::FUnknownPrivate::iidEqual (data, f.data); }
	bool operator != (FIDString uid) const { return !::Steinberg::FUnknownPrivate::iidEqual (data, uid); }
	bool operator != (TUID uid) const { return !::Steinberg::FUnknownPrivate::iidEqual (data, uid); }

	operator FIDString () const { return data; }
	operator char* () { return 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"). */
	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 = 0, int32 style = kINLINE_UID) const;

	void toTUID (TUID result) const;

	inline const TUID& toTUID () const
	{
		return data;
	}

//------------------------------------------------------------------------
protected:
	TUID data;
};

//------------------------------------------------------------------------
inline FUID::FUID (const TUID uid)
{
	memset (data, 0, sizeof (TUID));
	if (uid)
		memcpy (data, uid, sizeof (TUID));
}

//------------------------------------------------------------------------
// 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


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/geoconstants.h
// Created by  : Steinberg, 11/2014
// Description : Defines orientations and directions as also used by fpoint.h and frect.h
//
//-----------------------------------------------------------------------------
// 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

//------------------------------------------------------------------------
namespace Steinberg {

//------------------------------------------------------------------------
enum Direction
{
	kNorth,
	kNorthEast,
	kEast,
	kSouthEast,
	kSouth,
	kSouthWest,
	kWest,
	kNorthWest,
	kNoDirection,  //same position or center point of a geometry

	kNumberOfDirections
};

//------------------------------------------------------------------------
enum Orientation
{
	kHorizontal,
	kVertical,
	kNumberOfOrientations
};

//------------------------------------------------------------------------
namespace GeoConstants {

//------------------------------------------------------------------------
inline Direction toOpposite (Direction dir)
{
	switch (dir)
	{
		case kNorth :		return kSouth;
		case kNorthEast :	return kSouthWest;
		case kEast :		return kWest;
		case kSouthEast :	return kNorthWest;
		case kSouth :		return kNorth;
		case kSouthWest :	return kNorthEast;
		case kWest :		return kEast;
		case kNorthWest :	return kSouthEast;
		case kNoDirection : return kNoDirection;
		default:
			return kNumberOfDirections;
	}
}

//------------------------------------------------------------------------
inline Orientation toOrientation (Direction dir)
{
	switch (dir)
	{
		case kNorth :		return kVertical;
		case kEast :		return kHorizontal;
		case kSouth :		return kVertical;
		case kWest :		return kHorizontal;
		default:
			return kNumberOfOrientations;
	}
}

//------------------------------------------------------------------------
inline Orientation toOrthogonalOrientation (Orientation dir)
{
	switch (dir)
	{
		case kVertical :	return kHorizontal;
		case kHorizontal :	return kVertical;
		default:
			return kNumberOfOrientations;
	}
}

//------------------------------------------------------------------------
} // namespace GeoConstants
} // namespace Steinberg

repo_name: fedden/RenderMan

mime_type: text/x-c++


text:
//------------------------------------------------------------------------
// Project     : SDK Base
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/pluginbasefwd.h
// Created by  : Steinberg, 10/2014
// Description : Forward declarations for pluginterfaces base module
//
//-----------------------------------------------------------------------------
// 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

namespace Steinberg {

class FUnknown;
class FUID;

template <typename T> class IPtr;

class ICloneable;
class IDependent;
class IUpdateHandler;

class IBStream;

} // Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/ipluginbase.h
// Created by  : Steinberg, 01/2004
// Description : Basic Plug-in Interfaces
//
//-----------------------------------------------------------------------------
// 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 "funknown.h"
#include "fstrdefs.h"

namespace Steinberg {

//------------------------------------------------------------------------
/**  Basic interface to a Plug-in component.
\ingroup pluginBase
- [plug imp]
- initialize/terminate the Plug-in component

The host uses this interface to initialize and to terminate the Plug-in component.
The context that is passed to the initialize method contains any interface to the
host that the Plug-in will need to work. These interfaces can vary from category to category.
A list of supported host context interfaces should be included in the documentation
of a specific category. */
//------------------------------------------------------------------------
class IPluginBase: public FUnknown
{
public:
//------------------------------------------------------------------------
	/** The host passes a number of interfaces as context to initialize the Plug-in class.
		@note Extensive memory allocations etc. should be performed in this method rather than in the class' constructor!
		If the method does NOT return kResultOk, the object is released immediately. In this case terminate is not called! */
	virtual tresult PLUGIN_API initialize (FUnknown* context) = 0;

	/** This function is called before the Plug-in is unloaded and can be used for
	    cleanups. You have to release all references to any host application interfaces. */
	virtual tresult PLUGIN_API terminate () = 0;

//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IPluginBase, 0x22888DDB, 0x156E45AE, 0x8358B348, 0x08190625)

//------------------------------------------------------------------------
/** Basic Information about the class factory of the Plug-in.
\ingroup pluginBase
*/
//------------------------------------------------------------------------
struct PFactoryInfo
{
//------------------------------------------------------------------------
	enum FactoryFlags
	{
		kNoFlags					= 0,		///< Nothing
		kClassesDiscardable			= 1 << 0,	///< The number of exported classes can change each time the Module is loaded. If this flag is set, the host does not cache class information. This leads to a longer startup time because the host always has to load the Module to get the current class information.
		kLicenseCheck				= 1 << 1,	///< Class IDs of components are interpreted as Syncrosoft-License (LICENCE_UID). Loaded in a Steinberg host, the module will not be loaded when the license is not valid
		kComponentNonDiscardable	= 1 << 3,	///< Component won't be unloaded until process exit
		kUnicode                    = 1 << 4    ///< Components have entirely unicode encoded strings. (True for VST 3 Plug-ins so far)
	};

	enum
	{
		kURLSize = 256,
		kEmailSize = 128,
		kNameSize = 64
	};

//------------------------------------------------------------------------
	char8 vendor[kNameSize];		///< e.g. "Steinberg Media Technologies"
	char8 url[kURLSize];			///< e.g. "http://www.steinberg.de"
	char8 email[kEmailSize];		///< e.g. "info@steinberg.de"
	int32 flags;				///< (see above)
//------------------------------------------------------------------------
	PFactoryInfo (const char8* _vendor, const char8* _url, const char8* _email, int32 _flags)
	{
		strncpy8 (vendor, _vendor, kNameSize);
		strncpy8 (url, _url, kURLSize);
		strncpy8 (email, _email, kEmailSize);
		flags = _flags;
#ifdef UNICODE
		flags |= kUnicode;
#endif
	}
	PFactoryInfo () { memset (this, 0, sizeof (PFactoryInfo)); }
};

//------------------------------------------------------------------------
/**  Basic Information about a class provided by the Plug-in.
\ingroup pluginBase
*/
//------------------------------------------------------------------------
struct PClassInfo
{
//------------------------------------------------------------------------
	enum ClassCardinality
	{
		kManyInstances = 0x7FFFFFFF
	};

	enum
	{
		kCategorySize = 32,
		kNameSize = 64
	};
//------------------------------------------------------------------------
	TUID cid;                       ///< Class ID 16 Byte class GUID
	int32 cardinality;              ///< cardinality of the class, set to kManyInstances (see \ref ClassCardinality)
	char8 category[kCategorySize];  ///< class category, host uses this to categorize interfaces
	char8 name[kNameSize];          ///< class name, visible to the user
//------------------------------------------------------------------------

	PClassInfo (TUID _cid, int32 _cardinality, const char8* _category, const char8* _name)
	{
		memset (this, 0, sizeof (PClassInfo));
		memcpy (cid, _cid, sizeof (TUID));
		if (_category)
			strncpy8 (category, _category, kCategorySize);
		if (_name)
			strncpy8 (name, _name, kNameSize);
		cardinality = _cardinality;
	}
	PClassInfo () { memset (this, 0, sizeof (PClassInfo)); }
};

//------------------------------------------------------------------------
//  IPluginFactory interface declaration
//------------------------------------------------------------------------
/**	Class factory that any Plug-in defines for creating class instances.
\ingroup pluginBase
- [plug imp]

From the host's point of view a Plug-in module is a factory which can create
a certain kind of object(s). The interface IPluginFactory provides methods
to get information about the classes exported by the Plug-in and a
mechanism to create instances of these classes (that usually define the IPluginBase interface).

<b> An implementation is provided in public.sdk/source/common/pluginfactory.cpp </b>
\see GetPluginFactory
*/
//------------------------------------------------------------------------
class IPluginFactory : public FUnknown
{
public:
//------------------------------------------------------------------------
	/** Fill a PFactoryInfo structure with information about the Plug-in vendor. */
	virtual tresult PLUGIN_API getFactoryInfo (PFactoryInfo* info) = 0;

	/** Returns the number of exported classes by this factory.
	If you are using the CPluginFactory implementation provided by the SDK, it returns the number of classes you registered with CPluginFactory::registerClass. */
	virtual int32 PLUGIN_API countClasses () = 0;

	/** Fill a PClassInfo structure with information about the class at the specified index. */
	virtual tresult PLUGIN_API getClassInfo (int32 index, PClassInfo* info) = 0;

	/** Create a new class instance. */
	virtual tresult PLUGIN_API createInstance (FIDString cid, FIDString _iid, void** obj) = 0;

//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IPluginFactory, 0x7A4D811C, 0x52114A1F, 0xAED9D2EE, 0x0B43BF9F)

//------------------------------------------------------------------------
/**  Version 2 of Basic Information about a class provided by the Plug-in.
\ingroup pluginBase
*/
//------------------------------------------------------------------------
struct PClassInfo2
{
//------------------------------------------------------------------------
	TUID cid;									///< Class ID 16 Byte class GUID
	int32 cardinality;							///< cardinality of the class, set to kManyInstances (see \ref ClassCardinality)
	char8 category[PClassInfo::kCategorySize];	///< class category, host uses this to categorize interfaces
	char8 name[PClassInfo::kNameSize];			///< class name, visible to the user

	enum {
		kVendorSize = 64,
		kVersionSize = 64,
		kSubCategoriesSize = 128
	};

	uint32 classFlags;				///< flags used for a specific category, must be defined where category is defined
	char8 subCategories[kSubCategoriesSize];	///< module specific subcategories, can be more than one, logically added by the \c OR operator
	char8 vendor[kVendorSize];		///< overwrite vendor information from factory info
	char8 version[kVersionSize];	///< Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build)
	char8 sdkVersion[kVersionSize];	///< SDK version used to build this class (e.g. "VST 3.0")

//------------------------------------------------------------------------

	PClassInfo2 (const TUID _cid, int32 _cardinality, const char8* _category, const char8* _name,
		int32 _classFlags, const char8* _subCategories, const char8* _vendor, const char8* _version,
		const char8* _sdkVersion)
	{
		memset (this, 0, sizeof (PClassInfo2));
		memcpy (cid, _cid, sizeof (TUID));
		cardinality = _cardinality;
		if (_category)
			strncpy8 (category, _category, PClassInfo::kCategorySize);
		if (_name)
			strncpy8 (name, _name, PClassInfo::kNameSize);
		classFlags = _classFlags;
		if (_subCategories)
			strncpy8 (subCategories, _subCategories, kSubCategoriesSize);
		if (_vendor)
			strncpy8 (vendor, _vendor, kVendorSize);
		if (_version)
			strncpy8 (version, _version, kVersionSize);
		if (_sdkVersion)
			strncpy8 (sdkVersion, _sdkVersion, kVersionSize);
	}
	PClassInfo2 () { memset (this, 0, sizeof (PClassInfo2)); }
};

//------------------------------------------------------------------------
//  IPluginFactory2 interface declaration
//------------------------------------------------------------------------
/**	Version 2 of class factory supporting PClassInfo2.
\ingroup pluginBase
\copydoc IPluginFactory
*/
//------------------------------------------------------------------------
class IPluginFactory2 : public IPluginFactory
{
public:
//------------------------------------------------------------------------
	/** Returns the class info (version 2) for a given index. */
	virtual tresult PLUGIN_API getClassInfo2 (int32 index, PClassInfo2* info) = 0;

//------------------------------------------------------------------------
	static const FUID iid;
};
DECLARE_CLASS_IID (IPluginFactory2, 0x0007B650, 0xF24B4C0B, 0xA464EDB9, 0xF00B2ABB)

//------------------------------------------------------------------------
/** Unicode Version of Basic Information about a class provided by the Plug-in */
//------------------------------------------------------------------------
struct PClassInfoW
{
//------------------------------------------------------------------------
	TUID cid;							///< see \ref PClassInfo
	int32 cardinality;					///< see \ref PClassInfo
	char8 category[PClassInfo::kCategorySize];	///< see \ref PClassInfo
	char16 name[PClassInfo::kNameSize];	///< see \ref PClassInfo

	enum {
		kVendorSize = 64,
		kVersionSize = 64,
		kSubCategoriesSize = 128
	};

	uint32 classFlags;					///< flags used for a specific category, must be defined where category is defined
	char8 subCategories[kSubCategoriesSize];///< module specific subcategories, can be more than one, logically added by the \c OR operator
	char16 vendor[kVendorSize];			///< overwrite vendor information from factory info
	char16 version[kVersionSize];		///< Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build)
	char16 sdkVersion[kVersionSize];	///< SDK version used to build this class (e.g. "VST 3.0")

//------------------------------------------------------------------------
	PClassInfoW (const TUID _cid, int32 _cardinality, const char8* _category, const char16* _name,
		int32 _classFlags, const char8* _subCategories, const char16* _vendor, const char16* _version,
		const char16* _sdkVersion)
	{
		memset (this, 0, sizeof (PClassInfoW));
		memcpy (cid, _cid, sizeof (TUID));
		cardinality = _cardinality;
		if (_category)
			strncpy8 (category, _category, PClassInfo::kCategorySize);
		if (_name)
			strncpy16 (name, _name, PClassInfo::kNameSize);
		classFlags = _classFlags;
		if (_subCategories)
			strncpy8 (subCategories, _subCategories, kSubCategoriesSize);
		if (_vendor)
			strncpy16 (vendor, _vendor, kVendorSize);
		if (_version)
			strncpy16 (version, _version, kVersionSize);
		if (_sdkVersion)
			strncpy16 (sdkVersion, _sdkVersion, kVersionSize);
	}
	PClassInfoW () { memset (this, 0, sizeof (PClassInfoW)); }

	void fromAscii (const PClassInfo2& ci2)
	{
		memcpy (cid, ci2.cid, sizeof (TUID));
		cardinality = ci2.cardinality;
		strncpy8 (category, ci2.category, PClassInfo::kCategorySize);
		str8ToStr16 (name, ci2.name, PClassInfo::kNameSize);
		classFlags = ci2.classFlags;
		strncpy8 (subCategories, ci2.subCategories, kSubCategoriesSize);

		str8ToStr16 (vendor, ci2.vendor, kVendorSize);
		str8ToStr16 (version, ci2.version, kVersionSize);
		str8ToStr16 (sdkVersion, ci2.sdkVersion, kVersionSize);
	}
};

//------------------------------------------------------------------------
//  IPluginFactory3 interface declaration
//------------------------------------------------------------------------
/**	Version 3 of class factory supporting PClassInfoW.
\ingroup pluginBase
\copydoc IPluginFactory
*/
//------------------------------------------------------------------------
class IPluginFactory3 : public IPluginFactory2
{
public:
//------------------------------------------------------------------------
	/** Returns the unicode class info for a given index. */
	virtual tresult PLUGIN_API getClassInfoUnicode (int32 index, PClassInfoW* info) = 0;

	/** Receives information about host*/
	virtual tresult PLUGIN_API setHostContext (FUnknown* context) = 0;

//------------------------------------------------------------------------
	static const FUID iid;
};
DECLARE_CLASS_IID (IPluginFactory3, 0x4555A2AB, 0xC1234E57, 0x9B122910, 0x36878931)
//------------------------------------------------------------------------
} // namespace Steinberg

//------------------------------------------------------------------------
#define LICENCE_UID(l1, l2, l3, l4) \
{ \
	(int8)((l1 & 0xFF000000) >> 24), (int8)((l1 & 0x00FF0000) >> 16), \
	(int8)((l1 & 0x0000FF00) >>  8), (int8)((l1 & 0x000000FF)      ), \
	(int8)((l2 & 0xFF000000) >> 24), (int8)((l2 & 0x00FF0000) >> 16), \
	(int8)((l2 & 0x0000FF00) >>  8), (int8)((l2 & 0x000000FF)      ), \
	(int8)((l3 & 0xFF000000) >> 24), (int8)((l3 & 0x00FF0000) >> 16), \
	(int8)((l3 & 0x0000FF00) >>  8), (int8)((l3 & 0x000000FF)      ), \
	(int8)((l4 & 0xFF000000) >> 24), (int8)((l4 & 0x00FF0000) >> 16), \
	(int8)((l4 & 0x0000FF00) >>  8), (int8)((l4 & 0x000000FF)      )  \
}

//------------------------------------------------------------------------
// GetPluginFactory
//------------------------------------------------------------------------
/**  Plug-in entry point.
\ingroup pluginBase
Any Plug-in must define and export this function. \n
A typical implementation of GetPluginFactory looks like this
						\code
	IPluginFactory* PLUGIN_API GetPluginFactory ()
	{
		if (!gPluginFactory)
		{
			static PFactoryInfo factoryInfo =
			{
				"My Company Name",
				"http://www.mywebpage.com",
				"mailto:myemail@address.com",
				PFactoryInfo::kNoFlags
			};

			gPluginFactory = new CPluginFactory (factoryInfo);

			static PClassInfo componentClass =
			{
				INLINE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000), // replace by a valid uid
				1,
				"Service",    // category
				"Name"
			};

			gPluginFactory->registerClass (&componentClass, MyComponentClass::newInstance);
		}
		else
			gPluginFactory->addRef ();

		return gPluginFactory;
	}
					\endcode
\see \ref loadPlugin
*/
//------------------------------------------------------------------------
extern "C"
{
	Steinberg::IPluginFactory* PLUGIN_API GetPluginFactory ();
	typedef Steinberg::IPluginFactory* (PLUGIN_API *GetFactoryProc) ();
}


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/fvariant.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/fstrdefs.h"

//------------------------------------------------------------------------
namespace Steinberg {

class FUnknown;

//------------------------------------------------------------------------
//  FVariant struct declaration
//------------------------------------------------------------------------
/** A Value of variable type.
 \ingroup pluginBase
 */
class FVariant
{
//------------------------------------------------------------------------
public:
	enum
	{
		kEmpty = 0,
		kInteger = 1 << 0,
		kFloat = 1 << 1,
		kString8 = 1 << 2,
		kObject = 1 << 3,
		kOwner = 1 << 4,
		kString16 = 1 << 5
	};

//------------------------------------------------------------------------
	// ctors
	inline FVariant () { memset (this, 0, sizeof (FVariant)); }
	inline FVariant (const FVariant& variant);

	inline FVariant (int64 v) : type (kInteger), intValue (v) {}
	inline FVariant (double v) : type (kFloat), floatValue (v) {}
	inline FVariant (const char8* str) : type (kString8), string8 (str) {}
	inline FVariant (const char16* str) : type (kString16), string16 (str) {}
	inline FVariant (FUnknown* obj, bool owner = false) : type (kObject), object (obj)
	{
		setOwner (owner);
	}
	inline ~FVariant () { empty (); }

//------------------------------------------------------------------------
	inline FVariant& operator= (const FVariant& variant);

	inline void setInt (int64 v)
	{
		empty ();
		type = kInteger;
		intValue = v;
	}
	inline void setFloat (double v)
	{
		empty ();
		type = kFloat;
		floatValue = v;
	}
	inline void setString8 (const char8* v)
	{
		empty ();
		type = kString8;
		string8 = v;
	}
	inline void setString16 (const char16* v)
	{
		empty ();
		type = kString16;
		string16 = v;
	}

	inline void setObject (FUnknown* obj)
	{
		empty ();
		type = kObject;
		object = obj;
	}

	inline int64 getInt () const { return (type & kInteger) ? intValue : 0; }
	inline double getFloat () const { return (type & kFloat) ? floatValue : 0.; }
	inline double getNumber () const
	{
		return (type & kInteger) ? static_cast<double> (intValue) : (type & kFloat) ? floatValue :
																					  0.;
	}
	inline const char8* getString8 () const { return (type & kString8) ? string8 : 0; }
	inline const char16* getString16 () const { return (type & kString16) ? string16 : 0; }

	inline FUnknown* getObject () const { return (type & kObject) ? object : 0; }

	inline uint16 getType () const { return static_cast<uint16> (type & ~(kOwner)); }
	inline bool isEmpty () const { return getType () == kEmpty; }
	inline bool isOwner () const { return (type & kOwner) != 0; }
	inline bool isString () const { return (type & (kString8 | kString16)) != 0; }
	inline void setOwner (bool state)
	{
		if (state)
			type |= kOwner;
		else
			type &= ~kOwner;
	}

	void empty ();
//------------------------------------------------------------------------
	uint16 type;
	union
	{
		int64 intValue;
		double floatValue;
		const char8* string8;
		const char16* string16;
		FUnknown* object;
	};
};

//------------------------------------------------------------------------
inline bool operator== (const FVariant& v1, const FVariant& v2)
{
#if PLATFORM_64
	return v1.type == v2.type && v1.intValue == v2.intValue;
#else
	if (v1.type != v2.type)
		return false;
	if (v1.type & (FVariant::kString8 | FVariant::kString16 | FVariant::kObject))
		return v1.string8 == v2.string8; // pointer type comparisons
	return v1.intValue == v2.intValue; // intValue & double comparison

#endif
}

//------------------------------------------------------------------------
inline bool operator!= (const FVariant& v1, const FVariant& v2) { return !(v1 == v2); }

//------------------------------------------------------------------------
inline FVariant::FVariant (const FVariant& variant) : type (kEmpty) { *this = variant; }

//------------------------------------------------------------------------
inline void FVariant::empty ()
{
	if (type & kOwner)
	{
		if ((type & kString8) && string8)
			delete[] string8;
		else if ((type & kString16) && string16)
			delete[] string16;

		else if ((type & kObject) && object)
			object->release ();
	}
	memset (this, 0, sizeof (FVariant));
}

//------------------------------------------------------------------------
inline FVariant& FVariant::operator= (const FVariant& variant)
{
	empty ();

	type = variant.type;

	if ((type & kString8) && variant.string8)
	{
		string8 = new char8[strlen (variant.string8) + 1];
		strcpy (const_cast<char8*> (string8), variant.string8);
		type |= kOwner;
	}
	else if ((type & kString16) && variant.string16)
	{
		int32 len = strlen16 (variant.string16);
		string16 = new char16[len + 1];
		char16* tmp = const_cast<char16*> (string16);
		memcpy (tmp, variant.string16, len * sizeof (char16));
		tmp[len] = 0;
		type |= kOwner;
	}
	else if ((type & kObject) && variant.object)
	{
		object = variant.object;
		object->addRef ();
		type |= kOwner;
	}
	else
		intValue = variant.intValue; // copy memory

	return *this;
}

//------------------------------------------------------------------------
} // namespace Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/funknown.cpp
// 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.
//-----------------------------------------------------------------------------

#include "funknown.h"

#include "fstrdefs.h"

#include <stdio.h>

#if WINDOWS
#include <objbase.h>
#endif

#if MAC
#include <CoreFoundation/CoreFoundation.h>
#include <libkern/OSAtomic.h>

#if defined (__GNUC__) && (__GNUC__ >= 4) && !__LP64__
// on 32 bit Mac OS X we can safely ignore the format warnings as sizeof(int) == sizeof(long)
#pragma GCC diagnostic ignored "-Wformat"
#endif

#endif

#if LINUX
#include <ext/atomicity.h>
#endif

namespace Steinberg {

//------------------------------------------------------------------------
#if COM_COMPATIBLE
#if WINDOWS
#define GuidStruct GUID
#else
struct GuidStruct
{
    uint32  Data1;
    uint16 Data2;
    uint16 Data3;
    uint8  Data4[8];
};
#endif
#endif

static void toString8 (char8* string, const char* data, int32 i1, int32 i2);
static void fromString8 (const char8* string, char* data, int32 i1, int32 i2);
static uint32 makeLong (uint8 b1, uint8 b2, uint8 b3, uint8 b4);

//------------------------------------------------------------------------
//  FUnknownPrivate
//------------------------------------------------------------------------
namespace FUnknownPrivate {
//------------------------------------------------------------------------
int32 PLUGIN_API atomicAdd (int32& var, int32 d)
{
#if WINDOWS
	return InterlockedExchangeAdd (&var, d) + d;
#elif MAC
	return OSAtomicAdd32Barrier (d, (int32_t*)&var);
#elif LINUX
	__gnu_cxx::__atomic_add (&var, d);
	return var;
#else
#warning implement me!
	var += d;
	return var;
#endif
}
} // FUnknownPrivate

//------------------------------------------------------------------------
//	FUID implementation
//------------------------------------------------------------------------

FUID::FUID ()
{
	memset (data, 0, sizeof (TUID));
}

//------------------------------------------------------------------------
FUID::FUID (uint32 l1, uint32 l2, uint32 l3, uint32 l4)
{
	from4Int (l1, l2, l3, l4);
}

//------------------------------------------------------------------------
FUID::FUID (const FUID& f)
{
	memcpy (data, f.data, sizeof (TUID));
}

//------------------------------------------------------------------------
#if SMTG_CPP11_STDLIBSUPPORT
FUID::FUID (FUID&& other) {
	memcpy (data, other.data, sizeof (TUID));
}

FUID& FUID::operator= (FUID&& other)
{
	memcpy (data, other.data, sizeof (TUID));
	return *this;
}
#endif

//------------------------------------------------------------------------
bool FUID::generate ()
{
#if WINDOWS
	GUID guid;
	HRESULT hr = CoCreateGuid (&guid);
	switch (hr)
	{
		case RPC_S_OK:
			memcpy (data, (char*)&guid, sizeof (TUID));
			return true;

		case RPC_S_UUID_LOCAL_ONLY:
		default:
			return false;
	}

#elif MAC
	CFUUIDRef uuid = CFUUIDCreate (kCFAllocatorDefault);
	if (uuid)
	{
		CFUUIDBytes bytes = CFUUIDGetUUIDBytes (uuid);
		memcpy (data, (char*)&bytes, sizeof (TUID));
		CFRelease (uuid);
		return true;
	}
	return false;

#else
#warning implement me!
	return false;
#endif
}

//------------------------------------------------------------------------
bool FUID::isValid () const
{
	TUID nulluid = {0};

	return memcmp (data, nulluid, sizeof (TUID)) != 0;
}

//------------------------------------------------------------------------
FUID& FUID::operator = (const FUID& f)
{
	memcpy (data, f.data, sizeof (TUID));
	return *this;
}

//------------------------------------------------------------------------
FUID& FUID::operator = (FIDString uid)
{
	memcpy (data, uid, sizeof (TUID));
	return *this;
}

//------------------------------------------------------------------------
FUID& FUID::operator = (TUID uid)
{
	memcpy (data, uid, sizeof (TUID));
	return *this;
}

//------------------------------------------------------------------------
void FUID::from4Int (uint32 l1, uint32 l2, uint32 l3, uint32 l4)
{
#if COM_COMPATIBLE
	data [0]  = (char)((l1 & 0x000000FF)      );
	data [1]  = (char)((l1 & 0x0000FF00) >>  8);
	data [2]  = (char)((l1 & 0x00FF0000) >> 16);
	data [3]  = (char)((l1 & 0xFF000000) >> 24);
	data [4]  = (char)((l2 & 0x00FF0000) >> 16);
	data [5]  = (char)((l2 & 0xFF000000) >> 24);
	data [6]  = (char)((l2 & 0x000000FF)      );
	data [7]  = (char)((l2 & 0x0000FF00) >>  8);
	data [8]  = (char)((l3 & 0xFF000000) >> 24);
	data [9]  = (char)((l3 & 0x00FF0000) >> 16);
	data [10] = (char)((l3 & 0x0000FF00) >>  8);
	data [11] = (char)((l3 & 0x000000FF)      );
	data [12] = (char)((l4 & 0xFF000000) >> 24);
	data [13] = (char)((l4 & 0x00FF0000) >> 16);
	data [14] = (char)((l4 & 0x0000FF00) >>  8);
	data [15] = (char)((l4 & 0x000000FF)      );
#else
	data [0]  = (char)((l1 & 0xFF000000) >> 24);
	data [1]  = (char)((l1 & 0x00FF0000) >> 16);
	data [2]  = (char)((l1 & 0x0000FF00) >>  8);
	data [3]  = (char)((l1 & 0x000000FF)      );
	data [4]  = (char)((l2 & 0xFF000000) >> 24);
	data [5]  = (char)((l2 & 0x00FF0000) >> 16);
	data [6]  = (char)((l2 & 0x0000FF00) >>  8);
	data [7]  = (char)((l2 & 0x000000FF)      );
	data [8]  = (char)((l3 & 0xFF000000) >> 24);
	data [9]  = (char)((l3 & 0x00FF0000) >> 16);
	data [10] = (char)((l3 & 0x0000FF00) >>  8);
	data [11] = (char)((l3 & 0x000000FF)      );
	data [12] = (char)((l4 & 0xFF000000) >> 24);
	data [13] = (char)((l4 & 0x00FF0000) >> 16);
	data [14] = (char)((l4 & 0x0000FF00) >>  8);
	data [15] = (char)((l4 & 0x000000FF)      );
#endif
}

//------------------------------------------------------------------------
void FUID::to4Int (uint32& d1, uint32& d2, uint32& d3, uint32& d4) const
{
	d1 = getLong1 ();
	d2 = getLong2 ();
	d3 = getLong3 ();
	d4 = getLong4 ();
}

//------------------------------------------------------------------------
uint32 FUID::getLong1 () const
{
#if COM_COMPATIBLE
	return makeLong (data[3],  data[2],  data [1],  data [0]);
#else
	return makeLong (data[0],  data[1],  data [2],  data [3]);
#endif
}

//------------------------------------------------------------------------
uint32 FUID::getLong2 () const
{
#if COM_COMPATIBLE
	return makeLong (data[5],  data[4],  data [7],  data [6]);
#else
	return makeLong (data[4],  data[5],  data [6],  data [7]);
#endif
}

//------------------------------------------------------------------------
uint32 FUID::getLong3 () const
{
#if COM_COMPATIBLE
	return makeLong (data[8],  data[9],  data [10], data [11]);
#else
	return makeLong (data[8],  data[9],  data [10], data [11]);
#endif
}

//------------------------------------------------------------------------
uint32 FUID::getLong4 () const
{
#if COM_COMPATIBLE
	return makeLong (data[12], data[13], data [14], data [15]);
#else
	return makeLong (data[12], data[13], data [14], data [15]);
#endif
}

//------------------------------------------------------------------------
void FUID::toString (char8* string) const
{
	if (!string)
		return;

	#if COM_COMPATIBLE
	GuidStruct* g = (GuidStruct*)data;

	char8 s[17];
	Steinberg::toString8 (s, data, 8, 16);

	sprintf (string, "%08X%04X%04X%s", g->Data1, g->Data2, g->Data3, s);
	#else
	Steinberg::toString8 (string, data, 0, 16);
	#endif
}

//------------------------------------------------------------------------
bool FUID::fromString (const char8* string)
{
	if (!string || !*string)
		return false;
	if (strlen (string) != 32)
		return false;

	#if COM_COMPATIBLE
	GuidStruct g;
	char s[33];

	strcpy (s, string);
	s[8] = 0;
	sscanf (s, "%x", &g.Data1);
	strcpy (s, string + 8);
	s[4] = 0;
	sscanf (s, "%hx", &g.Data2);
	strcpy (s, string + 12);
	s[4] = 0;
	sscanf (s, "%hx", &g.Data3);

	memcpy (data, &g, 8);
	Steinberg::fromString8 (string + 16, data, 8, 16);
	#else
	Steinberg::fromString8 (string, data, 0, 16);
	#endif

	return true;
}

//------------------------------------------------------------------------
bool FUID::fromRegistryString (const char8* string)
{
	if (!string || !*string)
		return false;
	if (strlen (string) != 38)
		return false;

	// e.g. {c200e360-38c5-11ce-ae62-08002b2b79ef}

	#if COM_COMPATIBLE
	GuidStruct g;
	char8 s[10];

	strncpy (s, string + 1, 8);
	s[8] = 0;
	sscanf (s, "%x", &g.Data1);
	strncpy (s, string + 10, 4);
	s[4] = 0;
	sscanf (s, "%hx", &g.Data2);
	strncpy (s, string + 15, 4);
	s[4] = 0;
	sscanf (s, "%hx", &g.Data3);
	memcpy (data, &g, 8);

	Steinberg::fromString8 (string + 20, data, 8, 10);
	Steinberg::fromString8 (string + 25, data, 10, 16);
	#else
	Steinberg::fromString8 (string + 1, data, 0, 4);
	Steinberg::fromString8 (string + 10, data, 4, 6);
	Steinberg::fromString8 (string + 15, data, 6, 8);
	Steinberg::fromString8 (string + 20, data, 8, 10);
	Steinberg::fromString8 (string + 25, data, 10, 16);
	#endif

	return true;
}

//------------------------------------------------------------------------
void FUID::toRegistryString (char8* string) const
{
	// e.g. {c200e360-38c5-11ce-ae62-08002b2b79ef}

	#if COM_COMPATIBLE
	GuidStruct* g = (GuidStruct*)data;

	char8 s1[5];
	Steinberg::toString8 (s1, data, 8, 10);

	char8 s2[13];
	Steinberg::toString8 (s2, data, 10, 16);

	sprintf (string, "{%08X-%04X-%04X-%s-%s}", g->Data1, g->Data2, g->Data3, s1, s2);
	#else
	char8 s1[9];
	Steinberg::toString8 (s1, data, 0, 4);
	char8 s2[5];
	Steinberg::toString8 (s2, data, 4, 6);
	char8 s3[5];
	Steinberg::toString8 (s3, data, 6, 8);
	char8 s4[5];
	Steinberg::toString8 (s4, data, 8, 10);
	char8 s5[13];
	Steinberg::toString8 (s5, data, 10, 16);

	sprintf (string, "{%s-%s-%s-%s-%s}", s1, s2, s3, s4, s5);
	#endif
}

//------------------------------------------------------------------------
void FUID::print (char8* string, int32 style) const
{
	if (!string) // no string: debug output
	{
		char8 str [128];
		print (str, style);

		#if WINDOWS
		OutputDebugStringA (str);
		OutputDebugStringA ("\n");
		#else
		fprintf (stdout, "%s\n", str);
		#endif
		return;
	}

	uint32 l1, l2, l3, l4;
	to4Int (l1, l2, l3, l4);

	switch (style)
	{
		case kINLINE_UID:
			sprintf (string, "INLINE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4);
			break;

		case kDECLARE_UID:
			sprintf (string, "DECLARE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4);
			break;

		case kFUID:
			sprintf (string, "FUID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4);
			break;

		case kCLASS_UID:
		default:
			sprintf (string, "DECLARE_CLASS_IID (Interface, 0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4);
			break;
	}
}

//------------------------------------------------------------------------
void FUID::toTUID (TUID result) const
{
	memcpy (result, data, sizeof (TUID));
}

//------------------------------------------------------------------------
//  helpers
//------------------------------------------------------------------------
static uint32 makeLong (uint8 b1, uint8 b2, uint8 b3, uint8 b4)
{
	return (uint32(b1) << 24) | (uint32(b2) << 16) | (uint32(b3) << 8) | uint32(b4);
}

//------------------------------------------------------------------------
static void toString8 (char8* string, const char* data, int32 i1, int32 i2)
{
	*string = 0;
	for (int32 i = i1; i < i2; i++)
	{
		char8 s[3];
		sprintf (s, "%02X", (uint8)data[i]);
		strcat (string, s);
	}
}

//------------------------------------------------------------------------
static void fromString8 (const char8* string, char* data, int32 i1, int32 i2)
{
	for (int32 i = i1; i < i2; i++)
	{
		char8 s[3];
		s[0] = *string++;
		s[1] = *string++;
		s[2] = 0;

		int32 d = 0;
		sscanf (s, "%2x", &d);
		data[i] = (char)d;
	}
}

//------------------------------------------------------------------------
} // namespace Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/fplatform.h
// Created by  : Steinberg, 01/2004
// Description : Detect platform and set define
//
//-----------------------------------------------------------------------------
// 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

#define kLittleEndian 0
#define kBigEndian 1

#undef PLUGIN_API

#undef WINDOWS
#undef MAC

//-----------------------------------------------------------------------------
// WIN32 AND WIN64
#if defined (_WIN32)
	#define WINDOWS 1
	#define BYTEORDER kLittleEndian
	#define COM_COMPATIBLE 1
	#define PLUGIN_API __stdcall

	#ifndef _CRT_SECURE_NO_WARNINGS
		#define _CRT_SECURE_NO_WARNINGS
	#endif

	#pragma warning (disable : 4244) // Conversion from 'type1' to 'type2', possible loss of data.
	#pragma warning (disable : 4250) // Inheritance via dominance is allowed
	#pragma warning (disable : 4996) // deprecated functions

	#pragma warning (3 : 4189) // local variable is initialized but not referenced
	#pragma warning (3 : 4238) // nonstandard extension used : class rvalue used as lvalue

	#if defined (_WIN64)       // WIN64 only
		#define PLATFORM_64 1
	#endif
	#ifndef WIN32
		#define WIN32	1
	#endif

	#ifdef __cplusplus
		#define SMTG_CPP11	__cplusplus >= 201103L || _MSC_VER > 1600 || __INTEL_CXX11_MODE__
		#define SMTG_CPP11_STDLIBSUPPORT SMTG_CPP11
	#endif
//-----------------------------------------------------------------------------
// LINUX
#elif __gnu_linux__
	#define LINUX 1
	#include <endian.h>
	#if __BYTE_ORDER == __LITTLE_ENDIAN
		#define BYTEORDER kLittleEndian
	#else
		#define BYTEORDER kBigEndian
	#endif
	#define COM_COMPATIBLE 0
	#define PLUGIN_API
	#define PTHREADS 1
	#if __LP64__
		#define PLATFORM_64 1
	#endif
	#ifdef __cplusplus
		#include <cstddef>
		#define SMTG_CPP11 (__cplusplus >= 201103L)
		#ifndef SMTG_CPP11
			#error unsupported compiler
		#endif
		#define SMTG_CPP11_STDLIBSUPPORT 1
	#endif
//-----------------------------------------------------------------------------
// Mac and iOS
#elif __APPLE__
	#include <TargetConditionals.h>
	#define MAC 1
	#define PTHREADS 1
	#if !TARGET_OS_IPHONE
		#ifndef __CF_USE_FRAMEWORK_INCLUDES__
		#define __CF_USE_FRAMEWORK_INCLUDES__
		#endif
		#ifndef TARGET_API_MAC_CARBON
		#define TARGET_API_MAC_CARBON 1
		#endif
	#endif
	#if __LP64__
		#define PLATFORM_64 1
	#endif
	#if defined (__BIG_ENDIAN__)
		#define BYTEORDER kBigEndian
	#else
		#define BYTEORDER kLittleEndian
	#endif
	#define COM_COMPATIBLE 0
	#define PLUGIN_API

	#if !defined(__PLIST__) && !defined(SMTG_DISABLE_DEFAULT_DIAGNOSTICS)
		#ifdef __clang__
			#pragma GCC diagnostic ignored "-Wswitch-enum"
			#pragma GCC diagnostic ignored "-Wparentheses"
			#pragma GCC diagnostic ignored "-Wuninitialized"
			#if __clang_major__ >= 3
				#pragma GCC diagnostic ignored "-Wtautological-compare"
				#pragma GCC diagnostic ignored "-Wunused-value"
				#if __clang_major__ >= 4 || __clang_minor__ >= 1
					#pragma GCC diagnostic ignored "-Wswitch"
					#pragma GCC diagnostic ignored "-Wcomment"
				#endif
				#if __clang_major__ >= 5
					#pragma GCC diagnostic ignored "-Wunsequenced"
					#if __clang_minor__ >= 1
						#pragma GCC diagnostic ignored "-Wunused-const-variable"
					#endif
				#endif
			#endif
		#endif
	#endif
	#ifdef __cplusplus
		#include <cstddef>
		#define SMTG_CPP11 (__cplusplus >= 201103L || __INTEL_CXX11_MODE__)
		#if defined (_LIBCPP_VERSION) && SMTG_CPP11
		#define SMTG_CPP11_STDLIBSUPPORT 1
		#else
		#define SMTG_CPP11_STDLIBSUPPORT 0
		#endif
	#endif
#else
	#pragma error unknown platform

#endif
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
#if SMTG_CPP11
#define SMTG_OVERRIDE override
#else
#define SMTG_OVERRIDE
#endif


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : Helpers
// Filename    : pluginterfaces/base/ustring.cpp
// Created by  : Steinberg, 12/2005
// Description : UTF-16 String class
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------

#include "ustring.h"

#if WINDOWS
#include <stdio.h>
#pragma warning (disable : 4996)

#elif MAC
#include <CoreFoundation/CoreFoundation.h>

#elif LINUX
#include <cstring>
#include <string>
#include <codecvt>
#include <sstream>
#include <locale>

#include <wctype.h>
#include <wchar.h>

#endif

//------------------------------------------------------------------------
namespace Steinberg {

//------------------------------------------------------------------------
#if LINUX

//------------------------------------------------------------------------
namespace {

using Converter = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>;

//------------------------------------------------------------------------
Converter& converter ()
{
	static Converter instance;
	return instance;
}

//------------------------------------------------------------------------
} // anonymous

//------------------------------------------------------------------------
#endif // LINUX

//------------------------------------------------------------------------
/** Copy strings of different character width. */
//------------------------------------------------------------------------
template <class TDstChar, class TSrcChar>
void StringCopy (TDstChar* dst, int32 dstSize, const TSrcChar* src, int32 srcSize = -1)
{
	int32 count = dstSize;
	if (srcSize >= 0 && srcSize < dstSize)
		count = srcSize;
	for (int32 i = 0; i < count; i++)
	{
		dst[i] = (TDstChar)src[i];
		if (src[i] == 0)
			break;
	}
	dst[dstSize - 1] = 0;
}

//------------------------------------------------------------------------
/** Find length of null-terminated string. */
//------------------------------------------------------------------------
template <class TSrcChar>
int32 StringLength (const TSrcChar* src, int32 srcSize = -1)
{
	if (srcSize == 0)
		return 0;
	int32 length = 0;
	while (src[length])
	{
		length++;
		if (srcSize > 0 && length >= srcSize)
			break;
	}
	return length;
}

//------------------------------------------------------------------------
// UString
//------------------------------------------------------------------------
int32 UString::getLength () const
{
	return StringLength<char16> (thisBuffer, thisSize);
}

//------------------------------------------------------------------------
UString& UString::assign (const char16* src, int32 srcSize)
{
	StringCopy<char16, char16> (thisBuffer, thisSize, src, srcSize);
	return *this;
}

//------------------------------------------------------------------------
UString& UString::append (const char16* src, int32 srcSize)
{
	int32 length = getLength ();
	StringCopy<char16, char16> (thisBuffer + length, thisSize - length, src, srcSize);
	return *this;
}

//------------------------------------------------------------------------
const UString& UString::copyTo (char16* dst, int32 dstSize) const
{
	StringCopy<char16, char16> (dst, dstSize, thisBuffer, thisSize);
	return *this;
}

//------------------------------------------------------------------------
UString& UString::fromAscii (const char* src, int32 srcSize)
{
	StringCopy<char16, char> (thisBuffer, thisSize, src, srcSize);
	return *this;
}

//------------------------------------------------------------------------
const UString& UString::toAscii (char* dst, int32 dstSize) const
{
	StringCopy<char, char16> (dst, dstSize, thisBuffer, thisSize);
	return *this;
}

//------------------------------------------------------------------------
bool UString::scanFloat (double& value) const
{
#if WINDOWS
	return swscanf ((const wchar_t*)thisBuffer, L"%lf", &value) != -1;

#elif TARGET_API_MAC_CARBON
	CFStringRef cfStr = CFStringCreateWithBytes (0, (const UInt8 *)thisBuffer, getLength () * 2, kCFStringEncodingUTF16, false);
	if (cfStr)
	{
		value = CFStringGetDoubleValue (cfStr);
		CFRelease (cfStr);
		return true;
	}
	return false;

#elif LINUX
	auto str = converter ().to_bytes (thisBuffer);
	return sscanf (str.data (), "%lf", &value) == 1;

#else
#warning Implement me
	// implement me!
	return false;
#endif
}

//------------------------------------------------------------------------
bool UString::printFloat (double value, int32 precision)
{
#if WINDOWS
	return swprintf ((wchar_t*)thisBuffer, L"%.*lf", precision, value) != -1;
#elif MAC
	bool result = false;
	CFStringRef cfStr = CFStringCreateWithFormat (0, 0, CFSTR("%.*lf"), precision, value);
	if (cfStr)
	{
		memset (thisBuffer, 0, thisSize);
		CFRange range = {0, CFStringGetLength (cfStr)};
		CFStringGetBytes (cfStr, range, kCFStringEncodingUTF16, 0, false, (UInt8*)thisBuffer, thisSize, 0);
		CFRelease (cfStr);
		return true;
	}
	return result;
#elif LINUX
	auto utf8Buffer = reinterpret_cast<char*> (thisBuffer);
	auto len = snprintf (utf8Buffer, thisSize, "%.*lf", precision, value);
	if (len > 0)
	{
		auto utf16Buffer = reinterpret_cast<char16*> (thisBuffer);
		utf16Buffer[len] = 0;
		while (--len >= 0)
		{
			utf16Buffer[len] = utf8Buffer[len];
		}
		return true;
	}
	return false;
#else
#warning Implement me
	// implement me!
	return false;
#endif
}

//------------------------------------------------------------------------
bool UString::scanInt (int64& value) const
{
#if WINDOWS
	return swscanf ((const wchar_t*)thisBuffer, L"%I64d", &value) != -1;

#elif MAC
	CFStringRef cfStr = CFStringCreateWithBytes (0, (const UInt8 *)thisBuffer, getLength () * 2, kCFStringEncodingUTF16, false);
	if (cfStr)
	{
		value = CFStringGetIntValue (cfStr);
		CFRelease (cfStr);
		return true;
	}
	return false;

#elif LINUX
	auto str = converter ().to_bytes (thisBuffer);
	return sscanf (str.data (), "%lld", &value) == 1;

#else
#warning Implement me
	// implement me!
	return false;
#endif
}

//------------------------------------------------------------------------
bool UString::printInt (int64 value)
{
#if WINDOWS
	return swprintf ((wchar_t*)thisBuffer, L"%I64d", value) != -1;

#elif MAC
	CFStringRef cfStr = CFStringCreateWithFormat (0, 0, CFSTR("%lld"), value);
	if (cfStr)
	{
		memset (thisBuffer, 0, thisSize);
		CFRange range = {0, CFStringGetLength (cfStr)};
		CFStringGetBytes (cfStr, range, kCFStringEncodingUTF16, 0, false, (UInt8*)thisBuffer, thisSize, 0);
		CFRelease (cfStr);
		return true;
	}
	return false;
#elif LINUX
	auto utf8Buffer = reinterpret_cast<char*> (thisBuffer);
	auto len = snprintf (utf8Buffer, thisSize, "%lld", value);
	if (len > 0)
	{
		auto utf16Buffer = reinterpret_cast<char16*> (thisBuffer);
		utf16Buffer[len] = 0;
		while (--len >= 0)
		{
			utf16Buffer[len] = utf8Buffer[len];
		}
		return true;
	}
	return false;

#else
#warning Implement me
	// implement me!
	return false;
#endif
}
} // namespace Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/ibstream.h
// Created by  : Steinberg, 01/2004
// Description : Interface for reading/writing streams
//
//-----------------------------------------------------------------------------
// 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 "funknown.h"

namespace Steinberg {

//------------------------------------------------------------------------
/** Base class for streams.
\ingroup pluginBase
- read/write binary data from/to stream
- get/set stream read-write position (read and write position is the same)
*/
//------------------------------------------------------------------------

class IBStream: public FUnknown
{
public:
	enum IStreamSeekMode
	{
		kIBSeekSet = 0, ///< set absolute seek position
		kIBSeekCur,     ///< set seek position relative to current position
		kIBSeekEnd      ///< set seek position relative to stream end
	};

//------------------------------------------------------------------------
	/** Reads binary data from stream.
	\param buffer : destination buffer
	\param numBytes : amount of bytes to be read
	\param numBytesRead : result - how many bytes have been read from stream (set to 0 if this is of no interest) */
	virtual tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead = 0) = 0;

	/** Writes binary data to stream.
	\param buffer : source buffer
	\param numBytes : amount of bytes to write
	\param numBytesWritten : result - how many bytes have been written to stream (set to 0 if this is of no interest) */
	virtual tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten = 0) = 0;

	/** Sets stream read-write position.
	\param pos : new stream position (dependent on mode)
	\param mode : value of enum IStreamSeekMode
	\param result : new seek position (set to 0 if this is of no interest) */
	virtual tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result = 0) = 0;

	/** Gets current stream read-write position.
	\param pos : is assigned the current position if function succeeds */
	virtual tresult PLUGIN_API tell (int64* pos) = 0;
//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IBStream, 0xC3BF6EA2, 0x30994752, 0x9B6BF990, 0x1EE33E9B)

//------------------------------------------------------------------------
/** Stream with a size.
\ingroup pluginBase
[extends IBStream] when stream type supports it (like file and memory stream) */
//------------------------------------------------------------------------
class ISizeableStream: public FUnknown
{
public:
//------------------------------------------------------------------------
	/** Return the stream size */
	virtual tresult PLUGIN_API getStreamSize (int64& size) = 0;
	/** Set the steam size. File streams can only be resized if they are write enabled. */
	virtual tresult PLUGIN_API setStreamSize (int64 size) = 0;

//------------------------------------------------------------------------
	static const FUID iid;
};
DECLARE_CLASS_IID (ISizeableStream, 0x04F9549E, 0xE02F4E6E, 0x87E86A87, 0x47F4E17F)

//------------------------------------------------------------------------
} // namespace Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/ierrorcontext.h
// Created by  : Steinberg, 02/2008
// Description : Error Context 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/funknown.h"

namespace Steinberg {

class IString;

//------------------------------------------------------------------------
/** Interface for error handling.
[plug imp] \n
[released: Sequel 2] */
//------------------------------------------------------------------------
class IErrorContext : public FUnknown
{
public:
//------------------------------------------------------------------------
	/** Tells the plug-in to not show any UI elements on errors. */
	virtual void PLUGIN_API disableErrorUI (bool state) = 0;
	/** If an error happens and disableErrorUI was not set this should return kResultTrue if the plug-in already showed a message to the user what happened. */
	virtual tresult PLUGIN_API errorMessageShown () = 0;
	/** Fill message with error string. The host may show this to the user. */
	virtual tresult PLUGIN_API getErrorMessage (IString* message) = 0;

//------------------------------------------------------------------------
	static const FUID iid;
};
DECLARE_CLASS_IID (IErrorContext, 0x12BCD07B, 0x7C694336, 0xB7DA77C3, 0x444A0CD0)

//------------------------------------------------------------------------
} // namespace Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/falignpop.h
// Created by  : Steinberg, 01/2004
// Description : Restore alignment settings
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------

//---------------------------------------------------------------------------------------------------
#if TARGET_API_MAC_CARBON
	#if PLATFORM_64
		#pragma pack(pop)
	#else
		#pragma options align=reset
	#endif
#elif defined __BORLANDC__
	#pragma -a-
#elif WINDOWS
	#pragma pack(pop)
#endif
//---------------------------------------------------------------------------------------------------


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/smartpointer.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"
#if SMTG_CPP11_STDLIBSUPPORT
#include <memory>
#endif

//------------------------------------------------------------------------
namespace Steinberg {

//------------------------------------------------------------------------
// IPtr
//------------------------------------------------------------------------
/**	IPtr - Smart pointer template class.
 \ingroup pluginBase

 - can be used as an I* pointer
 - handles refCount of the interface
 - Usage example:
 \code
    IPtr<IPath> path (sharedPath);
    if (path)
        path->ascend ();
 \endcode
 */
//------------------------------------------------------------------------
template <class I>
class IPtr
{
public:
//------------------------------------------------------------------------
	inline IPtr (I* ptr, bool addRef = true);
	inline IPtr (const IPtr&);

	template <class T>
	inline IPtr (const IPtr<T>& other) : ptr (other.get ())
	{
		if (ptr)
			ptr->addRef ();
	}

	inline IPtr ();
	inline ~IPtr ();

	inline I* operator= (I* ptr);

	inline IPtr& operator= (const IPtr& other);

	template <class T>
	inline IPtr& operator= (const IPtr<T>& other)
	{
		operator= (other.get ());
		return *this;
	}

	inline operator I* () const { return ptr; } // act as I*
	inline I* operator-> () const { return ptr; } // act as I*

	inline I* get () const { return ptr; }

#if SMTG_CPP11_STDLIBSUPPORT
	inline IPtr (IPtr<I>&& movePtr) : ptr (nullptr) { *this = std::move (movePtr); }
	inline IPtr& operator= (IPtr<I>&& movePtr)
	{
		if (ptr)
			ptr->release ();
		ptr = movePtr.ptr;
		movePtr.ptr = nullptr;
		return *this;
	}
#endif
//------------------------------------------------------------------------
protected:
	I* ptr;
};

//------------------------------------------------------------------------
template <class I>
inline IPtr<I>::IPtr (I* _ptr, bool addRef) : ptr (_ptr)
{
	if (ptr && addRef)
		ptr->addRef ();
}

//------------------------------------------------------------------------
template <class I>
inline IPtr<I>::IPtr (const IPtr<I>& other) : ptr (other.ptr)
{
	if (ptr)
		ptr->addRef ();
}

//------------------------------------------------------------------------
template <class I>
inline IPtr<I>::IPtr () : ptr (0)
{
}

//------------------------------------------------------------------------
template <class I>
inline IPtr<I>::~IPtr ()
{
	if (ptr)
		ptr->release ();
}

//------------------------------------------------------------------------
template <class I>
inline I* IPtr<I>::operator= (I* _ptr)
{
	if (_ptr != ptr)
	{
		if (ptr)
			ptr->release ();
		ptr = _ptr;
		if (ptr)
			ptr->addRef ();
	}
	return ptr;
}

//------------------------------------------------------------------------
template <class I>
inline IPtr<I>& IPtr<I>::operator= (const IPtr<I>& _ptr)
{
	operator= (_ptr.ptr);
	return *this;
}

//------------------------------------------------------------------------
/** OPtr - "owning" smart pointer used for newly created FObjects.
 \ingroup pluginBase

 FUnknown implementations are supposed to have a refCount of 1 right after creation.
 So using an IPtr on newly created objects would lead to a leak.
 Instead the OPtr can be used in this case. \n
 Example:
 \code
 OPtr<IPath> path = FHostCreate (IPath, hostClasses);
 // no release is needed...
 \endcode
 The assignment operator takes ownership of a new object and releases the old.
 So its safe to write:
 \code
 OPtr<IPath> path = FHostCreate (IPath, hostClasses);
 path = FHostCreate (IPath, hostClasses);
 path = 0;
 \endcode
 This is the difference to using an IPtr with addRef=false.
 \code
 // DONT DO THIS:
 IPtr<IPath> path (FHostCreate (IPath, hostClasses), false);
 path = FHostCreate (IPath, hostClasses);
 path = 0;
 \endcode
 This will lead to a leak!
 */
//------------------------------------------------------------------------
template <class I>
class OPtr : public IPtr<I>
{
public:
//------------------------------------------------------------------------
	inline OPtr (I* p) : IPtr<I> (p, false) {}
	inline OPtr (const IPtr<I>& p) : IPtr<I> (p) {}
	inline OPtr (const OPtr<I>& p) : IPtr<I> (p) {}
	inline OPtr () {}
	inline I* operator= (I* _ptr)
	{
		if (_ptr != this->ptr)
		{
			if (this->ptr)
				this->ptr->release ();
			this->ptr = _ptr;
		}
		return this->ptr;
	}
};

//------------------------------------------------------------------------
/** Assigning newly created object to an IPtr.
 Example:
 \code
 IPtr<IPath> path = owned (FHostCreate (IPath, hostClasses));
 \endcode
 which is a slightly shorter form of writing:
 \code
 IPtr<IPath> path = OPtr<IPath> (FHostCreate (IPath, hostClasses));
 \endcode
 */
template <class I>
IPtr<I> owned (I* p)
{
	return IPtr<I> (p, false);
}

/** Assigning shared object to an IPtr.
 Example:
 \code
 IPtr<IPath> path = shared (iface.getXY ());
 \endcode
 */
template <class I>
IPtr<I> shared (I* p)
{
	return IPtr<I> (p, true);
}

#if SMTG_CPP11_STDLIBSUPPORT
//------------------------------------------------------------------------
// Ownership functionality
//------------------------------------------------------------------------
namespace SKI {
namespace Detail {
struct Adopt;
} // Detail

/** Strong typedef for shared reference counted objects.
 *	Use SKI::adopt to unwrap the provided object.
 * @tparam T Referenced counted type.
 */
template <typename T>
class Shared
{
	friend struct Detail::Adopt;
	T* obj = nullptr;
};

/** Strong typedef for transferring the ownership of reference counted objects.
 *	Use SKI::adopt to unwrap the provided object.
 * After calling adopt the reference in this object is null.
 * @tparam T Referenced counted type.
 */
template <typename T>
class Owned
{
	friend struct Detail::Adopt;
	T* obj = nullptr;
};

/** Strong typedef for using reference counted objects.
 *	Use SKI::adopt to unwrap the provided object.
 * After calling adopt the reference in this object is null.
 * @tparam T Referenced counted type.
 */
template <typename T>
class Used
{
	friend struct Detail::Adopt;
	T* obj = nullptr;
};

namespace Detail {

struct Adopt
{
	template <typename T>
	static IPtr<T> adopt (Shared<T>& ref)
	{
		using Steinberg::shared;
		return shared (ref.obj);
	}

	template <typename T>
	static IPtr<T> adopt (Owned<T>& ref)
	{
		using Steinberg::owned;
		IPtr<T> out = owned (ref.obj);
		ref.obj = nullptr;
		return out;
	}

	template <typename T>
	static T* adopt (Used<T>& ref)
	{
		return ref.obj;
	}

	template <template <typename> class OwnerType, typename T>
	static OwnerType<T> toOwnerType (T* obj)
	{
		OwnerType<T> out;
		out.obj = obj;
		return out;
	}
};

} // Detail

/** Common function to adopt referenced counted object.
  *	@tparam T			Referenced counted type.
  * @param ref			The reference to be adopted in a smart pointer.
  */
template <typename T>
IPtr<T> adopt (Shared<T>& ref) { return Detail::Adopt::adopt (ref); }

template <typename T>
IPtr<T> adopt (Shared<T>&& ref) { return Detail::Adopt::adopt (ref); }

/** Common function to adopt referenced counted object.
  *	@tparam T			Referenced counted type.
  * @param ref			The reference to be adopted in a smart pointer.
  */
template <typename T>
IPtr<T> adopt (Owned<T>& ref) { return Detail::Adopt::adopt (ref); }

template <typename T>
IPtr<T> adopt (Owned<T>&& ref) { return Detail::Adopt::adopt (ref); }

/** Common function to adopt referenced counted object.
  *	@tparam T			Referenced counted type.
  * @param ref			The reference to be adopted in a smart pointer.
  */
template <typename T>
T* adopt (Used<T>& ref) { return Detail::Adopt::adopt (ref); }

template <typename T>
T* adopt (Used<T>&& ref) { return Detail::Adopt::adopt (ref); }

/** Common function to wrap owned instances. */
template <typename T>
Owned<T> toOwned (T* obj) { return Detail::Adopt::toOwnerType<Owned> (obj); }

/** Common function to wrap shared instances. */
template <typename T>
Shared<T> toShared (T* obj) { return Detail::Adopt::toOwnerType<Shared> (obj); }

/** Common function to wrap used instances. */
template <typename T>
Used<T> toUsed (T* obj) { return Detail::Adopt::toOwnerType<Used> (obj); }

//------------------------------------------------------------------------
} // SKI
#endif
} // Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/futils.h
// Created by  : Steinberg, 01/2004
// Description : Basic utilities
//
//-----------------------------------------------------------------------------
// 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/ftypes.h"

namespace Steinberg {
//----------------------------------------------------------------------------
// min/max/etc. template functions
template <class T>
inline const T& Min (const T& a, const T& b)
{
	return b < a ? b : a;
}

template <class T>
inline const T& Max (const T& a, const T& b)
{
	return a < b ? b : a;
}

template <class T>
inline T Abs (const T& value)
{
	return (value >= (T)0) ? value : -value;
}

template <class T>
inline T Sign (const T& value)
{
	return (value == (T)0) ? 0 : ((value >= (T)0) ? 1 : -1);
}

template <class T>
inline T Bound (T minval, T maxval, T x)
{
	if (x < minval)
		return minval;
	else if (x > maxval)
		return maxval;
	return x;
}

template <class T>
void Swap (T& t1, T& t2)
{
	T tmp = t1;
	t1 = t2;
	t2 = tmp;
}

template <class T>
bool IsApproximateEqual (T t1, T t2, T epsilon)
{
	if (t1 == t2)
		return true;
	T diff = t1 - t2;
	if (diff < 0.0)
		diff = -diff;
	if (diff < epsilon)
		return true;
	return false;
}

template <class T>
inline T ToNormalized (const T& value, const int32 numSteps)
{
	return value / T (numSteps);
}

template <class T>
inline int32 FromNormalized (const T& norm, const int32 numSteps)
{
	return Min<int32> (numSteps, int32 (norm * (numSteps + 1)));
}

//------------------------------------------------------------------------
} // namespace Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/fstrdefs.h
// Created by  : Steinberg, 01/2004
// Description : Definitions for handling strings (Unicode / ASCII / Platforms)
//
//-----------------------------------------------------------------------------
// 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 "ftypes.h"

//----------------------------------------------------------------------------
// string methods defines unicode / ASCII
//----------------------------------------------------------------------------

// 16 bit string operations
#if SMTG_CPP11	// if c++11 unicode string literals
	#define SMTG_CPP11_CAT_PRIVATE_DONT_USE(a,b)			a ## b
	#if WINDOWS
		#define STR16(x) SMTG_CPP11_CAT_PRIVATE_DONT_USE(L,x)
	#else
		#define STR16(x) SMTG_CPP11_CAT_PRIVATE_DONT_USE(u,x)
	#endif
#else
	#include "conststringtable.h"
	#define STR16(x) Steinberg::ConstStringTable::instance ()->getString (x)
#endif

#ifdef UNICODE
	#define STR(x) STR16(x)
	#define tStrBufferSize(buffer) (sizeof(buffer)/sizeof(Steinberg::tchar))

#else
	#define STR(x) x
	#define tStrBufferSize(buffer) (sizeof(buffer))
#endif

#define str8BufferSize(buffer) (sizeof(buffer)/sizeof(Steinberg::char8))
#define str16BufferSize(buffer) (sizeof(buffer)/sizeof(Steinberg::char16))

#if WINDOWS
#define FORMAT_INT64A "I64d"
#define FORMAT_UINT64A "I64u"

#elif MAC || LINUX
#define FORMAT_INT64A  "lld"
#define FORMAT_UINT64A "llu"
#define stricmp		strcasecmp
#define strnicmp	strncasecmp
#endif

#ifdef UNICODE
#define FORMAT_INT64W STR(FORMAT_INT64A)
#define FORMAT_UINT64W STR(FORMAT_UINT64A)

#define FORMAT_INT64 FORMAT_INT64W
#define FORMAT_UINT64 FORMAT_UINT64W
#else
#define FORMAT_INT64 FORMAT_INT64A
#define FORMAT_UINT64 FORMAT_UINT64A
#endif

//----------------------------------------------------------------------------
// newline
//----------------------------------------------------------------------------
#if WINDOWS
#define ENDLINE_A   "\r\n"
#define ENDLINE_W   STR ("\r\n")
#elif MAC
#define ENDLINE_A   "\r"
#define ENDLINE_W   STR ("\r")
#elif LINUX
#define ENDLINE_A   "\n"
#define ENDLINE_W   STR ("\n")
#endif

#ifdef UNICODE
#define ENDLINE ENDLINE_W
#else
#define ENDLINE ENDLINE_A
#endif

#if WINDOWS && !defined(__GNUC__) && defined(_MSC_VER) && (_MSC_VER < 1900)
#define stricmp _stricmp
#define strnicmp _strnicmp
#define snprintf _snprintf
#endif

namespace Steinberg {

//----------------------------------------------------------------------------
static const tchar kEmptyString[] = { 0 };
static const char8 kEmptyString8[] = { 0 };
static const char16 kEmptyString16[] = { 0 };

#ifdef UNICODE
static const tchar kInfiniteSymbol[] = { 0x221E, 0 };
#else
static const tchar* const kInfiniteSymbol = STR ("oo");
#endif

//----------------------------------------------------------------------------
template <class T>
inline int32 _tstrlen (const T* wcs)
{
	const T* eos = wcs;

	while (*eos++)
		;

	return (int32) (eos - wcs - 1);
}

inline int32 tstrlen (const tchar* str) {return _tstrlen (str);}
inline int32 strlen8 (const char8* str) {return _tstrlen (str);}
inline int32 strlen16 (const char16* str) {return _tstrlen (str);}

//----------------------------------------------------------------------------
template <class T>
inline int32 _tstrcmp (const T* src, const T* dst)
{
	while (*src == *dst && *dst)
	{
		src++;
		dst++;
	}

	if (*src == 0 && *dst == 0)
		return 0;
	else if (*src == 0)
		return -1;
	else if (*dst == 0)
		return 1;
	else
		return (int32) (*src - *dst);
}

inline int32 tstrcmp (const tchar* src, const tchar* dst) {return _tstrcmp (src, dst);}
inline int32 strcmp8 (const char8* src, const char8* dst) {return _tstrcmp (src, dst);}
inline int32 strcmp16 (const char16* src, const char16* dst) {return _tstrcmp (src, dst);}

template <typename T>
inline int32 strcmpT (const T* first, const T* last);

template <>
inline int32 strcmpT<char8> (const char8* first, const char8* last) { return _tstrcmp (first, last); }

template <>
inline int32 strcmpT<char16> (const char16* first, const char16* last) { return _tstrcmp (first, last); }

//----------------------------------------------------------------------------
template <class T>
inline int32 _tstrncmp (const T* first, const T* last, uint32 count)
{
	if (count == 0)
		return 0;

	while (--count && *first && *first == *last)
	{
		first++;
		last++;
	}

	if (*first == 0 && *last == 0)
		return 0;
	else if (*first == 0)
		return -1;
	else if (*last == 0)
		return 1;
	else
		return (int32) (*first - *last);
}

inline int32 tstrncmp (const tchar* first, const tchar* last, uint32 count) {return _tstrncmp (first, last, count);}
inline int32 strncmp8 (const char8* first, const char8* last, uint32 count) {return _tstrncmp (first, last, count);}
inline int32 strncmp16 (const char16* first, const char16* last, uint32 count) {return _tstrncmp (first, last, count);}

template <typename T>
inline int32 strncmpT (const T* first, const T* last, uint32 count);

template <>
inline int32 strncmpT<char8> (const char8* first, const char8* last, uint32 count) { return _tstrncmp (first, last, count); }

template <>
inline int32 strncmpT<char16> (const char16* first, const char16* last, uint32 count) {return _tstrncmp (first, last, count); }

//----------------------------------------------------------------------------
template <class T>
inline T* _tstrcpy (T* dst, const T* src)
{
	T* cp = dst;
	while ((*cp++ = *src++) != 0) // copy string
		;
	return dst;
}
inline tchar* tstrcpy (tchar* dst, const tchar* src) {return _tstrcpy (dst, src);}
inline char8* strcpy8 (char8* dst, const char8* src) {return _tstrcpy (dst, src);}
inline char16* strcpy16 (char16* dst, const char16* src) {return _tstrcpy (dst, src);}

//----------------------------------------------------------------------------
template <class T>
inline T* _tstrncpy (T* dest, const T* source, uint32 count)
{
	T* start = dest;
	while (count && (*dest++ = *source++) != 0) // copy string
		count--;

	if (count) // pad out with zeros
	{
		while (--count)
			*dest++ = 0;
	}
	return start;
}

inline tchar* tstrncpy (tchar* dest, const tchar* source, uint32 count) {return _tstrncpy (dest, source, count);}
inline char8* strncpy8 (char8* dest, const char8* source, uint32 count) {return _tstrncpy (dest, source, count);}
inline char16* strncpy16 (char16* dest, const char16* source, uint32 count) {return _tstrncpy (dest, source, count);}

//----------------------------------------------------------------------------
template <class T>
inline T* _tstrcat (T* dst, const T* src)
{
	T* cp = dst;

	while (*cp)
		cp++; // find end of dst

	while ((*cp++ = *src++) != 0) // Copy src to end of dst
		;

	return dst;
}

inline tchar* tstrcat (tchar* dst, const tchar* src) {return _tstrcat (dst, src); }
inline char8* strcat8 (char8* dst, const char8* src) {return _tstrcat (dst, src); }
inline char16* strcat16 (char16* dst, const char16* src) {return _tstrcat (dst, src); }

//----------------------------------------------------------------------------
inline void str8ToStr16 (char16* dst, const char8* src, int32 n = -1)
{
	int32 i = 0;
	for (;;)
	{
		if (i == n)
		{
			dst[i] = 0;
			return;
		}

#if BYTEORDER == kBigEndian
		char8* pChr = (char8*)&dst[i];
		pChr[0] = 0;
		pChr[1] = src[i];
#else
		dst[i] = src[i];
#endif

		if (src[i] == 0)
			break;

		i++;
	}

	while (n > i)
	{
		dst[i] = 0;
		i++;
	}
}

//------------------------------------------------------------------------
inline bool FIDStringsEqual (FIDString id1, FIDString id2)
{
	return (id1 && id2) ? (strcmp8 (id1, id2) == 0) : false;
}

static const uint32 kPrintfBufferSize = 4096;

//------------------------------------------------------------------------
} // namespace Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/icloneable.h
// Created by  : Steinberg, 11/2007
// Description : Interface for object copies
//
//-----------------------------------------------------------------------------
// 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 "funknown.h"

namespace Steinberg {

//------------------------------------------------------------------------
/**  Interface allowing an object to be copied.
[plug & host imp] \n
[released: N4.12] \n
*/
//------------------------------------------------------------------------
class ICloneable : public FUnknown
{
public:
//------------------------------------------------------------------------
	/** Create exact copy of the object */
	virtual FUnknown* PLUGIN_API clone () = 0;
//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (ICloneable, 0xD45406B9, 0x3A2D4443, 0x9DAD9BA9, 0x85A1454B)

//------------------------------------------------------------------------
} // namespace Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/conststringtable.h
// Created by  : Steinberg, 09/2007
// Description : constant unicode string table
//
//-----------------------------------------------------------------------------
// 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 "ftypes.h"

namespace Steinberg {

//------------------------------------------------------------------------
/**	Constant unicode string table.
Used for conversion from ASCII string literals to char16.
*/
//------------------------------------------------------------------------
class ConstStringTable
{
public:
	static ConstStringTable* instance ();

	/** Returns a char16 string of a ASCII string literal*/
	const char16* getString (const char8* str) const;
	/** Returns a char16 character of a ASCII character */
	const char16 getString (const char8 str) const;

protected:
	ConstStringTable ();
	~ConstStringTable ();
};

//------------------------------------------------------------------------
} // namespace Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : SDK Core Interfaces
// Filename    : pluginterfaces/base/falignpush.h
// Created by  : Steinberg, 01/2004
// Description : Set alignment settings
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------
#if TARGET_API_MAC_CARBON
	#if PLATFORM_64
		#pragma pack(push, 16)
	#else
		#pragma options align=mac68k
	#endif
#elif defined __BORLANDC__
	#pragma -a8
#elif WINDOWS
	#pragma pack(push)
	#if PLATFORM_64
		#pragma pack(16)
	#else
		#pragma pack(8)
	#endif
#endif
//----------------------------------------------------------------------------------------------