Initial release
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
*/
|
||||
@@ -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
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
@@ -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
|
||||
//----------------------------------------------------------------------------------------------
|
||||
@@ -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)
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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
@@ -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))
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user