Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,106 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : SDK Core Interfaces
// Filename : pluginterfaces/base/conststringtable.cpp
// 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.
//-----------------------------------------------------------------------------
#include "conststringtable.h"
#include <cstring>
#include <map>
namespace Steinberg {
static std::map<const char8*, char16*>* stringMap;
static std::map<const char8, char16>* charMap;
static char16* generateUTF16 (const char8* str);
//----------------------------------------------------------------------------
ConstStringTable* ConstStringTable::instance ()
{
static ConstStringTable stringTable;
return &stringTable;
}
//----------------------------------------------------------------------------
const char16* ConstStringTable::getString (const char8* str) const
{
std::map<const char8*, char16*>::iterator iter = stringMap->find (str);
if (iter != stringMap->end ())
return iter->second;
char16* uStr = generateUTF16 (str);
stringMap->insert (std::make_pair (str, uStr));
return uStr;
}
//----------------------------------------------------------------------------
char16 ConstStringTable::getString (const char8 str) const
{
std::map<const char8, char16>::iterator iter = charMap->find (str);
if (iter != charMap->end ())
return iter->second;
char16 uStr = 0;
#if BYTEORDER == kBigEndian
char8* puStr = (char8*)&uStr;
puStr[1] = str;
#else
uStr = str;
#endif
charMap->insert (std::make_pair (str, uStr));
return uStr;
}
//----------------------------------------------------------------------------
ConstStringTable::ConstStringTable ()
{
stringMap = new std::map<const char8*, char16*>;
charMap = new std::map<const char8, char16>;
}
//----------------------------------------------------------------------------
ConstStringTable::~ConstStringTable ()
{
// free out allocated strings
{
std::map<const char8*, char16*>::iterator iter = stringMap->begin ();
while (iter != stringMap->end ())
{
delete[] iter->second;
iter++;
}
} // delete iterator on map before deleting the map
delete stringMap;
delete charMap;
}
//----------------------------------------------------------------------------
char16* generateUTF16 (const char8* str)
{
int32 len = (int32)strlen (str);
char16* result = new char16[len + 1];
for (int32 i = 0; i < len; i++)
{
#if BYTEORDER == kBigEndian
char8* pChr = (char8*)&result[i];
pChr[0] = 0;
pChr[1] = str[i];
#else
result[i] = str[i];
#endif
}
result[len] = 0;
return result;
}
//------------------------------------------------------------------------
} // namespace Steinberg
@@ -0,0 +1,44 @@
//-----------------------------------------------------------------------------
// 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 */
char16 getString (const char8 str) const;
protected:
ConstStringTable ();
~ConstStringTable ();
};
//------------------------------------------------------------------------
} // namespace Steinberg
+40
View File
@@ -0,0 +1,40 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : SDK Core Interface IID definitions
// Filename : pluginterfaces/base/coreiids.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.
// 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 "pluginterfaces/base/funknown.h"
#include "pluginterfaces/base/ibstream.h"
#include "pluginterfaces/base/icloneable.h"
#include "pluginterfaces/base/ipluginbase.h"
#include "pluginterfaces/base/iupdatehandler.h"
//------------------------------------------------------------------------
namespace Steinberg {
DEF_CLASS_IID (IPluginBase)
DEF_CLASS_IID (IPluginFactory)
DEF_CLASS_IID (IPluginFactory2)
DEF_CLASS_IID (IPluginFactory3)
DEF_CLASS_IID (FUnknown)
DEF_CLASS_IID (ICloneable)
DEF_CLASS_IID (IDependent)
DEF_CLASS_IID (IUpdateHandler)
DEF_CLASS_IID (IBStream)
DEF_CLASS_IID (ISizeableStream)
//------------------------------------------------------------------------
} // namespace Steinberg
+449
View File
@@ -0,0 +1,449 @@
//------------------------------------------------------------------------
// Project : SDK Core
//
// Category : Basic Host Service Interfaces
// Filename : pluginterfaces/base/doc.h
// Created by : Steinberg, 01/2004
// Description : doc for doxygen
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
/**
********************************************************************
\mainpage VST Module Architecture
********************************************************************
\tableofcontents
********************************************************************
\section piVstMa Introduction
********************************************************************
\b VST-MA is a component model system which is used in all <a href="http://www.steinberg.net" target=_blank>Steinberg</a> host applications
as the basic layer for plug-in support as well as for internal application components.\n
It is object-oriented, cross-platform and (almost) compiler-independent. \n
The basics are very much like Microsoft(R) COM, so if you are familiar with
this technology, understanding VST-MA should be quite easy.
\b VST-MA is provided in C++ only. Interfaces in C++ are expressed as pure virtual class
(which is a class with nothing but abstract methods). Unlike COM there is no support for C or other
languages yet - simply because there has been no need for this so far. But all \b VST-MA interfaces
can be transformed into different representations in case this should be inevitable some day. \n
It is currently available for Windows and Mac OS X.
The C++ files belonging to \b VST-MA are located in the following folders:
- <a href="../../pluginterfaces/base" target=_blank>pluginterfaces/base</a>
- <a href="../../pluginterfaces/gui" target=_blank>pluginterfaces/gui</a>
\b Note: The name 'VST Module Architecture' has only little relation to the 'Virtual Studio Technology' itself. \n
It describes the basic layer for any plug-in category supported in <a href="http://www.steinberg.net" target=_blank>Steinberg</a> hosts. \b VST-MA
existed long before it was used as a base for VST 3 ifself.
\n
\n
********************************************************************
\section piInterfaces Interfaces
********************************************************************
**********************************
\subsection funknown FUnknown
**********************************
Steinberg::FUnknown is the basic interface of \b VST-MA. All other interfaces are directly or
indirectly derived from it.
\n
\n
**********************************
\subsection iid IID/CID
**********************************
Each interface has a unique identifier (IID) of type Steinberg::FUID. It is used to retrieve a new
interface from another one (Steinberg::FUnknown::queryInterface). It is important to understand the
difference between interface identifier and component identifier.\n
A component-ID or class-ID (CID) is used to identify a concrete implementation class and is usually passed to a class factory in order
to create the corresponding component. \n
So a lot of different classes (with different class identifiers) can implement the same interfaces.
\n
\n
**********************************
\subsection direction Direction
**********************************
An interface may have a \b direction, meaning that the interface is expected to be
implemented either in the plug-in or in the host. The nature of an interface is documented like this:
\n \n
- <b>[host imp] </b>: the host implements the interface
- <b>[plug imp] </b>: the plug-in implements the interface
.
\n
When neither of these is specified, the interface can be used in both ways.
\n
\n
**********************************
\subsection version Versioning and inheritance
**********************************
Unlike C++ classes, interfaces do not use inheritance to express specializations of objects.
Inheritance is used for versioning only. One of the strict rules is, that once an interface has been
released, it must never change again. Adding new functionality to an interface requires a new version
(usually an ordinal number is added to its name in this case).\n
A new version inherits the old version(s)
of the interface, so the old and the new methods are combined in one interface. This is why specializations
need to be modeled as separate interfaces! If a specialized interface were to inherit from the basic interface
as well, an implementation class that needs to implement all of these interfaces would inherit the base
interface twice, causing the compiler to run into ambiguities. So the specialization relation
to a basic interface can only be expressed in the documentation: \n \n
- ISpecialInterface [\b extends IBaseInterface] => means IBaseInterface::queryInterface (ISpecialInterface::iid, ...) can be used to retrieve the derived
interface.
.
\n
You can find some example code here: \ref versionInheritance
\n
\n
**********************************
\subsection com COM Compatibility
**********************************
The first layer of \b VST-MA is binary-compatible to \b COM. The Vtable and interface identifier of
FUnknown match with the corresponding COM interface IUnknown. The main difference is the organization
and creation of components by a host application. \b VST-MA does not require any Microsoft(R) COM source file.
You can find information about \b COM on pages like: \n
- \htmlonly <a href="http://www.microsoft.com/Com/resources/comdocs.asp" target="_blank">http://www.microsoft.com/Com/resources/comdocs.asp</a>\endhtmlonly.
\n
\n
**********************************
\subsection basic Basic Interfaces
**********************************
- Steinberg::FUnknown
- Steinberg::IPluginBase
- Steinberg::IPluginFactory
.
\n
\n
**********************************
\subsection helper Helper Classes
**********************************
- Steinberg::FUID
- Steinberg::FUnknownPtr
.
\n
\see \ref howtoClass
\n
\n
********************************************************************
\section piPlugins Plug-ins
********************************************************************
**********************************
\subsection module Module Factory
**********************************
A module (Windows: Dynamic Link Library, MAC: Mach-O Bundle) contains the implementation
of one or more components (e.g. VST 3 effects). A \b VST-MA module must contain a class factory
where meta-data and create-methods for the components are registered. \n
The host has access to this factory through the Steinberg::IPluginFactory interface. This is the anchor point for the module
and it is realized as a C-style export function named GetPluginFactory. You can find an export
definition file in folder - <a href="../../public.sdk/win/stdplug.def" target=_blank>public.sdk/win/stdplug.def</a>
which can be used to export this function. \n
GetPluginFactory is declared as follows:
\code{.cpp}
IPluginFactory* PLUGIN_API GetPluginFactory ()
\endcode
\n
**********************************
\subsection Locations
**********************************
Component modules do not require registration like DirectX. The host application expects component modules to be located in predefined folders of the file system.
These folders and their subfolders are scanned for \b VST-MA modules during application startup. Each folder serves a special purpose:
- The application's \c Components subfolder (e.g. "C:\Program Files\Steinberg\Cubase SX\Components") is used for components tightly bound to the application. No other application should use it.
- Components that are shared between all <a href="http://www.steinberg.net" target=_blank>Steinberg</a> hosts are located at:
- Win: "/Program Files/Common Files/Steinberg/shared components"
- Mac: "/Library/Application Support/Steinberg/Components/"
- For special purpose plug-in types, additional locations can be defined. Please refer to the corresponding documentation to find out if additional folders are used and where to find them.
\n
\n
**********************************
\subsection Categories
**********************************
Any class that the factory can create is assigned to a category. It is this category that tells
the host the purpose of the class (and gives a hint of which interfaces it might implement). \n
A class is also described with a name and it has a unique id.
- For example, the category for import/export filters is <b>"Project Filter"</b> and for VST 3 audio plug-ins <b>"Audio Module Class"</b>.
- "Service" is a special category. The purpose of a class of this category is completely
unknown to the host. It is be loaded automatically during program start
(provided that the user did not deactivate it).
- Since the factory can create any number of classes, one component library can contain
multiple components of any type.
\n
\n
**********************************
\subsection IPluginBase
**********************************
The entry-point interface for any component class is Steinberg::IPluginBase. The host uses this
interface to initialize and to terminate the plug-in component. When the host initializes the
plug-in, it passes a so called context. This context contains any interface to the host that
the plug-in will need to work.
\n
\n
**********************************
\subsection purpose Purpose-specific interfaces
**********************************
Each plug-in category (VST 3 Effects, Project import/export Filters, Audio Codecs, etc...) defines its own set of purpose-specific interfaces. These are not part of the basic VST-MA layer.
\n
\n
\see \ref loadPlugin
\n
\n
********************************************************************
\section Unicode Unicode
********************************************************************
Beginning with version 5 of Cubase and Nuendo, the internal structure of the host was modified to
better support internationalization. Therefore, string handling was changed to utilize
<A HREF="http://en.wikipedia.org/wiki/Unicode">Unicode</A> strings whenever strings are passed
around. As a consequence, all the interfaces to plug-ins have changed from using ASCI to Unicode strings
for call and return parameters. So in turn, all plug-in must be adapted to support
Unicode. This has major consequences in that:
- Unicode hosts (Cubase 5 or later) will only work with Unicode plug-ins. When loading a plug-in,
a Unicode host checks the plug-in's type and will not load any non-Unicode plug-ins.
\n
- Unicode plug-ins will <b>not</b> load in non-Unicode hosts. When loading a Unicode plug-in
requests information from the host and will not load, if no Unicode host is detected.
Therefore, if a plug-in is supposed to work with both older and newer hosts, it is best to provide
two versions of the plug-in.
\n
\n
**********************************
\subsection plugunicode Plug-ins for Unicode hosts
**********************************
Writing plug-ins that are supposed to work only with Unicode hosts is easy. Use a current version
of this SDK and develop a plug-in as usual. Make sure that you only ever pass Unicode
<a href="http://en.wikipedia.org/wiki/UTF-16">UTF-16</a> strings to interfaces that
have strings as call parameters and also be prepared that strings returned by these interfaces are
always <a href="http://en.wikipedia.org/wiki/UTF-16">UTF-16</a>. Therefore, to make things easier, it is recommended that Unicode strings are used throughout the
plug-in's implementation, in order to avoid back and forth conversions.
Also, use the Steinberg::String and Steinberg::ConstString classes from
the Base module, they have been designed to work universally on both Mac and Win.
\n
\n
**********************************
\subsection migrating Migrating from non-Unicode to Unicode
**********************************
In <a href="http://www.steinberg.net" target="_blank">Steinberg</a> SDKs released before Cubase 5 the interface functions were using pointers of type <c> char </c>
for passing strings to and from the host. These have been changed now to using Steinberg's defined
type <c> tchar </c> which is equivalent to <c> char16 </c>, i.e. 16 bit character. In theory, there are
many ways for representing 16 bits characters, but we chose
to use the industry standard <a href="http://en.wikipedia.org/wiki/Unicode">Unicode</a>, so strings
are expected to be encoded in <a href="http://en.wikipedia.org/wiki/UTF-16">UTF-16</a>. \n
Accordingly, also the implementation of a plug-in needs to be adapted to deal correctly with Unicode
encoded strings, as well as only ever passing Unicode strings to the host.
\n
\n
<b>Technical note</b>: Changing a function from using 8 bit to 16 bit character pointers may seem as only a
minor modification, but in interface design this is a major intrusion, because an interface is
a contract to the outside world that is never to be changed. Therefore, classes that are changed
to use Unicode strings are distinguished and also receive a new unique class ID.
\n
\n
**********************************
\subsection backward SDK backward compatibility
**********************************
Even with the current SDK it is still possible to develop non-Unicode plug-ins. In the
file <a href="../../pluginterfaces/base/ftypes.h">pluginterfaces/base/ftypes.h</a>, the line "#define UNICODE_OFF"
is commented out, by uncommenting it you can revert all interfaces to using single byte ASCII strings.
Alternatively you can also specify UNICODE_OFF as a preprocessor definition in your project file.\n
Also, the plug-in's factory info now does not define the Unicode flag anymore, so a Unicode host sees the compiled
plug-in as non-Unicode. Also, when reverting to single byte strings the plug-in's implementation also
has to be changed to behave correctly.
\n
\n
<b>Technical note</b>: When undefining Unicode, the class IDs also revert to the old ones.
\n
\n
*/
//******************************************************
/**
\page howtoClass How to derive a class from an interface
*********************************************************
In the first example we derive a class directly from FUnknown, using some of the helper macros provided by the SDK.
\code{.cpp}
class CMyClass: public FUnknown
{
public:
CMyClass ();
virtual ~CMyClass ();
DECLARE_FUNKNOWN_METHODS // declares queryInterface, addRef and release
};
CMyClass::CMyClass ()
{
FUNKNOWN_CTOR // init reference counter, increment global object counter
}
CMyClass::~CMyClass ()
{
FUNKNOWN_DTOR // decrement global object counter
}
IMPLEMENT_REFCOUNT (CMyClass) // implements reference counting
tresult CMyClass::queryInterface (const char* iid, void** obj)
{
QUERY_INTERFACE (iid, obj, ::FUnknown::iid, CMyClass)
return kNoInterface;
}
\endcode
Developing a class with more than one interface is done by multiple inheritance. Additionally you have to provide an appropriate cast for each interface in the queryInterface method.
\code{.cpp}
class CMyMultiClass : public Steinberg::IPluginBase,
public Steinberg::IPlugController,
public Steinberg::IEditorFactory
{
public:
DECLARE_FUNKNOWN_METHODS
// declare the methods of all inherited interfaces here...
};
IMPLEMENT_REFCOUNT (CMyMultiClass) // implements reference counting
tresult CMyMultiClass::queryInterface (const char* iid, void** obj)
{
QUERY_INTERFACE (iid, obj, Steinberg::FUnknown::iid, IPluginBase)
QUERY_INTERFACE (iid, obj, Steinberg::IPluginBase::iid, IPluginBase)
QUERY_INTERFACE (iid, obj, Steinberg::IPlugController::iid, IPlugController)
QUERY_INTERFACE (iid, obj, Steinberg::IEditorFactory::iid, IEditorFactory)
*obj = 0;
return kNoInterface;
}
\endcode
*/
//********************************************************************
/** \page versionInheritance Interface Versions and Inheritance
********************************************************************
\par
Unlike C++ classes, \b VST-MA interfaces do not use inheritance to express
specializations of objects. Usually all interfaces are derived from
FUnknown. This is because interfaces must \b never change after they
have been released. The VST Module Architecture Interfaces use inheritance
only for versioning! All specializations will be modeled as
separate interfaces!
For example the C++ classes
\code{.cpp}
class Shape
{
public:
void setPosition (long x, long y);
protected:
long x;
long y;
};
class Rect : public Shape
{
public:
void setDimension (long width, long height);
protected:
long width;
long height;
};
\endcode
expressed in \b VST-MA, define an interface for each inheritance level:
\code{.cpp}
class IShape : public FUnknown
{
public:
virtual void setPosition (long x, long y) = 0;
};
class IRect : public FUnknown
{
public:
virtual void setDimension (long width, long height) = 0;
};
\endcode
In the next program version there need to be changes to
the \c Shape class that look like this:
\code{.cpp}
class Shape
{
public:
void setPosition (long x, long y);
void setColor (Color color);
protected:
long x;
long y;
Color color;
};
\endcode
The \b VST-MA representation now reflect the changes to Shape by adding a
new interface that inherits from IShape and looks like the following
code, while the former interface definitions remain the same:
\code{.cpp}
class IShape2 : public IShape
{
public:
virtual void setColor (Color color) = 0;
};
\endcode
*/
//********************************************************************
/** \page loadPlugin How the host will load a plug-in
********************************************************************
\par
The host application will handle a plug-in in the following manner
(some code is Windows-specific!):
\code{.cpp}
HMODULE hModule = LoadLibrary ("SomePlugin.dll");
if (hModule)
{
InitModuleProc initProc = (InitModuleProc)GetProcAddress (hModule, "InitDll");
if (initProc)
{
if (initProc () == false)
{
FreeLibrary (module);
return false;
}
}
GetFactoryProc proc = (GetFactoryProc)GetProcAddress (hModule, "GetPluginFactory");
IPluginFactory* factory = proc ? proc () : 0;
if (factory)
{
for (int32 i = 0; i < factory->countClasses (); i++)
{
PClassInfo ci;
factory->getClassInfo (i, &ci);
FUnknown* obj;
factory->createInstance (ci.cid, FUnknown::iid, (void**)&obj);
...
obj->release ();
}
factory->release ();
}
ExitModuleProc exitProc = (ExitModuleProc)GetProcAddress (hModule, "ExitDll");
if (exitProc)
exitProc ();
FreeLibrary (hModule);
}
\endcode
*/
+27
View File
@@ -0,0 +1,27 @@
//-----------------------------------------------------------------------------
// 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 SMTG_OS_MACOS
#pragma pack(pop)
#elif defined __BORLANDC__
#pragma -a-
#elif SMTG_OS_WINDOWS
#pragma pack(pop)
#elif SMTG_OS_LINUX
#pragma pack(pop)
#endif
//---------------------------------------------------------------------------------------------------
+46
View File
@@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// 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 SMTG_OS_MACOS
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#pragma GCC diagnostic ignored "-Wpragma-pack"
#if SMTG_PLATFORM_64
#pragma pack(push, 16)
#else
#pragma pack(push, 1)
#endif
#elif defined __BORLANDC__
#pragma -a8
#elif SMTG_OS_WINDOWS
//! @brief warning C4103: alignment changed after including header, may be due to missing #pragma pack(pop)
#ifdef _MSC_VER
#pragma warning(disable : 4103)
#endif
#pragma pack(push)
#if SMTG_PLATFORM_64
#pragma pack(16)
#else
#pragma pack(8)
#endif
#elif SMTG_OS_LINUX
#if SMTG_PLATFORM_64
#pragma pack(push, 16)
#else
#pragma pack(push, 8)
#endif
#endif
//----------------------------------------------------------------------------------------------
+333
View File
@@ -0,0 +1,333 @@
//-----------------------------------------------------------------------------
// 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
// values for BYTEORDER according to the used platform
#define kLittleEndian 0
#define kBigEndian 1
#undef PLUGIN_API
#if !defined (__INTEL_CXX11_MODE__)
#define SMTG_INTEL_CXX11_MODE 0
#else
#define SMTG_INTEL_CXX11_MODE __INTEL_CXX11_MODE__
#endif
#if !defined (__INTEL_COMPILER)
#define SMTG_INTEL_COMPILER 0
#else
#define SMTG_INTEL_COMPILER __INTEL_COMPILER
#endif
//-----------------------------------------------------------------------------
// WIN32 AND WIN64 (WINDOWS)
//-----------------------------------------------------------------------------
#if defined (_WIN32)
//-----------------------------------------------------------------------------
#define SMTG_OS_LINUX 0
#define SMTG_OS_MACOS 0
#define SMTG_OS_WINDOWS 1
#define SMTG_OS_IOS 0
#define SMTG_OS_OSX 0
#if defined (_M_IX86)
#define SMTG_CPU_X86 1
#else
#define SMTG_CPU_X86 0
#endif
#if defined (_M_AMD64) // expected: "&& !defined(_M_ARM64EC)", but performance with IPP is better than native ARM code
#define SMTG_CPU_X86_64 1
#else
#define SMTG_CPU_X86_64 0
#endif
#if defined (_M_ARM)
#define SMTG_CPU_ARM 1
#else
#define SMTG_CPU_ARM 0
#endif
#if defined (_M_ARM64)
#define SMTG_CPU_ARM_64 1
#else
#define SMTG_CPU_ARM_64 0
#endif
#if defined (_M_ARM64EC)
#define SMTG_CPU_ARM_64EC 1
#else
#define SMTG_CPU_ARM_64EC 0
#endif
#define SMTG_OS_WINDOWS_ARM (SMTG_CPU_ARM_64EC || SMTG_CPU_ARM_64 || SMTG_CPU_ARM)
#define BYTEORDER kLittleEndian
#define COM_COMPATIBLE 1
#define PLUGIN_API __stdcall
#define SMTG_PTHREADS 0
#define SMTG_EXPORT_SYMBOL __declspec (dllexport)
#define SMTG_HIDDEN_SYMBOL
#ifdef _MSC_VER
#if !defined (SMTG_DISABLE_DEFAULT_DIAGNOSTICS)
#pragma warning (disable : 4244) //! @brief warning C4244: Conversion from 'type1' to 'type2', possible loss of data.
#pragma warning (disable : 4250) //! @brief warning C4250: Inheritance via dominance is allowed
#pragma warning (3 : 4189) //! @brief warning C4189: local variable is initialized but not referenced
#pragma warning (3 : 4238) //! @brief warning C4238: nonstandard extension used: class rvalue used as lvalue
#endif
#endif // _MSC_VER
#if defined (_WIN64) || defined (_M_ARM64)
#define SMTG_PLATFORM_64 1
#else
#define SMTG_PLATFORM_64 0
#endif
#ifndef WIN32
#define WIN32 1
#endif
#ifdef __cplusplus
#define SMTG_CPP11 (__cplusplus >= 201103L || _MSC_VER > 1600 || SMTG_INTEL_CXX11_MODE)
#define SMTG_CPP11_STDLIBSUPPORT SMTG_CPP11
#define SMTG_CPP14 (__cplusplus >= 201402L || ((_MSC_FULL_VER >= 190024210L) && (_MSVC_LANG >= 201402L)))
#define SMTG_CPP17 (__cplusplus >= 201703L || ((_MSC_FULL_VER >= 190024210L) && (_MSVC_LANG >= 201703L)))
#define SMTG_CPP20 (__cplusplus >= 202002L)
#define SMTG_CPP23 (__cplusplus >= 202302L)
#define SMTG_HAS_NOEXCEPT ((_MSC_FULL_VER >= 190023026L) || (SMTG_INTEL_CXX11_MODE && SMTG_INTEL_COMPILER >= 1300))
#if ((_MSC_FULL_VER >= 190024210L) || (SMTG_INTEL_CXX11_MODE && SMTG_INTEL_COMPILER >= 1500) || (defined (__MINGW32__) && SMTG_CPP11))
#define SMTG_HAS_CPP11_CONSTEXPR 1
#else
#define SMTG_HAS_CPP11_CONSTEXPR 0
#endif
#if (((_MSC_VER >= 1915L) && (_MSVC_LANG >= 201402L)) || (SMTG_INTEL_CXX11_MODE && SMTG_INTEL_COMPILER > 1700) || (defined (__MINGW32__) && SMTG_CPP14))
#define SMTG_HAS_CPP14_CONSTEXPR 1
#else
#define SMTG_HAS_CPP14_CONSTEXPR 0
#endif
#endif //__cplusplus
#define SMTG_DEPRECATED_ATTRIBUTE(message) __declspec (deprecated ("Is Deprecated: " message))
//-----------------------------------------------------------------------------
// LINUX
//-----------------------------------------------------------------------------
#elif (defined (__gnu_linux__) && __gnu_linux__) || (defined (__linux__) && __linux__)
#define SMTG_OS_LINUX 1
#define SMTG_OS_MACOS 0
#define SMTG_OS_WINDOWS 0
#define SMTG_OS_WINDOWS_ARM 0
#define SMTG_OS_IOS 0
#define SMTG_OS_OSX 0
#define SMTG_CPU_X86 __i386__
#define SMTG_CPU_X86_64 __x86_64__
#if defined (__arm__)
#define SMTG_CPU_ARM __arm__
#else
#define SMTG_CPU_ARM 0
#endif
#if defined (__aarch64__)
#define SMTG_CPU_ARM_64 __aarch64__
#else
#define SMTG_CPU_ARM_64 0
#endif
#define SMTG_CPU_ARM_64EC 0
#include <endian.h>
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define BYTEORDER kLittleEndian
#else
#define BYTEORDER kBigEndian
#endif
#define COM_COMPATIBLE 0
#define PLUGIN_API
#define SMTG_PTHREADS 1
#define SMTG_EXPORT_SYMBOL __attribute__ ((visibility ("default")))
#define SMTG_HIDDEN_SYMBOL __attribute__ ((visibility ("hidden")))
#if __LP64__
#define SMTG_PLATFORM_64 1
#else
#define SMTG_PLATFORM_64 0
#endif
#ifdef __cplusplus
#include <cstddef>
#define SMTG_CPP11 (__cplusplus >= 201103L)
#ifndef SMTG_CPP11
#error unsupported compiler
#endif
#define SMTG_CPP14 (__cplusplus >= 201402L)
#define SMTG_CPP17 (__cplusplus >= 201703L)
#define SMTG_CPP20 (__cplusplus >= 202002L)
#define SMTG_CPP23 (__cplusplus >= 202302L)
#if defined (__GNUG__) && __GNUG__ < 8
#define SMTG_CPP11_STDLIBSUPPORT 0
#else
#define SMTG_CPP11_STDLIBSUPPORT 1
#endif
#define SMTG_HAS_NOEXCEPT 1
#define SMTG_HAS_CPP11_CONSTEXPR SMTG_CPP11
#define SMTG_HAS_CPP14_CONSTEXPR SMTG_CPP14
#endif // __cplusplus
//-----------------------------------------------------------------------------
// Mac and iOS
//-----------------------------------------------------------------------------
#elif __APPLE__
#include <TargetConditionals.h>
#define SMTG_OS_LINUX 0
#define SMTG_OS_MACOS 1
#define SMTG_OS_WINDOWS 0
#define SMTG_OS_WINDOWS_ARM 0
#define SMTG_OS_IOS TARGET_OS_IPHONE
#define SMTG_OS_OSX TARGET_OS_MAC && !TARGET_OS_IPHONE
#define SMTG_CPU_X86 TARGET_CPU_X86
#define SMTG_CPU_X86_64 TARGET_CPU_X86_64
#define SMTG_CPU_ARM TARGET_CPU_ARM
#define SMTG_CPU_ARM_64 TARGET_CPU_ARM64
#define SMTG_CPU_ARM_64EC 0
#if !SMTG_OS_IOS
#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 SMTG_PLATFORM_64 1
#else
#define SMTG_PLATFORM_64 0
#endif
#if defined (__BIG_ENDIAN__)
#define BYTEORDER kBigEndian
#else
#define BYTEORDER kLittleEndian
#endif
#define COM_COMPATIBLE 0
#define PLUGIN_API
#define SMTG_PTHREADS 1
#define SMTG_EXPORT_SYMBOL __attribute__ ((visibility ("default")))
#define SMTG_HIDDEN_SYMBOL __attribute__ ((visibility ("hidden")))
#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 || SMTG_INTEL_CXX11_MODE)
#define SMTG_CPP14 (__cplusplus >= 201402L)
#define SMTG_CPP17 (__cplusplus >= 201703L)
#define SMTG_CPP20 (__cplusplus >= 202002L)
#define SMTG_CPP23 (__cplusplus >= 202302L)
#if defined (_LIBCPP_VERSION) && SMTG_CPP11
#define SMTG_CPP11_STDLIBSUPPORT 1
#define SMTG_HAS_NOEXCEPT 1
#else
#define SMTG_CPP11_STDLIBSUPPORT 0
#define SMTG_HAS_NOEXCEPT 0
#endif
#define SMTG_HAS_CPP11_CONSTEXPR SMTG_CPP11
#define SMTG_HAS_CPP14_CONSTEXPR SMTG_CPP14
#endif // __cplusplus
//-----------------------------------------------------------------------------
// Unknown Platform
//-----------------------------------------------------------------------------
#else
#pragma error unknown platform
#endif
//-----------------------------------------------------------------------------
#if !SMTG_RENAME_ASSERT
#undef WINDOWS
#undef MAC
#undef PTHREADS
#undef PLATFORM_64
#if SMTG_OS_WINDOWS
#define WINDOWS SMTG_OS_WINDOWS
#endif
#if SMTG_OS_MACOS
#define MAC SMTG_OS_MACOS
#endif
#define PLATFORM_64 SMTG_PLATFORM_64
#define PTHREADS SMTG_PTHREADS
#endif
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#if SMTG_CPP11
#define SMTG_OVERRIDE override
#else
#define SMTG_OVERRIDE
#endif
#if SMTG_HAS_CPP11_CONSTEXPR
#define SMTG_CONSTEXPR constexpr
#else
#define SMTG_CONSTEXPR
#endif
#if SMTG_HAS_CPP14_CONSTEXPR
#define SMTG_CONSTEXPR14 constexpr
#else
#define SMTG_CONSTEXPR14
#endif
#if SMTG_HAS_NOEXCEPT
#define SMTG_NOEXCEPT noexcept
#else
#define SMTG_NOEXCEPT
#endif
//-----------------------------------------------------------------------------
// Deprecation setting
//-----------------------------------------------------------------------------
#ifndef SMTG_DEPRECATED_ATTRIBUTE
#if SMTG_CPP17
#define SMTG_DEPRECATED_ATTRIBUTE(msg) [[deprecated(msg)]]
#else
#define SMTG_DEPRECATED_ATTRIBUTE(msg)
#endif
#endif
#define SMTG_DEPRECATED_MSG(msg) SMTG_DEPRECATED_ATTRIBUTE(msg)
//-----------------------------------------------------------------------------
+293
View File
@@ -0,0 +1,293 @@
//-----------------------------------------------------------------------------
// 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
#define STR16(x) SMTG_CPP11_CAT_PRIVATE_DONT_USE(u,x)
#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 SMTG_OS_WINDOWS
#define FORMAT_INT64A "I64d"
#define FORMAT_UINT64A "I64u"
#elif SMTG_OS_MACOS || SMTG_OS_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 SMTG_OS_WINDOWS
#define ENDLINE_A "\r\n"
#define ENDLINE_W STR ("\r\n")
#elif SMTG_OS_MACOS
#define ENDLINE_A "\r"
#define ENDLINE_W STR ("\r")
#elif SMTG_OS_LINUX
#define ENDLINE_A "\n"
#define ENDLINE_W STR ("\n")
#endif
#ifdef UNICODE
#define ENDLINE ENDLINE_W
#else
#define ENDLINE ENDLINE_A
#endif
#if SMTG_OS_WINDOWS && !defined(__GNUC__) && defined(_MSC_VER)
#define stricmp _stricmp
#define strnicmp _strnicmp
#if (_MSC_VER < 1900)
#define snprintf _snprintf
#endif
#endif
namespace Steinberg {
//----------------------------------------------------------------------------
static SMTG_CONSTEXPR const tchar kEmptyString[] = { 0 };
static SMTG_CONSTEXPR const char8 kEmptyString8[] = { 0 };
static SMTG_CONSTEXPR const char16 kEmptyString16[] = { 0 };
#ifdef UNICODE
static SMTG_CONSTEXPR const tchar kInfiniteSymbol[] = { 0x221E, 0 };
#else
static SMTG_CONSTEXPR const tchar* const kInfiniteSymbol = STR ("oo");
#endif
//----------------------------------------------------------------------------
template <class T>
inline SMTG_CONSTEXPR14 int32 _tstrlen (const T* wcs)
{
const T* eos = wcs;
while (*eos++)
;
return (int32) (eos - wcs - 1);
}
inline SMTG_CONSTEXPR14 int32 tstrlen (const tchar* str) {return _tstrlen (str);}
inline SMTG_CONSTEXPR14 int32 strlen8 (const char8* str) {return _tstrlen (str);}
inline SMTG_CONSTEXPR14 int32 strlen16 (const char16* str) {return _tstrlen (str);}
//----------------------------------------------------------------------------
template <class T>
inline SMTG_CONSTEXPR14 int32 _tstrcmp (const T* src, const T* dst)
{
while (*src == *dst && *dst)
{
src++;
dst++;
}
if (*src == 0 && *dst == 0)
return 0;
if (*src == 0)
return -1;
if (*dst == 0)
return 1;
return (int32) (*src - *dst);
}
inline SMTG_CONSTEXPR14 int32 tstrcmp (const tchar* src, const tchar* dst) {return _tstrcmp (src, dst);}
inline SMTG_CONSTEXPR14 int32 strcmp8 (const char8* src, const char8* dst) {return _tstrcmp (src, dst);}
inline SMTG_CONSTEXPR14 int32 strcmp16 (const char16* src, const char16* dst) {return _tstrcmp (src, dst);}
template <typename T>
inline SMTG_CONSTEXPR14 int32 strcmpT (const T* first, const T* last);
template <>
inline SMTG_CONSTEXPR14 int32 strcmpT<char8> (const char8* first, const char8* last) { return _tstrcmp (first, last); }
template <>
inline SMTG_CONSTEXPR14 int32 strcmpT<char16> (const char16* first, const char16* last) { return _tstrcmp (first, last); }
//----------------------------------------------------------------------------
template <class T>
inline SMTG_CONSTEXPR14 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;
if (*first == 0)
return -1;
if (*last == 0)
return 1;
return (int32) (*first - *last);
}
inline SMTG_CONSTEXPR14 int32 tstrncmp (const tchar* first, const tchar* last, uint32 count) {return _tstrncmp (first, last, count);}
inline SMTG_CONSTEXPR14 int32 strncmp8 (const char8* first, const char8* last, uint32 count) {return _tstrncmp (first, last, count);}
inline SMTG_CONSTEXPR14 int32 strncmp16 (const char16* first, const char16* last, uint32 count) {return _tstrncmp (first, last, count);}
template <typename T>
inline SMTG_CONSTEXPR14 int32 strncmpT (const T* first, const T* last, uint32 count);
template <>
inline SMTG_CONSTEXPR14 int32 strncmpT<char8> (const char8* first, const char8* last, uint32 count) { return _tstrncmp (first, last, count); }
template <>
inline SMTG_CONSTEXPR14 int32 strncmpT<char16> (const char16* first, const char16* last, uint32 count) {return _tstrncmp (first, last, count); }
//----------------------------------------------------------------------------
template <class T>
inline SMTG_CONSTEXPR14 T* _tstrcpy (T* dst, const T* src)
{
T* cp = dst;
while ((*cp++ = *src++) != 0) // copy string
;
return dst;
}
inline SMTG_CONSTEXPR14 tchar* tstrcpy (tchar* dst, const tchar* src) {return _tstrcpy (dst, src);}
inline SMTG_CONSTEXPR14 char8* strcpy8 (char8* dst, const char8* src) {return _tstrcpy (dst, src);}
inline SMTG_CONSTEXPR14 char16* strcpy16 (char16* dst, const char16* src) {return _tstrcpy (dst, src);}
//----------------------------------------------------------------------------
template <class T>
inline SMTG_CONSTEXPR14 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 SMTG_CONSTEXPR14 tchar* tstrncpy (tchar* dest, const tchar* source, uint32 count) {return _tstrncpy (dest, source, count);}
inline SMTG_CONSTEXPR14 char8* strncpy8 (char8* dest, const char8* source, uint32 count) {return _tstrncpy (dest, source, count);}
inline SMTG_CONSTEXPR14 char16* strncpy16 (char16* dest, const char16* source, uint32 count) {return _tstrncpy (dest, source, count);}
//----------------------------------------------------------------------------
template <class T>
inline SMTG_CONSTEXPR14 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 SMTG_CONSTEXPR14 tchar* tstrcat (tchar* dst, const tchar* src) {return _tstrcat (dst, src); }
inline SMTG_CONSTEXPR14 char8* strcat8 (char8* dst, const char8* src) {return _tstrcat (dst, src); }
inline SMTG_CONSTEXPR14 char16* strcat16 (char16* dst, const char16* src) {return _tstrcat (dst, src); }
//----------------------------------------------------------------------------
inline SMTG_CONSTEXPR14 void str8ToStr16 (char16* dst, const char8* src, int32 n = -1)
{
int32 i = 0;
for (;;)
{
if (i == (n - 1))
{
dst[i] = 0;
return;
}
#if BYTEORDER == kBigEndian
char8* pChr = (char8*)&dst[i];
pChr[0] = 0;
pChr[1] = src[i];
#else
dst[i] = static_cast<char16> (src[i]);
#endif
if (src[i] == 0)
break;
i++;
}
while (n > i)
{
dst[i] = 0;
i++;
}
}
//------------------------------------------------------------------------
inline SMTG_CONSTEXPR14 bool FIDStringsEqual (FIDString id1, FIDString id2)
{
return (id1 && id2) ? (strcmp8 (id1, id2) == 0) : false;
}
static SMTG_CONSTEXPR const uint32 kPrintfBufferSize = 4096;
#if SMTG_OS_WINDOWS
/* cast between wchar_t and char16 */
inline wchar_t* wscast (char16* s) { static_assert (sizeof (wchar_t) == sizeof (char16), ""); return reinterpret_cast<wchar_t*> (s); }
inline char16* wscast (wchar_t* s) { static_assert (sizeof (wchar_t) == sizeof (char16), ""); return reinterpret_cast<char16*> (s);}
inline const wchar_t* wscast (const char16* s) { static_assert (sizeof (wchar_t) == sizeof (char16), ""); return reinterpret_cast<const wchar_t*> (s); }
inline const char16* wscast (const wchar_t* s) { static_assert (sizeof (wchar_t) == sizeof (char16), ""); return reinterpret_cast<const char16*> (s); }
#endif
//------------------------------------------------------------------------
} // namespace Steinberg
+183
View File
@@ -0,0 +1,183 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : SDK Core Interfaces
// Filename : pluginterfaces/base/ftypes.h
// Created by : Steinberg, 01/2004
// Description : Basic data types
//
//-----------------------------------------------------------------------------
// 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 "fplatform.h"
#include <cstdint>
//#define UNICODE_OFF // disable / enable unicode
#ifdef UNICODE_OFF
#ifdef UNICODE
#undef UNICODE
#endif
#else
#define UNICODE 1
#endif
#ifdef UNICODE
#define _UNICODE 1
#endif
namespace Steinberg
{
//-----------------------------------------------------------------
/** Integral Types
* \defgroup smtgtypedef Steinberg Data Types
* Data Types defined by Steinberg SDK
* @{
*/
typedef char int8;
typedef uint8_t uint8;
typedef unsigned char uchar;
typedef int16_t int16;
typedef uint16_t uint16;
typedef int32_t int32;
typedef uint32_t uint32;
static const int32 kMaxInt32 = INT32_MAX;
static const int32 kMinInt32 = INT32_MIN;
static const int32 kMaxLong = kMaxInt32;
static const int32 kMinLong = kMinInt32;
static const uint32 kMaxInt32u = UINT32_MAX;
typedef int64_t int64;
typedef uint64_t uint64;
static const int64 kMaxInt64 = INT64_MAX;
static const int64 kMinInt64 = INT64_MIN;
static const uint64 kMaxInt64u = UINT64_MAX;
//-----------------------------------------------------------------
// other Semantic Types
typedef int64 TSize; // byte (or other) sizes
typedef int32 tresult; // result code
//-----------------------------------------------------------------
static const float kMaxFloat = 3.40282346638528860E38;
static const double kMaxDouble = 1.7976931348623158E308;
#if SMTG_PLATFORM_64
typedef uint64 TPtrInt;
#else
typedef uint32 TPtrInt;
#endif
//------------------------------------------------------------------
// Boolean
typedef uint8 TBool;
//------------------------------------------------------------------
// Char / Strings
typedef char char8;
typedef char16_t char16;
#ifdef UNICODE
typedef char16 tchar;
#else
typedef char8 tchar;
#endif
typedef const char8* CStringA;
typedef const char16* CStringW;
typedef const tchar* CString;
inline bool strEmpty (const tchar* str) { return (!str || *str == 0); }
inline bool str8Empty (const char8* str) { return (!str || *str == 0); }
inline bool str16Empty (const char16* str) { return (!str || *str == 0); }
typedef const char8* FIDString; // identifier as string (used for attributes, messages)
const FIDString kPlatformStringWin = "WIN";
const FIDString kPlatformStringMac = "MAC";
const FIDString kPlatformStringIOS = "IOS";
const FIDString kPlatformStringLinux = "Linux";
#if SMTG_OS_WINDOWS
const FIDString kPlatformString = kPlatformStringWin;
#elif SMTG_OS_IOS
const FIDString kPlatformString = kPlatformStringIOS;
#elif SMTG_OS_MACOS
const FIDString kPlatformString = kPlatformStringMac;
#elif SMTG_OS_LINUX
const FIDString kPlatformString = kPlatformStringLinux;
#endif
//------------------------------------------------------------------------
/** Coordinates */
typedef int32 UCoord;
static const UCoord kMaxCoord = ((UCoord)0x7FFFFFFF);
static const UCoord kMinCoord = ((UCoord)-0x7FFFFFFF);
/**@}*/
//----------------------------------------------------------------------------
} // namespace Steinberg
//----------------------------------------------------------------------------
/** Byte-order Conversion Macros
*/
#define SWAP_32(l) { \
unsigned char* p = (unsigned char*)& (l); \
unsigned char t; \
t = p[0]; p[0] = p[3]; p[3] = t; t = p[1]; p[1] = p[2]; p[2] = t; }
#define SWAP_16(w) { \
unsigned char* p = (unsigned char*)& (w); \
unsigned char t; \
t = p[0]; p[0] = p[1]; p[1] = t; }
#define SWAP_64(i) { \
unsigned char* p = (unsigned char*)& (i); \
unsigned char t; \
t = p[0]; p[0] = p[7]; p[7] = t; t = p[1]; p[1] = p[6]; p[6] = t; \
t = p[2]; p[2] = p[5]; p[5] = t; t = p[3]; p[3] = p[4]; p[4] = t;}
namespace Steinberg
{
static inline void FSwap (int8&) {}
static inline void FSwap (uint8&) {}
static inline void FSwap (int16& i16) { SWAP_16 (i16) }
static inline void FSwap (uint16& i16) { SWAP_16 (i16) }
static inline void FSwap (int32& i32) { SWAP_32 (i32) }
static inline void FSwap (uint32& i32) { SWAP_32 (i32) }
static inline void FSwap (int64& i64) { SWAP_64 (i64) }
static inline void FSwap (uint64& i64) { SWAP_64 (i64) }
}
// always inline macros (only when RELEASE is 1)
//----------------------------------------------------------------------------
#if defined(RELEASE) && RELEASE
#if SMTG_OS_MACOS || SMTG_OS_LINUX || defined(__MINGW32__)
#define SMTG_ALWAYS_INLINE __inline__ __attribute__((__always_inline__))
#define SMTG_NEVER_INLINE __attribute__((noinline))
#elif SMTG_OS_WINDOWS
#define SMTG_ALWAYS_INLINE __forceinline
#define SMTG_NEVER_INLINE __declspec(noinline)
#endif
#endif
#ifndef SMTG_ALWAYS_INLINE
#define SMTG_ALWAYS_INLINE inline
#endif
#ifndef SMTG_NEVER_INLINE
#define SMTG_NEVER_INLINE
#endif
#ifndef SMTG_CPP11_STDLIBSUPPORT
// Enable this for old compilers
// #define nullptr NULL
#endif
+494
View File
@@ -0,0 +1,494 @@
//-----------------------------------------------------------------------------
// 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 <cstdio>
#if SMTG_OS_WINDOWS
#include <objbase.h>
#elif SMTG_OS_MACOS
#include <CoreFoundation/CoreFoundation.h>
#if !defined (SMTG_USE_STDATOMIC_H)
#if defined(MAC_OS_X_VERSION_10_11) && defined(MAC_OS_X_VERSION_MIN_REQUIRED)
#define SMTG_USE_STDATOMIC_H (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_11)
#else
#define SMTG_USE_STDATOMIC_H 0
#endif
#endif // !defined (SMTG_USE_STDATOMIC_H)
#if !SMTG_USE_STDATOMIC_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 // !SMTG_USE_STDATOMIC_H
#endif // SMTG_OS_MACOS
#if SMTG_OS_LINUX
#if !defined (SMTG_USE_STDATOMIC_H)
#if defined (__ANDROID__) || defined(_LIBCPP_VERSION)
#define SMTG_USE_STDATOMIC_H 1
#else
#include <ext/atomicity.h>
#endif
#endif // !defined (SMTG_USE_STDATOMIC_H)
#include <stdlib.h>
#endif
#if defined (SMTG_USE_STDATOMIC_H) && SMTG_USE_STDATOMIC_H
#include <stdatomic.h>
#endif
namespace Steinberg {
//------------------------------------------------------------------------
#if COM_COMPATIBLE
#if SMTG_OS_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 SMTG_USE_STDATOMIC_H
return atomic_fetch_add (reinterpret_cast<atomic_int_least32_t*> (&var), d) + d;
#else
#if SMTG_OS_WINDOWS
#ifdef __MINGW32__
return InterlockedExchangeAdd (reinterpret_cast<long volatile*>(&var), d) + d;
#else
return InterlockedExchangeAdd ((LONG*)&var, d) + d;
#endif
#elif SMTG_OS_MACOS
return OSAtomicAdd32Barrier (d, (int32_t*)&var);
#elif defined(__ANDROID__)
return atomic_fetch_add ((atomic_int*)&var, d) + d;
#elif SMTG_OS_LINUX
__gnu_cxx::__atomic_add (&var, d);
return var;
#else
#warning implement me!
var += d;
return var;
#endif
#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 SMTG_OS_WINDOWS
GUID guid;
HRESULT hr = CoCreateGuid (&guid);
switch (hr)
{
case RPC_S_OK: memcpy (data, (char*)&guid, sizeof (TUID)); return true;
case (HRESULT)RPC_S_UUID_LOCAL_ONLY:
default: return false;
}
#elif SMTG_OS_MACOS
CFUUIDRef uuid = CFUUIDCreate (kCFAllocatorDefault);
if (uuid)
{
CFUUIDBytes bytes = CFUUIDGetUUIDBytes (uuid);
memcpy (data, (char*)&bytes, sizeof (TUID));
CFRelease (uuid);
return true;
}
return false;
#elif SMTG_OS_LINUX
srand ((size_t)this);
for (int32 i = 0; i < 16; i++)
data[i] = static_cast<unsigned char>(rand ());
return true;
#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;
}
//------------------------------------------------------------------------
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
auto* 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
auto* 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);
snprintf (string, 40, "{%s-%s-%s-%s-%s}", s1, s2, s3, s4, s5);
#endif
}
//------------------------------------------------------------------------
void FUID::print (int32 style, char8* string, size_t stringBufferSize) const
{
if (!string || stringBufferSize == 0) // no string: debug output
{
char8 str[128];
print (style, str, 128);
#if SMTG_OS_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:
// length is 60 (with null-terminate)
snprintf (string, stringBufferSize, "INLINE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1,
l2, l3, l4);
break;
case kDECLARE_UID:
// length is 61 (with null-terminate)
snprintf (string, stringBufferSize, "DECLARE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1,
l2, l3, l4);
break;
case kFUID:
// length is 54 (with null-terminate)
snprintf (string, stringBufferSize, "FUID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3,
l4);
break;
case kCLASS_UID:
default:
// length is 78 (with null-terminate)
snprintf (string, stringBufferSize,
"DECLARE_CLASS_IID (Interface, 0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3,
l4);
break;
}
}
//------------------------------------------------------------------------
// 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];
snprintf (s, 3, "%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
+564
View File
@@ -0,0 +1,564 @@
//-----------------------------------------------------------------------------
// 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 <cstring>
#if SMTG_CPP11_STDLIBSUPPORT
#include <type_traits>
#endif
//------------------------------------------------------------------------
/*! \defgroup pluginBase Basic Interfaces
*/
//------------------------------------------------------------------------
// Unique Identifier macros
//------------------------------------------------------------------------
#if COM_COMPATIBLE
#define INLINE_UID(l1, l2, l3, l4) \
{ \
(::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x000000FF) ), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x0000FF00) >> 8), \
(::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x00FF0000) >> 16), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0xFF000000) >> 24), \
(::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x00FF0000) >> 16), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0xFF000000) >> 24), \
(::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x000000FF) ), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x0000FF00) >> 8), \
(::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x00FF0000) >> 16), \
(::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x000000FF) ), \
(::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x00FF0000) >> 16), \
(::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x000000FF) ) \
}
#else
#define INLINE_UID(l1, l2, l3, l4) \
{ \
(::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x00FF0000) >> 16), \
(::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x000000FF) ), \
(::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x00FF0000) >> 16), \
(::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x000000FF) ), \
(::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x00FF0000) >> 16), \
(::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x000000FF) ), \
(::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x00FF0000) >> 16), \
(::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x000000FF) ) \
}
#endif
//------------------------------------------------------------------------
#define DECLARE_UID(name, l1, l2, l3, l4) SMTG_CONSTEXPR14 ::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 SMTG_CONSTEXPR14 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 SMTG_CONSTEXPR14 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; }
#if defined(SMTG_FUNKNOWN_DTOR_ASSERT) && SMTG_FUNKNOWN_DTOR_ASSERT
#include <cassert>
#define FUNKNOWN_DTOR { assert (__funknownRefCount == 0); }
#else
#define FUNKNOWN_DTOR
#endif
//------------------------------------------------------------------------
#define QUERY_INTERFACE(iid, obj, InterfaceIID, InterfaceName) \
if (::Steinberg::FUnknownPrivate::iidEqual (iid, InterfaceIID)) \
{ \
addRef (); \
*obj = static_cast< InterfaceName* >(this); \
return ::Steinberg::kResultOk; \
}
//------------------------------------------------------------------------
#define IMPLEMENT_QUERYINTERFACE(ClassName, InterfaceName, ClassIID) \
::Steinberg::tresult PLUGIN_API ClassName::queryInterface (const ::Steinberg::TUID _iid, void** obj)\
{ \
QUERY_INTERFACE (_iid, obj, ::Steinberg::FUnknown::iid, InterfaceName) \
QUERY_INTERFACE (_iid, obj, ClassIID, InterfaceName) \
*obj = nullptr; \
return ::Steinberg::kNoInterface; \
}
//------------------------------------------------------------------------
#define IMPLEMENT_FUNKNOWN_METHODS(ClassName,InterfaceName,ClassIID) \
IMPLEMENT_REFCOUNT (ClassName) \
IMPLEMENT_QUERYINTERFACE (ClassName, InterfaceName, ClassIID)
//------------------------------------------------------------------------
// Result Codes
//------------------------------------------------------------------------
namespace Steinberg {
//------------------------------------------------------------------------
#if COM_COMPATIBLE
#if SMTG_OS_WINDOWS
enum
{
kNoInterface = static_cast<tresult>(0x80004002L), // E_NOINTERFACE
kResultOk = static_cast<tresult>(0x00000000L), // S_OK
kResultTrue = kResultOk,
kResultFalse = static_cast<tresult>(0x00000001L), // S_FALSE
kInvalidArgument = static_cast<tresult>(0x80070057L), // E_INVALIDARG
kNotImplemented = static_cast<tresult>(0x80004001L), // E_NOTIMPL
kInternalError = static_cast<tresult>(0x80004005L), // E_FAIL
kNotInitialized = static_cast<tresult>(0x8000FFFFL), // E_UNEXPECTED
kOutOfMemory = static_cast<tresult>(0x8007000EL) // E_OUTOFMEMORY
};
#else
enum
{
kNoInterface = static_cast<tresult>(0x80000004L), // E_NOINTERFACE
kResultOk = static_cast<tresult>(0x00000000L), // S_OK
kResultTrue = kResultOk,
kResultFalse = static_cast<tresult>(0x00000001L), // S_FALSE
kInvalidArgument = static_cast<tresult>(0x80000003L), // E_INVALIDARG
kNotImplemented = static_cast<tresult>(0x80000001L), // E_NOTIMPL
kInternalError = static_cast<tresult>(0x80000008L), // E_FAIL
kNotInitialized = static_cast<tresult>(0x8000FFFFL), // E_UNEXPECTED
kOutOfMemory = static_cast<tresult>(0x80000002L) // E_OUTOFMEMORY
};
#endif
#else
enum
{
kNoInterface = -1,
kResultOk,
kResultTrue = kResultOk,
kResultFalse,
kInvalidArgument,
kNotImplemented,
kInternalError,
kNotInitialized,
kOutOfMemory
};
#endif
/** \ingroup smtgtypedef */
/**@{*/
//------------------------------------------------------------------------
typedef int64 LARGE_INT; // obsolete
//------------------------------------------------------------------------
// FUID class declaration
//------------------------------------------------------------------------
typedef char TUID[16]; ///< plain UID type
/**@}*/
#if SMTG_CPP14
//------------------------------------------------------------------------
inline SMTG_CONSTEXPR14 void copyTUID (char* dst, const char* src)
{
for (auto i = 0; i < 16; ++i)
dst[i] = src[i];
}
#endif
//------------------------------------------------------------------------
/* FUnknown private */
namespace FUnknownPrivate {
SMTG_ALWAYS_INLINE bool iidEqual (const void* iid1, const void* iid2)
{
const uint64* p1 = reinterpret_cast<const uint64*> (iid1);
const uint64* p2 = reinterpret_cast<const uint64*> (iid2);
return p1[0] == p2[0] && p1[1] == p2[1];
}
int32 PLUGIN_API atomicAdd (int32& value, int32 amount);
}
//------------------------------------------------------------------------
/** Handling 16 Byte Globally Unique Identifiers.
\ingroup pluginBase
Each interface declares its identifier as static member inside the interface
namespace (e.g. FUnknown::iid).
*/
class FUID
{
public:
//------------------------------------------------------------------------
FUID ();
FUID (uint32 l1, uint32 l2, uint32 l3, uint32 l4);
FUID (const FUID&);
virtual ~FUID () {}
#if SMTG_CPP11_STDLIBSUPPORT
FUID (FUID&& other);
FUID& operator= (FUID&& other);
#endif
/** Generates a new Unique Identifier (UID).
Will return true for success. If the return value is false, either no
UID is generated or the UID is not guaranteed to be unique worldwide. */
bool generate ();
/** Checks if the UID data is valid.
The default constructor initializes the memory with zeros. */
bool isValid () const;
FUID& operator = (const FUID& f);
bool operator == (const FUID& f) const { return ::Steinberg::FUnknownPrivate::iidEqual (data, f.data); }
bool operator < (const FUID& f) const { return memcmp (data, f.data, sizeof (TUID)) < 0; }
bool operator != (const FUID& f) const { return !::Steinberg::FUnknownPrivate::iidEqual (data, f.data); }
uint32 getLong1 () const;
uint32 getLong2 () const;
uint32 getLong3 () const;
uint32 getLong4 () const;
void from4Int (uint32 d1, uint32 d2, uint32 d3, uint32 d4);
void to4Int (uint32& d1, uint32& d2, uint32& d3, uint32& d4) const;
typedef char8 String[33];
/** Converts UID to a string.
The string will be 32 characters long, representing the hexadecimal values
of each data byte (e.g. "9127BE30160E4BB69966670AA6087880").
Typical use-case is:
\code{.cpp}
char8[33] strUID = {0};
FUID uid;
if (uid.generate ())
uid.toString (strUID);
\endcode
*/
void toString (char8* string) const;
/** Sets the UID data from a string.
The string has to be 32 characters long, where each character-pair is
the ASCII-encoded hexadecimal value of the corresponding data byte. */
bool fromString (const char8* string);
/** Converts UID to a string in Microsoft(R) OLE format.
(e.g. "{c200e360-38c5-11ce-ae62-08002b2b79ef}") */
void toRegistryString (char8* string) const;
/** Sets the UID data from a string in Microsoft(R) 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 style can be chosen from the FUID::UIDPrintStyle enumeration.
\param string is the output string if not NULL.
\param stringBufferSize is the size of the output string */
void print (int32 style, char8* string = nullptr, size_t stringBufferSize = 0) const;
template <size_t N>
inline explicit FUID (const char (&uid)[N])
{
#if SMTG_CPP11_STDLIBSUPPORT
static_assert (N == sizeof (TUID), "only TUID allowed");
#endif
memcpy (data, uid, sizeof (TUID));
}
inline void toTUID (TUID result) const { memcpy (result, data, sizeof (TUID)); }
inline operator const TUID& () const { return data; }
inline const TUID& toTUID () const { return data; }
static FUID fromTUID (const TUID uid)
{
FUID res;
if (uid)
memcpy (res.data, uid, sizeof (TUID));
return res;
}
//------------------------------------------------------------------------
protected:
TUID data;
};
#if SMTG_CPP11_STDLIBSUPPORT
template <typename T>
inline bool operator== (const FUID& f1, T f2)
{
static_assert (
std::is_same<typename std::remove_cv<T>::type, FUID>::value,
"Do not compare a FUID with a TUID directly. Either convert the TUID to a FUID and compare them or use FUnknownPrivate::iidEqual");
return f1.operator== (f2);
}
#endif
//------------------------------------------------------------------------
// FUnknown
//------------------------------------------------------------------------
/** The basic interface of all interfaces.
\ingroup pluginBase
- The FUnknown::queryInterface method is used to retrieve pointers to other
interfaces of the object.
- FUnknown::addRef and FUnknown::release manage the lifetime of the object.
If no more references exist, the object is destroyed in memory.
Interfaces are identified by 16 byte Globally Unique Identifiers.
The SDK provides a class called FUID for this purpose.
\ref howtoClass
*/
class FUnknown
{
public:
//------------------------------------------------------------------------
/** Query for a pointer to the specified interface.
Returns kResultOk on success or kNoInterface if the object does not implement the interface.
The object has to call addRef when returning an interface.
\param _iid : (in) 16 Byte interface identifier (-> FUID)
\param obj : (out) On return, *obj points to the requested interface */
virtual tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) = 0;
/** Adds a reference and returns 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 returns 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{.cpp}
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; }
#if SMTG_CPP11_STDLIBSUPPORT
inline FUnknownPtr (FUnknownPtr&& p) SMTG_NOEXCEPT : IPtr<I> (std::move (p)) {}
inline FUnknownPtr& operator= (FUnknownPtr&& p) SMTG_NOEXCEPT
{
IPtr<I>::operator= (std::move (p));
return *this;
}
#endif
};
#if SMTG_CPP11_STDLIBSUPPORT
//------------------------------------------------------------------------
namespace FUnknownPrivate {
template <typename T>
struct Void : std::false_type
{
using Type = void;
};
template <typename T>
using VoidT = typename Void<T>::Type;
//------------------------------------------------------------------------
/**
* This type trait detects if a class has an @c iid member variable. It is used to detect if
* the FUID and DECLARE_CLASS_IID method or the U::UID method is used.
*/
template <typename T, typename U = void>
struct HasIIDType : std::false_type
{
};
//------------------------------------------------------------------------
template <typename T>
struct HasIIDType<T, FUnknownPrivate::VoidT<typename T::IID>> : std::true_type
{
};
//------------------------------------------------------------------------
} // FUnknownPrivate
//------------------------------------------------------------------------
/** @return the TUID for an interface which uses the U::UID method. */
template <typename T,
typename std::enable_if<FUnknownPrivate::HasIIDType<T>::value>::type* = nullptr>
const TUID& getTUID ()
{
return T::IID::toTUID ();
}
//------------------------------------------------------------------------
/** @return the TUID for an interface which uses the FUID and DECLARE_CLASS_IID method. */
template <typename T,
typename std::enable_if<!FUnknownPrivate::HasIIDType<T>::value>::type* = nullptr>
const TUID& getTUID ()
{
return T::iid.toTUID ();
}
#else // SMTG_CPP11_STDLIBSUPPORT
template<typename T>
const TUID& getTUID ()
{
return T::iid.toTUID ();
}
#endif // SMTG_CPP11_STDLIBSUPPORT
//------------------------------------------------------------------------
template <class I>
inline FUnknownPtr<I>::FUnknownPtr (FUnknown* unknown)
{
if (unknown && unknown->queryInterface (getTUID<I> (), (void**)&this->ptr) != kResultOk)
this->ptr = 0;
}
//------------------------------------------------------------------------
template <class I>
inline I* FUnknownPtr<I>::operator= (FUnknown* unknown)
{
I* newPtr = 0;
if (unknown && unknown->queryInterface (getTUID<I> (), (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{.cpp}
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{.cpp}
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
+464
View File
@@ -0,0 +1,464 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : SDK Core
//
// Category : SDK Core Interfaces
// Filename : pluginterfaces/base/funknownimpl.h
// Created by : Steinberg, 10/2021
// Description : Steinberg Module Architecture Interface Implementation Helper
//
//-----------------------------------------------------------------------------
// 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/funknown.h"
#include <atomic>
#include <type_traits>
//------------------------------------------------------------------------
#if !(SMTG_CPP11)
#error "C++11 is required for this header"
#endif
// clang-format off
/**
This header provides classes for working with FUnknown.
An interface which shall support Steinbergs Module Architecture should inherit from U::Unknown and provide a typedef
@c IID of type U::UID.
On OS X you can generate an U::UID and copy it to the clipboard with the following shell command:
@code
uuidgen | { read id; echo -n "using IID = U::UID<0x${id:0:8}, 0x${id:9:4}${id:14:4}, 0x${id:19:4}${id:24:4}, 0x${id:28:8}>;" ; } | pbcopy
@endcode
Example:
@code{.cpp}
struct IFoo : public U::Unknown
{
// Use a generated random uid here.
using IID = U::UID<0x01234567, 0x89012345, 0x67890123, 0x45678901>;
virtual void bar () = 0;
};
@endcode
A class implementing the interface @c IFoo uses the U::Implements template to specify the
interfaces it implements. All interfaces which the class should derive from need to be listed in the
U::Directly template.
Example:
@code{.cpp}
struct FooImpl : public U::Implements<U::Directly<IFoo>>
{
void bar () override {}
};
@endcode
To check if a class can provide a specific interface use the U::cast function.
Example:
@code{.cpp}
void test (U::Unknown* obj)
{
if (auto foo = U::cast<IFoo> (obj))
{
// obj provided IFoo
}
}
@endcode
The U::Implements class supports a second template parameter U::Indirectly for specifying
a list of interfaces which should be available via @c queryInterface but not inherited from.
This is useful if an interface extends another interface.
Example:
@code{.cpp}
struct IBar : public IFoo
{
using IID = U::UID<0x11223344, 0x55667788, 0x99001122, 0x33445566>;
virtual void baz () = 0;
};
struct BarImpl : public U::Implements<U::Directly<IBar>, U::Indirectly<IFoo>>
{
void bar () override {}
void baz () override {}
};
@endcode
In some cases a class shall be extended and an additional interface implemented.
This is possible with the U::Extends template which is a generalization of the U::Implements
template and allows specifying a base class from which should be inherited.
Example:
@code{.cpp}
struct ITest : public U::Unknown
{
using IID = U::UID<0x99887766, 0x55443322, 0x11009988, 0x77665544>;
virtual bool equal (int a, int b) const = 0;
};
struct TestImpl : public U::Extends<FooImpl, U::Directly<ITest>>
{
bool equal (int a, int b) const override { return a == b; }
};
@endcode
To pass arbitrary arguments to the specified base class one can use the inherited @c Base
typedef. All arguments passed to @c Base are automatically perfectly forwarded to the base class.
In the following example the value 42 is passed to the @c AlternativeFooImpl base class:
@code{.cpp}
struct AlternativeFooImpl : public U::Implements<U::Directly<IFoo>>
{
AlternativeFooImpl (int dummy = 0) : dummy {dummy} {}
void bar () override {}
int dummy;
};
struct AlternativeTestImpl : public U::Extends<AlternativeFooImpl, U::Directly<ITest>>
{
AlternativeTestImpl () : Base {42} {}
bool equal (int a, int b) const override { return a == b; }
};
@endcode
*/
// clang-format on
//------------------------------------------------------------------------
namespace Steinberg {
namespace FUnknownImpl {
/** Typedef to keep everything in this namespace. */
using Unknown = FUnknown;
/** A base class which hides the FUnknown::iid static var */
struct HideIIDBase : FUnknown
{
using iid = void;
};
/** Common destroyer policy for ski object instances.*/
struct Destroyer
{
template <typename UnknownT>
static void destroy (UnknownT* ptr)
{
if (!!ptr)
ptr->release ();
}
};
template <typename Base, typename D, typename I>
class ImplementsImpl;
/**
* This class provides a compile-time uid and enables interfaces to specify a UID as a simple
* typedef. This way the FUID, DECLARE_CLASS_IID and DEF_CLASS_IID code can be omitted.
*/
template <uint32 t1, uint32 t2, uint32 t3, uint32 t4>
struct UID
{
enum : int8
{
l1_1 = static_cast<int8> ((t1 & 0xFF000000) >> 24),
l1_2 = static_cast<int8> ((t1 & 0x00FF0000) >> 16),
l1_3 = static_cast<int8> ((t1 & 0x0000FF00) >> 8),
l1_4 = static_cast<int8> ((t1 & 0x000000FF)),
l2_1 = static_cast<int8> ((t2 & 0xFF000000) >> 24),
l2_2 = static_cast<int8> ((t2 & 0x00FF0000) >> 16),
l2_3 = static_cast<int8> ((t2 & 0x0000FF00) >> 8),
l2_4 = static_cast<int8> ((t2 & 0x000000FF)),
l3_1 = static_cast<int8> ((t3 & 0xFF000000) >> 24),
l3_2 = static_cast<int8> ((t3 & 0x00FF0000) >> 16),
l3_3 = static_cast<int8> ((t3 & 0x0000FF00) >> 8),
l3_4 = static_cast<int8> ((t3 & 0x000000FF)),
l4_1 = static_cast<int8> ((t4 & 0xFF000000) >> 24),
l4_2 = static_cast<int8> ((t4 & 0x00FF0000) >> 16),
l4_3 = static_cast<int8> ((t4 & 0x0000FF00) >> 8),
l4_4 = static_cast<int8> ((t4 & 0x000000FF))
};
UID () = delete;
static constexpr TUID data = {
#if COM_COMPATIBLE
l1_4, l1_3, l1_2, l1_1, l2_2, l2_1, l2_4, l2_3,
#else
l1_1, l1_2, l1_3, l1_4, l2_1, l2_2, l2_3, l2_4,
#endif
l3_1, l3_2, l3_3, l3_4, l4_1, l4_2, l4_3, l4_4,
};
static const TUID& toTUID () { return data; }
};
/** @return the TUID for an interface. */
template <typename T>
const TUID& getTUID ()
{
return ::Steinberg::getTUID<T> ();
}
/**
* Checks if the given Unknown can provide the specified interface and returns it in an IPtr.
*
* @return an IPtr pointing to an instance of the requested interface or nullptr in case the
* object does not provide the interface.
*/
template <typename I>
IPtr<I> cast (Unknown* u)
{
I* out = nullptr;
return u && u->queryInterface (getTUID<I> (), reinterpret_cast<void**> (&out)) == kResultOk ?
owned (out) :
nullptr;
}
/** Casts to Unknown* and then to the specified interface. */
template <typename I, typename S, typename T, typename U>
IPtr<I> cast (ImplementsImpl<S, T, U>* u)
{
return cast<I> (u->unknownCast ());
}
/** Casts to Unknown* and then to the specified interface. */
template <typename I, typename T>
IPtr<I> cast (const IPtr<T>& u)
{
return cast<I> (u.get ());
}
//------------------------------------------------------------------------
namespace Detail {
/**
* This struct implements reference counting for the @c U::Implements template.
* It also provides a @c queryInterface method stub to support @c queryInterface
* call made in the @c U::Implements template.
*/
struct RefCounted
{
//------------------------------------------------------------------------
RefCounted () = default;
RefCounted (const RefCounted&) {}
RefCounted (RefCounted&& other) SMTG_NOEXCEPT : refCount {other.refCount.load ()} {}
virtual ~RefCounted () = default;
RefCounted& operator= (const RefCounted&) { return *this; }
RefCounted& operator= (RefCounted&& other) SMTG_NOEXCEPT
{
refCount = other.refCount.load ();
return *this;
}
uint32 PLUGIN_API addRef () { return ++refCount; }
uint32 PLUGIN_API release ()
{
auto rc = --refCount;
if (rc == 0)
{
destroyInstance ();
refCount = -1000;
delete this;
return uint32 ();
}
return rc;
}
//------------------------------------------------------------------------
private:
virtual void destroyInstance () {}
std::atomic<int32> refCount {1};
};
//------------------------------------------------------------------------
struct NonDestroyable
{
//------------------------------------------------------------------------
NonDestroyable () = default;
virtual ~NonDestroyable () = default;
uint32 PLUGIN_API addRef () { return 1000; }
uint32 PLUGIN_API release () { return 1000; }
private:
virtual void destroyInstance () {}
};
//------------------------------------------------------------------------
template <typename T>
struct QueryInterfaceEnd : T
{
//------------------------------------------------------------------------
tresult PLUGIN_API queryInterface (const TUID /*iid*/, void** obj)
{
*obj = nullptr;
return kNoInterface;
}
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Detail
/**
* This struct is used to group a list of interfaces from which should be inherited and which
* should be available via the @c queryInterface method.
*/
template <typename... T>
struct Directly
{
};
/**
* This struct is used to group a list of interfaces from which should not be inherited but which
* should be available via the @c queryInterface method.
*/
template <typename... T>
struct Indirectly
{
};
template <typename Base, typename D, typename I>
class ImplementsImpl
{
static_assert (sizeof (Base) == -1, "use U::Directly and U::Indirectly to specify interfaces");
};
template <typename Base, typename... DirectInterfaces, typename... IndirectInterfaces>
class ImplementsImpl<Base, Indirectly<IndirectInterfaces...>, Directly<DirectInterfaces...>>
{
static_assert (sizeof (Base) == -1, "U::Indirectly only allowed after U::Directly");
};
/** This class implements the required virtual methods for the U::Unknown class. */
template <typename BaseClass, typename I, typename... DirectIFs, typename... IndirectIFs>
class ImplementsImpl<BaseClass, Directly<I, DirectIFs...>, Indirectly<IndirectIFs...>>
: public BaseClass, public I, public DirectIFs...
{
public:
//------------------------------------------------------------------------
/**
* This is a convenience typedef for the deriving class to pass arguments to the
* constructor, which are in turn passed to the base class of this class.
*/
using Base = ImplementsImpl<BaseClass, Directly<I, DirectIFs...>, Indirectly<IndirectIFs...>>;
template <typename... Args>
ImplementsImpl (Args&&... args) : BaseClass {std::forward<Args> (args)...}
{
}
tresult PLUGIN_API queryInterface (const TUID tuid, void** obj) override
{
if (!obj)
return kInvalidArgument;
if (queryInterfaceImpl<I, DirectIFs...> (tuid, *obj) ||
queryInterfaceImpl<IndirectIFs...> (tuid, *obj))
{
static_cast<Unknown*> (*obj)->addRef ();
return kResultOk;
}
return BaseClass::queryInterface (tuid, obj);
}
uint32 PLUGIN_API addRef () override { return BaseClass::addRef (); }
uint32 PLUGIN_API release () override { return BaseClass::release (); }
Unknown* unknownCast () { return static_cast<Unknown*> (static_cast<I*> (this)); }
//------------------------------------------------------------------------
private:
template <typename Interface>
inline constexpr bool match (const TUID tuid) const noexcept
{
return reinterpret_cast<const uint64*> (tuid)[0] ==
reinterpret_cast<const uint64*> (getTUID<Interface> ())[0] &&
reinterpret_cast<const uint64*> (tuid)[1] ==
reinterpret_cast<const uint64*> (getTUID<Interface> ())[1];
}
template <int = 0>
inline constexpr bool queryInterfaceImpl (const TUID, void*&) const noexcept
{
return false;
}
template <typename Interface, typename... RemainingInterfaces>
inline bool queryInterfaceImpl (const TUID tuid, void*& obj) noexcept
{
if (match<Interface> (tuid) || match<Unknown> (tuid))
{
obj = static_cast<Interface*> (this);
return true;
}
obj = getInterface<RemainingInterfaces...> (tuid);
return obj != nullptr;
}
template <int = 0>
inline constexpr void* getInterface (const TUID) const noexcept
{
return nullptr;
}
template <typename Interface, typename... RemainingInterfaces>
inline void* getInterface (const TUID tuid) noexcept
{
return match<Interface> (tuid) ? static_cast<Interface*> (this) :
getInterface<RemainingInterfaces...> (tuid);
}
};
/** This typedef enables using a custom base class with the interface implementation. */
template <typename BaseClass, typename D, typename I = Indirectly<>>
using Extends = ImplementsImpl<BaseClass, D, I>;
/** This typedef provides the interface implementation. */
template <typename D, typename I = Indirectly<>>
using Implements = ImplementsImpl<Detail::QueryInterfaceEnd<Detail::RefCounted>, D, I>;
/** This typedef provides the interface implementation for objects which should not be destroyed via
* FUnknown::release (like singletons). */
template <typename D, typename I = Indirectly<>>
using ImplementsNonDestroyable =
ImplementsImpl<Detail::QueryInterfaceEnd<Detail::NonDestroyable>, D, I>;
//------------------------------------------------------------------------
} // FUnknownImpl
//------------------------------------------------------------------------
/** Shortcut namespace for implementing FUnknown based objects. */
namespace U {
using Unknown = FUnknownImpl::HideIIDBase;
using FUnknownImpl::UID;
using FUnknownImpl::Extends;
using FUnknownImpl::Implements;
using FUnknownImpl::ImplementsNonDestroyable;
using FUnknownImpl::Directly;
using FUnknownImpl::Indirectly;
using FUnknownImpl::cast;
using FUnknownImpl::getTUID;
//------------------------------------------------------------------------
} // namespace U
} // namespace Steinberg
+107
View File
@@ -0,0 +1,107 @@
//-----------------------------------------------------------------------------
// 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;
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)));
}
//----------------------------------------------------------------------------
// Four character constant
#ifndef CCONST
#define CCONST(a, b, c, d) \
((((int32) (a)) << 24) | (((int32) (b)) << 16) | (((int32) (c)) << 8) | (((int32) (d)) << 0))
#endif
//------------------------------------------------------------------------
} // namespace Steinberg
+298
View File
@@ -0,0 +1,298 @@
//-----------------------------------------------------------------------------
// 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"
#include "pluginterfaces/base/funknown.h"
#include <cstdlib>
//------------------------------------------------------------------------
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 (bool b) : type (kInteger), intValue (b) {}
inline FVariant (uint32 v) : type (kInteger), intValue (v) {}
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 set (bool b)
{
setInt (b);
}
inline void set (uint32 v)
{
setInt (v);
}
inline void set (int64 v)
{
setInt (v);
}
inline void set (double v)
{
setFloat (v);
}
inline void set (const char8* c)
{
setString8 (c);
}
inline void set (const char16* c)
{
setString16 (c);
}
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;
}
template <typename T>
inline T get () const;
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 : nullptr; }
inline const char16* getString16 () const { return (type & kString16) ? string16 : nullptr; }
inline FUnknown* getObject () const { return (type & kObject) ? object : nullptr; }
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 SMTG_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
}
template <>
inline bool FVariant::get<bool> () const
{
return getInt () != 0;
}
template <>
inline uint32 FVariant::get<uint32> () const
{
return static_cast<uint32> (getInt ());
}
template <>
inline int32 FVariant::get<int32> () const
{
return static_cast<int32> (getInt ());
}
template <>
inline int64 FVariant::get<int64> () const
{
return static_cast<int64> (getInt ());
}
template <>
inline float FVariant::get<float> () const
{
return static_cast<float> (getFloat ());
}
template <>
inline double FVariant::get<double> () const
{
return getFloat ();
}
template <>
inline const char8* FVariant::get<const char8*> () const
{
return getString8 ();
}
template <>
inline const char16* FVariant::get<const char16*> () const
{
return getString16 ();
}
template <>
inline FUnknown* FVariant::get<FUnknown*> () const
{
return getObject ();
}
//------------------------------------------------------------------------
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)
free (const_cast<char8*> (string8)); // should match DELETESTR8
else if ((type & kString16) && string16)
free (const_cast<char16*> (string16)); // should match DELETESTR16
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 = static_cast<char8*> (malloc (strlen (variant.string8) + 1)); // should match NEWSTR8
strcpy (const_cast<char8*> (string8), variant.string8);
type |= kOwner;
}
else if ((type & kString16) && variant.string16)
{
auto len = static_cast<size_t> (strlen16 (variant.string16));
string16 = static_cast<char16*> (malloc ((len + 1) * sizeof (char16))); // should match NEWSTR16
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
@@ -0,0 +1,97 @@
//-----------------------------------------------------------------------------
// 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
+87
View File
@@ -0,0 +1,87 @@
//-----------------------------------------------------------------------------
// 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 = nullptr) = 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 = nullptr) = 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 = nullptr) = 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
+41
View File
@@ -0,0 +1,41 @@
//-----------------------------------------------------------------------------
// 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]
- [released: N4.12]
*/
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
@@ -0,0 +1,48 @@
//-----------------------------------------------------------------------------
// 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]
- [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
+174
View File
@@ -0,0 +1,174 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : SDK Core Interfaces
// Filename : pluginterfaces/base/ipersistent.h
// Created by : Steinberg, 09/2004
// Description : Plug-In Storage 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 "pluginterfaces/base/funknown.h"
namespace Steinberg {
class FVariant;
class IAttributes;
//------------------------------------------------------------------------
/** Persistent Object Interface.
[plug imp] \n
This interface is used to store/restore attributes of an object.
An IPlugController can implement this interface to handle presets.
The gui-xml for a preset control looks like this:
\code
....
<view name="PresetView" data="Preset"/>
....
<template name="PresetView">
<view name="preset control" size="0, 0, 100, 20"/>
<switch name="store preset" size="125,0,80,20" style="push|immediate" title="Store" />
<switch name="remove preset" size="220,0,80,20" style="push|immediate" title="Delete" />
</template>
\endcode
The tag data="Preset" tells the host to create a preset controller that handles the
3 values named "preset control", "store preset", and "remove preset".
*/
class IPersistent: public FUnknown
{
public:
//------------------------------------------------------------------------
/** The class ID must be a 16 bytes unique id that is used to create the object.
This ID is also used to identify the preset list when used with presets. */
virtual tresult PLUGIN_API getClassID (char8* uid) = 0;
/** Store all members/data in the passed IAttributes. */
virtual tresult PLUGIN_API saveAttributes (IAttributes* ) = 0;
/** Restore all members/data from the passed IAttributes. */
virtual tresult PLUGIN_API loadAttributes (IAttributes* ) = 0;
//------------------------------------------------------------------------
static const FUID iid;
};
DECLARE_CLASS_IID (IPersistent, 0xBA1A4637, 0x3C9F46D0, 0xA65DBA0E, 0xB85DA829)
/** \ingroup smtgtypedef */
/**@{*/
typedef FIDString IAttrID;
/**@}*/
//------------------------------------------------------------------------
/** Object Data Archive Interface.
- [host imp]
- store data/objects/binary/subattributes in the archive
- read stored data from the archive
All data stored to the archive are identified by a string (IAttrID), which must be unique on each
IAttribute level.
The basic set/get methods make use of the FVariant class defined in 'funknown.h'.
For a more convenient usage of this interface, you should use the functions defined
in namespace PAttributes (public.sdk/source/common/pattributes.h+cpp) !!
\ingroup frameworkHostClasses
*/
class IAttributes: public FUnknown
{
public:
//------------------------------------------------------------------------
/*! \name Methods to write attributes
********************************************************************************************************
*/
//@{
/** Store any data in the archive. It is even possible to store sub-attributes by creating
* a new IAttributes instance via the IHostClasses interface and pass it to the parent in the
* FVariant. In this case the archive must take the ownership of the newly created object,
* which is true for all objects that have been created only for storing. You tell the archive
* to take ownership by adding the FVariant::kOwner flag to the FVariant::type member (data.type
* |= FVariant::kOwner). When using the PAttributes functions, this is done through a function
* parameter.*/
virtual tresult PLUGIN_API set (IAttrID attrID /*in*/, const FVariant& data /*in*/) = 0;
/** Store a list of data in the archive. Please note that the type of data is not mixable! So
* you can only store a list of integers or a list of doubles/strings/etc. You can also store a
* list of subattributes or other objects that implement the IPersistent interface.*/
virtual tresult PLUGIN_API queue (IAttrID listID /*in*/, const FVariant& data /*in*/) = 0;
/** Store binary data in the archive. Parameter 'copyBytes' specifies if the passed data should
* be copied. The archive cannot take the ownership of binary data. Either it just references a
* buffer in order to write it to a file (copyBytes = false) or it copies the data to its own
* buffers (copyBytes = true). When binary data should be stored in the default pool for
* example, you must always copy it!*/
virtual tresult PLUGIN_API setBinaryData (IAttrID attrID /*in*/, void* data /*in*/,
uint32 bytes /*in*/, bool copyBytes /*in*/) = 0;
//@}
/*! \name Methods to read attributes
********************************************************************************************************
*/
//@{
/** Get data previously stored to the archive. */
virtual tresult PLUGIN_API get (IAttrID attrID /*in*/, FVariant& data /*out*/) = 0;
/** Get list of data previously stored to the archive. As long as there are queue members the
* method will return kResultTrue. When the queue is empty, the methods returns kResultFalse.
* All lists except from object lists can be reset which means that the items can be read once
* again. \see IAttributes::resetQueue */
virtual tresult PLUGIN_API unqueue (IAttrID listID /*in*/, FVariant& data /*out*/) = 0;
/** Get the amount of items in a queue. */
virtual int32 PLUGIN_API getQueueItemCount (IAttrID attrId /*in*/) = 0;
/** Reset a queue. If you need to restart reading a queue, you have to reset it. You can reset a
* queue at any time.*/
virtual tresult PLUGIN_API resetQueue (IAttrID attrID /*in*/) = 0;
/** Reset all queues in the archive.*/
virtual tresult PLUGIN_API resetAllQueues () = 0;
/** Read binary data from the archive. The data is copied into the passed buffer. The size of
* that buffer must fit the size of data stored in the archive which can be queried via
* IAttributes::getBinaryDataSize */
virtual tresult PLUGIN_API getBinaryData (IAttrID attrID /*in*/, void* data /*inout*/,
uint32 bytes /*in*/) = 0;
/** Get the size in bytes of binary data in the archive. */
virtual uint32 PLUGIN_API getBinaryDataSize (IAttrID attrID /*in*/) = 0;
//@}
//------------------------------------------------------------------------
static const FUID iid;
};
DECLARE_CLASS_IID (IAttributes, 0xFA1E32F9, 0xCA6D46F5, 0xA982F956, 0xB1191B58)
//------------------------------------------------------------------------
/** Extended access to Attributes; supports Attribute retrieval via iteration.
- [host imp]
- [released] C7/N6
\ingroup frameworkHostClasses
*/
class IAttributes2 : public IAttributes
{
public:
/** Returns the number of existing attributes. */
virtual int32 PLUGIN_API countAttributes () const = 0;
/** Returns the attribute's ID for the given index. */
virtual IAttrID PLUGIN_API getAttributeID (int32 index /*in*/) const = 0;
//------------------------------------------------------------------------
static const FUID iid;
};
DECLARE_CLASS_IID (IAttributes2, 0x1382126A, 0xFECA4871, 0x97D52A45, 0xB042AE99)
//------------------------------------------------------------------------
} // namespace Steinberg
+522
View File
@@ -0,0 +1,522 @@
//-----------------------------------------------------------------------------
// 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: IPluginBase
\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.
\param context, passed by the host, is mandatory and should implement IHostApplication
@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 /*in*/) = 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
{
/** Nothing */
kNoFlags = 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. */
kClassesDiscardable = 1 << 0,
/** This flag is deprecated, do not use anymore, resp. it will get ignored from
Cubase/Nuendo 12 and later. */
kLicenseCheck = 1 << 1,
/** Component will not be unloaded until process exit */
kComponentNonDiscardable = 1 << 3,
/** Components have entirely unicode encoded strings (True for VST 3 plug-ins so far). */
kUnicode = 1 << 4
};
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 FactoryFlags above)
//------------------------------------------------------------------------
SMTG_CONSTEXPR14 PFactoryInfo (const char8* _vendor, const char8* _url, const char8* _email,
int32 _flags)
#if SMTG_CPP14
: vendor (), url (), email (), flags ()
#endif
{
strncpy8 (vendor, _vendor, kNameSize);
strncpy8 (url, _url, kURLSize);
strncpy8 (email, _email, kEmailSize);
flags = _flags;
#ifdef UNICODE
flags |= kUnicode;
#endif
}
#if SMTG_CPP11
constexpr PFactoryInfo () : vendor (), url (), email (), flags () {}
#else
PFactoryInfo () { memset (this, 0, sizeof (PFactoryInfo)); }
#endif
};
//------------------------------------------------------------------------
/** Basic Information about a class provided by the plug-in.
\ingroup pluginBase
*/
struct PClassInfo
{
//------------------------------------------------------------------------
enum ClassCardinality
{
kManyInstances = 0x7FFFFFFF
};
enum
{
kCategorySize = 32,
kNameSize = 64
};
//------------------------------------------------------------------------
/** Class ID 16 Byte class GUID */
TUID cid;
/** Cardinality of the class, set to kManyInstances (see \ref PClassInfo::ClassCardinality) */
int32 cardinality;
/** Class category, host uses this to categorize interfaces */
char8 category[kCategorySize];
/** Class name, visible to the user */
char8 name[kNameSize];
//------------------------------------------------------------------------
SMTG_CONSTEXPR14 PClassInfo (const TUID _cid, int32 _cardinality, const char8* _category,
const char8* _name)
#if SMTG_CPP14
: cid (), cardinality (), category (), name ()
#endif
{
#if SMTG_CPP14
copyTUID (cid, _cid);
#else
memset (this, 0, sizeof (PClassInfo));
memcpy (cid, _cid, sizeof (TUID));
#endif
if (_category)
strncpy8 (category, _category, kCategorySize);
if (_name)
strncpy8 (name, _name, kNameSize);
cardinality = _cardinality;
}
#if SMTG_CPP11
constexpr PClassInfo () : cid (), cardinality (), category (), name () {}
#else
PClassInfo () { memset (this, 0, sizeof (PClassInfo)); }
#endif
};
//------------------------------------------------------------------------
// IPluginFactory interface declaration
//------------------------------------------------------------------------
/** Class factory that any plug-in defines for creating class instances: IPluginFactory
\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 /*inout*/) = 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 /*in*/, PClassInfo* info /*inout*/) = 0;
/** Create a new class instance. */
virtual tresult PLUGIN_API createInstance (FIDString cid /*in*/, FIDString _iid /*in*/,
void** obj /*out*/) = 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
{
//------------------------------------------------------------------------
/** Class ID 16 Byte class GUID */
TUID cid;
/** Cardinality of the class, set to kManyInstances (see \ref PClassInfo::ClassCardinality) */
int32 cardinality;
/** Class category, host uses this to categorize interfaces */
char8 category[PClassInfo::kCategorySize];
/** Class name, visible to the user */
char8 name[PClassInfo::kNameSize];
enum {
kVendorSize = 64,
kVersionSize = 64,
kSubCategoriesSize = 128
};
/** flags used for a specific category, must be defined where category is defined */
uint32 classFlags;
/** module specific subcategories, can be more than one, logically added by the OR operator */
char8 subCategories[kSubCategoriesSize];
/** overwrite vendor information from factory info */
char8 vendor[kVendorSize];
/** Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build) */
char8 version[kVersionSize];
/** SDK version used to build this class (e.g. "VST 3.0") */
char8 sdkVersion[kVersionSize];
//------------------------------------------------------------------------
SMTG_CONSTEXPR14 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)
#if SMTG_CPP14
: cid ()
, cardinality ()
, category ()
, name ()
, classFlags ()
, subCategories ()
, vendor ()
, version ()
, sdkVersion ()
#endif
{
#if SMTG_CPP14
copyTUID (cid, _cid);
#else
memset (this, 0, sizeof (PClassInfo2));
memcpy (cid, _cid, sizeof (TUID));
#endif
cardinality = _cardinality;
if (_category)
strncpy8 (category, _category, PClassInfo::kCategorySize);
if (_name)
strncpy8 (name, _name, PClassInfo::kNameSize);
classFlags = static_cast<uint32> (_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);
}
#if SMTG_CPP11
constexpr PClassInfo2 ()
: cid ()
, cardinality ()
, category ()
, name ()
, classFlags ()
, subCategories ()
, vendor ()
, version ()
, sdkVersion ()
{
}
#else
PClassInfo2 () { memset (this, 0, sizeof (PClassInfo2)); }
#endif
};
//------------------------------------------------------------------------
// IPluginFactory2 interface declaration
//------------------------------------------------------------------------
/** Version 2 of class factory supporting PClassInfo2: IPluginFactory2
\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 /*in*/, PClassInfo2* info /*out*/) = 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
};
/** flags used for a specific category, must be defined where category is defined */
uint32 classFlags;
/** module specific subcategories, can be more than one, logically added by the OR operator */
char8 subCategories[kSubCategoriesSize];
/** overwrite vendor information from factory info */
char16 vendor[kVendorSize];
/** Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build) */
char16 version[kVersionSize];
/** SDK version used to build this class (e.g. "VST 3.0") */
char16 sdkVersion[kVersionSize];
//------------------------------------------------------------------------
SMTG_CONSTEXPR14 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)
#if SMTG_CPP14
: cid ()
, cardinality ()
, category ()
, name ()
, classFlags ()
, subCategories ()
, vendor ()
, version ()
, sdkVersion ()
#endif
{
#if SMTG_CPP14
copyTUID (cid, _cid);
#else
memset (this, 0, sizeof (PClassInfoW));
memcpy (cid, _cid, sizeof (TUID));
#endif
cardinality = _cardinality;
if (_category)
strncpy8 (category, _category, PClassInfo::kCategorySize);
if (_name)
strncpy16 (name, _name, PClassInfo::kNameSize);
classFlags = static_cast<uint32> (_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);
}
#if SMTG_CPP11
constexpr PClassInfoW ()
: cid ()
, cardinality ()
, category ()
, name ()
, classFlags ()
, subCategories ()
, vendor ()
, version ()
, sdkVersion ()
{
}
#else
PClassInfoW () { memset (this, 0, sizeof (PClassInfoW)); }
#endif
SMTG_CONSTEXPR14 void fromAscii (const PClassInfo2& ci2)
{
#if SMTG_CPP14
copyTUID (cid, ci2.cid);
#else
memcpy (cid, ci2.cid, sizeof (TUID));
#endif
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: IPluginFactory3
\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 /*in*/,
PClassInfoW* info /*out*/) = 0;
/** Receives information about host*/
virtual tresult PLUGIN_API setHostContext (FUnknown* context /*in*/) = 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{.cpp}
SMTG_EXPORT_SYMBOL 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"
{
SMTG_EXPORT_SYMBOL Steinberg::IPluginFactory* PLUGIN_API GetPluginFactory ();
typedef Steinberg::IPluginFactory* (PLUGIN_API *GetFactoryProc) ();
}
@@ -0,0 +1,122 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : SDK Core Interfaces
// Filename : pluginterfaces/base/iplugincompatibility.h
// Created by : Steinberg, 02/2022
// 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 "ibstream.h"
//------------------------------------------------------------------------
namespace Steinberg {
//------------------------------------------------------------------------
/** moduleinfo.json
The moduleinfo.json describes the contents of the plug-in in a JSON5 compatible format (See https://json5.org/).
It contains the factory info (see PFactoryInfo), the contained classes (see PClassInfo), the
included snapshots and a list of compatibility of the included classes.
An example moduleinfo.json:
\code
{
"Name": "",
"Version": "1.0",
"Factory Info": {
"Vendor": "Steinberg Media Technologies",
"URL": "http://www.steinberg.net",
"E-Mail": "mailto:info@steinberg.de",
"Flags": {
"Unicode": true,
"Classes Discardable": false,
"Component Non Discardable": false,
},
},
"Compatibility": [
{
"New": "B9F9ADE1CD9C4B6DA57E61E3123535FD",
"Old": [
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // just an example
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", // another example
],
},
],
"Classes": [
{
"CID": "B9F9ADE1CD9C4B6DA57E61E3123535FD",
"Category": "Audio Module Class",
"Name": "AGainSimple VST3",
"Vendor": "Steinberg Media Technologies",
"Version": "1.3.0.1",
"SDKVersion": "VST 3.7.4",
"Sub Categories": [
"Fx",
],
"Class Flags": 0,
"Cardinality": 2147483647,
"Snapshots": [
],
},
],
}
\endcode
*/
#define kPluginCompatibilityClass "Plugin Compatibility Class"
//------------------------------------------------------------------------
/** optional interface to query the compatibility of the plug-ins classes
- [plug imp]
A plug-in can add a class with this interface to its class factory if it cannot provide a
moduleinfo.json file in its plug-in package/bundle where the compatibility is normally part of.
If the module contains a moduleinfo.json the host will ignore this class.
The class must write into the stream an UTF-8 encoded json description of the compatibility of
the other classes in the factory.
It is expected that the JSON5 written starts with an array:
\code
[
{
"New": "B9F9ADE1CD9C4B6DA57E61E3123535FD",
"Old": [
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // just an example
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", // another example
],
},
]
\endcode
*/
class IPluginCompatibility : public FUnknown
{
public:
/** get the compatibility stream
* @param stream the stream the plug-in must write the UTF8 encoded JSON5 compatibility
* string.
* @return kResultTrue on success
*/
virtual tresult PLUGIN_API getCompatibilityJSON (IBStream* stream) = 0;
//------------------------------------------------------------------------
static const FUID iid;
};
DECLARE_CLASS_IID (IPluginCompatibility, 0x4AFD4B6A, 0x35D7C240, 0xA5C31414, 0xFB7D15E6)
//------------------------------------------------------------------------
} // Steinberg
@@ -0,0 +1,80 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : SDK Core Interfaces
// Filename : pluginterfaces/base/istringresult.h
// Created by : Steinberg, 01/2005
// Description : Strings 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 {
//------------------------------------------------------------------------
/** Interface to return an ascii string of variable size.
In order to manage memory allocation and deallocation properly,
this interface is used to transfer a string as result parameter of
a method requires a string of unknown size.
- [host imp] or [plug imp]
- [released: SX 4]
*/
class IStringResult : public FUnknown
{
public:
//------------------------------------------------------------------------
virtual void PLUGIN_API setText (const char8* text) = 0;
//------------------------------------------------------------------------
static const FUID iid;
};
DECLARE_CLASS_IID (IStringResult, 0x550798BC, 0x872049DB, 0x84920A15, 0x3B50B7A8)
//------------------------------------------------------------------------
/** Interface to a string of variable size and encoding.
- [host imp] or [plug imp]
- [released: ]
*/
class IString : public FUnknown
{
public:
//------------------------------------------------------------------------
/** Assign ASCII string */
virtual void PLUGIN_API setText8 (const char8* text) = 0;
/** Assign unicode string */
virtual void PLUGIN_API setText16 (const char16* text) = 0;
/** Return ASCII string. If the string is unicode so far, it will be converted.
So you need to be careful, because the conversion can result in data loss.
It is save though to call getText8 if isWideString() returns false */
virtual const char8* PLUGIN_API getText8 () = 0;
/** Return unicode string. If the string is ASCII so far, it will be converted. */
virtual const char16* PLUGIN_API getText16 () = 0;
/** !Do not use this method! Early implementations take the given pointer as
internal string and this will cause problems because 'free' will be used to delete the passed memory.
Later implementations will redirect 'take' to setText8 and setText16 */
virtual void PLUGIN_API take (void* s, bool isWide) = 0;
/** Returns true if the string is in unicode format, returns false if the string is ASCII */
virtual bool PLUGIN_API isWideString () const = 0;
//------------------------------------------------------------------------
static const FUID iid;
};
DECLARE_CLASS_IID (IString, 0xF99DB7A3, 0x0FC14821, 0x800B0CF9, 0x8E348EDF)
//------------------------------------------------------------------------
} // namespace Steinberg
@@ -0,0 +1,98 @@
//------------------------------------------------------------------------
// Project : Steinberg Module Architecture SDK
//
// Category : Basic Host Service Interfaces
// Filename : pluginterfaces/base/iupdatehandler.h
// Created by : Steinberg, 01/2004
// Description : Update handling
//
//-----------------------------------------------------------------------------
// 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 IDependent;
//------------------------------------------------------------------------
/** Host implements dependency handling for plugins.
- [host imp]
- [get this interface from IHostClasses]
- [released N3.1]
- Install/Remove change notifications
- Trigger updates when an object has changed
Can be used between host-objects and the Plug-In or
inside the Plug-In to handle internal updates!
\see IDependent
\ingroup frameworkHostClasses
*/
class IUpdateHandler: public FUnknown
{
public:
//------------------------------------------------------------------------
/** Install update notification for given object. It is essential to
remove all dependencies again using 'removeDependent'! Dependencies
are not removed automatically when the 'object' is released!
\param object : interface to object that sends change notifications
\param dependent : interface through which the update is passed */
virtual tresult PLUGIN_API addDependent (FUnknown* object, IDependent* dependent) = 0;
/** Remove a previously installed dependency.*/
virtual tresult PLUGIN_API removeDependent (FUnknown* object, IDependent* dependent) = 0;
/** Inform all dependents, that object has changed.
\param object is the object that has changed
\param message is a value of enum IDependent::ChangeMessage, usually IDependent::kChanged - can be
a private message as well (only known to sender and dependent)*/
virtual tresult PLUGIN_API triggerUpdates (FUnknown* object, int32 message) = 0;
/** Same as triggerUpdates, but delivered in idle (usefull to collect updates).*/
virtual tresult PLUGIN_API deferUpdates (FUnknown* object, int32 message) = 0;
static const FUID iid;
};
DECLARE_CLASS_IID (IUpdateHandler, 0xF5246D56, 0x86544d60, 0xB026AFB5, 0x7B697B37)
//------------------------------------------------------------------------
/** A dependent will get notified about changes of a model.
[plug imp]
- notify changes of a model
\see IUpdateHandler
\ingroup frameworkHostClasses
*/
class IDependent: public FUnknown
{
public:
//------------------------------------------------------------------------
/** Inform the dependent, that the passed FUnknown has changed. */
virtual void PLUGIN_API update (FUnknown* changedUnknown, int32 message) = 0;
enum ChangeMessage
{
kWillChange,
kChanged,
kDestroyed,
kWillDestroy,
kStdChangeMessageLast = kWillDestroy
};
//------------------------------------------------------------------------
static const FUID iid;
};
DECLARE_CLASS_IID (IDependent, 0xF52B7AAE, 0xDE72416d, 0x8AF18ACE, 0x9DD7BD5E)
//------------------------------------------------------------------------
} // namespace Steinberg
+196
View File
@@ -0,0 +1,196 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : SDK Core Interfaces
// Filename : pluginterfaces/base/keycodes.h
// Created by : Steinberg, 01/2004
// Description : Key Code Definitions
//
//-----------------------------------------------------------------------------
// 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 {
//------------------------------------------------------------------------------
/** Virtual Key Codes.
OS-independent enumeration of virtual keycodes.
*/
enum VirtualKeyCodes
{
KEY_BACK = 1,
KEY_TAB,
KEY_CLEAR,
KEY_RETURN,
KEY_PAUSE,
KEY_ESCAPE,
KEY_SPACE,
KEY_NEXT,
KEY_END,
KEY_HOME,
KEY_LEFT,
KEY_UP,
KEY_RIGHT,
KEY_DOWN,
KEY_PAGEUP,
KEY_PAGEDOWN,
KEY_SELECT,
KEY_PRINT,
KEY_ENTER,
KEY_SNAPSHOT,
KEY_INSERT,
KEY_DELETE,
KEY_HELP,
KEY_NUMPAD0,
KEY_NUMPAD1,
KEY_NUMPAD2,
KEY_NUMPAD3,
KEY_NUMPAD4,
KEY_NUMPAD5,
KEY_NUMPAD6,
KEY_NUMPAD7,
KEY_NUMPAD8,
KEY_NUMPAD9,
KEY_MULTIPLY,
KEY_ADD,
KEY_SEPARATOR,
KEY_SUBTRACT,
KEY_DECIMAL,
KEY_DIVIDE,
KEY_F1,
KEY_F2,
KEY_F3,
KEY_F4,
KEY_F5,
KEY_F6,
KEY_F7,
KEY_F8,
KEY_F9,
KEY_F10,
KEY_F11,
KEY_F12,
KEY_NUMLOCK,
KEY_SCROLL,
KEY_SHIFT,
KEY_CONTROL,
KEY_ALT,
KEY_EQUALS, // only occurs on a Mac
KEY_CONTEXTMENU, // Windows only
// multimedia keys
KEY_MEDIA_PLAY,
KEY_MEDIA_STOP,
KEY_MEDIA_PREV,
KEY_MEDIA_NEXT,
KEY_VOLUME_UP,
KEY_VOLUME_DOWN,
KEY_F13,
KEY_F14,
KEY_F15,
KEY_F16,
KEY_F17,
KEY_F18,
KEY_F19,
KEY_F20,
KEY_F21,
KEY_F22,
KEY_F23,
KEY_F24,
KEY_SUPER, // Win-Key on Windows, Ctrl-Key on macOS
VKEY_FIRST_CODE = KEY_BACK,
VKEY_LAST_CODE = KEY_SUPER,
VKEY_FIRST_ASCII = 128
/*
KEY_0 - KEY_9 are the same as ASCII '0' - '9' (0x30 - 0x39) + FIRST_ASCII
KEY_A - KEY_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A) + FIRST_ASCII
*/
};
//------------------------------------------------------------------------------
inline SMTG_CONSTEXPR14 tchar VirtualKeyCodeToChar (uint8 vKey)
{
if (vKey >= VKEY_FIRST_ASCII)
return (tchar)(vKey - VKEY_FIRST_ASCII + 0x30);
else if (vKey == KEY_SPACE)
return ' ';
return 0;
}
//------------------------------------------------------------------------------
inline SMTG_CONSTEXPR14 uint8 CharToVirtualKeyCode (tchar character)
{
if ((character >= 0x30 && character <= 0x39) || (character >= 0x41 && character <= 0x5A))
return (uint8)(character - 0x30 + VKEY_FIRST_ASCII);
if (character == ' ')
return (uint8)KEY_SPACE;
return 0;
}
/** OS-independent enumeration of virtual modifier-codes. */
enum KeyModifier
{
kShiftKey = 1 << 0, ///< same on Windows and macOS
kAlternateKey = 1 << 1, ///< same on Windows and macOS
kCommandKey = 1 << 2, ///< Windows: ctrl key; macOS: cmd key
kControlKey = 1 << 3 ///< Windows: win key, macOS: ctrl key
};
/** Simple data-struct representing a key-stroke on the keyboard. */
struct KeyCode
{
/** The associated character. */
tchar character {0};
/** The associated virtual key-code. */
uint8 virt {0};
/** The associated virtual modifier-code. */
uint8 modifier {0};
/** Constructs a new KeyCode. */
SMTG_CONSTEXPR14 KeyCode (tchar character = 0, uint8 virt = 0, uint8 modifier = 0)
: character (character), virt (virt), modifier (modifier)
{
}
SMTG_CONSTEXPR14 KeyCode& operator= (const KeyCode& other) SMTG_NOEXCEPT
{
character = other.character;
virt = other.virt;
modifier = other.modifier;
return *this;
}
};
/** Utility functions to handle key-codes.
* @see Steinberg::KeyCode
*/
namespace KeyCodes {}
namespace KeyCodes {
/** Is only a modifier pressed on the keyboard? */
template <typename Key>
bool isModifierOnlyKey (const Key& key)
{
return (key.character == 0 && (key.virt == KEY_SHIFT || key.virt == KEY_ALT ||
key.virt == KEY_CONTROL || key.virt == KEY_SUPER));
}
//------------------------------------------------------------------------
} // namespace KeyCodes
} // namespace Steinberg
@@ -0,0 +1,35 @@
//------------------------------------------------------------------------
// 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;
struct KeyCode;
//------------------------------------------------------------------------
} // namespace Steinberg
+386
View File
@@ -0,0 +1,386 @@
//-----------------------------------------------------------------------------
// 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 <utility>
#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) SMTG_NOEXCEPT : ptr (movePtr.take ()) { }
template <typename T>
inline IPtr (IPtr<T>&& movePtr) SMTG_NOEXCEPT : ptr (movePtr.take ()) { }
inline IPtr& operator= (IPtr<I>&& movePtr) SMTG_NOEXCEPT
{
if (ptr)
ptr->release ();
ptr = movePtr.take ();
return *this;
}
template <typename T>
inline IPtr& operator= (IPtr<T>&& movePtr)
{
if (ptr)
ptr->release ();
ptr = movePtr.take ();
return *this;
}
#endif
inline void reset (I* obj = nullptr)
{
if (ptr)
ptr->release();
ptr = obj;
}
I* take () SMTG_NOEXCEPT
{
I* out = ptr;
ptr = nullptr;
return out;
}
template <typename T>
static IPtr<T> adopt (T* obj) SMTG_NOEXCEPT { return IPtr<T> (obj, false); }
//------------------------------------------------------------------------
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 ();
ptr = nullptr; //TODO_CORE: how much does this cost? is this something hiding for us?
}
}
//------------------------------------------------------------------------
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
//------------------------------------------------------------------------
} // namespace Steinberg
@@ -0,0 +1,55 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : SDK Core Interfaces
// Filename : pluginterfaces/base/typesizecheck.h
// Created by : Steinberg, 08/2018
// Description : Compile time type size check macro
//
//-----------------------------------------------------------------------------
// 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
#define SMTG_TYPE_STATIC_CHECK(Operator, Type, Platform64Size, MacOS32Size, Win32Size, \
Linux32Size) \
namespace { \
template <typename Type, size_t w, size_t x, size_t y, size_t z> \
struct Operator##Check##Type \
{ \
constexpr Operator##Check##Type () \
{ \
static_assert (Operator (Type) == \
(SMTG_PLATFORM_64 ? w : SMTG_OS_MACOS ? x : SMTG_OS_LINUX ? z : y), \
"Struct " #Operator " error: " #Type); \
} \
}; \
static constexpr Operator##Check##Type<Type, Platform64Size, MacOS32Size, Win32Size, \
Linux32Size> \
instance##Operator##Type; \
}
/** Check the size of a structure depending on compilation platform
* Used to check that structure sizes don't change between SDK releases.
*/
#define SMTG_TYPE_SIZE_CHECK(Type, Platform64Size, MacOS32Size, Win32Size, Linux32Size) \
SMTG_TYPE_STATIC_CHECK (sizeof, Type, Platform64Size, MacOS32Size, Win32Size, Linux32Size)
/** Check the alignment of a structure depending on compilation platform
* Used to check that structure alignments don't change between SDK releases.
*/
#define SMTG_TYPE_ALIGN_CHECK(Type, Platform64Size, MacOS32Size, Win32Size, Linux32Size) \
SMTG_TYPE_STATIC_CHECK (alignof, Type, Platform64Size, MacOS32Size, Win32Size, Linux32Size)
#else
// need static_assert
#define SMTG_TYPE_SIZE_CHECK(Type, Platform64Size, MacOS32Size, Win32Size, Linux32Size)
#endif
+118
View File
@@ -0,0 +1,118 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : SDK Core Interfaces
// Filename : pluginterfaces/base/ucolorspec.h
// Created by : Steinberg, 02/2006 (Host: S4.1)
// Description : GUI data types
//
//-----------------------------------------------------------------------------
// 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 {
//------------------------------------------------------------------------
/** Colors
* \ingroup smtgtypedef */
/**@{*/
typedef uint32 ColorSpec;
typedef uint8 ColorComponent;
typedef ColorSpec UColorSpec; // legacy support
typedef ColorComponent UColorComponent; // legacy support
/**@}*/
/** Create color specifier with RGB values (alpha is opaque) */
inline SMTG_CONSTEXPR ColorSpec MakeColorSpec (ColorComponent r, ColorComponent g, ColorComponent b)
{
return 0xFF000000 | ((ColorSpec)r) << 16 | ((ColorSpec)g) << 8 | (ColorSpec)b;
}
/** Create color specifier with RGBA values */
inline SMTG_CONSTEXPR ColorSpec MakeColorSpec (ColorComponent r, ColorComponent g, ColorComponent b, ColorComponent a)
{
return ((ColorSpec)a) << 24 | ((ColorSpec)r) << 16 | ((ColorSpec)g) << 8 | (uint32)b;
}
inline SMTG_CONSTEXPR ColorComponent GetBlue (ColorSpec cs) { return (ColorComponent)(cs & 0x000000FF); }
inline SMTG_CONSTEXPR ColorComponent GetGreen (ColorSpec cs) { return (ColorComponent)((cs >> 8) & 0x000000FF); }
inline SMTG_CONSTEXPR ColorComponent GetRed (ColorSpec cs) { return (ColorComponent)((cs >> 16) & 0x000000FF); }
inline SMTG_CONSTEXPR ColorComponent GetAlpha (ColorSpec cs) { return (ColorComponent)((cs >> 24) & 0x000000FF); }
inline void SetBlue (ColorSpec& argb, ColorComponent b) { argb = (argb & 0xFFFFFF00) | (ColorSpec)(b); }
inline void SetGreen (ColorSpec& argb, ColorComponent g) { argb = (argb & 0xFFFF00FF) | (((ColorSpec)g) << 8); }
inline void SetRed (ColorSpec& argb, ColorComponent r) { argb = (argb & 0xFF00FFFF) | (((ColorSpec)r) << 16); }
inline void SetAlpha (ColorSpec& argb, ColorComponent a) { argb = (argb & 0x00FFFFFF) | (((ColorSpec)a) << 24); }
/** Normalized color components*/
/** { */
inline double NormalizeColorComponent (ColorComponent c) { return c / 255.0; }
inline ColorComponent DenormalizeColorComponent (double c) { return static_cast<ColorComponent> (c * 255.0); }
inline void SetAlphaNorm (ColorSpec& argb, double a) { SetAlpha (argb, DenormalizeColorComponent (a)); }
inline double GetAlphaNorm (ColorSpec cs) { return (NormalizeColorComponent (GetAlpha (cs))); }
inline double NormalizeAlpha (uint8 alpha) {return NormalizeColorComponent (alpha);}
inline ColorComponent DenormalizeAlpha (double alphaNorm) { return DenormalizeColorComponent (alphaNorm); }
/** } */
inline ColorSpec StripAlpha (ColorSpec argb) { return (argb & 0x00FFFFFF); }
inline ColorSpec SMTG_CONSTEXPR BlendColor (ColorSpec color, double opacity)
{
return MakeColorSpec (
GetRed (color),
GetGreen (color),
GetBlue (color),
static_cast<ColorComponent> (GetAlpha(color) * opacity)
);
}
enum StandardColor //TODO_REFACTOR: change to enum class (c++11)
{
kBlack = 0,
kWhite,
kGray5,
kGray10,
kGray20,
kGray30,
kGray40,
kGray50,
kGray60,
kGray70,
kGray80,
kGray90,
kRed,
kLtRed,
kDkRed,
kGreen,
kLtGreen,
kDkGreen,
kBlue,
kLtBlue,
kDkBlue,
kMagenta,
kLtMagenta,
kDkMagenta,
kYellow,
kLtYellow,
kDkYellow,
kOrange,
kLtOrange,
kDkOrange,
kGold,
kBlack50,
kBlack70,
kNumStandardColors,
kLtGray = kGray20,
kGray = kGray50,
kDkGray = kGray70
};
}
+275
View File
@@ -0,0 +1,275 @@
//-----------------------------------------------------------------------------
// 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 SMTG_OS_WINDOWS
#include <cstdio>
#ifdef _MSC_VER
#pragma warning (disable : 4996) // deprecated functions
#endif
#elif SMTG_OS_MACOS
#include <CoreFoundation/CoreFoundation.h>
#elif SMTG_OS_LINUX
#include <cstring>
#include <string>
#include <codecvt>
#include <sstream>
#include <locale>
#include <wctype.h>
#include <wchar.h>
#endif
//------------------------------------------------------------------------
namespace Steinberg {
//------------------------------------------------------------------------
#if SMTG_OS_LINUX
//------------------------------------------------------------------------
namespace {
using Converter = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>;
//------------------------------------------------------------------------
Converter& converter ()
{
static Converter instance;
return instance;
}
//------------------------------------------------------------------------
} // anonymous
//------------------------------------------------------------------------
#endif // SMTG_OS_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, i.e. StringLength (L"ABC\0") => 3 */
//------------------------------------------------------------------------
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 SMTG_OS_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 SMTG_OS_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 SMTG_OS_WINDOWS
return swprintf ((wchar_t*)thisBuffer, L"%.*lf", precision, value) != -1;
#elif SMTG_OS_MACOS
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 SMTG_OS_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 SMTG_OS_WINDOWS
return swscanf ((const wchar_t*)thisBuffer, L"%I64d", &value) != -1;
#elif SMTG_OS_MACOS
CFStringRef cfStr = CFStringCreateWithBytes (0, (const UInt8 *)thisBuffer, getLength () * 2, kCFStringEncodingUTF16, false);
if (cfStr)
{
value = CFStringGetIntValue (cfStr);
CFRelease (cfStr);
return true;
}
return false;
#elif SMTG_OS_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 SMTG_OS_WINDOWS
return swprintf ((wchar_t*)thisBuffer, L"%I64d", value) != -1;
#elif SMTG_OS_MACOS
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 SMTG_OS_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
+120
View File
@@ -0,0 +1,120 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : Helpers
// Filename : pluginterfaces/base/ustring.h
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "ftypes.h"
//------------------------------------------------------------------------
namespace Steinberg {
//------------------------------------------------------------------------
/** UTF-16 string class without buffer management.
Note: that some characters are encoded in 2 UTF16 code units (surrogate pair),
this means that getLength returns the number of code unit, not the count of character! */
class UString
{
public:
//------------------------------------------------------------------------
/** Construct from UTF-16 string, size is in code unit (count of char16) */
UString (char16* buffer, int32 size) : thisBuffer (buffer), thisSize (size) {}
/** returns buffer size */
int32 getSize () const { return thisSize; }
/** cast to char16* */
operator const char16* () const { return thisBuffer; }
/** Returns length of string (in code unit). Note this is not the count of character! */
int32 getLength () const;
/** Copy from UTF-16 buffer (srcSize is in code unit (count of char16)). */
UString& assign (const char16* src, int32 srcSize = -1);
/** Append UTF-16 buffer (srcSize is in code unit (count of char16)). */
UString& append (const char16* src, int32 srcSize = -1);
/** Copy to UTF-16 buffer (dstSize is in code unit (count of char16)). */
const UString& copyTo (char16* dst, int32 dstSize) const;
/** Copy from ASCII string (srcSize is in code unit (count of char16)). */
UString& fromAscii (const char* src, int32 srcSize = -1);
UString& assign (const char* src, int32 srcSize = -1) { return fromAscii (src, srcSize); }
/** Copy to ASCII string. */
const UString& toAscii (char* dst, int32 dstSize) const;
/** Scan integer from string. */
bool scanInt (int64& value) const;
/** Print integer to string. */
bool printInt (int64 value);
/** Scan float from string. */
bool scanFloat (double& value) const;
/** Print float to string. */
bool printFloat (double value, int32 precision = 4);
//------------------------------------------------------------------------
protected:
char16* thisBuffer;
int32 thisSize; ///< size in code unit (not in byte!)
};
//------------------------------------------------------------------------
/** UTF-16 string with fixed buffer size.
*/
template <int32 maxSize>
class UStringBuffer : public UString
{
public:
//------------------------------------------------------------------------
UStringBuffer () : UString (data, maxSize) { data[0] = 0; }
/** Construct from UTF-16 string. */
UStringBuffer (const char16* src, int32 srcSize = -1) : UString (data, maxSize)
{
data[0] = 0;
if (src)
assign (src, srcSize);
}
/** Construct from ASCII string. */
UStringBuffer (const char* src, int32 srcSize = -1) : UString (data, maxSize)
{
data[0] = 0;
if (src)
fromAscii (src, srcSize);
}
//------------------------------------------------------------------------
protected:
char16 data[maxSize];
};
//------------------------------------------------------------------------
/** Predefined UTF-16 string array types.
* \ingroup smtgtypedef */
/**@{*/
typedef UStringBuffer<128> UString128; ///< 128 character UTF-16 string
typedef UStringBuffer<256> UString256; ///< 256 character UTF-16 string
/**@}*/
} // namespace Steinberg
//------------------------------------------------------------------------
#define USTRING(asciiString) Steinberg::UString256 (asciiString)
#define USTRINGSIZE(var) (sizeof (var) / sizeof (Steinberg::char16))
//------------------------------------------------------------------------