Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
[submodule "base"]
path = base
url = ../vst3_base
[submodule "cmake"]
path = cmake
url = ../vst3_cmake
[submodule "doc"]
path = doc
url = ../vst3_doc
[submodule "pluginterfaces"]
path = pluginterfaces
url = ../vst3_pluginterfaces
[submodule "public.sdk"]
path = public.sdk
url = ../vst3_public_sdk
[submodule "tutorials"]
path = tutorials
url = ../vst3_tutorials
[submodule "vstgui4"]
path = vstgui4
url = ../vstgui
+187
View File
@@ -0,0 +1,187 @@
cmake_minimum_required (VERSION 3.25.0)
# Specify the minimum version of the target platform
if(NOT DEFINED ENV{MACOSX_DEPLOYMENT_TARGET})
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "macOS deployment target")
endif()
# Global options which can bet set on command line e.g.: cmake -DSMTG_ENABLE_VST3_PLUGIN_EXAMPLES=OFF ...
option(SMTG_ENABLE_VST3_PLUGIN_EXAMPLES "Enable VST 3 Plug-in Examples" ON)
option(SMTG_ENABLE_VST3_HOSTING_EXAMPLES "Enable VST 3 Hosting Examples" ON)
option(SMTG_ENABLE_VSTGUI_SUPPORT "Enable VSTGUI Support" ON)
option(SMTG_ENABLE_WAYLAND_SUPPORT "Enable Wayland Support (Linux only)" OFF)
# -------------------------------------------------------------------------------
# Includes
# -------------------------------------------------------------------------------
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
include(SMTG_VST3_SDK)
# -------------------------------------------------------------------------------
# SDK Project
# -------------------------------------------------------------------------------
project(vstsdk
VERSION 3.8.0
DESCRIPTION "Steinberg VST 3 Software Development Kit"
HOMEPAGE_URL "https://www.steinberg.net"
)
smtg_setup_platform_toolset()
smtg_setup_symbol_visibility()
set(ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
# Set the location of the VST 3 SDK
set(SDK_ROOT "${ROOT}")
set(public_sdk_SOURCE_DIR ${SDK_ROOT}/public.sdk)
set(pluginterfaces_SOURCE_DIR ${SDK_ROOT}/pluginterfaces)
if(SMTG_ENABLE_VSTGUI_SUPPORT)
set(VSTGUI_ENABLE_WAYLAND_SUPPORT ${SMTG_ENABLE_WAYLAND_SUPPORT})
smtg_enable_vstgui_support(VSTGUI_SOURCE_DIR "${ROOT}/vstgui4")
endif()
include_directories(${ROOT} ${SDK_ROOT})
# -------------------------------------------------------------------------------
# From Here this is optional...
# -------------------------------------------------------------------------------
# CORE AUDIO SDK, AAX SDK
# -------------------------------------------------------------------------------
setupCoreAudioSupport()
setupAaxSupport()
include(SMTG_FindJack)
# -------------------------------------------------------------------------------
# Projects
# -------------------------------------------------------------------------------
set(SDK_IDE_LIBS_FOLDER FOLDER "Libraries")
#---Add base libraries---------------------------
smtg_create_lib_base_target()
smtg_create_pluginterfaces_target()
smtg_create_public_sdk_common_target()
smtg_create_public_sdk_target()
smtg_create_public_sdk_hosting_target()
set(VST_SDK TRUE) # used for pluginterfaces and public.sdk modules which provides only a subset of them for VST-SDK
add_subdirectory(public.sdk/source/vst/interappaudio)
#---Add Wrappers (AU, AAX)-----------------------
if (NOT SMTG_ENABLE_AUV2_BUILDS)
add_subdirectory(public.sdk/source/vst/auwrapper)
endif()
if(NOT "${SMTG_AAX_SDK_PATH}" STREQUAL "")
add_subdirectory(public.sdk/source/vst/aaxwrapper)
endif()
# Add hosting examples, it includes the validator (must be done before any plug-ins to support running the validator after building)
set(SDK_IDE_HOSTING_EXAMPLES_FOLDER FOLDER "Hosting-Examples")
add_subdirectory(public.sdk/samples/vst-hosting)
# Add utilities
set(SDK_IDE_UTILITIES_FOLDER FOLDER "Utilities")
add_subdirectory(public.sdk/samples/vst-utilities)
#---Add VST 3 examples (plug-ins and hosting)-----
if(SMTG_ENABLE_VST3_PLUGIN_EXAMPLES)
set(SDK_IDE_PLUGIN_EXAMPLES_FOLDER FOLDER "PlugIn-Examples")
add_subdirectory(public.sdk/samples/vst)
add_subdirectory(public.sdk/source/vst/auv3wrapper)
endif()
# -------------------------------------------------------------------------------
# IDE sorting
# -------------------------------------------------------------------------------
include(SMTG_CustomModuleTarget)
set_property(
TARGET
sdk
sdk_common
sdk_hosting
base
pluginterfaces
cmake_modules
cmake_VST_modules
PROPERTY
${SDK_IDE_LIBS_FOLDER}
)
if(TARGET base_ios)
set_property(
TARGET
base_ios
pluginterfaces_ios
PROPERTY
${SDK_IDE_LIBS_FOLDER}
)
endif()
if(SMTG_ENABLE_VSTGUI_SUPPORT)
set_property(
TARGET
vstgui
vstgui_support
vstgui_uidescription
PROPERTY
${SDK_IDE_LIBS_FOLDER}
)
if(TARGET vstgui_standalone)
set_target_properties(vstgui_standalone
PROPERTIES
${SDK_IDE_LIBS_FOLDER}
)
endif()
endif()
if(TARGET aax_wrapper)
set_target_properties(aax_wrapper
PROPERTIES
${SDK_IDE_LIBS_FOLDER}
)
endif()
# -------------------------------------------------------------------------------
# macOS & iOS collection targets
# -------------------------------------------------------------------------------
option(SMTG_VSTSDK_GENERATE_MACOS_IOS_COLLECTION_TARGETS "Create macOS and iOS collection targets" OFF)
if(SMTG_VSTSDK_GENERATE_MACOS_IOS_COLLECTION_TARGETS)
function(get_all_targets var)
set(targets)
get_all_targets_recursive(targets ${CMAKE_CURRENT_SOURCE_DIR})
set(${var} ${targets} PARENT_SCOPE)
endfunction()
macro(get_all_targets_recursive targets dir)
get_property(subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
foreach(subdir ${subdirectories})
get_all_targets_recursive(${targets} ${subdir})
endforeach()
get_property(current_targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
list(APPEND ${targets} ${current_targets})
endmacro()
get_all_targets(all_targets)
add_custom_target(iOS_Targets)
add_custom_target(macOS_Targets)
foreach(target_name ${all_targets})
if(${target_name} MATCHES "ios")
add_dependencies(iOS_Targets ${target_name})
else()
add_dependencies(macOS_Targets ${target_name})
endif()
endforeach()
endif()
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025, Steinberg Media Technologies GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+295
View File
@@ -0,0 +1,295 @@
<div style="text-align:center">
<img src="https://steinbergmedia.github.io/vst3_doc/gfx/vst3_logo.jpg" alt="VST 3 SDK" /></div>
# Welcome to VST SDK 3.8.x
## Table Of Contents
1. [The VST SDK package](#100)
1. [System requirements](#200)
1. [About VST plug-ins in general](#300)
1. [About VST 3](#400)
1. [How to build VST 3](#500)
1. [Contributing](#600)
1. [License & Usage guidelines](#700)
<div id='100'/>
## The VST SDK package contains
- VST 3 API
- VST 3 Implementation Helper Classes
- AAX, AUv3 and AU Wrappers
- VST 3 plug-ins Examples
The full **VST 3 SDK** is available [here!](https://www.steinberg.net/en/company/developers.html). It contains:
- VST 3 plug-in Test Host Application/Validator,
<div id='200'/>
## System requirements
Supported Platforms:
| Operating System | Architecture | Compiler | Notes |
| :-------------------------------- | :---------------------------- | :-------------------- | :-------------------------------- |
| Windows 11 | x86, x86_64, arm64, arm64EC | MSVC 2022 | |
| Windows 8.1/10 | x86, x86_64 | MSVC 2019, MSVC 2022 | |
| macOS 10.13 - 15 | x86, x86_64, Apple Silicon | Xcode 10 - 16 | |
| iOS 13 - 18 | arm64 | Xcode 11 - 16 | |
| Linux - Ubuntu 24.04 LTS | x86_64 | GCC 13.3 and higher | Visual Studio Code, Qt Creator |
---
<div id='300'/>
## About VST plug-ins in general
A VST plug-in is an audio processing component that is utilized within a host application. This host application provides the audio or/and event streams that are processed by the plug-in's code. Generally speaking, a VST plug-in can take a stream of audio data, apply a process to the audio, and return the result to the host application. A VST plug-in performs its process normally using the processor of the computer. The audio stream is broken down into a series of blocks. The host supplies the blocks in sequence. The host and its current environment control the block-size. The VST plug-in maintains the status of all its own parameters relating to the running process: The host does not maintain any information about what the plug-in did with the last block of data it processed.
From the host application's point of view, a VST plug-in is a black box with an arbitrary number of inputs, outputs (Event (MIDI) or Audio), and associated parameters. The host needs no implicit knowledge of the plug-in's process to be able to use it. The plug-in process can use whatever parameters it wishes, internally to the process, but depending on the capabilities of the host, it can allow the changes to user parameters to be automated by the host.
The source code of a VST plug-in is platform independent, but the delivery system depends on the platform architecture:
- On **Windows**, a VST plug-in is a multi-threaded DLL (Dynamic Link Library), recently packaged into a folder structure.
- On **Mac OS X**, a VST plug-in is a Mach-O Bundle
- On **Linux**, a VST plug-in is a package
To learn more about VST you can:
- subscribe to the [VST Developer Forum](https://sdk.steinberg.net)
- check the 3rd Party Developer Support section at [www.steinberg.net](https://www.steinberg.net/en/company/developers.html)
- check the VST 3 SDK online documentation under: [steinbergmedia.github.io/vst3_dev_portal](https://steinbergmedia.github.io/vst3_dev_portal/pages/index.html)
- check the online documentation under: [steinbergmedia.github.io/vst3_doc](https://steinbergmedia.github.io/vst3_doc)
---
<div id='400'/>
## About VST 3
VST 3 is a general rework of the long-serving VST plug-in interface. It is not compatible with the older VST versions, but it includes some new features and possibilities. We have redesigned the API to make it not only far easier and more reliable for developers to work with, but have also provided completely new possibilities for plug-ins. These include:
### 1. Improved Performance with the Silence Flag
Processing can optionally be applied to plug-ins only when audio signals are present on their respective inputs, so VST 3 plug-ins can apply their processing economically and only when it is needed.
### 2. Multiple Dynamic I/Os
VST 3 plug-ins are no longer limited to a fixed number of inputs and outputs, and their I/O configuration can dynamically adapt to the channel configuration. Side-chains are also very easily realizable. This includes the possibility to deactivate unused busses after loading and even reactivate those when needed. This cleans up the mixer and further helps to reduce CPU load.
### 3. Sample-accurate Automation
VST 3 also features vastly improved parameter automation with sample accuracy and support for ramped automation data, allowing completely accurate and rapid parameter automation changes.
### 4. Logical Parameter Organization
The VST 3 plug-in parameters are displayed in a tree structure. Parameters are grouped into sections which represent the structure of the plug-in. Plug-ins can communicate their internal structure for the purpose of overview, but also for some associated functionality (eg. program-lists).
### 5. Resizeable UI Editor
VST 3 defines a way to allow resizing of the plug-in editor by a user.
### 6. Mouse Over Support
The host could ask the plug-in which parameter is under the mouse.
### 7. Context Menu Support
VST 3 defines a way to allow the host to add its own entries in the plug-in context menu of a specific parameter.
### 8. Channel Context Information
A VST 3 plug-in could access some channel information where it is instantiated: name, color, ...
### 9. Note Expression
VST 3 defines with Note Expression a new way of event controller editing. The plug-in is able to break free from the limitations of MIDI controller events by providing access to new VST 3 controller events that circumvent the laws of MIDI and provide articulation information for each individual note (event) in a polyphonic arrangement according to its noteId.
### 10. 3D Support
VST 3 supports new speaker configurations like Ambisonic, Atmos, Auro 3D or 22.2.
### 11. Factory Concept
VST 3 plug-in library could export multiple plug-ins and in this way replaces the shell concept of VST 2 (kPlugCategShell).
### 12. Support Remote control Representation
VST 3 plug-in can deliver a specific parameter mapping for remote controls like Nuage.
### 13. Others
While designing VST 3, we performed a careful analysis of the existing functionality of VST and rewrote the interfaces from scratch. In doing so, we focused a lot on providing clear interfaces and their documentation in order to avoid usage errors from the deepest possible layer.
Some more features implemented specifically for developers include:
- More stable technical host/plug-in environment
- Advanced technical definition of the standard
- Modular approach
- Separation of UI and processing
- Advanced Preset System
- Multiple plug-ins per Library
- Test Host included
- Automated Testing Environment
- Validator (small command line Test Host) and plug-in examples code included
---
<div id='500'/>
## How to build VST 3
### Get the source code from GitHub
```c
git clone --recursive https://github.com/steinbergmedia/vst3sdk.git
```
### Build the examples on Windows
- Create a folder for the build and move to this folder (using cd):
```c
mkdir build
cd build
```
- Generate the Solution/Projects: provide the path of the Project where CMakeLists.txt is located:
```c
// examples:
cmake.exe -G "Visual Studio 17 2022" -A x64 ..\vst3sdk
// or without symbolic links
cmake.exe -G "Visual Studio 17 2022" -A x64 ..\vst3sdk -DSMTG_CREATE_PLUGIN_LINK=0
// or by using the local user program folder (FOLDERID_UserProgramFilesCommon) as VST3 folder
cmake.exe -G "Visual Studio 17 2022" -A x64 -DSMTG_PLUGIN_TARGET_USER_PROGRAM_FILES_COMMON=1
```
- Now you can build the plug-in (you can use Visual Studio too):
```c
msbuild.exe vstsdk.sln
// (or alternatively for example for release)
cmake --build . --config Release
```
Note: If you have any issue with symbolic links, check [Preparation on Windows](https://steinbergmedia.github.io/vst3_dev_portal/pages/Getting+Started/Preparation+on+Windows.html) for potential solutions.
### Build the examples on macOS
- Create a folder for the build and move to this folder (using cd):
```c
mkdir build
cd build
```
- Generate the Solution/Projects: provide the path of the Project where CMakeLists.txt is located:
```c
// For XCode:
cmake -GXcode ../vst3sdk
// Without XCode (here debug variant):
cmake -DCMAKE_BUILD_TYPE=Debug ../
```
- Now you can build the plug-in (you can use XCode too):
```c
xcodebuild
// (or alternatively for example for release)
cmake --build . --config Release
```
### Build the examples on Linux
- Install the required packages [Package Requirements](https://steinbergmedia.github.io/vst3_dev_portal/pages/Getting+Started/How+to+setup+my+system.html#for-linux)
- Create a folder for the build and move to this folder (using cd):
```c
mkdir build
cd build
```
- Generate the Solution/Projects: provide the path of the Project where CMakeLists.txt is located:
```c
cmake ../vst3sdk
```
- Now you can build the plug-in:
```c
make
// (or alternatively for example for release)
cmake --build . --config Release
```
### Build using cmake-gui
- start the cmake-gui Application
- **Browse Source...**: select the folder vst3sdk
- **Browse Build...**: select a folder where the outputs (projects/...) will be created. Typically, a folder named "build"
- you can check the SMTG Options
- Press **Configure**
- Press **Generate** and the project will be created
<div id='600'/>
## Contributing
For bug reports and features requests, please visit the [VST Developer Forum](https://sdk.steinberg.net)
<div id='700'/>
## License & Usage guidelines
- **VST 3 SDK** is under [MIT license](https://tlo.mit.edu/understand-ip/exploring-mit-open-source-license-comprehensive-guide).
- Developers can adopt the [MIT license](https://tlo.mit.edu/understand-ip/exploring-mit-open-source-license-comprehensive-guide) for full open-source integration.
- Licensing under **GPLv3** and the **Steinberg proprietary license** is no longer available.
- Code licensed under [MIT license](https://tlo.mit.edu/understand-ip/exploring-mit-open-source-license-comprehensive-guide) can be used, modified, and redistributed freely — including in commercial products — provided [MIT license](https://tlo.mit.edu/understand-ip/exploring-mit-open-source-license-comprehensive-guide) terms are followed.
More details are found at [www.steinberg.net/sdklicenses_vst3](http://www.steinberg.net/sdklicenses_vst3)
### Trademark and Logo Usage
#### General Principle
Trademark usage (e.g. "VST" name or logo) is optional under [MIT license](https://tlo.mit.edu/understand-ip/exploring-mit-open-source-license-comprehensive-guide), but if used, must comply with Steinberg's official trademark rules.
#### Permitted Use (if selected)
If you choose to display the **VST Compatible Logo** or refer to the **VST trademark**:
- Logos must be used in unaltered form.
- Use must follow the official usage guidelines provided in the SDK.
- The trademark/logo must appear only in clear product-related contexts, such as:
- Splash screens
- About boxes
- Product websites
- Documentation and manuals
This ensures legal compliance and brand consistency.
#### Prohibited Use
- Using “VST” (or derivatives like “VSTi”) in company or product names.
- Applying the logo or trademark to non-VST-compatible products.
- Associating the trademark with offensive, obscene, or inappropriate content.
#### VST trademark and/or VST Compatible Logo
If you choose to display the **VST trademark** and/or **VST Compatible Logo**, you must observe the *Steinberg VST Usage Guidelines*.
*Purpose*: To assist Steinberg in enforcing and protecting the **VST trademark** in international jurisdictions.
#### Notes for Developers
- The *Steinberg VST Usage Guidelines* are included in the SDK.
- Use of branding is not required under [MIT license](https://tlo.mit.edu/understand-ip/exploring-mit-open-source-license-comprehensive-guide), but if you choose to use it, trademark compliance is mandatory.
- Non-compliance with logo guidelines does not affect your MIT rights (but may result in trademark violations).
#### Best Practice Recommendation
Although optional, we encourage developers using VST under [MIT license](https://tlo.mit.edu/understand-ip/exploring-mit-open-source-license-comprehensive-guide) to follow the *Steinberg VST Usage Guidelines*.It fosters ecosystem-wide recognition, improves end-user trust, and supports the long-term visibility of the **VST** brand.
Binary file not shown.
+24
View File
@@ -0,0 +1,24 @@
//-----------------------------------------------------------------------------
MIT License
Copyright (c) 2025, Steinberg Media Technologies GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
//---------------------------------------------------------------------------------
+10
View File
@@ -0,0 +1,10 @@
# Welcome to VST SDK 3 base
Here you can find some helper classes useful for developing **VST 3** plug-ins.
## License & Usage guidelines
More details are found at [www.steinberg.net/sdklicenses_vst3](http://www.steinberg.net/sdklicenses_vst3)
----
Return to [VST 3 SDK](https://github.com/steinbergmedia/vst3sdk)
+32
View File
@@ -0,0 +1,32 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/baseidds.cpp
// Created by : Steinberg, 01/2008
// 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 "pluginterfaces/base/funknown.h"
#include "pluginterfaces/base/istringresult.h"
#include "pluginterfaces/base/ipersistent.h"
namespace Steinberg {
DEF_CLASS_IID (IString)
DEF_CLASS_IID (IStringResult)
DEF_CLASS_IID (IPersistent)
DEF_CLASS_IID (IAttributes)
DEF_CLASS_IID (IAttributes2)
//------------------------------------------------------------------------
} // namespace Steinberg
+67
View File
@@ -0,0 +1,67 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/classfactoryhelpers.h
// Created by : Steinberg, 03/2017
// Description : Class factory
//
//-----------------------------------------------------------------------------
// 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
//------------------------------------------------------------------------------
// Helper Macros. Not intended for direct use.
// Use:
// META_CLASS(className),
// META_CLASS_IFACE(className,Interface),
// META_CLASS_SINGLE(className,Interface)
// instead.
//------------------------------------------------------------------------------
#define META_CREATE_FUNC(funcName) static FUnknown* funcName ()
#define CLASS_CREATE_FUNC(className) \
namespace Meta { \
META_CREATE_FUNC (make##className) { return (NEW className)->unknownCast (); } \
}
#define SINGLE_CREATE_FUNC(className) \
namespace Meta { \
META_CREATE_FUNC (make##className) { return className::instance ()->unknownCast (); } \
}
#define _META_CLASS(className) \
namespace Meta { \
static Steinberg::MetaClass meta##className ((#className), Meta::make##className); \
}
#define _META_CLASS_IFACE(className, Interface) \
namespace Meta { \
static Steinberg::MetaClass meta##Interface##className ((#className), Meta::make##className, \
Interface##_iid); \
}
/** TODO
*/
#define META_CLASS(className) \
CLASS_CREATE_FUNC (className) \
_META_CLASS (className)
/** TODO
*/
#define META_CLASS_IFACE(className, Interface) \
CLASS_CREATE_FUNC (className) \
_META_CLASS_IFACE (className, Interface)
/** TODO
*/
#define META_CLASS_SINGLE(className, Interface) \
SINGLE_CREATE_FUNC (className) \
_META_CLASS_IFACE (className, Interface)
+621
View File
@@ -0,0 +1,621 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fbuffer.cpp
// Created by : Steinberg, 2008
// Description :
//
//-----------------------------------------------------------------------------
// 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 "base/source/fbuffer.h"
#include "base/source/fstring.h"
#include <cstdlib>
namespace Steinberg {
//-------------------------------------------------------------------------------------
Buffer::Buffer ()
: buffer (nullptr)
, memSize (0)
, fillSize (0)
, delta (defaultDelta)
{}
//-------------------------------------------------------------------------------------
Buffer::Buffer (uint32 s, uint8 initVal)
: buffer (nullptr)
, memSize (s)
, fillSize (0)
, delta (defaultDelta)
{
if (memSize == 0)
return;
buffer = (int8*)::malloc (memSize);
if (buffer)
memset (buffer, initVal, memSize);
else
memSize = 0;
}
//-------------------------------------------------------------------------------------
Buffer::Buffer (uint32 s)
: buffer (nullptr)
, memSize (s)
, fillSize (0)
, delta (defaultDelta)
{
if (memSize == 0)
return;
buffer = (int8*)::malloc (memSize);
if (!buffer)
memSize = 0;
}
//-------------------------------------------------------------------------------------
Buffer::Buffer (const void* b , uint32 s)
: buffer (nullptr)
, memSize (s)
, fillSize (s)
, delta (defaultDelta)
{
if (memSize == 0)
return;
buffer = (int8*)::malloc (memSize);
if (buffer)
memcpy (buffer, b, memSize);
else
{
memSize = 0;
fillSize = 0;
}
}
//-------------------------------------------------------------------------------------
Buffer::Buffer (const Buffer& bufferR)
: buffer (nullptr)
, memSize (bufferR.memSize)
, fillSize (bufferR.fillSize)
, delta (bufferR.delta)
{
if (memSize == 0)
return;
buffer = (int8*)::malloc (memSize);
if (buffer)
memcpy (buffer, bufferR.buffer, memSize);
else
memSize = 0;
}
//-------------------------------------------------------------------------------------
Buffer::~Buffer ()
{
if (buffer)
::free (buffer);
buffer = nullptr;
}
//-------------------------------------------------------------------------------------
void Buffer::operator = (const Buffer& b2)
{
if (&b2 != this)
{
setSize (b2.memSize);
if (b2.memSize > 0 && buffer)
memcpy (buffer, b2.buffer, b2.memSize);
fillSize = b2.fillSize;
delta = b2.delta;
}
}
//-------------------------------------------------------------------------------------
bool Buffer::operator == (const Buffer& b2)const
{
if (&b2 == this)
return true;
if (b2.getSize () != getSize ())
return false;
return memcmp (this->int8Ptr (), b2.int8Ptr (), getSize ()) == 0 ? true : false;
}
//-------------------------------------------------------------------------------------
uint32 Buffer::get (void* b, uint32 size)
{
uint32 maxGet = memSize - fillSize;
if (size > maxGet)
size = maxGet;
if (size > 0)
memcpy (b, buffer + fillSize, size);
fillSize += size;
return size;
}
//-------------------------------------------------------------------------------------
bool Buffer::put (char16 c)
{
return put ((const void*)&c, sizeof (c));
}
//-------------------------------------------------------------------------------------
bool Buffer::put (uint8 byte)
{
if (grow (fillSize + 1) == false)
return false;
buffer [fillSize++] = byte;
return true;
}
//-------------------------------------------------------------------------------------
bool Buffer::put (char c)
{
if (grow (fillSize + 1) == false)
return false;
buffer [fillSize++] = c;
return true;
}
//-------------------------------------------------------------------------------------
bool Buffer::put (const void* toPut, uint32 s)
{
if (!toPut)
return false;
if (grow (fillSize + s) == false)
return false;
memcpy (buffer + fillSize, toPut, s);
fillSize += s;
return true;
}
//-------------------------------------------------------------------------------------
bool Buffer::put (const String& str)
{
return put ((const void*)str.text () , (str.length () + 1) * sizeof (tchar));
}
//-------------------------------------------------------------------------------------
bool Buffer::appendString8 (const char8* s)
{
if (!s)
return false;
uint32 len = (uint32) strlen (s);
return put (s, len);
}
//-------------------------------------------------------------------------------------
bool Buffer::appendString16 (const char16* s)
{
if (!s)
return false;
ConstString str (s);
uint32 len = (uint32) str.length () * sizeof (char16);
return put (s, len);
}
//-------------------------------------------------------------------------------------
bool Buffer::prependString8 (const char8* s)
{
if (!s)
return false;
uint32 len = (uint32) strlen (s);
if (len > 0)
{
shiftStart (len);
memcpy (buffer, s, len);
return true;
}
return false;
}
//-------------------------------------------------------------------------------------
bool Buffer::prependString16 (const char16* s)
{
if (!s)
return false;
ConstString str (s);
uint32 len = (uint32) str.length () * sizeof (char16);
if (len > 0)
{
shiftStart (len);
memcpy (buffer, s, len);
return true;
}
return false;
}
//-------------------------------------------------------------------------------------
bool Buffer::prependString8 (char8 c)
{
shiftStart (sizeof (char));
char* b = (char*)buffer;
b [0] = c;
return true;
}
//-------------------------------------------------------------------------------------
bool Buffer::prependString16 (char16 c)
{
shiftStart (sizeof (char16));
char16* b = (char16*)buffer;
b [0] = c;
return true;
}
//-------------------------------------------------------------------------------------
bool Buffer::copy (uint32 from, uint32 to, uint32 bytes)
{
if (from + bytes > memSize || bytes == 0)
return false;
if (to + bytes > memSize)
setSize (to + bytes);
if (from + bytes > to && from < to)
{ // overlap
Buffer tmp (buffer + from, bytes);
memcpy (buffer + to, tmp, bytes);
}
else
memcpy (buffer + to, buffer + from, bytes);
return true;
}
//-------------------------------------------------------------------------------------
bool Buffer::makeHexString (String& result)
{
unsigned char* data = uint8Ptr ();
uint32 bytes = getSize ();
if (data == nullptr || bytes == 0)
return false;
char8* stringBuffer = NEWSTR8 ((bytes * 2) + 1);
if (!stringBuffer)
return false;
int32 count = 0;
while (bytes > 0)
{
unsigned char t1 = ((*data) >> 4) & 0x0F;
unsigned char t2 = (*data) & 0x0F;
if (t1 < 10)
t1 += '0';
else
t1 = t1 - 10 + 'A';
if (t2 < 10)
t2 += '0';
else
t2 = t2 - 10 + 'A';
stringBuffer [count++] = t1;
stringBuffer [count++] = t2;
data++;
bytes--;
}
stringBuffer [count] = 0;
result.take ((void*)stringBuffer, false);
return true;
}
//-------------------------------------------------------------------------------------
bool Buffer::fromHexString (const char8* string)
{
flush ();
if (string == nullptr)
return false;
int32 len = strlen8 (string);
if (len == 0 || ((len & 1) == 1)/*odd number*/ )
return false;
setSize (len / 2);
unsigned char* data = uint8Ptr ();
bool upper = true;
int32 count = 0;
while (count < len)
{
char c = string [count];
unsigned char d = 0;
if (c >= '0' && c <= '9') d += c - '0';
else if (c >= 'A' && c <= 'F') d += c - 'A' + 10;
else if (c >= 'a' && c <= 'f') d += c - 'a' + 10;
else return false; // no hex string
if (upper)
data [count >> 1] = static_cast<unsigned char> (d << 4);
else
data [count >> 1] += d;
upper = !upper;
count++;
}
setFillSize (len / 2);
return true;
}
//------------------------------------------------------------------------
void Buffer::set (uint8 value)
{
if (buffer)
memset (buffer, value, memSize);
}
//-------------------------------------------------------------------------------------
bool Buffer::setFillSize (uint32 c)
{
if (c <= memSize)
{
fillSize = c;
return true;
}
return false;
}
//-------------------------------------------------------------------------------------
bool Buffer::truncateToFillSize ()
{
if (fillSize < memSize)
setSize (fillSize);
return true;
}
//-------------------------------------------------------------------------------------
bool Buffer::grow (uint32 newSize)
{
if (newSize > memSize)
{
if (delta == 0)
delta = defaultDelta;
uint32 s = ((newSize + delta - 1) / delta) * delta;
return setSize (s);
}
return true;
}
//------------------------------------------------------------------------
void Buffer::shiftAt (uint32 position, int32 amount)
{
if (amount > 0)
{
if (grow (fillSize + amount))
{
if (position < fillSize)
memmove (buffer + amount + position, buffer + position, fillSize - position);
fillSize += amount;
}
}
else if (amount < 0 && fillSize > 0)
{
uint32 toRemove = -amount;
if (toRemove < fillSize)
{
if (position < fillSize)
memmove (buffer + position, buffer + toRemove + position, fillSize - position - toRemove);
fillSize -= toRemove;
}
}
}
//-------------------------------------------------------------------------------------
void Buffer::move (int32 amount, uint8 initVal)
{
if (memSize == 0)
return;
if (amount > 0)
{
if ((uint32)amount < memSize)
{
memmove (buffer + amount, buffer, memSize - amount);
memset (buffer, initVal, amount);
}
else
memset (buffer, initVal, memSize);
}
else
{
uint32 toRemove = -amount;
if (toRemove < memSize)
{
memmove (buffer, buffer + toRemove, memSize - toRemove);
memset (buffer + memSize - toRemove, initVal, toRemove);
}
else
memset (buffer, initVal, memSize);
}
}
//-------------------------------------------------------------------------------------
bool Buffer::setSize (uint32 newSize)
{
if (memSize != newSize)
{
if (buffer)
{
if (newSize > 0)
{
int8* newBuffer = (int8*) ::realloc (buffer, newSize);
if (newBuffer == nullptr)
{
newBuffer = (int8*)::malloc (newSize);
if (newBuffer)
{
uint32 tmp = newSize;
if (tmp > memSize)
tmp = memSize;
memcpy (newBuffer, buffer, tmp);
::free (buffer);
buffer = newBuffer;
}
else
{
::free (buffer);
buffer = nullptr;
}
}
else
buffer = newBuffer;
}
else
{
::free (buffer);
buffer = nullptr;
}
}
else
buffer = (int8*)::malloc (newSize);
if (newSize > 0 && !buffer)
memSize = 0;
else
memSize = newSize;
if (fillSize > memSize)
fillSize = memSize;
}
return (newSize > 0) == (buffer != nullptr);
}
//-------------------------------------------------------------------------------------
void Buffer::fillup (uint8 value)
{
if (getFree () > 0)
memset (buffer + fillSize, value, getFree ());
}
//-------------------------------------------------------------------------------------
int8* Buffer::operator + (uint32 i)
{
if (i < memSize)
return buffer + i;
static int8 eof;
eof = 0;
return &eof;
}
//-------------------------------------------------------------------------------------
bool Buffer::swap (int16 swapSize)
{
return swap (buffer, memSize, swapSize);
}
//-------------------------------------------------------------------------------------
bool Buffer::swap (void* buffer, uint32 bufferSize, int16 swapSize)
{
if (swapSize != kSwap16 && swapSize != kSwap32 && swapSize != kSwap64)
return false;
if (swapSize == kSwap16)
{
for (uint32 count = 0 ; count < bufferSize ; count += 2)
{
SWAP_16 ( * (((int16*)buffer) + count) );
}
}
else if (swapSize == kSwap32)
{
for (uint32 count = 0 ; count < bufferSize ; count += 4)
{
SWAP_32 ( * (((int32*)buffer) + count) );
}
}
else if (swapSize == kSwap64)
{
for (uint32 count = 0 ; count < bufferSize ; count += 8)
{
SWAP_64 ( * (((int64*)buffer) + count) );
}
}
return true;
}
//-------------------------------------------------------------------------------------
void Buffer::take (Buffer& from)
{
setSize (0);
memSize = from.memSize;
fillSize = from.fillSize;
buffer = from.buffer;
from.buffer = nullptr;
from.memSize = 0;
from.fillSize = 0;
}
//-------------------------------------------------------------------------------------
int8* Buffer::pass ()
{
int8* res = buffer;
buffer = nullptr;
memSize = 0;
fillSize = 0;
return res;
}
//-------------------------------------------------------------------------------------
bool Buffer::toWideString (int32 sourceCodePage)
{
if (getFillSize () > 0)
{
if (str8 () [getFillSize () - 1] != 0) // multiByteToWideString only works with 0-terminated strings
endString8 ();
Buffer dest (getFillSize () * sizeof (char16));
int32 result = String::multiByteToWideString (dest.str16 (), str8 (), dest.getFree () / sizeof (char16), sourceCodePage);
if (result > 0)
{
dest.setFillSize ((result - 1) * sizeof (char16));
take (dest);
return true;
}
return false;
}
return true;
}
//-------------------------------------------------------------------------------------
bool Buffer::toMultibyteString (int32 destCodePage)
{
if (getFillSize () > 0)
{
int32 textLength = getFillSize () / sizeof (char16); // wideStringToMultiByte only works with 0-terminated strings
if (str16 () [textLength - 1] != 0)
endString16 ();
Buffer dest (getFillSize ());
int32 result = String::wideStringToMultiByte (dest.str8 (), str16 (), dest.getFree (), destCodePage);
if (result > 0)
{
dest.setFillSize (result - 1);
take (dest);
return true;
}
return false;
}
return true;
}
//------------------------------------------------------------------------
} // namespace Steinberg
+286
View File
@@ -0,0 +1,286 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fbuffer.h
// Created by : Steinberg, 2008
// Description :
//
//-----------------------------------------------------------------------------
// 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"
#include <cstring>
namespace Steinberg {
class String;
//------------------------------------------------------------------------
/** Buffer.
@ingroup adt
A Buffer is an object-oriented wrapper for a piece of memory.
It adds several utility functions, e.g. for managing the size of the Buffer,
appending or prepending values or strings to it.
Internally it uses the standard memory functions malloc(), free(), etc. */
//------------------------------------------------------------------------
class Buffer
{
public:
//---------------------------------------------------------------------
/** Default constructor, allocates no memory at all.
*/
Buffer ();
/** Constructor - creates a new Buffer with a given size and copies contents from optional memory pointer.
\param[in] b : optional memory pointer with the size of at least the given size
\param[in] size : the size of the new Buffer to be allocated, in bytes.
*/
Buffer (const void* b, uint32 size);
/** Constructor - creates a new Buffer with a given size and fills it all with a given value.
\param[in] size : the size of the new Buffer to be allocated, in bytes.
\param[in] initVal : the initial value the Buffer will be completely filled with
*/
Buffer (uint32 size, uint8 initVal);
/** Constructor - creates a new Buffer with a given size.
\param[in] size : the size of the new Buffer to be allocated, in bytes.
*/
Buffer (uint32 size);
/** Copy constructor - creates a new Buffer from a given Buffer.
\param[in] buff : the Buffer from which all memory will be copied to the new one
*/
Buffer (const Buffer& buff);
/** Destructor - deallocates the internal memory.
*/
virtual ~Buffer ();
/** Assignment operator - copies contents from a given Buffer and increases the size if necessary.
\param[in] buff : the Buffer from which all memory will be copied
*/
void operator = (const Buffer& buff);
/** Comparison operator - copies contents from a given Buffer and increases the size if necessary.
\param[in] buff : the Buffer to be compared to
\return true, if the given Buffer's content is equal to this one, else false
*/
bool operator == (const Buffer& buff)const;
uint32 getSize () const {return memSize;} ///< \return the actual size of the Buffer's memory, in bytes.
/** Sets a new size for this Buffer, keeping as much content as possible.
\param[in] newSize : the new size for the Buffer, in bytes, newSize maybe zero
\return true, if the new size could be adapted, else false
*/
bool setSize (uint32 newSize);
/** Increases the Buffer to the next block, block size given by delta.
\param[in] memSize : the new minimum size of the Buffer, newSize maybe zero
\return true, if the Buffer could be grown successfully, else false
*/
bool grow (uint32 memSize);
bool setMaxSize (uint32 size) {return grow (size);} ///< see \ref grow()
void fillup (uint8 initVal = 0); ///< set from fillSize to end
uint32 getFillSize ()const {return fillSize;} ///< \return the actual fill size
bool setFillSize (uint32 c); ///< sets a new fill size, does not change any memory
inline void flush () {setFillSize (0);} ///< sets fill size to zero
bool truncateToFillSize (); ///< \return always true, truncates the size of the Buffer to the actual fill size
bool isFull () const { return (fillSize == memSize); } ///< \return true, if all memory is filled up, else false
uint32 getFree () const { return (memSize - fillSize); }///< \return remaining memory
inline void shiftStart (int32 amount) {return shiftAt (0, amount);} ///< moves all memory by given amount, grows the Buffer if necessary
void shiftAt (uint32 position, int32 amount); ///< moves memory starting at the given position
void move (int32 amount, uint8 initVal = 0); ///< shifts memory at start without growing the buffer, so data is lost and initialized with init val
bool copy (uint32 from, uint32 to, uint32 bytes); ///< copies a number of bytes from one position to another, the size may be adapted
uint32 get (void* b, uint32 size); ///< copy to buffer from fillSize, and shift fillSize
void setDelta (uint32 d) {delta = d;} ///< define the block size by which the Buffer grows, see \ref grow()
bool put (uint8); ///< append value at end, grows Buffer if necessary
bool put (char16 c); ///< append value at end, grows Buffer if necessary
bool put (char c); ///< append value at end, grows Buffer if necessary
bool put (const void* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
bool put (void* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
bool put (uint8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
bool put (char8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
bool put (const uint8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
bool put (const char8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
bool put (const String&); ///< append String at end, grows Buffer if necessary
void set (uint8 value); ///< fills complete Buffer with given value
// strings ----------------
bool appendString (const tchar* s);
bool appendString (tchar* s);
bool appendString (tchar c) { return put (c); }
bool appendString8 (const char8* s);
bool appendString16 (const char16* s);
bool appendString8 (char8* s) { return appendString8 ((const char8*)s); }
bool appendString8 (unsigned char* s) { return appendString8 ((const char8*)s); }
bool appendString8 (const unsigned char* s) { return appendString8 ((const char8*)s); }
bool appendString8 (char8 c) { return put ((uint8)c); }
bool appendString8 (unsigned char c) { return put (c); }
bool appendString16 (char16 c) { return put (c); }
bool appendString16 (char16* s) { return appendString16 ((const char16*)s); }
bool prependString (const tchar* s);
bool prependString (tchar* s);
bool prependString (tchar c);
bool prependString8 (const char8* s);
bool prependString16 (const char16* s);
bool prependString8 (char8 c);
bool prependString8 (unsigned char c) { return prependString8 ((char8)c); }
bool prependString8 (char8* s) { return prependString8 ((const char8*)s); }
bool prependString8 (unsigned char* s) { return prependString8((const char8*)s); }
bool prependString8 (const unsigned char* s) { return prependString8 ((const char8*)s); }
bool prependString16 (char16 c);
bool prependString16 (char16* s) { return prependString16 ((const char16*)s); }
bool operator+= (const char* s) { return appendString8 (s); }
bool operator+= (char c) { return appendString8 (c); }
bool operator+= (const char16* s) { return appendString16 (s); }
bool operator+= (char16 c) { return appendString16 (c); }
bool operator= (const char* s) { flush (); return appendString8 (s); }
bool operator= (const char16* s) { flush (); return appendString16 (s); }
bool operator= (char8 c) { flush (); return appendString8 (c); }
bool operator= (char16 c) { flush (); return appendString16 (c); }
void endString () {put (tchar (0));}
void endString8 () {put (char8 (0));}
void endString16 () {put (char16 (0));}
bool makeHexString (String& result);
bool fromHexString (const char8* string);
// conversion
operator void* () const { return (void*)buffer; } ///< conversion
inline tchar* str () const {return (tchar*)buffer;} ///< conversion
inline char8* str8 () const {return (char8*)buffer;} ///< conversion
inline char16* str16 () const {return (char16*)buffer;} ///< conversion
inline int8* int8Ptr () const {return (int8*)buffer;} ///< conversion
inline uint8* uint8Ptr () const {return (uint8*)buffer; } ///< conversion
inline int16* int16Ptr () const {return (int16*)buffer; } ///< conversion
inline uint16* uint16Ptr () const {return (uint16*)buffer; } ///< conversion
inline int32* int32Ptr () const {return (int32*)buffer; } ///< conversion
inline uint32* uint32Ptr () const {return (uint32*)buffer; } ///< conversion
inline float* floatPtr () const {return (float*)buffer; } ///< conversion
inline double* doublePtr () const {return (double*)buffer; } ///< conversion
inline char16* wcharPtr () const {return (char16*)buffer;} ///< conversion
int8* operator + (uint32 i); ///< \return the internal Buffer's address plus the given offset i, zero if offset is out of range
int32 operator ! () { return buffer == nullptr; }
enum swapSize
{
kSwap16 = 2,
kSwap32 = 4,
kSwap64 = 8
};
bool swap (int16 swapSize); ///< swap all bytes of this Buffer by the given swapSize
static bool swap (void* buffer, uint32 bufferSize, int16 swapSize); ///< utility, swap given number of bytes in given buffer by the given swapSize
void take (Buffer& from); ///< takes another Buffer's memory, frees the current Buffer's memory
int8* pass (); ///< pass the current Buffer's memory
/** Converts a Buffer's content to UTF-16 from a given multi-byte code page, Buffer must contain char8 of given encoding.
\param[in] sourceCodePage : the actual code page of the Buffer's content
\return true, if the conversion was successful, else false
*/
virtual bool toWideString (int32 sourceCodePage); // Buffer contains char8 of given encoding -> utf16
/** Converts a Buffer's content from UTF-16 to a given multi-byte code page, Buffer must contain UTF-16 encoded characters.
\param[in] destCodePage : the desired code page to convert the Buffer's content to
\return true, if the conversion was successful, else false
*/
virtual bool toMultibyteString (int32 destCodePage); // Buffer contains utf16 -> char8 of given encoding
//------------------------------------------------------------------------
protected:
static const uint32 defaultDelta = 0x1000; // 0x1000
int8* buffer;
uint32 memSize;
uint32 fillSize;
uint32 delta;
};
inline bool Buffer::put (void* p, uint32 count) { return put ((const void*)p , count ); }
inline bool Buffer::put (uint8 * p, uint32 count) { return put ((const void*)p , count ); }
inline bool Buffer::put (char8* p, uint32 count) { return put ((const void*)p , count ); }
inline bool Buffer::put (const uint8* p, uint32 count) { return put ((const void*)p , count ); }
inline bool Buffer::put (const char8* p, uint32 count) { return put ((const void*)p , count ); }
//------------------------------------------------------------------------
inline bool Buffer::appendString (const tchar* s)
{
#ifdef UNICODE
return appendString16 (s);
#else
return appendString8 (s);
#endif
}
//------------------------------------------------------------------------
inline bool Buffer::appendString (tchar* s)
{
#ifdef UNICODE
return appendString16 (s);
#else
return appendString8 (s);
#endif
}
//------------------------------------------------------------------------
inline bool Buffer::prependString (const tchar* s)
{
#ifdef UNICODE
return prependString16 (s);
#else
return prependString8 (s);
#endif
}
//------------------------------------------------------------------------
inline bool Buffer::prependString (tchar* s)
{
#ifdef UNICODE
return prependString16 (s);
#else
return prependString8 (s);
#endif
}
//------------------------------------------------------------------------
inline bool Buffer::prependString (tchar c)
{
#ifdef UNICODE
return prependString16 (c);
#else
return prependString8 (c);
#endif
}
//------------------------------------------------------------------------
} // namespace Steinberg
+302
View File
@@ -0,0 +1,302 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fcleanup.h
// Created by : Steinberg, 2008
// Description : Template classes for automatic resource cleanup
//
//-----------------------------------------------------------------------------
// 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 <cstdlib>
namespace Steinberg {
/** Template definition for classes that help guarding against memory leaks.
A stack allocated object of this type automatically deletes an at construction time passed
dynamically allocated single object when it reaches the end of its scope. \n\n
Intended usage:
\code
{
int* pointerToInt = new int;
Steinberg::FDeleter<int> deleter (pointerToInt);
// Do something with the variable behind pointerToInt.
} // No memory leak here, destructor of deleter cleans up the integer.
\endcode
*/
//------------------------------------------------------------------------
template <class T>
struct FDeleter
{
/// Constructor. _toDelete is a pointer to the dynamically allocated object that is to be
/// deleted when this FDeleter object's destructor is executed.
FDeleter (T* _toDelete) : toDelete (_toDelete) {}
/// Destructor. Calls delete on the at construction time passed pointer.
~FDeleter ()
{
if (toDelete)
delete toDelete;
}
T* toDelete; ///< Remembers the object that is to be deleted during destruction.
};
/** Template definition for classes that help guarding against memory leaks.
A stack allocated object of this type automatically deletes an at construction time passed
dynamically allocated array of objects when it reaches the end of its scope. \n\n
Intended usage:
\code
{
int* pointerToIntArray = new int[10];
Steinberg::FArrayDeleter<int> deleter (pointerToIntArray);
// Do something with the array behind pointerToIntArray.
} // No memory leak here, destructor of deleter cleans up the integer array.
\endcode
*/
//------------------------------------------------------------------------
template <class T>
struct FArrayDeleter
{
/// Constructor. _arrayToDelete is a pointer to the dynamically allocated array of objects that
/// is to be deleted when this FArrayDeleter object's destructor is executed.
FArrayDeleter (T* _arrayToDelete) : arrayToDelete (_arrayToDelete) {}
/// Destructor. Calls delete[] on the at construction time passed pointer.
~FArrayDeleter ()
{
if (arrayToDelete)
delete[] arrayToDelete;
}
T* arrayToDelete; ///< Remembers the array of objects that is to be deleted during destruction.
};
/** Template definition for classes that help guarding against dangling pointers.
A stack allocated object of this type automatically resets an at construction time passed
pointer to null when it reaches the end of its scope. \n\n
Intended usage:
\code
int* pointerToInt = 0;
{
int i = 1;
pointerToInt = &i;
Steinberg::FPtrNuller<int> ptrNuller (pointerToInt);
// Do something with pointerToInt.
} // No dangling pointer here, pointerToInt is reset to 0 by destructor of ptrNuller.
\endcode
*/
//------------------------------------------------------------------------
template <class T>
struct FPtrNuller
{
/// Constructor. _toNull is a reference to the pointer that is to be reset to NULL when this
/// FPtrNuller object's destructor is executed.
FPtrNuller (T*& _toNull) : toNull (_toNull) {}
/// Destructor. Calls delete[] on the at construction time passed pointer.
~FPtrNuller () { toNull = 0; }
T*& toNull; ///< Remembers the pointer that is to be set to NULL during destruction.
};
/** Template definition for classes that help resetting an object's value.
A stack allocated object of this type automatically resets the value of an at construction time
passed object to null when it reaches the end of its scope. \n\n Intended usage: \code int theObject
= 0;
{
Steinberg::FNuller<int> theNuller (theObject);
theObject = 1;
} // Here the destructor of theNuller resets the value of theObject to 0.
\endcode
*/
//------------------------------------------------------------------------
template <class T>
struct FNuller
{
/// Constructor. _toNull is a reference to the object that is to be assigned 0 when this FNuller
/// object's destructor is executed.
FNuller (T& _toNull) : toNull (_toNull) {}
/// Destructor. Assigns 0 to the at construction time passed object reference.
~FNuller () { toNull = 0; }
T& toNull; ///< Remembers the object that is to be assigned 0 during destruction.
};
/** Class definition for objects that help resetting boolean variables.
A stack allocated object of this type automatically sets an at construction time passed
boolean variable immediately to TRUE and resets the same variable to FALSE when it
reaches the end of its own scope. \n\n
Intended usage:
\code
bool theBoolean = false;
{
Steinberg::FBoolSetter theBoolSetter (theBoolean);
// Here the constructor of theBoolSetter sets theBoolean to TRUE.
// Do something.
} // Here the destructor of theBoolSetter resets theBoolean to FALSE.
\endcode
*/
//------------------------------------------------------------------------
template <class T>
struct FBooleanSetter
{
/// Constructor. _toSet is a reference to the boolean that is set to TRUE immediately in this
/// constructor call and gets reset to FALSE when this FBoolSetter object's destructor is
/// executed.
FBooleanSetter (T& _toSet) : toSet (_toSet) { toSet = true; }
/// Destructor. Resets the at construction time passed boolean to FALSE.
~FBooleanSetter () { toSet = false; }
T& toSet; ///< Remembers the boolean that is to be reset during destruction.
};
using FBoolSetter = FBooleanSetter<bool>;
/** Class definition for objects that help setting boolean variables.
A stack allocated object of this type automatically sets an at construction time passed
boolean variable to TRUE if the given condition is met. At the end of its own scope the
stack object will reset the same boolean variable to FALSE, if it wasn't set so already. \n\n
Intended usage:
\code
bool theBoolean = false;
{
bool creativityFirst = true;
Steinberg::FConditionalBoolSetter theCBSetter (theBoolean, creativityFirst);
// Here the constructor of theCBSetter sets theBoolean to the value of creativityFirst.
// Do something.
} // Here the destructor of theCBSetter resets theBoolean to FALSE.
\endcode
*/
//------------------------------------------------------------------------
struct FConditionalBoolSetter
{
/// Constructor. _toSet is a reference to the boolean that is to be set. If the in the second
/// parameter given condition is TRUE then also _toSet is set to TRUE immediately.
FConditionalBoolSetter (bool& _toSet, bool condition) : toSet (_toSet)
{
if (condition)
toSet = true;
}
/// Destructor. Resets the at construction time passed boolean to FALSE.
~FConditionalBoolSetter () { toSet = false; }
bool& toSet; ///< Remembers the boolean that is to be reset during destruction.
};
/** Template definition for classes that help closing resources.
A stack allocated object of this type automatically calls the close method of an at
construction time passed object when it reaches the end of its scope.
It goes without saying that the given type needs to have a close method. \n\n
Intended usage:
\code
struct CloseableObject
{
void close() {};
};
{
CloseableObject theObject;
Steinberg::FCloser<CloseableObject> theCloser (&theObject);
// Do something.
} // Here the destructor of theCloser calls the close method of theObject.
\endcode
*/
template <class T>
struct FCloser
{
/// Constructor. _obj is the pointer on which close is to be called when this FCloser object's
/// destructor is executed.
FCloser (T* _obj) : obj (_obj) {}
/// Destructor. Calls the close function on the at construction time passed pointer.
~FCloser ()
{
if (obj)
obj->close ();
}
T* obj; ///< Remembers the pointer on which close is to be called during destruction.
};
/** Class definition for objects that help guarding against memory leaks.
A stack allocated object of this type automatically frees the "malloced" memory behind an at
construction time passed pointer when it reaches the end of its scope.
*/
//------------------------------------------------------------------------
/*! \class FMallocReleaser
*/
//------------------------------------------------------------------------
class FMallocReleaser
{
public:
/// Constructor. _data is the pointer to the memory on which free is to be called when this
/// FMallocReleaser object's destructor is executed.
FMallocReleaser (void* _data) : data (_data) {}
/// Destructor. Calls the free function on the at construction time passed pointer.
~FMallocReleaser ()
{
if (data)
free (data);
}
//------------------------------------------------------------------------
protected:
void* data; ///< Remembers the pointer on which free is to be called during destruction.
};
//------------------------------------------------------------------------
} // namespace Steinberg
#if SMTG_OS_MACOS
typedef const void* CFTypeRef;
extern "C" {
extern void CFRelease (CFTypeRef cf);
}
namespace Steinberg {
/** Class definition for objects that helps releasing CoreFoundation objects.
A stack allocated object of this type automatically releases an at construction time
passed CoreFoundation object when it reaches the end of its scope.
Only available on Macintosh platform.
*/
//------------------------------------------------------------------------
/*! \class CFReleaser
*/
//------------------------------------------------------------------------
class CFReleaser
{
public:
/// Constructor. _obj is the reference to an CoreFoundation object which is to be released when this CFReleaser object's destructor is executed.
CFReleaser (CFTypeRef _obj) : obj (_obj) {}
/// Destructor. Releases the at construction time passed object.
~CFReleaser () { if (obj) CFRelease (obj); }
protected:
CFTypeRef obj; ///< Remembers the object which is to be released during destruction.
};
//------------------------------------------------------------------------
} // namespace Steinberg
#endif // SMTG_OS_MACOS
+367
View File
@@ -0,0 +1,367 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fcommandline.h
// Created by : Steinberg, 2007
// Description : Very simple command-line parser. @see Steinberg::CommandLine
//
//-----------------------------------------------------------------------------
// 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 <algorithm>
#include <deque>
#include <initializer_list>
#include <iterator>
#include <map>
#include <sstream>
#include <vector>
namespace Steinberg {
//------------------------------------------------------------------------
/** Very simple command-line parser.
Parses the command-line into a CommandLine::VariablesMap.\n
The command-line parser uses CommandLine::Descriptions to define the available options.
@b Example:
\code
#include "base/source/fcommandline.h"
#include <iostream>
int main (int argc, char* argv[])
{
using namespace std;
CommandLine::Descriptions desc;
CommandLine::VariablesMap valueMap;
desc.addOptions ("myTool")
("help", "produce help message")
("opt1", string(), "option 1")
("opt2", string(), "option 2")
;
CommandLine::parse (argc, argv, desc, valueMap);
if (valueMap.hasError () || valueMap.count ("help"))
{
cout << desc << "\n";
return 1;
}
if (valueMap.count ("opt1"))
{
cout << "Value of option 1 " << valueMap["opt1"] << "\n";
}
if (valueMap.count ("opt2"))
{
cout << "Value of option 2 " << valueMap["opt2"] << "\n";
}
return 0;
}
\endcode
@note
This is a "header only" implementation.\n
If you need the declarations in more than one cpp file, you have to define
@c SMTG_NO_IMPLEMENTATION in all but one file.
*/
//------------------------------------------------------------------------
namespace CommandLine {
//------------------------------------------------------------------------
/** Command-line parsing result.
This is the result of the parser.\n
- Use hasError() to check for errors.\n
- To test if a option was specified on the command-line use: count()\n
- To retrieve the value of an options, use operator [](const VariablesMapContainer::key_type
k)\n
*/
//------------------------------------------------------------------------
class VariablesMap
{
bool mParaError;
using VariablesMapContainer = std::map<std::string, std::string>;
VariablesMapContainer mVariablesMapContainer;
public:
VariablesMap () : mParaError (false) {} ///< Constructor. Creates a empty VariablesMap.
bool hasError () const { return mParaError; } ///< Returns @c true when an error has occurred.
void setError () { mParaError = true; } ///< Sets the error state to @c true.
/** Retrieve the value of option @c k.*/
std::string& operator[] (const VariablesMapContainer::key_type k);
/** Retrieve the value of option @c k. */
const std::string& operator[] (const VariablesMapContainer::key_type k) const;
/** Returns @c != @c 0 if command-line contains option @c k. */
VariablesMapContainer::size_type count (const VariablesMapContainer::key_type k) const;
};
//! type of the list of elements on the command line that are not handled by options parsing
using FilesVector = std::vector<std::string>;
//------------------------------------------------------------------------
/** The description of one single command-line option.
Normally you rarely use a Description directly.\n
In most cases you will use the Descriptions::addOptions (const std::string&) method to create
and add descriptions.
*/
//------------------------------------------------------------------------
class Description : public std::string
{
public:
/** Construct a Description */
Description (const std::string& name, const std::string& help,
const std::string& valueType);
std::string mHelp; ///< The help string for this option.
std::string mType; ///< The type of this option (kBool, kString).
static const std::string kBool;
static const std::string kString;
};
//------------------------------------------------------------------------
/** List of command-line option descriptions.
Use addOptions (const std::string&) to add Descriptions.
*/
//------------------------------------------------------------------------
class Descriptions
{
using DescriptionsList = std::deque<Description>;
DescriptionsList mDescriptions;
std::string mCaption;
public:
/** Sets the command-line tool caption and starts adding Descriptions. */
Descriptions& addOptions (const std::string& caption = "",
std::initializer_list<Description>&& options = {});
/** Parse the command-line. */
bool parse (int ac, char* av[], VariablesMap& result, FilesVector* files = nullptr) const;
/** Print a brief description for the command-line tool into the stream @c os. */
void print (std::ostream& os) const;
/** Add a new switch. Only */
Descriptions& operator () (const std::string& name, const std::string& help);
/** Add a new option of type @c inType. Currently only std::string is supported. */
template <typename Type>
Descriptions& operator () (const std::string& name, const Type& inType, std::string help);
};
//------------------------------------------------------------------------
// If you need the declarations in more than one cpp file you have to define
// SMTG_NO_IMPLEMENTATION in all but one file.
//------------------------------------------------------------------------
#ifndef SMTG_NO_IMPLEMENTATION
//------------------------------------------------------------------------
/*! If command-line contains option @c k more than once, only the last value will survive. */
//------------------------------------------------------------------------
std::string& VariablesMap::operator[] (const VariablesMapContainer::key_type k)
{
return mVariablesMapContainer[k];
}
//------------------------------------------------------------------------
/*! If command-line contains option @c k more than once, only the last value will survive. */
//------------------------------------------------------------------------
const std::string& VariablesMap::operator[] (const VariablesMapContainer::key_type k) const
{
return (*const_cast<VariablesMap*> (this))[k];
}
//------------------------------------------------------------------------
VariablesMap::VariablesMapContainer::size_type VariablesMap::count (
const VariablesMapContainer::key_type k) const
{
return mVariablesMapContainer.count (k);
}
//------------------------------------------------------------------------
/** Add a new option with a string as parameter. */
//------------------------------------------------------------------------
template <>
Descriptions& Descriptions::operator () (const std::string& name, const std::string& inType,
std::string help)
{
mDescriptions.emplace_back (name, help, inType);
return *this;
}
/** Parse the command - line. */
bool parse (int ac, char* av[], const Descriptions& desc, VariablesMap& result,
FilesVector* files = nullptr);
/** Make Descriptions stream able. */
std::ostream& operator<< (std::ostream& os, const Descriptions& desc);
const std::string Description::kBool = "bool";
const std::string Description::kString = "string";
//------------------------------------------------------------------------
/*! In most cases you will use the Descriptions::addOptions (const std::string&) method to create
and add descriptions.
@param[in] name of the option.
@param[in] help a help description for this option.
@param[out] valueType Description::kBool or Description::kString.
*/
Description::Description (const std::string& name, const std::string& help,
const std::string& valueType)
: std::string (name), mHelp (help), mType (valueType)
{
}
//------------------------------------------------------------------------
/*! Returning a reference to *this, enables chaining of calls to operator()(const std::string&,
const std::string&).
@param[in] name of the added option.
@param[in] help a help description for this option.
@return a reference to *this.
*/
Descriptions& Descriptions::operator () (const std::string& name, const std::string& help)
{
mDescriptions.emplace_back (name, help, Description::kBool);
return *this;
}
//------------------------------------------------------------------------
/*! <b>Usage example:</b>
@code
CommandLine::Descriptions desc;
desc.addOptions ("myTool") // Set caption to "myTool"
("help", "produce help message") // add switch -help
("opt1", string(), "option 1") // add string option -opt1
("opt2", string(), "option 2") // add string option -opt2
;
@endcode
@note
The operator() is used for every additional option.
Or with initializer list :
@code
CommandLine::Descriptions desc;
desc.addOptions ("myTool", // Set caption to "myTool"
{{"help", "produce help message", Description::kBool}, // add switch -help
{"opt1", "option 1", Description::kString}, // add string option -opt1
{"opt2", "option 2", Description::kString}} // add string option -opt2
);
@endcode
@param[in] caption the caption of the command-line tool.
@param[in] options initializer list with options
@return a reverense to *this.
*/
Descriptions& Descriptions::addOptions (const std::string& caption,
std::initializer_list<Description>&& options)
{
mCaption = caption;
std::move (options.begin (), options.end (), std::back_inserter (mDescriptions));
return *this;
}
//------------------------------------------------------------------------
/*! @param[in] ac count of command-line parameters
@param[in] av command-line as array of strings
@param[out] result the parsing result
@param[out] files optional list of elements on the command line that are not handled by options
parsing
*/
bool Descriptions::parse (int ac, char* av[], VariablesMap& result, FilesVector* files) const
{
using namespace std;
for (int i = 1; i < ac; i++)
{
string current = av[i];
if (current[0] == '-')
{
int pos = current[1] == '-' ? 2 : 1;
current = current.substr (pos, string::npos);
DescriptionsList::const_iterator found =
find (mDescriptions.begin (), mDescriptions.end (), current);
if (found != mDescriptions.end ())
{
result[*found] = "true";
if (found->mType != Description::kBool)
{
if (((i + 1) < ac) && *av[i + 1] != '-')
{
result[*found] = av[++i];
}
else
{
result[*found] = "error!";
result.setError ();
return false;
}
}
}
else
{
result.setError ();
return false;
}
}
else if (files)
files->push_back (av[i]);
}
return true;
}
//------------------------------------------------------------------------
/*! The description includes the help strings for all options. */
//------------------------------------------------------------------------
void Descriptions::print (std::ostream& os) const
{
if (!mCaption.empty ())
os << mCaption << ":\n";
size_t maxLength = 0u;
std::for_each (mDescriptions.begin (), mDescriptions.end (),
[&] (const Description& d) { maxLength = std::max (maxLength, d.size ()); });
for (const Description& opt : mDescriptions)
{
os << "-" << opt;
for (auto s = opt.size (); s < maxLength; ++s)
os << " ";
os << " | " << opt.mHelp << "\n";
}
}
//------------------------------------------------------------------------
std::ostream& operator<< (std::ostream& os, const Descriptions& desc)
{
desc.print (os);
return os;
}
//------------------------------------------------------------------------
/*! @param[in] ac count of command-line parameters
@param[in] av command-line as array of strings
@param[in] desc Descriptions including all allowed options
@param[out] result the parsing result
@param[out] files optional list of elements on the command line that are not handled by options
parsing
*/
bool parse (int ac, char* av[], const Descriptions& desc, VariablesMap& result, FilesVector* files)
{
return desc.parse (ac, av, result, files);
}
#endif
//------------------------------------------------------------------------
} // namespace CommandLine
} // namespace Steinberg
+320
View File
@@ -0,0 +1,320 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fdebug.cpp
// Created by : Steinberg, 1995
// Description : There are 2 levels of debugging messages:
// DEVELOPMENT During development
// RELEASE Program is shipping.
//
//-----------------------------------------------------------------------------
// 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 "base/source/fdebug.h"
#if SMTG_OS_WINDOWS
#include <windows.h>
bool AmIBeingDebugged ()
{
return IsDebuggerPresent ();
}
#endif
#if SMTG_OS_LINUX
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
//--------------------------------------------------------------------------
bool AmIBeingDebugged ()
{
// TODO: check if GDB or LLDB is attached
return true;
}
#endif
#if SMTG_OS_MACOS
#include <stdbool.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <unistd.h>
//------------------------------------------------------------------------
// from Technical Q&A QA1361 (http://developer.apple.com/qa/qa2004/qa1361.html)
//------------------------------------------------------------------------
bool AmIBeingDebugged ()
// Returns true if the current process is being debugged (either
// running under the debugger or has a debugger attached post facto).
{
int mib[4];
struct kinfo_proc info;
size_t size;
// Initialize the flags so that, if sysctl fails for some bizarre
// reason, we get a predictable result.
info.kp_proc.p_flag = 0;
// Initialize mib, which tells sysctl the info we want, in this case
// we're looking for information about a specific process ID.
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = getpid ();
// Call sysctl.
size = sizeof (info);
sysctl (mib, sizeof (mib) / sizeof (*mib), &info, &size, NULL, 0);
// We're being debugged if the P_TRACED flag is set.
return ((info.kp_proc.p_flag & P_TRACED) != 0);
}
#endif // SMTG_OS_MACOS
#if DEVELOPMENT
#include <cassert>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <mutex>
#if SMTG_OS_WINDOWS
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#if _MSC_VER
#include <intrin.h>
#endif
#define vsnprintf _vsnprintf
#define snprintf _snprintf
#elif SMTG_OS_MACOS
#include <errno.h>
#include <mach/mach_init.h>
#include <mach/mach_time.h>
#include <new>
#include <signal.h>
#define THREAD_ALLOC_WATCH 0 // check allocations on specific threads
#if THREAD_ALLOC_WATCH
mach_port_t watchThreadID = 0;
#endif
#endif
AssertionHandler gAssertionHandler = nullptr;
AssertionHandler gPreAssertionHook = nullptr;
DebugPrintLogger gDebugPrintLogger = nullptr;
//--------------------------------------------------------------------------
static const int kDebugPrintfBufferSize = 10000;
static bool neverDebugger = false; // so I can switch it off in the debugger...
static std::once_flag neverDebuggerEnvCheckFlag {};
//--------------------------------------------------------------------------
static void initNeverDebugger ()
{
std::call_once (neverDebuggerEnvCheckFlag, [] () {
// add this environment variable to not stop in the debugger on ASSERT
if (std::getenv ("SMTG_DEBUG_IGNORE_ASSERT"))
{
neverDebugger = true;
}
});
}
//--------------------------------------------------------------------------
static void printDebugString (const char* string)
{
if (!string)
return;
if (gDebugPrintLogger)
{
gDebugPrintLogger (string);
}
else
{
#if SMTG_OS_MACOS || defined(__MINGW32__)
fprintf (stderr, "%s", string);
#elif SMTG_OS_WINDOWS
OutputDebugStringA (string);
#endif
}
}
//--------------------------------------------------------------------------
// printf style debugging output
//--------------------------------------------------------------------------
void FDebugPrint (const char* format, ...)
{
char string[kDebugPrintfBufferSize];
va_list marker;
va_start (marker, format);
vsnprintf (string, kDebugPrintfBufferSize, format, marker);
printDebugString (string);
}
//--------------------------------------------------------------------------
// printf style debugging output
//--------------------------------------------------------------------------
void FDebugBreak (const char* format, ...)
{
char string[kDebugPrintfBufferSize];
va_list marker;
va_start (marker, format);
vsnprintf (string, kDebugPrintfBufferSize, format, marker);
printDebugString (string);
// The Pre-assertion hook is always called, even if we're not running in the debugger,
// so that we can log asserts without displaying them
if (gPreAssertionHook)
{
gPreAssertionHook (string);
}
initNeverDebugger ();
if (neverDebugger)
return;
if (AmIBeingDebugged ())
{
// do not crash if no debugger present
// If there is an assertion handler defined then let this override the UI
// and tell us whether we want to break into the debugger
bool breakIntoDebugger = true;
if (gAssertionHandler && gAssertionHandler (string) == false)
{
breakIntoDebugger = false;
}
if (breakIntoDebugger)
{
#if SMTG_OS_WINDOWS && _MSC_VER
__debugbreak (); // intrinsic version of DebugBreak()
#elif SMTG_OS_MACOS && __arm64__
raise (SIGSTOP);
#elif __ppc64__ || __ppc__ || __arm__
kill (getpid (), SIGINT);
#elif __i386__ || __x86_64__
{
__asm__ volatile ("int3");
}
#endif
}
}
}
//--------------------------------------------------------------------------
void FPrintLastError (const char* file, int line)
{
#if SMTG_OS_WINDOWS
LPVOID lpMessageBuffer = nullptr;
FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr,
GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&lpMessageBuffer, 0, nullptr);
FDebugPrint ("%s(%d) : %s\n", file, line, lpMessageBuffer);
LocalFree (lpMessageBuffer);
#endif
#if SMTG_OS_MACOS
#if !__MACH__
extern int errno;
#endif
FDebugPrint ("%s(%d) : Errno %d\n", file, line, errno);
#endif
}
#if SMTG_OS_MACOS
//------------------------------------------------------------------------
void* operator new (size_t size, int, const char* file, int line)
{
#if THREAD_ALLOC_WATCH
mach_port_t threadID = mach_thread_self ();
if (watchThreadID == threadID)
{
FDebugPrint ("Watched Thread Allocation : %s (Line:%d)\n", file ? file : "Unknown", line);
}
#endif
try
{
return ::operator new (size);
}
catch (std::bad_alloc exception)
{
FDebugPrint ("bad_alloc exception : %s (Line:%d)", file ? file : "Unknown", line);
}
return (void*)-1;
}
//------------------------------------------------------------------------
void* operator new[] (size_t size, int, const char* file, int line)
{
#if THREAD_ALLOC_WATCH
mach_port_t threadID = mach_thread_self ();
if (watchThreadID == threadID)
{
FDebugPrint ("Watched Thread Allocation : %s (Line:%d)\n", file ? file : "Unknown", line);
}
#endif
try
{
return ::operator new[] (size);
}
catch (std::bad_alloc exception)
{
FDebugPrint ("bad_alloc exception : %s (Line:%d)", file ? file : "Unknown", line);
}
return (void*)-1;
}
//------------------------------------------------------------------------
void operator delete (void* p, int, const char* file, int line)
{
(void)file;
(void)line;
::operator delete (p);
}
//------------------------------------------------------------------------
void operator delete[] (void* p, int, const char* file, int line)
{
(void)file;
(void)line;
::operator delete[] (p);
}
#endif // SMTG_OS_MACOS
#endif // DEVELOPMENT
static bool smtg_unit_testing_active = false; // ugly hack to unit testing ...
//------------------------------------------------------------------------
bool isSmtgUnitTesting ()
{
return smtg_unit_testing_active;
}
//------------------------------------------------------------------------
void setSmtgUnitTesting ()
{
smtg_unit_testing_active = true;
}
+226
View File
@@ -0,0 +1,226 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fdebug.h
// Created by : Steinberg, 1995
// Description : There are 2 levels of debugging messages:
// DEVELOPMENT During development
// RELEASE Program is shipping.
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/** @file base/source/fdebug.h
Debugging tools.
There are 2 levels of debugging messages:
- DEVELOPMENT
- During development
- RELEASE
- Program is shipping.
*/
//-----------------------------------------------------------------------------
#pragma once
#include "pluginterfaces/base/ftypes.h"
#include <cstring>
#if SMTG_OS_MACOS
#include <new>
#endif
/** Returns true if a debugger is attached. */
bool AmIBeingDebugged ();
//-----------------------------------------------------------------------------
// development / release
//-----------------------------------------------------------------------------
#if !defined (DEVELOPMENT) && !defined (RELEASE)
#ifdef _DEBUG
#define DEVELOPMENT 1
#elif defined (NDEBUG)
#define RELEASE 1
#else
#error DEVELOPMENT, RELEASE, _DEBUG, or NDEBUG must be defined!
#endif
#endif
//-----------------------------------------------------------------------------
#if SMTG_OS_WINDOWS
/** Disable compiler warning:
* C4291: "No matching operator delete found; memory will not be freed if initialization throws an
* exception. A placement new is used for which there is no placement delete." */
#if DEVELOPMENT && defined(_MSC_VER)
#pragma warning(disable : 4291)
#pragma warning(disable : 4985)
#endif
#endif // SMTG_OS_WINDOWS
#if DEVELOPMENT
//-----------------------------------------------------------------------------
/** If "f" is not true and a debugger is present, send an error string to the debugger for display
and cause a breakpoint exception to occur in the current process. SMTG_ASSERT is removed
completely in RELEASE configuration. So do not pass methods calls to this macro that are expected
to exist in the RELEASE build (for method calls that need to be present in a RELEASE build, use
the VERIFY macros instead)*/
#define SMTG_ASSERT(f) \
if (!(f)) \
FDebugBreak ("%s(%d) : Assert failed: %s\n", __FILE__, __LINE__, #f);
#define SMTG_ASSERT_MSG(f, msg) \
if (!(f)) \
FDebugBreak ("%s(%d) : Assert failed: [%s] [%s]\n", __FILE__, __LINE__, #f, msg);
/** Send "comment" string to the debugger for display. */
#define SMTG_WARNING(comment) FDebugPrint ("%s(%d) : %s\n", __FILE__, __LINE__, comment);
/** Send the last error string to the debugger for display. */
#define SMTG_PRINTSYSERROR FPrintLastError (__FILE__, __LINE__);
/** If a debugger is present, send string "s" to the debugger for display and
cause a breakpoint exception to occur in the current process. */
#define SMTG_DEBUGSTR(s) FDebugBreak (s);
/** Use VERIFY for calling methods "f" having a bool result (expecting them to return 'true')
The call of "f" is not removed in RELEASE builds, only the result verification. eg: SMTG_VERIFY
(isValid ()) */
#define SMTG_VERIFY(f) SMTG_ASSERT (f)
/** Use VERIFY_IS for calling methods "f" and expect a certain result "r".
The call of "f" is not removed in RELEASE builds, only the result verification. eg:
SMTG_VERIFY_IS (callMethod (), kResultOK) */
#define SMTG_VERIFY_IS(f, r) \
if ((f) != (r)) \
FDebugBreak ("%s(%d) : Assert failed: %s\n", __FILE__, __LINE__, #f);
/** Use VERIFY_NOT for calling methods "f" and expect the result to be anything else but "r".
The call of "f" is not removed in RELEASE builds, only the result verification. eg:
SMTG_VERIFY_NOT (callMethod (), kResultError) */
#define SMTG_VERIFY_NOT(f, r) \
if ((f) == (r)) \
FDebugBreak ("%s(%d) : Assert failed: %s\n", __FILE__, __LINE__, #f);
/** @name Shortcut macros for sending strings to the debugger for display.
First parameter is always the format string (printf like).
*/
///@{
#define SMTG_DBPRT0(a) FDebugPrint (a);
#define SMTG_DBPRT1(a, b) FDebugPrint (a, b);
#define SMTG_DBPRT2(a, b, c) FDebugPrint (a, b, c);
#define SMTG_DBPRT3(a, b, c, d) FDebugPrint (a, b, c, d);
#define SMTG_DBPRT4(a, b, c, d, e) FDebugPrint (a, b, c, d, e);
#define SMTG_DBPRT5(a, b, c, d, e, f) FDebugPrint (a, b, c, d, e, f);
///@}
/** @name Helper functions for the above defined macros.
You shouldn't use them directly (if you do so, don't forget "#if DEVELOPMENT")!
It is recommended to use the macros instead.
*/
///@{
void FDebugPrint (const char* format, ...);
void FDebugBreak (const char* format, ...);
void FPrintLastError (const char* file, int line);
///@}
/** @name Provide a custom assertion handler and debug print handler, eg
so that we can provide an assert with a custom dialog, or redirect
the debug output to a file or stream.
*/
///@{
using AssertionHandler = bool (*) (const char* message);
extern AssertionHandler gAssertionHandler;
extern AssertionHandler gPreAssertionHook;
using DebugPrintLogger = void (*) (const char* message);
extern DebugPrintLogger gDebugPrintLogger;
///@}
/** Definition of memory allocation macros:
Use "NEW" to allocate storage for individual objects.
Use "NEWVEC" to allocate storage for an array of objects. */
#if SMTG_OS_MACOS
void* operator new (size_t, int, const char*, int);
void* operator new[] (size_t, int, const char*, int);
void operator delete (void* p, int, const char* file, int line);
void operator delete[] (void* p, int, const char* file, int line);
#ifndef NEW
#define NEW new (1, __FILE__, __LINE__)
#define NEWVEC new (1, __FILE__, __LINE__)
#endif
#define DEBUG_NEW DEBUG_NEW_LEAKS
#elif SMTG_OS_WINDOWS && defined(_MSC_VER)
#ifndef NEW
void* operator new (size_t, int, const char*, int);
#define NEW new (1, __FILE__, __LINE__)
#define NEWVEC new (1, __FILE__, __LINE__)
#endif
#else
#ifndef NEW
#define NEW new
#define NEWVEC new
#endif
#endif
#else
/** if DEVELOPMENT is not set, these macros will do nothing. */
#define SMTG_ASSERT(f)
#define SMTG_ASSERT_MSG(f, msg)
#define SMTG_WARNING(s)
#define SMTG_PRINTSYSERROR
#define SMTG_DEBUGSTR(s)
#define SMTG_VERIFY(f) f;
#define SMTG_VERIFY_IS(f, r) f;
#define SMTG_VERIFY_NOT(f, r) f;
#define SMTG_DBPRT0(a)
#define SMTG_DBPRT1(a, b)
#define SMTG_DBPRT2(a, b, c)
#define SMTG_DBPRT3(a, b, c, d)
#define SMTG_DBPRT4(a, b, c, d, e)
#define SMTG_DBPRT5(a, b, c, d, e, f)
#ifndef NEW
#define NEW new
#define NEWVEC new
#endif
#endif
// replace #if SMTG_CPPUNIT_TESTING
bool isSmtgUnitTesting ();
void setSmtgUnitTesting ();
#if !SMTG_RENAME_ASSERT
#if SMTG_OS_WINDOWS
#undef ASSERT
#endif
#define ASSERT SMTG_ASSERT
#define WARNING SMTG_WARNING
#define DEBUGSTR SMTG_DEBUGSTR
#define VERIFY SMTG_VERIFY
#define VERIFY_IS SMTG_VERIFY_IS
#define VERIFY_NOT SMTG_VERIFY_NOT
#define PRINTSYSERROR SMTG_PRINTSYSERROR
#define DBPRT0 SMTG_DBPRT0
#define DBPRT1 SMTG_DBPRT1
#define DBPRT2 SMTG_DBPRT2
#define DBPRT3 SMTG_DBPRT3
#define DBPRT4 SMTG_DBPRT4
#define DBPRT5 SMTG_DBPRT5
#endif
+244
View File
@@ -0,0 +1,244 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fdynlib.cpp
// Created by : Steinberg, 1998
// Description : Dynamic library loading
//
//-----------------------------------------------------------------------------
// 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 "base/source/fdynlib.h"
#include "pluginterfaces/base/fstrdefs.h"
#include "base/source/fstring.h"
#if SMTG_OS_WINDOWS
#include <windows.h>
#elif SMTG_OS_MACOS
#include <mach-o/dyld.h>
#include <CoreFoundation/CoreFoundation.h>
#if !SMTG_OS_IOS
static const Steinberg::tchar kUnixDelimiter = STR ('/');
#endif
#endif
namespace Steinberg {
#if SMTG_OS_MACOS
#include <dlfcn.h>
// we ignore for the moment that the NSAddImage functions are deprecated
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
static bool CopyProcessPath (Steinberg::String& name)
{
Dl_info info;
if (dladdr ((const void*)CopyProcessPath, &info))
{
if (info.dli_fname)
{
name.assign (info.dli_fname);
#ifdef UNICODE
name.toWideString ();
#endif
return true;
}
}
return false;
}
#endif
//------------------------------------------------------------------------
// FDynLibrary
//------------------------------------------------------------------------
FDynLibrary::FDynLibrary (const tchar* n, bool addExtension)
: isloaded (false)
, instance (nullptr)
{
if (n)
init (n, addExtension);
}
//------------------------------------------------------------------------
FDynLibrary::~FDynLibrary ()
{
unload ();
}
//------------------------------------------------------------------------
bool FDynLibrary::init (const tchar* n, bool addExtension)
{
if (isLoaded ())
return true;
Steinberg::String name (n);
#if SMTG_OS_WINDOWS
if (addExtension)
name.append (STR (".dll"));
instance = LoadLibrary (name);
if (instance)
isloaded = true;
#elif SMTG_OS_MACOS
isBundle = false;
// first check if it is a bundle
if (addExtension)
name.append (STR (".bundle"));
if (name.getChar16 (0) != STR('/')) // no absoltue path
{
Steinberg::String p;
if (CopyProcessPath (p))
{
Steinberg::int32 index = p.findLast (STR ('/'));
p.remove (index+1);
name = p + name;
}
}
CFStringRef fsString = (CFStringRef)name.toCFStringRef ();
CFURLRef url = CFURLCreateWithFileSystemPath (NULL, fsString, kCFURLPOSIXPathStyle, true);
if (url)
{
CFBundleRef bundle = CFBundleCreate (NULL, url);
if (bundle)
{
if (CFBundleLoadExecutable (bundle))
{
isBundle = true;
instance = (void*)bundle;
}
else
CFRelease (bundle);
}
CFRelease (url);
}
CFRelease (fsString);
name.assign (n);
#if !SMTG_OS_IOS
if (!isBundle)
{
// now we check for a dynamic library
firstSymbol = NULL;
if (addExtension)
{
name.append (STR (".dylib"));
}
// Only if name is a relative path we use the Process Path as root:
if (name[0] != kUnixDelimiter)
{
Steinberg::String p;
if (CopyProcessPath (p))
{
Steinberg::int32 index = p.findLast (STR ("/"));
p.remove (index+1);
p.append (name);
p.toMultiByte (Steinberg::kCP_Utf8);
instance = (void*) NSAddImage (p, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
}
}
// Last but not least let the system search for it
//
if (instance == 0)
{
name.toMultiByte (Steinberg::kCP_Utf8);
instance = (void*) NSAddImage (name, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
}
}
#endif // !SMTG_OS_IOS
if (instance)
isloaded = true;
#endif
return isloaded;
}
//------------------------------------------------------------------------
bool FDynLibrary::unload ()
{
if (!isLoaded ())
return false;
#if SMTG_OS_WINDOWS
FreeLibrary ((HINSTANCE)instance);
#elif SMTG_OS_MACOS
if (isBundle)
{
if (CFGetRetainCount ((CFTypeRef)instance) == 1)
CFBundleUnloadExecutable ((CFBundleRef)instance);
CFRelease ((CFBundleRef)instance);
}
else
{
// we don't use this anymore as the darwin dyld can't unload dynamic libraries yet and may crash
/* if (firstSymbol)
{
NSModule module = NSModuleForSymbol ((NSSymbol)firstSymbol);
if (module)
NSUnLinkModule (module, NSUNLINKMODULE_OPTION_NONE);
}*/
}
#endif
instance = nullptr;
isloaded = false;
return true;
}
//------------------------------------------------------------------------
void* FDynLibrary::getProcAddress (const char* name)
{
if (!isloaded)
return nullptr;
#if SMTG_OS_WINDOWS
return (void*)GetProcAddress ((HINSTANCE)instance, name);
#elif SMTG_OS_MACOS
if (isBundle)
{
CFStringRef functionName = CFStringCreateWithCString (NULL, name, kCFStringEncodingASCII);
void* result = CFBundleGetFunctionPointerForName ((CFBundleRef)instance, functionName);
CFRelease (functionName);
return result;
}
#if !SMTG_OS_IOS
else
{
char* symbolName = (char*) malloc (strlen (name) + 2);
strcpy (symbolName, "_");
strcat (symbolName, name);
NSSymbol symbol;
symbol = NSLookupSymbolInImage ((const struct mach_header*)instance, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
free (symbolName);
if (symbol)
{
if (firstSymbol == NULL)
firstSymbol = symbol;
return NSAddressOfSymbol (symbol);
}
}
#endif // !SMTG_OS_IOS
return nullptr;
#else
return nullptr;
#endif
}
//------------------------------------------------------------------------
} // namespace Steinberg
+92
View File
@@ -0,0 +1,92 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fdynlib.h
// Created by : Steinberg, 1998
// Description : Dynamic library loading
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------
/** @file base/source/fdynlib.h
Platform independent dynamic library loading. */
//------------------------------------------------------------------------
#pragma once
#include "pluginterfaces/base/ftypes.h"
#include "base/source/fobject.h"
namespace Steinberg {
//------------------------------------------------------------------------
/** Platform independent dynamic library loader. */
//------------------------------------------------------------------------
class FDynLibrary : public FObject
{
public:
//------------------------------------------------------------------------
/** Constructor.
Loads the specified dynamic library.
@param[in] name the path of the library to load.
@param[in] addExtension if @c true append the platform dependent default extension to @c name.
@remarks
- If @c name specifies a full path, the FDynLibrary searches only that path for the library.
- If @c name specifies a relative path or a name without path,
FDynLibrary uses a standard search strategy of the current platform to find the library;
- If @c name is @c NULL the library is not loaded.
- Use init() to load the library. */
FDynLibrary (const tchar* name = nullptr, bool addExtension = true);
/** Destructor.
The destructor unloads the library.*/
~FDynLibrary () override;
/** Loads the library if not already loaded.
This function is normally called by FDynLibrary().
@remarks If the library is already loaded, this call has no effect. */
bool init (const tchar* name, bool addExtension = true);
/** Returns the address of the procedure @c name */
void* getProcAddress (const char* name);
/** Returns true when the library was successfully loaded. */
bool isLoaded () {return isloaded;}
/** Unloads the library if it is loaded.
This function is called by ~FDynLibrary (). */
bool unload ();
/** Returns the platform dependent representation of the library instance. */
void* getPlatformInstance () const { return instance; }
#if SMTG_OS_MACOS
/** Returns @c true if the library is a bundle (Mac only). */
bool isBundleLib () const { return isBundle; }
#endif
//------------------------------------------------------------------------
OBJ_METHODS(FDynLibrary, FObject)
protected:
bool isloaded;
void* instance;
#if SMTG_OS_MACOS
void* firstSymbol;
bool isBundle;
#endif
};
//------------------------------------------------------------------------
} // namespace Steinberg
+274
View File
@@ -0,0 +1,274 @@
//------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fobject.cpp
// Created by : Steinberg, 2008
// Description : Basic Object implementing FUnknown
//
//-----------------------------------------------------------------------------
// 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 "base/source/fobject.h"
#include "base/thread/include/flock.h"
#include <functional>
#include <vector>
#define SMTG_VALIDATE_DEPENDENCY_COUNT DEVELOPMENT // validating dependencyCount
#if SMTG_DEPENDENCY_COUNT
#include "base/source/updatehandler.h"
#define SMTG_DEPENDENCY_CHECK_LEVEL 1 // 1 => minimal assert, 2 => full assert
#endif // SMTG_DEPENDENCY_COUNT
namespace Steinberg {
// Entry point for addRef/release tracking. See fobjecttracker.h
//------------------------------------------------------------------------
#if DEVELOPMENT
using FObjectTrackerFn = std::function<void (FObject*, bool)>;
FObjectTrackerFn gFObjectTracker = nullptr;
#endif
IUpdateHandler* FObject::gUpdateHandler = nullptr;
//------------------------------------------------------------------------
const FUID FObject::iid;
//------------------------------------------------------------------------
struct FObjectIIDInitializer
{
// the object iid is always generated so that different components
// only can cast to their own objects
// this initializer must be after the definition of FObject::iid, otherwise
// the default constructor of FUID will clear the generated iid
FObjectIIDInitializer () { const_cast<FUID&> (FObject::iid).generate (); }
} gFObjectIidInitializer;
//------------------------------------------------------------------------
FObject::~FObject ()
{
#if SMTG_DEPENDENCY_COUNT && DEVELOPMENT
static bool localNeverDebugger = false;
#endif
#if DEVELOPMENT
if (refCount > 1)
FDebugPrint ("Refcount is %d when trying to delete %s\n", refCount, isA ());
#endif
#if SMTG_DEPENDENCY_COUNT
#if SMTG_DEPENDENCY_CHECK_LEVEL >= 1
if (gUpdateHandler)
{
#if DEVELOPMENT
SMTG_ASSERT (dependencyCount == 0 || localNeverDebugger);
#endif // DEVELOPMENT
}
#endif
#endif // SMTG_DEPENDENCY_COUNT
#if SMTG_VALIDATE_DEPENDENCY_COUNT
if (!gUpdateHandler || gUpdateHandler != UpdateHandler::instance (false))
return;
auto updateHandler = UpdateHandler::instance ();
if (!updateHandler || updateHandler == this)
return;
SMTG_ASSERT ((updateHandler->checkDeferred (this) == false || localNeverDebugger) &&
"'this' has scheduled a deferUpdate that was not yet delivered");
if (updateHandler->hasDependencies (this))
{
SMTG_ASSERT (
(false || localNeverDebugger) &&
"Another object is still dependent on 'this'. This leads to zombie entries in the dependency map that can later crash.");
FDebugPrint ("Object still has dependencies %x %s\n", this, this->isA ());
updateHandler->printForObject (this);
}
#endif // SMTG_VALIDATE_DEPENDENCY_COUNT
}
//------------------------------------------------------------------------
uint32 PLUGIN_API FObject::addRef ()
{
#if DEVELOPMENT
if (gFObjectTracker)
{
gFObjectTracker (this, true);
}
#endif
return FUnknownPrivate::atomicAdd (refCount, 1);
}
//------------------------------------------------------------------------
uint32 PLUGIN_API FObject::release ()
{
#if DEVELOPMENT
if (gFObjectTracker)
{
gFObjectTracker (this, false);
}
#endif
auto rc = FUnknownPrivate::atomicAdd (refCount, -1);
if (rc == 0)
{
refCount = -1000;
delete this;
return 0;
}
return rc;
}
//------------------------------------------------------------------------
tresult PLUGIN_API FObject::queryInterface (const TUID _iid, void** obj)
{
QUERY_INTERFACE (_iid, obj, FUnknown::iid, FUnknown)
QUERY_INTERFACE (_iid, obj, IDependent::iid, IDependent)
QUERY_INTERFACE (_iid, obj, FObject::iid, FObject)
*obj = nullptr;
return kNoInterface;
}
//------------------------------------------------------------------------
void FObject::addDependent (IDependent* dep)
{
if (!gUpdateHandler)
return;
gUpdateHandler->addDependent (unknownCast (), dep);
#if SMTG_DEPENDENCY_COUNT
dependencyCount++;
#endif
}
//------------------------------------------------------------------------
void FObject::removeDependent (IDependent* dep)
{
#if SMTG_DEPENDENCY_COUNT && DEVELOPMENT
static bool localNeverDebugger = false;
#endif
if (!gUpdateHandler)
return;
#if SMTG_DEPENDENCY_COUNT
if (gUpdateHandler != UpdateHandler::instance (false))
{
gUpdateHandler->removeDependent (unknownCast (), dep);
dependencyCount--;
return;
}
#if SMTG_DEPENDENCY_CHECK_LEVEL > 1
SMTG_ASSERT ((dependencyCount > 0 || localNeverDebugger) &&
"All dependencies have already been removed - mmichaelis 7/2021");
#endif
size_t removeCount;
UpdateHandler::instance ()->removeDependent (unknownCast (), dep, removeCount);
if (removeCount == 0)
{
#if SMTG_DEPENDENCY_CHECK_LEVEL > 1
SMTG_ASSERT (localNeverDebugger && "No dependency to remove - ygrabit 8/2021");
#endif
}
else
{
SMTG_ASSERT ((removeCount == 1 || localNeverDebugger) &&
"Duplicated dependencies established - mmichaelis 7/2021");
}
dependencyCount -= (int16)removeCount;
#else
gUpdateHandler->removeDependent (unknownCast (), dep);
#endif // SMTG_DEPENDENCY_COUNT
}
//------------------------------------------------------------------------
void FObject::changed (int32 msg)
{
if (gUpdateHandler)
gUpdateHandler->triggerUpdates (unknownCast (), msg);
else
updateDone (msg);
}
//------------------------------------------------------------------------
void FObject::deferUpdate (int32 msg)
{
if (gUpdateHandler)
gUpdateHandler->deferUpdates (unknownCast (), msg);
else
updateDone (msg);
}
//------------------------------------------------------------------------
/** Automatic creation and destruction of singleton instances. */
//------------------------------------------------------------------------
namespace Singleton {
using ObjectVector = std::vector<FObject**>;
ObjectVector* singletonInstances = nullptr;
bool singletonsTerminated = false;
Steinberg::Base::Thread::FLock* singletonsLock;
bool isTerminated ()
{
return singletonsTerminated;
}
void lockRegister ()
{
if (!singletonsLock) // assume first call not from multiple threads
singletonsLock = NEW Steinberg::Base::Thread::FLock;
singletonsLock->lock ();
}
void unlockRegister ()
{
singletonsLock->unlock ();
}
void registerInstance (FObject** o)
{
SMTG_ASSERT (singletonsTerminated == false)
if (singletonsTerminated == false)
{
if (singletonInstances == nullptr)
singletonInstances = NEW std::vector<FObject**>;
singletonInstances->push_back (o);
}
}
struct Deleter
{
~Deleter ()
{
singletonsTerminated = true;
if (singletonInstances)
{
for (Steinberg::FObject** obj : *singletonInstances)
{
(*obj)->release ();
*obj = nullptr;
obj = nullptr;
}
delete singletonInstances;
singletonInstances = nullptr;
}
delete singletonsLock;
singletonsLock = nullptr;
}
} deleter;
}
//------------------------------------------------------------------------
} // namespace Steinberg
+558
View File
@@ -0,0 +1,558 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fobject.h
// Created by : Steinberg, 2008
// Description : Basic Object implementing FUnknown
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------
/** @file base/source/fobject.h
Basic Object implementing FUnknown. */
//------------------------------------------------------------------------
#pragma once
#include "pluginterfaces/base/funknown.h"
#include "pluginterfaces/base/iupdatehandler.h"
#include "base/source/fdebug.h" // use of NEW
#define SMTG_DEPENDENCY_COUNT DEVELOPMENT
namespace Steinberg {
//----------------------------------
using FClassID = FIDString;
//------------------------------------------------------------------------
// Basic FObject - implements FUnknown + IDependent
//------------------------------------------------------------------------
/** Implements FUnknown and IDependent.
FObject is a polymorphic class that implements IDependent (of SKI module) and therefore derived from
FUnknown, which is the most abstract base class of all.
All COM-like virtual methods of FUnknown such as queryInterface(), addRef(), release() are
implemented here. On top of that, dependency-related methods are implemented too.
Pointer casting is done via the template methods FCast, either FObject to FObject or FUnknown to
FObject.
FObject supports a new singleton concept, therefore these objects are deleted automatically upon
program termination.
- Runtime type information: An object can be queried at runtime, of what class it is. To do this
correctly, every class must override some methods. This is simplified by using the OBJ_METHODS
macros
@see
- FUnknown
- IDependent
- IUpdateHandler
*/
//------------------------------------------------------------------------
class FObject : public IDependent
{
public:
//------------------------------------------------------------------------
FObject () = default; ///< default constructor...
FObject (const FObject&) ///< overloaded constructor...
: refCount (1)
#if SMTG_DEPENDENCY_COUNT
, dependencyCount (0)
#endif
{}
FObject& operator= (const FObject&) { return *this; } ///< overloads operator "=" as the reference assignment
virtual ~FObject (); ///< destructor...
// OBJECT_METHODS
static inline FClassID getFClassID () {return "FObject";} ///< return Class ID as an ASCII string (statically)
virtual FClassID isA () const {return FObject::getFClassID ();} ///< a local alternative to getFClassID ()
virtual bool isA (FClassID s) const {return isTypeOf (s, false);} ///< evaluates if the passed ID is of the FObject type
virtual bool isTypeOf (FClassID s, bool /*askBaseClass*/ = true) const {return classIDsEqual (s, FObject::getFClassID ());}
///< evaluates if the passed ID is of the FObject type
int32 getRefCount () {return refCount;} ///< returns the current interface reference count
FUnknown* unknownCast () {return this;} ///< get FUnknown interface from object
// FUnknown
tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE; ///< please refer to FUnknown::queryInterface ()
uint32 PLUGIN_API addRef () SMTG_OVERRIDE; ///< please refer to FUnknown::addref ()
uint32 PLUGIN_API release () SMTG_OVERRIDE; ///< please refer to FUnknown::release ()
// IDependent
void PLUGIN_API update (FUnknown* /*changedUnknown*/, int32 /*message*/) SMTG_OVERRIDE {}
///< empty virtual method that should be overridden by derived classes for data updates upon changes
// IDependency
virtual void addDependent (IDependent* dep); ///< adds dependency to the object
virtual void removeDependent (IDependent* dep); ///< removes dependency from the object
virtual void changed (int32 msg = kChanged); ///< Inform all dependents, that the object has changed.
virtual void deferUpdate (int32 msg = kChanged); ///< Similar to triggerUpdates, except only delivered in idle (usefull in collecting updates).
virtual void updateDone (int32 /* msg */) {} ///< empty virtual method that should be overridden by derived classes
virtual bool isEqualInstance (FUnknown* d) {return this == d;}
static void setUpdateHandler (IUpdateHandler* handler) {gUpdateHandler = handler;} ///< set method for the local attribute
static IUpdateHandler* getUpdateHandler () {return gUpdateHandler;} ///< get method for the local attribute
// static helper functions
static inline bool classIDsEqual (FClassID ci1, FClassID ci2); ///< compares (evaluates) 2 class IDs
static inline FObject* unknownToObject (FUnknown* unknown); ///< pointer conversion from FUnknown to FObject
/** convert from FUnknown to FObject */
template <class Class>
static inline IPtr<Class> fromUnknown (FUnknown* unknown);
/** Special UID that is used to cast an FUnknown pointer to a FObject */
static const FUID iid;
//------------------------------------------------------------------------
protected:
int32 refCount = 1; ///< COM-model local reference count
#if SMTG_DEPENDENCY_COUNT
int16 dependencyCount = 0;
#endif
static IUpdateHandler* gUpdateHandler;
};
//------------------------------------------------------------------------
// conversion from FUnknown to FObject subclass
//------------------------------------------------------------------------
template <class C>
inline IPtr<C> FObject::fromUnknown (FUnknown* unknown)
{
if (unknown)
{
FObject* object = nullptr;
if (unknown->queryInterface (FObject::iid, (void**)&object) == kResultTrue && object)
{
if (object->isTypeOf (C::getFClassID (), true))
return IPtr<C> (static_cast<C*> (object), false);
object->release ();
}
}
return {};
}
//------------------------------------------------------------------------
inline FObject* FObject::unknownToObject (FUnknown* unknown)
{
FObject* object = nullptr;
if (unknown)
{
unknown->queryInterface (FObject::iid, (void**)&object);
if (object)
{
if (object->release () == 0)
object = nullptr;
}
}
return object;
}
//------------------------------------------------------------------------
inline bool FObject::classIDsEqual (FClassID ci1, FClassID ci2)
{
return (ci1 && ci2) ? (strcmp (ci1, ci2) == 0) : false;
}
//-----------------------------------------------------------------------
/** FCast overload 1 - FObject to FObject */
//-----------------------------------------------------------------------
template <class C>
inline C* FCast (const FObject* object)
{
if (object && object->isTypeOf (C::getFClassID (), true))
return (C*) object;
return nullptr;
}
//-----------------------------------------------------------------------
/** FCast overload 2 - FUnknown to FObject */
//-----------------------------------------------------------------------
template <class C>
inline C* FCast (FUnknown* unknown)
{
FObject* object = FObject::unknownToObject (unknown);
return FCast<C> (object);
}
//-----------------------------------------------------------------------
/** ICast - casting from FObject to FUnknown Interface */
//-----------------------------------------------------------------------
template<class I>
inline IPtr<I> ICast (FObject* object)
{
return FUnknownPtr<I> (object ? object->unknownCast () : nullptr);
}
//-----------------------------------------------------------------------
/** ICast - casting from FUnknown to another FUnknown Interface */
//-----------------------------------------------------------------------
template<class I>
inline IPtr<I> ICast (FUnknown* object)
{
return FUnknownPtr<I> (object);
}
//------------------------------------------------------------------------
template <class C>
inline C* FCastIsA (const FObject* object)
{
if (object && object->isA (C::getFClassID ()))
return (C*)object;
return nullptr;
}
#ifndef SMTG_HIDE_DEPRECATED_INLINE_FUNCTIONS
//-----------------------------------------------------------------------
/** \deprecated FUCast - casting from FUnknown to Interface */
//-----------------------------------------------------------------------
template <class C>
SMTG_DEPRECATED_MSG("use ICast<>") inline C* FUCast (FObject* object)
{
return FUnknownPtr<C> (object ? object->unknownCast () : nullptr);
}
template <class C>
SMTG_DEPRECATED_MSG("use ICast<>") inline C* FUCast (FUnknown* object)
{
return FUnknownPtr<C> (object);
}
#endif // SMTG_HIDE_DEPRECATED_FUNCTIONS
//------------------------------------------------------------------------
/** @name Convenience methods that call release or delete respectively
on a pointer if it is non-zero, and then set the pointer to zero.
Note: you should prefer using IPtr or OPtr instead of these methods
whenever possible.
<b>Examples:</b>
@code
~Foo ()
{
// instead of ...
if (somePointer)
{
somePointer->release ();
somePointer = 0;
}
// ... just being lazy I write
SafeRelease (somePointer)
}
@endcode
*/
///@{
//-----------------------------------------------------------------------
template <class I>
inline void SafeRelease (I *& ptr)
{
if (ptr)
{
ptr->release ();
ptr = 0;
}
}
//-----------------------------------------------------------------------
template <class I>
inline void SafeRelease (IPtr<I> & ptr)
{
ptr = 0;
}
//-----------------------------------------------------------------------
template <class T>
inline void SafeDelete (T *& ptr)
{
if (ptr)
{
delete ptr;
ptr = 0;
}
}
///@}
//-----------------------------------------------------------------------
template <class T>
inline void AssignShared (T*& dest, T* newPtr)
{
if (dest == newPtr)
return;
if (dest)
dest->release ();
dest = newPtr;
if (dest)
dest->addRef ();
}
//-----------------------------------------------------------------------
template <class T>
inline void AssignSharedDependent (IDependent* _this, T*& dest, T* newPtr)
{
if (dest == newPtr)
return;
if (dest)
dest->removeDependent (_this);
AssignShared (dest, newPtr);
if (dest)
dest->addDependent (_this);
}
//-----------------------------------------------------------------------
template <class T>
inline void AssignSharedDependent (IDependent* _this, IPtr<T>& dest, T* newPtr)
{
if (dest == newPtr)
return;
if (dest)
dest->removeDependent (_this);
dest = newPtr;
if (dest)
dest->addDependent (_this);
}
//-----------------------------------------------------------------------
template <class T>
inline void SafeReleaseDependent (IDependent* _this, T*& dest)
{
if (dest)
dest->removeDependent (_this);
SafeRelease (dest);
}
//-----------------------------------------------------------------------
template <class T>
inline void SafeReleaseDependent (IDependent* _this, IPtr<T>& dest)
{
if (dest)
dest->removeDependent (_this);
SafeRelease (dest);
}
//------------------------------------------------------------------------
/** Automatic creation and destruction of singleton instances. */
namespace Singleton {
/** registers an instance (type FObject) */
void registerInstance (FObject** o);
/** Returns true when singleton instances were already released. */
bool isTerminated ();
/** lock and unlock the singleton registration for multi-threading safety */
void lockRegister ();
void unlockRegister ();
}
//------------------------------------------------------------------------
} // namespace Steinberg
//-----------------------------------------------------------------------
#define SINGLETON(ClassName) \
static ClassName* instance (bool create = true) \
{ \
static Steinberg::FObject* inst = nullptr; \
if (inst == nullptr && create && Steinberg::Singleton::isTerminated () == false) \
{ \
Steinberg::Singleton::lockRegister (); \
if (inst == nullptr) \
{ \
inst = NEW ClassName; \
Steinberg::Singleton::registerInstance (&inst); \
} \
Steinberg::Singleton::unlockRegister (); \
} \
return (ClassName*)inst; \
}
//-----------------------------------------------------------------------
#define OBJ_METHODS(className, baseClass) \
static inline Steinberg::FClassID getFClassID () {return (#className);} \
virtual Steinberg::FClassID isA () const SMTG_OVERRIDE {return className::getFClassID ();} \
virtual bool isA (Steinberg::FClassID s) const SMTG_OVERRIDE {return isTypeOf (s, false);} \
virtual bool isTypeOf (Steinberg::FClassID s, bool askBaseClass = true) const SMTG_OVERRIDE \
{ return (FObject::classIDsEqual (s, #className) ? true : (askBaseClass ? baseClass::isTypeOf (s, true) : false)); }
//------------------------------------------------------------------------
/** Delegate refcount functions to BaseClass.
BaseClase must implement ref counting.
*/
//------------------------------------------------------------------------
#define REFCOUNT_METHODS(BaseClass) \
virtual Steinberg::uint32 PLUGIN_API addRef ()SMTG_OVERRIDE{ return BaseClass::addRef (); } \
virtual Steinberg::uint32 PLUGIN_API release ()SMTG_OVERRIDE{ return BaseClass::release (); }
//------------------------------------------------------------------------
/** @name Macros to implement FUnknown::queryInterface ().
<b>Examples:</b>
@code
class Foo : public FObject, public IFoo2, public IFoo3
{
...
DEFINE_INTERFACES
DEF_INTERFACE (IFoo2)
DEF_INTERFACE (IFoo3)
END_DEFINE_INTERFACES (FObject)
REFCOUNT_METHODS(FObject)
// Implement IFoo2 interface ...
// Implement IFoo3 interface ...
...
};
@endcode
*/
///@{
//------------------------------------------------------------------------
/** Start defining interfaces. */
//------------------------------------------------------------------------
#define DEFINE_INTERFACES \
Steinberg::tresult PLUGIN_API queryInterface (const Steinberg::TUID iid, void** obj) SMTG_OVERRIDE \
{
//------------------------------------------------------------------------
/** Add a interfaces. */
//------------------------------------------------------------------------
#define DEF_INTERFACE(InterfaceName) \
QUERY_INTERFACE (iid, obj, Steinberg::getTUID<InterfaceName> (), InterfaceName)
//------------------------------------------------------------------------
/** End defining interfaces. */
//------------------------------------------------------------------------
#define END_DEFINE_INTERFACES(BaseClass) \
return BaseClass::queryInterface (iid, obj); \
}
///@}
//------------------------------------------------------------------------
/** @name Convenient macros to implement Steinberg::FUnknown::queryInterface ().
<b>Examples:</b>
@code
class Foo : public FObject, public IFoo2, public IFoo3
{
...
DEF_INTERFACES_2(IFoo2,IFoo3,FObject)
REFCOUNT_METHODS(FObject)
...
};
@endcode
*/
///@{
//------------------------------------------------------------------------
#define DEF_INTERFACES_1(InterfaceName,BaseClass) \
DEFINE_INTERFACES \
DEF_INTERFACE (InterfaceName) \
END_DEFINE_INTERFACES (BaseClass)
//------------------------------------------------------------------------
#define DEF_INTERFACES_2(InterfaceName1,InterfaceName2,BaseClass) \
DEFINE_INTERFACES \
DEF_INTERFACE (InterfaceName1) \
DEF_INTERFACE (InterfaceName2) \
END_DEFINE_INTERFACES (BaseClass)
//------------------------------------------------------------------------
#define DEF_INTERFACES_3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
DEFINE_INTERFACES \
DEF_INTERFACE (InterfaceName1) \
DEF_INTERFACE (InterfaceName2) \
DEF_INTERFACE (InterfaceName3) \
END_DEFINE_INTERFACES (BaseClass)
//------------------------------------------------------------------------
#define DEF_INTERFACES_4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
DEFINE_INTERFACES \
DEF_INTERFACE (InterfaceName1) \
DEF_INTERFACE (InterfaceName2) \
DEF_INTERFACE (InterfaceName3) \
DEF_INTERFACE (InterfaceName4) \
END_DEFINE_INTERFACES (BaseClass)
///@}
//------------------------------------------------------------------------
/** @name Convenient macros to implement Steinberg::FUnknown methods.
<b>Examples:</b>
@code
class Foo : public FObject, public IFoo2, public IFoo3
{
...
FUNKNOWN_METHODS2(IFoo2,IFoo3,FObject)
...
};
@endcode
*/
///@{
#define FUNKNOWN_METHODS(InterfaceName,BaseClass) \
DEF_INTERFACES_1(InterfaceName,BaseClass) \
REFCOUNT_METHODS(BaseClass)
#define FUNKNOWN_METHODS2(InterfaceName1,InterfaceName2,BaseClass) \
DEF_INTERFACES_2(InterfaceName1,InterfaceName2,BaseClass) \
REFCOUNT_METHODS(BaseClass)
#define FUNKNOWN_METHODS3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
DEF_INTERFACES_3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
REFCOUNT_METHODS(BaseClass)
#define FUNKNOWN_METHODS4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
DEF_INTERFACES_4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
REFCOUNT_METHODS(BaseClass)
///@}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
#if COM_COMPATIBLE
//------------------------------------------------------------------------
/** @name Macros to implement IUnknown interfaces with FObject.
<b>Examples:</b>
@code
class MyEnumFormat : public FObject, IEnumFORMATETC
{
...
COM_UNKNOWN_METHODS (IEnumFORMATETC, IUnknown)
...
};
@endcode
*/
///@{
//------------------------------------------------------------------------
#define IUNKNOWN_REFCOUNT_METHODS(BaseClass) \
STDMETHOD_ (ULONG, AddRef) (void) {return BaseClass::addRef ();} \
STDMETHOD_ (ULONG, Release) (void) {return BaseClass::release ();}
//------------------------------------------------------------------------
#define COM_QUERY_INTERFACE(iid, obj, InterfaceName) \
if (riid == __uuidof(InterfaceName)) \
{ \
addRef (); \
*obj = (InterfaceName*)this; \
return kResultOk; \
}
//------------------------------------------------------------------------
#define COM_OBJECT_QUERY_INTERFACE(InterfaceName,BaseClass) \
STDMETHOD (QueryInterface) (REFIID riid, void** object) \
{ \
COM_QUERY_INTERFACE (riid, object, InterfaceName) \
return BaseClass::queryInterface ((FIDString)&riid, object); \
}
//------------------------------------------------------------------------
#define COM_UNKNOWN_METHODS(InterfaceName,BaseClass) \
COM_OBJECT_QUERY_INTERFACE(InterfaceName,BaseClass) \
IUNKNOWN_REFCOUNT_METHODS(BaseClass)
///@}
#endif // COM_COMPATIBLE
+182
View File
@@ -0,0 +1,182 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fstdmethods.h
// Created by : Steinberg, 2007
// Description : Convenient macros to create setter and getter methods.
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------
/** @file base/source/fstdmethods.h
Convenient macros to create setter and getter methods. */
//------------------------------------------------------------------------
#pragma once
//----------------------------------------------------------------------------------
/** @name Methods for flags.
Macros to create setter and getter methods for flags.
Usage example with DEFINE_STATE:
\code
class MyClass
{
public:
MyClass () : flags (0) {}
DEFINE_FLAG (flags, isFlagged, 1<<0)
DEFINE_FLAG (flags, isMine, 1<<1)
private:
uint32 flags;
};
void someFunction ()
{
MyClass c;
if (c.isFlagged ()) // check the flag
c.isFlagged (false); // set the flag
}
\endcode
*/
//----------------------------------------------------------------------------------
///@{
/** Create Methods with @c get and @c set prefix. */
#define DEFINE_STATE(flagVar,methodName,value)\
void set##methodName (bool state) { if (state) flagVar |= (value); else flagVar &= ~(value); }\
bool get##methodName ()const { return (flagVar & (value)) != 0; }
/** Create Methods with @c get prefix.
There is only a 'get' method. */
#define DEFINE_GETSTATE(flagVar,methodName,value)\
bool get##methodName ()const { return (flagVar & (value)) != 0; }
/** Create Methods.
Same name for the getter and setter. */
#define DEFINE_FLAG(flagVar,methodName,value)\
void methodName (bool state) { if (state) flagVar |= (value); else flagVar &= ~(value); }\
bool methodName ()const { return (flagVar & (value)) != 0; }
/** Create Methods.
There is only a 'get' method. */
#define DEFINE_GETFLAG(flagVar,methodName,value)\
bool methodName ()const { return (flagVar & (value)) != 0; }
/** Create @c static Methods.
Same name for the getter and setter. */
#define DEFINE_FLAG_STATIC(flagVar,methodName,value)\
static void methodName (bool __state) { if (__state) flagVar |= (value); else flagVar &= ~(value); }\
static bool methodName () { return (flagVar & (value)) != 0; }
///@}
//----------------------------------------------------------------------------------
/** @name Methods for data members.
Macros to create setter and getter methods for class members.
<b>Examples:</b>
\code
class MyClass
{
public:
DATA_MEMBER (double, distance, Distance)
STRING_MEMBER (Steinberg::String, name, Name)
SHARED_MEMBER (FUnknown, userData, UserData)
CLASS_MEMBER (Steinberg::Buffer, bufferData, BufferData)
POINTER_MEMBER (Steinberg::FObject, refOnly, RefOnly)
};
\endcode
*/
//--------------------------------------------------------------------------------------
///@{
/** Build-in member (pass by value). */
#define DATA_MEMBER(type,varName,methodName)\
public:void set##methodName (type v) { varName = v;}\
type get##methodName ()const { return varName; }\
protected: type varName; public:
//** Object member (pass by reference). */
#define CLASS_MEMBER(type,varName,methodName)\
public:void set##methodName (const type& v){ varName = v;}\
const type& get##methodName () const { return varName; }\
protected: type varName; public:
//** Simple pointer. */
#define POINTER_MEMBER(type,varName,methodName)\
public:void set##methodName (type* ptr){ varName = ptr;}\
type* get##methodName ()const { return varName; }\
private: type* varName; public:
//** Shared member - FUnknown / FObject / etc */
#define SHARED_MEMBER(type,varName,methodName)\
public:void set##methodName (type* v){ varName = v;}\
type* get##methodName ()const { return varName; }\
private: IPtr<type> varName; public:
//** Owned member - FUnknown / FObject / CmObject etc */
#define OWNED_MEMBER(type,varName,methodName)\
public:void set##methodName (type* v){ varName = v;}\
type* get##methodName ()const { return varName; }\
private: OPtr<type> varName; public:
//** tchar* / String class member - set by const tchar*, return by reference */
#define STRING_MEMBER(type,varName,methodName)\
public:void set##methodName (const tchar* v){ varName = v;}\
const type& get##methodName () const { return varName; }\
protected: type varName; public:
//** char8* / String class member - set by const char8*, return by reference */
#define STRING8_MEMBER(type,varName,methodName)\
public:void set##methodName (const char8* v){ varName = v;}\
const type& get##methodName () const { return varName; }\
protected: type varName; public:
//** Standard String Member Steinberg::String */
#define STRING_MEMBER_STD(varName,methodName) STRING_MEMBER(Steinberg::String,varName,methodName)
#define STRING8_MEMBER_STD(varName,methodName) STRING8_MEMBER(Steinberg::String,varName,methodName)
///@}
// obsolete names
#define DEFINE_VARIABLE(type,varName,methodName) DATA_MEMBER(type,varName,methodName)
#define DEFINE_POINTER(type,varName,methodName) POINTER_MEMBER(type,varName,methodName)
#define DEFINE_MEMBER(type,varName,methodName) CLASS_MEMBER(type,varName,methodName)
//------------------------------------------------------------------------
// for implementing comparison operators using a class member or a compare method:
//------------------------------------------------------------------------
#define COMPARE_BY_MEMBER_METHODS(className,memberName) \
bool operator == (const className& other) const {return (memberName == other.memberName);} \
bool operator != (const className& other) const {return (memberName != other.memberName);} \
bool operator < (const className& other) const {return (memberName < other.memberName);} \
bool operator > (const className& other) const {return (memberName > other.memberName);} \
bool operator <= (const className& other) const {return (memberName <= other.memberName);} \
bool operator >= (const className& other) const {return (memberName >= other.memberName);}
#define COMPARE_BY_MEMORY_METHODS(className) \
bool operator == (const className& other) const {return memcmp (this, &other, sizeof (className)) == 0;} \
bool operator != (const className& other) const {return memcmp (this, &other, sizeof (className)) != 0;} \
bool operator < (const className& other) const {return memcmp (this, &other, sizeof (className)) < 0;} \
bool operator > (const className& other) const {return memcmp (this, &other, sizeof (className)) > 0;} \
bool operator <= (const className& other) const {return memcmp (this, &other, sizeof (className)) <= 0;} \
bool operator >= (const className& other) const {return memcmp (this, &other, sizeof (className)) >= 0;}
#define COMPARE_BY_COMPARE_METHOD(className,methodName) \
bool operator == (const className& other) const {return methodName (other) == 0;} \
bool operator != (const className& other) const {return methodName (other) != 0;} \
bool operator < (const className& other) const {return methodName (other) < 0;} \
bool operator > (const className& other) const {return methodName (other) > 0;} \
bool operator <= (const className& other) const {return methodName (other) <= 0; } \
bool operator >= (const className& other) const {return methodName (other) >= 0; }
+736
View File
@@ -0,0 +1,736 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fstreamer.cpp
// Created by : Steinberg, 15.12.2005
// Description : Extract of typed stream i/o methods from FStream
//
//-----------------------------------------------------------------------------
// 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 "fstreamer.h"
#include "base/source/fstring.h"
#include "base/source/fbuffer.h"
#include "pluginterfaces/base/ibstream.h"
#ifndef UNICODE
#include "pluginterfaces/base/futils.h"
#endif
namespace Steinberg {
//------------------------------------------------------------------------
// IBStreamer
//------------------------------------------------------------------------
IBStreamer::IBStreamer (IBStream* stream, int16 _byteOrder)
: FStreamer (_byteOrder)
, stream (stream)
{}
//------------------------------------------------------------------------
TSize IBStreamer::readRaw (void* buffer, TSize size)
{
int32 numBytesRead = 0;
stream->read (buffer, (int32)size, &numBytesRead);
return numBytesRead;
}
//------------------------------------------------------------------------
TSize IBStreamer::writeRaw (const void* buffer, TSize size)
{
int32 numBytesWritten = 0;
stream->write ((void*)buffer, (int32)size, &numBytesWritten);
return numBytesWritten;
}
//------------------------------------------------------------------------
int64 IBStreamer::seek (int64 pos, FSeekMode mode)
{
int64 result = -1;
stream->seek (pos, mode, &result);
return result;
}
//------------------------------------------------------------------------
int64 IBStreamer::tell ()
{
int64 pos = 0;
stream->tell (&pos);
return pos;
}
//------------------------------------------------------------------------
// FStreamSizeHolder Implementation
//------------------------------------------------------------------------
FStreamSizeHolder::FStreamSizeHolder (FStreamer &s)
: stream (s), sizePos (-1)
{}
//------------------------------------------------------------------------
void FStreamSizeHolder::beginWrite ()
{
sizePos = stream.tell ();
stream.writeInt32 (0L);
}
//------------------------------------------------------------------------
int32 FStreamSizeHolder::endWrite ()
{
if (sizePos < 0)
return 0;
int64 currentPos = stream.tell ();
stream.seek (sizePos, kSeekSet);
int32 size = int32 (currentPos - sizePos - sizeof (int32));
stream.writeInt32 (size);
stream.seek (currentPos, kSeekSet);
return size;
}
//------------------------------------------------------------------------
int32 FStreamSizeHolder::beginRead ()
{
sizePos = stream.tell ();
int32 size = 0;
stream.readInt32 (size);
sizePos += size + sizeof (int32);
return size;
}
//------------------------------------------------------------------------
void FStreamSizeHolder::endRead ()
{
if (sizePos >= 0)
stream.seek (sizePos, kSeekSet);
}
//------------------------------------------------------------------------
// FStreamer
//------------------------------------------------------------------------
FStreamer::FStreamer (int16 _byteOrder)
: byteOrder (_byteOrder)
{}
// int8 / char -----------------------------------------------------------
//------------------------------------------------------------------------
bool FStreamer::writeChar8 (char8 c)
{
return writeRaw ((void*)&c, sizeof (char8)) == sizeof (char8);
}
//------------------------------------------------------------------------
bool FStreamer::readChar8 (char8& c)
{
return readRaw ((void*)&c, sizeof (char8)) == sizeof (char8);
}
//------------------------------------------------------------------------
bool FStreamer::writeUChar8 (unsigned char c)
{
return writeRaw ((void*)&c, sizeof (unsigned char)) == sizeof (unsigned char);
}
//------------------------------------------------------------------------
bool FStreamer::readUChar8 (unsigned char& c)
{
return readRaw ((void*)&c, sizeof (unsigned char)) == sizeof (unsigned char);
}
//------------------------------------------------------------------------
bool FStreamer::writeChar16 (char16 c)
{
if (BYTEORDER != byteOrder)
SWAP_16 (c);
return writeRaw ((void*)&c, sizeof (char16)) == sizeof (char16);
}
//------------------------------------------------------------------------
bool FStreamer::readChar16 (char16& c)
{
if (readRaw ((void*)&c, sizeof (char16)) == sizeof (char16))
{
if (BYTEORDER != byteOrder)
SWAP_16 (c);
return true;
}
c = 0;
return false;
}
//------------------------------------------------------------------------
bool FStreamer::writeInt8 (int8 c)
{
return writeRaw ((void*)&c, sizeof (int8)) == sizeof (int8);
}
//------------------------------------------------------------------------
bool FStreamer::readInt8 (int8& c)
{
return readRaw ((void*)&c, sizeof (int8)) == sizeof (int8);
}
//------------------------------------------------------------------------
bool FStreamer::writeInt8u (uint8 c)
{
return writeRaw ((void*)&c, sizeof (uint8)) == sizeof (uint8);
}
//------------------------------------------------------------------------
bool FStreamer::readInt8u (uint8& c)
{
return readRaw ((void*)&c, sizeof (uint8)) == sizeof (uint8);
}
// int16 -----------------------------------------------------------------
//------------------------------------------------------------------------
bool FStreamer::writeInt16 (int16 i)
{
if (BYTEORDER != byteOrder)
SWAP_16 (i);
return writeRaw ((void*)&i, sizeof (int16)) == sizeof (int16);
}
//------------------------------------------------------------------------
bool FStreamer::readInt16 (int16& i)
{
if (readRaw ((void*)&i, sizeof (int16)) == sizeof (int16))
{
if (BYTEORDER != byteOrder)
SWAP_16 (i);
return true;
}
i = 0;
return false;
}
//------------------------------------------------------------------------
bool FStreamer::writeInt16Array (const int16* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!writeInt16 (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::readInt16Array (int16* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!readInt16 (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::writeInt16u (uint16 i)
{
if (BYTEORDER != byteOrder)
SWAP_16 (i);
return writeRaw ((void*)&i, sizeof (uint16)) == sizeof (uint16);
}
//------------------------------------------------------------------------
bool FStreamer::readInt16u (uint16& i)
{
if (readRaw ((void*)&i, sizeof (uint16)) == sizeof (uint16))
{
if (BYTEORDER != byteOrder)
SWAP_16 (i);
return true;
}
i = 0;
return false;
}
//------------------------------------------------------------------------
bool FStreamer::writeInt16uArray (const uint16* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!writeInt16u (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::readInt16uArray (uint16* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!readInt16u (array[i]))
return false;
}
return true;
}
// int32 -----------------------------------------------------------------
//------------------------------------------------------------------------
bool FStreamer::writeInt32 (int32 i)
{
if (BYTEORDER != byteOrder)
SWAP_32 (i);
return writeRaw ((void*)&i, sizeof (int32)) == sizeof (int32);
}
//------------------------------------------------------------------------
bool FStreamer::readInt32 (int32& i)
{
if (readRaw ((void*)&i, sizeof (int32)) == sizeof (int32))
{
if (BYTEORDER != byteOrder)
SWAP_32 (i);
return true;
}
i = 0;
return false;
}
//------------------------------------------------------------------------
bool FStreamer::writeInt32Array (const int32* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!writeInt32 (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::readInt32Array (int32* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!readInt32 (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::writeInt32u (uint32 i)
{
if (BYTEORDER != byteOrder)
SWAP_32 (i);
return writeRaw ((void*)&i, sizeof (uint32)) == sizeof (uint32);
}
//------------------------------------------------------------------------
bool FStreamer::readInt32u (uint32& i)
{
if (readRaw ((void*)&i, sizeof (uint32)) == sizeof (uint32))
{
if (BYTEORDER != byteOrder)
SWAP_32 (i);
return true;
}
i = 0;
return false;
}
//------------------------------------------------------------------------
bool FStreamer::writeInt32uArray (const uint32* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!writeInt32u (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::readInt32uArray (uint32* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!readInt32u (array[i]))
return false;
}
return true;
}
// int64 -----------------------------------------------------------------
//------------------------------------------------------------------------
bool FStreamer::writeInt64 (int64 i)
{
if (BYTEORDER != byteOrder)
SWAP_64 (i);
return writeRaw ((void*)&i, sizeof (int64)) == sizeof (int64);
}
//------------------------------------------------------------------------
bool FStreamer::readInt64 (int64& i)
{
if (readRaw ((void*)&i, sizeof (int64)) == sizeof (int64))
{
if (BYTEORDER != byteOrder)
SWAP_64 (i);
return true;
}
i = 0;
return false;
}
//------------------------------------------------------------------------
bool FStreamer::writeInt64Array (const int64* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!writeInt64 (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::readInt64Array (int64* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!readInt64 (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::writeInt64u (uint64 i)
{
if (BYTEORDER != byteOrder)
SWAP_64 (i);
return writeRaw ((void*)&i, sizeof (uint64)) == sizeof (uint64);
}
//------------------------------------------------------------------------
bool FStreamer::readInt64u (uint64& i)
{
if (readRaw ((void*)&i, sizeof (uint64)) == sizeof (uint64))
{
if (BYTEORDER != byteOrder)
SWAP_64 (i);
return true;
}
i = 0;
return false;
}
//------------------------------------------------------------------------
bool FStreamer::writeInt64uArray (const uint64* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!writeInt64u (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::readInt64uArray (uint64* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!readInt64u (array[i]))
return false;
}
return true;
}
// float / double --------------------------------------------------------
//------------------------------------------------------------------------
bool FStreamer::writeFloat (float f)
{
if (BYTEORDER != byteOrder)
SWAP_32 (f);
return writeRaw ((void*)&f, sizeof (float)) == sizeof (float);
}
//------------------------------------------------------------------------
bool FStreamer::readFloat (float& f)
{
if (readRaw ((void*)&f, sizeof (float)) == sizeof (float))
{
if (BYTEORDER != byteOrder)
SWAP_32 (f);
return true;
}
f = 0.f;
return false;
}
//------------------------------------------------------------------------
bool FStreamer::writeFloatArray (const float* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!writeFloat (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::readFloatArray (float* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!readFloat (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::writeDouble (double d)
{
if (BYTEORDER != byteOrder)
SWAP_64 (d);
return writeRaw ((void*)&d, sizeof (double)) == sizeof (double);
}
//------------------------------------------------------------------------
bool FStreamer::readDouble (double& d)
{
if (readRaw ((void*)&d, sizeof (double)) == sizeof (double))
{
if (BYTEORDER != byteOrder)
SWAP_64 (d);
return true;
}
d = 0.0;
return false;
}
//------------------------------------------------------------------------
bool FStreamer::writeDoubleArray (const double* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!writeDouble (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::readDoubleArray (double* array, int32 count)
{
for (int32 i = 0; i < count; i++)
{
if (!readDouble (array[i]))
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::readBool (bool& b)
{
int16 v = 0;
bool res = readInt16 (v);
b = (v != 0);
return res;
}
//------------------------------------------------------------------------
bool FStreamer::writeBool (bool b)
{
return writeInt16 ((int16)b);
}
//------------------------------------------------------------------------
TSize FStreamer::writeString8 (const char8* ptr, bool terminate)
{
TSize size = strlen (ptr);
if (terminate) // write \0
size++;
return writeRaw ((void*)ptr, size);
}
//------------------------------------------------------------------------
TSize FStreamer::readString8 (char8* ptr, TSize size)
{
if (size < 1 || ptr == nullptr)
return 0;
TSize i = 0;
char8 c = 0;
while (i < size)
{
if (readRaw ((void*)&c, sizeof (char)) != sizeof (char))
break;
ptr[i] = c;
if (c == '\n' || c == '\0')
break;
i++;
}
// remove at end \n (LF) or \r\n (CR+LF)
if (c == '\n')
{
if (i > 0 && ptr[i - 1] == '\r')
i--;
}
if (i >= size)
i = size - 1;
ptr[i] = 0;
return i;
}
//------------------------------------------------------------------------
bool FStreamer::writeStringUtf8 (const tchar* ptr)
{
bool isUtf8 = false;
String str (ptr);
if (str.isAsciiString () == false)
{
str.toMultiByte (kCP_Utf8);
isUtf8 = true;
}
else
{
str.toMultiByte ();
}
if (isUtf8)
if (writeRaw (kBomUtf8, kBomUtf8Length) != kBomUtf8Length)
return false;
TSize size = str.length () + 1;
if (writeRaw (str.text8 (), size) != size)
return false;
return true;
}
//------------------------------------------------------------------------
int32 FStreamer::readStringUtf8 (tchar* ptr, int32 nChars)
{
char8 c = 0;
ptr [0] = 0;
Buffer tmp;
tmp.setDelta (1024);
while (true)
{
if (readRaw ((void*)&c, sizeof (char)) != sizeof (char))
break;
tmp.put (c);
if (c == '\0')
break;
}
char8* source = tmp.str8 ();
uint32 codePage = kCP_Default; // for legacy take default page if no utf8 bom is present...
if (tmp.getFillSize () > 2)
{
if (memcmp (source, kBomUtf8, kBomUtf8Length) == 0)
{
codePage = kCP_Utf8;
source += 3;
}
}
if (tmp.getFillSize () > 1)
{
#ifdef UNICODE
ConstString::multiByteToWideString (ptr, source, nChars, codePage);
#else
if (codePage == kCP_Utf8)
{
Buffer wideBuffer (tmp.getFillSize () * 3);
ConstString::multiByteToWideString (wideBuffer.wcharPtr (), source, wideBuffer.getSize () / 2, kCP_Utf8);
ConstString::wideStringToMultiByte (ptr, wideBuffer.wcharPtr (), nChars);
}
else
{
memcpy (ptr, source, Min<TSize> (nChars, tmp.getFillSize ()));
}
#endif
}
ptr[nChars - 1] = 0;
return ConstString (ptr).length ();
}
//------------------------------------------------------------------------
bool FStreamer::writeStr8 (const char8* s)
{
int32 length = (s) ? (int32) strlen (s) + 1 : 0;
if (!writeInt32 (length))
return false;
if (length > 0)
return writeRaw (s, sizeof (char8) * length) == static_cast<TSize>(sizeof (char8) * length);
return true;
}
//------------------------------------------------------------------------
int32 FStreamer::getStr8Size (const char8* s)
{
return sizeof (int32) + (int32)strlen (s) + 1;
}
//------------------------------------------------------------------------
char8* FStreamer::readStr8 ()
{
int32 length;
if (!readInt32 (length))
return nullptr;
// check corruption
if (length > 262144)
return nullptr;
char8* s = (length > 0) ? NEWSTR8 (length) : nullptr;
if (s)
readRaw (s, length * sizeof (char8));
return s;
}
//------------------------------------------------------------------------
bool FStreamer::skip (uint32 bytes)
{
int8 tmp;
while (bytes-- > 0)
{
if (readInt8 (tmp) == false)
return false;
}
return true;
}
//------------------------------------------------------------------------
bool FStreamer::pad (uint32 bytes)
{
while (bytes-- > 0)
{
if (writeInt8 (0) == false)
return false;
}
return true;
}
//------------------------------------------------------------------------
} // namespace Steinberg
+222
View File
@@ -0,0 +1,222 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fstreamer.h
// Created by : Steinberg, 12/2005
// Description : Extract of typed stream i/o methods from FStream
//
//-----------------------------------------------------------------------------
// 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 {
//------------------------------------------------------------------------
enum FSeekMode
{
kSeekSet,
kSeekCurrent,
kSeekEnd
};
//------------------------------------------------------------------------
// FStreamer
//------------------------------------------------------------------------
/** Byteorder-aware base class for typed stream i/o. */
//------------------------------------------------------------------------
class FStreamer
{
public:
//------------------------------------------------------------------------
FStreamer (int16 byteOrder = BYTEORDER);
virtual ~FStreamer () {}
/** @name Implementing class must override. */
///@{
virtual TSize readRaw (void*, TSize) = 0; ///< Read one buffer of size.
virtual TSize writeRaw (const void*, TSize) = 0; ///< Write one buffer of size.
virtual int64 seek (int64, FSeekMode) = 0; ///< Set file position for stream.
virtual int64 tell () = 0; ///< Return current file position.
///@}
/** @name Streams are byteOrder aware. */
///@{
inline void setByteOrder (int32 e) { byteOrder = (int16)e; }
inline int32 getByteOrder () const { return byteOrder; }
///@}
/** @name read and write int8 and char. */
///@{
bool writeChar8 (char8);
bool readChar8 (char8&);
bool writeUChar8 (unsigned char);
bool readUChar8 (unsigned char&);
bool writeChar16 (char16 c);
bool readChar16 (char16& c);
bool writeInt8 (int8 c);
bool readInt8 (int8& c);
bool writeInt8u (uint8 c);
bool readInt8u (uint8& c);
///@}
/** @name read and write int16. */
///@{
bool writeInt16 (int16);
bool readInt16 (int16&);
bool writeInt16Array (const int16* array, int32 count);
bool readInt16Array (int16* array, int32 count);
bool writeInt16u (uint16);
bool readInt16u (uint16&);
bool writeInt16uArray (const uint16* array, int32 count);
bool readInt16uArray (uint16* array, int32 count);
///@}
/** @name read and write int32. */
///@{
bool writeInt32 (int32);
bool readInt32 (int32&);
bool writeInt32Array (const int32* array, int32 count);
bool readInt32Array (int32* array, int32 count);
bool writeInt32u (uint32);
bool readInt32u (uint32&);
bool writeInt32uArray (const uint32* array, int32 count);
bool readInt32uArray (uint32* array, int32 count);
///@}
/** @name read and write int64. */
///@{
bool writeInt64 (int64);
bool readInt64 (int64&);
bool writeInt64Array (const int64* array, int32 count);
bool readInt64Array (int64* array, int32 count);
bool writeInt64u (uint64);
bool readInt64u (uint64&);
bool writeInt64uArray (const uint64* array, int32 count);
bool readInt64uArray (uint64* array, int32 count);
///@}
/** @name read and write float and float array. */
///@{
bool writeFloat (float);
bool readFloat (float&);
bool writeFloatArray (const float* array, int32 count);
bool readFloatArray (float* array, int32 count);
///@}
/** @name read and write double and double array. */
///@{
bool writeDouble (double);
bool readDouble (double&);
bool writeDoubleArray (const double* array, int32 count);
bool readDoubleArray (double* array, int32 count);
///@}
/** @name read and write Boolean. */
///@{
bool writeBool (bool); ///< Write one boolean
bool readBool (bool&); ///< Read one bool.
///@}
/** @name read and write Strings. */
///@{
TSize writeString8 (const char8* ptr, bool terminate = false); ///< a direct output function writing only one string (ascii 8bit)
TSize readString8 (char8* ptr, TSize size); ///< a direct input function reading only one string (ascii) (ended by a \n or \0 or eof)
bool writeStr8 (const char8* ptr); ///< write a string length (strlen) and string itself
char8* readStr8 (); ///< read a string length and string text (The return string must be deleted when use is finished)
static int32 getStr8Size (const char8* ptr); ///< returns the size of a saved string
bool writeStringUtf8 (const tchar* ptr); ///< always terminated, converts to utf8 if non ascii characters are in string
int32 readStringUtf8 (tchar* ptr, int32 maxSize); ///< read a UTF8 string
///@}
bool skip (uint32 bytes);
bool pad (uint32 bytes);
//------------------------------------------------------------------------
protected:
int16 byteOrder;
};
//------------------------------------------------------------------------
/** FStreamSizeHolder Declaration
remembers size of stream chunk for backward compatibility.
<b>Example:</b>
@code
externalize (a)
{
FStreamSizeHolder sizeHolder;
sizeHolder.beginWrite (); // sets start mark, writes dummy size
a << ....
sizeHolder.endWrite (); // jumps to start mark, updates size, jumps back here
}
internalize (a)
{
FStreamSizeHolder sizeHolder;
sizeHolder.beginRead (); // reads size, mark
a >> ....
sizeHolder.endRead (); // jumps forward if new version has larger size
}
@endcode
*/
//------------------------------------------------------------------------
class FStreamSizeHolder
{
public:
FStreamSizeHolder (FStreamer &s);
void beginWrite (); ///< remembers position and writes 0
int32 endWrite (); ///< writes and returns size (since the start marker)
int32 beginRead (); ///< returns size
void endRead (); ///< jump to end of chunk
protected:
FStreamer &stream;
int64 sizePos;
};
class IBStream;
//------------------------------------------------------------------------
// IBStreamer
//------------------------------------------------------------------------
/** Wrapper class for typed reading/writing from or to IBStream.
Can be used framework-independent in plug-ins. */
//------------------------------------------------------------------------
class IBStreamer: public FStreamer
{
public:
//------------------------------------------------------------------------
/** Constructor for a given IBSTream and a byteOrder. */
IBStreamer (IBStream* stream, int16 byteOrder = BYTEORDER);
IBStream* getStream () { return stream; } ///< Returns the associated IBStream.
// FStreamer overrides:
TSize readRaw (void*, TSize) SMTG_OVERRIDE; ///< Read one buffer of size.
TSize writeRaw (const void*, TSize) SMTG_OVERRIDE; ///< Write one buffer of size.
int64 seek (int64, FSeekMode) SMTG_OVERRIDE; ///< Set file position for stream.
int64 tell () SMTG_OVERRIDE; ///< Return current file position.
//------------------------------------------------------------------------
protected:
IBStream* stream;
};
//------------------------------------------------------------------------
} // namespace Steinberg
File diff suppressed because it is too large Load Diff
+758
View File
@@ -0,0 +1,758 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/fstring.h
// Created by : Steinberg, 2008
// Description : 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 "pluginterfaces/base/ftypes.h"
#include "pluginterfaces/base/fstrdefs.h"
#include "pluginterfaces/base/istringresult.h"
#include "pluginterfaces/base/ipersistent.h"
#include "base/source/fobject.h"
#include <cstdarg>
#include <cstdlib>
namespace Steinberg {
class FVariant;
class String;
#ifdef UNICODE
static const bool kWideStringDefault = true;
#else
static const bool kWideStringDefault = false;
#endif
static const uint16 kBomUtf16 = 0xFEFF; ///< UTF16 Byte Order Mark
static const char8* const kBomUtf8 = "\xEF\xBB\xBF"; ///< UTF8 Byte Order Mark
static const int32 kBomUtf8Length = 3;
enum MBCodePage
{
kCP_ANSI = 0, ///< Default ANSI codepage.
kCP_MAC_ROMAN = 2, ///< Default Mac codepage.
kCP_ANSI_WEL = 1252, ///< West European Latin Encoding.
kCP_MAC_CEE = 10029, ///< Mac Central European Encoding.
kCP_Utf8 = 65001, ///< UTF8 Encoding.
kCP_ShiftJIS = 932, ///< Shifted Japan Industrial Standard Encoding.
kCP_US_ASCII = 20127, ///< US-ASCII (7-bit).
kCP_Default = kCP_ANSI ///< Default ANSI codepage.
};
enum UnicodeNormalization
{
kUnicodeNormC, ///< Unicode normalization Form C, canonical composition.
kUnicodeNormD, ///< Unicode normalization Form D, canonical decomposition.
kUnicodeNormKC, ///< Unicode normalization form KC, compatibility composition.
kUnicodeNormKD ///< Unicode normalization form KD, compatibility decomposition.
};
//------------------------------------------------------------------------
// Helper functions to create hash codes from string data.
//------------------------------------------------------------------------
extern uint32 hashString8 (const char8* s, uint32 m);
extern uint32 hashString16 (const char16* s, uint32 m);
inline uint32 hashString (const tchar* s, uint32 m)
{
#ifdef UNICODE
return hashString16 (s, m);
#else
return hashString8 (s, m);
#endif
}
//-----------------------------------------------------------------------------
/** Invariant String.
@ingroup adt
A base class which provides methods to work with its
member string. Neither of the operations allows modifying the member string and
that is why all operation are declared as const.
There are operations for access, comparison, find, numbers and conversion.
Almost all operations exist in three versions for char8, char16 and the
polymorphic type tchar. The type tchar can either be char8 or char16 depending
on whether UNICODE is activated or not.*/
//-----------------------------------------------------------------------------
class ConstString
{
public:
//-----------------------------------------------------------------------------
ConstString (const char8* str, int32 length = -1); ///< Assign from string of type char8 (length=-1: all)
ConstString (const char16* str, int32 length = -1); ///< Assign from string of type char16 (length=-1: all)
ConstString (const ConstString& str, int32 offset = 0, int32 length = -1); ///< Copy constructor (length=-1: all).
ConstString (const FVariant& var); ///< Assign a string from FVariant
ConstString ();
virtual ~ConstString () {} ///< Destructor.
// access -----------------------------------------------------------------
virtual int32 length () const {return static_cast<int32> (len);} ///< Return length of string
inline bool isEmpty () const {return buffer == nullptr || len == 0;} ///< Return true if string is empty
operator const char8* () const {return text8 ();} ///< Returns pointer to string of type char8 (no modification allowed)
operator const char16* () const {return text16 ();} ///< Returns pointer to string of type char16(no modification allowed)
inline tchar operator[] (short idx) const {return getChar (static_cast<uint32> (idx));} ///< Returns character at 'idx'
inline tchar operator[] (long idx) const {return getChar (static_cast<uint32> (idx));}
inline tchar operator[] (int idx) const {return getChar (static_cast<uint32> (idx));}
inline tchar operator[] (unsigned short idx) const {return getChar (idx);}
inline tchar operator[] (unsigned long idx) const {return getChar (static_cast<uint32> (idx));}
inline tchar operator[] (unsigned int idx) const {return getChar (idx);}
inline virtual const char8* text8 () const; ///< Returns pointer to string of type char8
inline virtual const char16* text16 () const; ///< Returns pointer to string of type char16
inline virtual const tchar* text () const; ///< Returns pointer to string of type tchar
inline virtual const void* ptr () const {return buffer;} ///< Returns pointer to string of type void
inline virtual char8 getChar8 (uint32 index) const; ///< Returns character of type char16 at 'index'
inline virtual char16 getChar16 (uint32 index) const; ///< Returns character of type char8 at 'index'
inline tchar getChar (uint32 index) const; ///< Returns character of type tchar at 'index'
inline tchar getCharAt (uint32 index) const; ///< Returns character of type tchar at 'index', no conversion!
bool testChar8 (uint32 index, char8 c) const; ///< Returns true if character is equal at position 'index'
bool testChar16 (uint32 index, char16 c) const;
inline bool testChar (uint32 index, char8 c) const {return testChar8 (index, c);}
inline bool testChar (uint32 index, char16 c) const {return testChar16 (index, c);}
bool extract (String& result, uint32 idx, int32 n = -1) const; ///< Get n characters long substring starting at index (n=-1: until end)
int32 copyTo8 (char8* str, uint32 idx = 0, int32 n = -1) const;
int32 copyTo16 (char16* str, uint32 idx = 0, int32 n = -1) const;
int32 copyTo (tchar* str, uint32 idx = 0, int32 n = -1) const;
void copyTo (IStringResult* result) const; ///< Copies whole member string
void copyTo (IString& string) const; ///< Copies whole member string
inline uint32 hash (uint32 tsize) const
{
return isWide ? hashString16 (buffer16, tsize) : hashString8 (buffer8, tsize) ;
}
//-------------------------------------------------------------------------
// compare ----------------------------------------------------------------
enum CompareMode
{
kCaseSensitive, ///< Comparison is done with regard to character's case
kCaseInsensitive ///< Comparison is done without regard to character's case
};
int32 compareAt (uint32 index, const ConstString& str, int32 n = -1, CompareMode m = kCaseSensitive) const; ///< Compare n characters of str with n characters of this starting at index (return: see above)
int32 compare (const ConstString& str, int32 n, CompareMode m = kCaseSensitive) const; ///< Compare n characters of str with n characters of this (return: see above)
int32 compare (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Compare all characters of str with this (return: see above)
int32 naturalCompare (const ConstString& str, CompareMode mode = kCaseSensitive) const;
bool startsWith (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Check if this starts with str
bool endsWith (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Check if this ends with str
bool contains (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Check if this contains str
// static methods
static bool isCharSpace (char8 character); ///< Returns true if character is a space
static bool isCharSpace (char16 character); ///< @copydoc isCharSpace(const char8)
static bool isCharAlpha (char8 character); ///< Returns true if character is an alphabetic character
static bool isCharAlpha (char16 character); ///< @copydoc isCharAlpha(const char8)
static bool isCharAlphaNum (char8 character); ///< Returns true if character is an alphanumeric character
static bool isCharAlphaNum (char16 character); ///< @copydoc isCharAlphaNum(const char8)
static bool isCharDigit (char8 character); ///< Returns true if character is a number
static bool isCharDigit (char16 character); ///< @copydoc isCharDigit(const char8)
static bool isCharAscii (char8 character); ///< Returns true if character is in ASCII range
static bool isCharAscii (char16 character); ///< Returns true if character is in ASCII range
static bool isCharUpper (char8 character);
static bool isCharUpper (char16 character);
static bool isCharLower (char8 character);
static bool isCharLower (char16 character);
//-------------------------------------------------------------------------
/** @name Find first occurrence of n characters of str in this (n=-1: all) ending at endIndex (endIndex = -1: all)*/
///@{
inline int32 findFirst (const ConstString& str, int32 n = -1, CompareMode m = kCaseSensitive, int32 endIndex = -1) const {return findNext (0, str, n, m, endIndex);}
inline int32 findFirst (char8 c, CompareMode m = kCaseSensitive, int32 endIndex = -1) const {return findNext (0, c, m, endIndex);}
inline int32 findFirst (char16 c, CompareMode m = kCaseSensitive, int32 endIndex = -1) const {return findNext (0, c, m, endIndex);}
///@}
/** @name Find next occurrence of n characters of str starting at startIndex in this (n=-1: all) ending at endIndex (endIndex = -1: all)*/
///@{
int32 findNext (int32 startIndex, const ConstString& str, int32 n = -1, CompareMode = kCaseSensitive, int32 endIndex = -1) const;
int32 findNext (int32 startIndex, char8 c, CompareMode = kCaseSensitive, int32 endIndex = -1) const;
int32 findNext (int32 startIndex, char16 c, CompareMode = kCaseSensitive, int32 endIndex = -1) const;
///@}
/** @name Find previous occurrence of n characters of str starting at startIndex in this (n=-1: all) */
///@{
int32 findPrev (int32 startIndex, const ConstString& str, int32 n = -1, CompareMode = kCaseSensitive) const;
int32 findPrev (int32 startIndex, char8 c, CompareMode = kCaseSensitive) const;
int32 findPrev (int32 startIndex, char16 c, CompareMode = kCaseSensitive) const;
///@}
inline int32 findLast (const ConstString& str, int32 n = -1, CompareMode m = kCaseSensitive) const {return findPrev (-1, str, n, m);} ///< Find last occurrence of n characters of str in this (n=-1: all)
inline int32 findLast (char8 c, CompareMode m = kCaseSensitive) const {return findPrev (-1, c, m);}
inline int32 findLast (char16 c, CompareMode m = kCaseSensitive) const {return findPrev (-1, c, m);}
int32 countOccurences (char8 c, uint32 startIndex, CompareMode = kCaseSensitive) const; ///< Counts occurences of c within this starting at index
int32 countOccurences (char16 c, uint32 startIndex, CompareMode = kCaseSensitive) const;
int32 getFirstDifferent (const ConstString& str, CompareMode = kCaseSensitive) const; ///< Returns position of first different character
//-------------------------------------------------------------------------
// numbers ----------------------------------------------------------------
bool isDigit (uint32 index) const; ///< Returns true if character at position is a digit
bool scanFloat (double& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to double value starting at offset
bool scanInt64 (int64& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to int64 value starting at offset
bool scanUInt64 (uint64& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to uint64 value starting at offset
bool scanInt32 (int32& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to int32 value starting at offset
bool scanUInt32 (uint32& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to uint32 value starting at offset
bool scanHex (uint8& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to hex/uint8 value starting at offset
int32 getTrailingNumberIndex (uint32 width = 0) const; ///< Returns start index of trailing number
int64 getTrailingNumber (int64 fallback = 0) const; ///< Returns result of scanInt64 or the fallback
int64 getNumber () const; ///< Returns result of scanInt64
// static methods
static bool scanInt64_8 (const char8* text, int64& value, bool scanToEnd = true); ///< Converts string of type char8 to int64 value
static bool scanInt64_16 (const char16* text, int64& value, bool scanToEnd = true); ///< Converts string of type char16 to int64 value
static bool scanInt64 (const tchar* text, int64& value, bool scanToEnd = true); ///< Converts string of type tchar to int64 value
static bool scanUInt64_8 (const char8* text, uint64& value, bool scanToEnd = true); ///< Converts string of type char8 to uint64 value
static bool scanUInt64_16 (const char16* text, uint64& value, bool scanToEnd = true); ///< Converts string of type char16 to uint64 value
static bool scanUInt64 (const tchar* text, uint64& value, bool scanToEnd = true); ///< Converts string of type tchar to uint64 value
static bool scanInt32_8 (const char8* text, int32& value, bool scanToEnd = true); ///< Converts string of type char8 to int32 value
static bool scanInt32_16 (const char16* text, int32& value, bool scanToEnd = true); ///< Converts string of type char16 to int32 value
static bool scanInt32 (const tchar* text, int32& value, bool scanToEnd = true); ///< Converts string of type tchar to int32 value
static bool scanUInt32_8 (const char8* text, uint32& value, bool scanToEnd = true); ///< Converts string of type char8 to int32 value
static bool scanUInt32_16 (const char16* text, uint32& value, bool scanToEnd = true); ///< Converts string of type char16 to int32 value
static bool scanUInt32 (const tchar* text, uint32& value, bool scanToEnd = true); ///< Converts string of type tchar to int32 value
static bool scanHex_8 (const char8* text, uint8& value, bool scanToEnd = true); ///< Converts string of type char8 to hex/unit8 value
static bool scanHex_16 (const char16* text, uint8& value, bool scanToEnd = true); ///< Converts string of type char16 to hex/unit8 value
static bool scanHex (const tchar* text, uint8& value, bool scanToEnd = true); ///< Converts string of type tchar to hex/unit8 value
//-------------------------------------------------------------------------
// conversion -------------------------------------------------------------
void toVariant (FVariant& var) const;
static char8 toLower (char8 c); ///< Converts to lower case
static char8 toUpper (char8 c); ///< Converts to upper case
static char16 toLower (char16 c);
static char16 toUpper (char16 c);
static int32 multiByteToWideString (char16* dest, const char8* source, int32 wcharCount, uint32 sourceCodePage = kCP_Default); ///< If dest is zero, this returns the maximum number of bytes needed to convert source
static int32 wideStringToMultiByte (char8* dest, const char16* source, int32 char8Count, uint32 destCodePage = kCP_Default); ///< If dest is zero, this returns the maximum number of bytes needed to convert source
bool isWideString () const {return isWide != 0;} ///< Returns true if string is wide
bool isAsciiString () const; ///< Checks if all characters in string are in ascii range
bool isNormalized (UnicodeNormalization = kUnicodeNormC); ///< On PC only kUnicodeNormC is working
#if SMTG_OS_WINDOWS
ConstString (const wchar_t* str, int32 length = -1) : ConstString (wscast (str), length) {}
operator const wchar_t* () const { return wscast (text16 ());}
#endif
#if SMTG_OS_MACOS
virtual void* toCFStringRef (uint32 encoding = 0xFFFF, bool mutableCFString = false) const; ///< CFString conversion
#endif
//-------------------------------------------------------------------------
//-----------------------------------------------------------------------------
protected:
union
{
void* buffer;
char8* buffer8;
char16* buffer16;
};
uint32 len : 30;
uint32 isWide : 1;
};
//-----------------------------------------------------------------------------
/** String.
@ingroup adt
Extends class ConstString by operations which allow modifications.
If allocated externally and passed in via take() or extracted via pass(), memory
is expected to be allocated with C's malloc() (rather than new) and deallocated with free().
Use the NEWSTR8/16 and DELETESTR8/16 macros below.
\see ConstString */
//-----------------------------------------------------------------------------
class String : public ConstString
{
public:
//-----------------------------------------------------------------------------
String ();
String (const char8* str, MBCodePage codepage, int32 n = -1, bool isTerminated = true); ///< assign n characters of str and convert to wide string by using the specified codepage
String (const char8* str, int32 n = -1, bool isTerminated = true); ///< assign n characters of str (-1: all)
String (const char16* str, int32 n = -1, bool isTerminated = true); ///< assign n characters of str (-1: all)
String (const String& str, int32 n = -1); ///< assign n characters of str (-1: all)
String (const ConstString& str, int32 n = -1); ///< assign n characters of str (-1: all)
String (const FVariant& var); ///< assign from FVariant
String (IString* str); ///< assign from IString
~String () SMTG_OVERRIDE;
#if SMTG_CPP11_STDLIBSUPPORT
String (String&& str);
String& operator= (String&& str);
#endif
// access------------------------------------------------------------------
void updateLength (); ///< Call this when the string is truncated outside (not recommended though)
const char8* text8 () const SMTG_OVERRIDE;
const char16* text16 () const SMTG_OVERRIDE;
char8 getChar8 (uint32 index) const SMTG_OVERRIDE;
char16 getChar16 (uint32 index) const SMTG_OVERRIDE;
bool setChar8 (uint32 index, char8 c);
bool setChar16 (uint32 index, char16 c);
inline bool setChar (uint32 index, char8 c) {return setChar8 (index, c);}
inline bool setChar (uint32 index, char16 c) {return setChar16 (index, c);}
//-------------------------------------------------------------------------
// assignment--------------------------------------------------------------
String& operator= (const char8* str) {return assign (str);} ///< Assign from a string of type char8
String& operator= (const char16* str) {return assign (str);}
String& operator= (const ConstString& str) {return assign (str);}
String& operator= (const String& str) {return assign (str);}
String& operator= (char8 c) {return assign (c);}
String& operator= (char16 c) {return assign (c);}
String& assign (const ConstString& str, int32 n = -1); ///< Assign n characters of str (-1: all)
String& assign (const char8* str, int32 n = -1, bool isTerminated = true); ///< Assign n characters of str (-1: all)
String& assign (const char16* str, int32 n = -1, bool isTerminated = true); ///< Assign n characters of str (-1: all)
String& assign (char8 c, int32 n = 1);
String& assign (char16 c, int32 n = 1);
//-------------------------------------------------------------------------
// concat------------------------------------------------------------------
String& append (const ConstString& str, int32 n = -1); ///< Append n characters of str to this (n=-1: all)
String& append (const char8* str, int32 n = -1); ///< Append n characters of str to this (n=-1: all)
String& append (const char16* str, int32 n = -1); ///< Append n characters of str to this (n=-1: all)
String& append (const char8 c, int32 n = 1); ///< Append char c n times
String& append (const char16 c, int32 n = 1); ///< Append char c n times
String& insertAt (uint32 idx, const ConstString& str, int32 n = -1); ///< Insert n characters of str at position idx (n=-1: all)
String& insertAt (uint32 idx, const char8* str, int32 n = -1); ///< Insert n characters of str at position idx (n=-1: all)
String& insertAt (uint32 idx, const char16* str, int32 n = -1); ///< Insert n characters of str at position idx (n=-1: all)
String& insertAt (uint32 idx, char8 c) {char8 str[] = {c, 0}; return insertAt (idx, str, 1);}
String& insertAt (uint32 idx, char16 c) {char16 str[] = {c, 0}; return insertAt (idx, str, 1);}
String& operator+= (const String& str) {return append (str);}
String& operator+= (const ConstString& str) {return append (str);}
String& operator+= (const char8* str) {return append (str);}
String& operator+= (const char16* str) {return append (str);}
String& operator+= (const char8 c) {return append (c);}
String& operator+= (const char16 c) {return append (c);}
//-------------------------------------------------------------------------
// replace-----------------------------------------------------------------
String& replace (uint32 idx, int32 n1, const ConstString& str, int32 n2 = -1); ///< Replace n1 characters of this (starting at idx) with n2 characters of str (n1,n2=-1: until end)
String& replace (uint32 idx, int32 n1, const char8* str, int32 n2 = -1); ///< Replace n1 characters of this (starting at idx) with n2 characters of str (n1,n2=-1: until end)
String& replace (uint32 idx, int32 n1, const char16* str, int32 n2 = -1); ///< Replace n1 characters of this (starting at idx) with n2 characters of str (n1,n2=-1: until end)
int32 replace (const char8* toReplace, const char8* toReplaceWith, bool all = false, CompareMode m = kCaseSensitive); ///< Replace find string with replace string - returns number of replacements
int32 replace (const char16* toReplace, const char16* toReplaceWith, bool all = false, CompareMode m = kCaseSensitive); ///< Replace find string with replace string - returns number of replacements
bool replaceChars8 (const char8* toReplace, char8 toReplaceBy); ///< Returns true when any replacement was done
bool replaceChars16 (const char16* toReplace, char16 toReplaceBy);
inline bool replaceChars8 (char8 toReplace, char8 toReplaceBy) {char8 str[] = {toReplace, 0}; return replaceChars8 (str, toReplaceBy);}
inline bool replaceChars16 (char16 toReplace, char16 toReplaceBy) {char16 str[] = {toReplace, 0}; return replaceChars16 (str, toReplaceBy);}
inline bool replaceChars (char8 toReplace, char8 toReplaceBy) {return replaceChars8 (toReplace, toReplaceBy);}
inline bool replaceChars (char16 toReplace, char16 toReplaceBy) {return replaceChars16 (toReplace, toReplaceBy);}
inline bool replaceChars (const char8* toReplace, char8 toReplaceBy) {return replaceChars8 (toReplace, toReplaceBy);}
inline bool replaceChars (const char16* toReplace, char16 toReplaceBy) {return replaceChars16 (toReplace, toReplaceBy);}
//-------------------------------------------------------------------------
// remove------------------------------------------------------------------
String& remove (uint32 index = 0, int32 n = -1); ///< Remove n characters from string starting at index (n=-1: until end)
enum CharGroup {kSpace, kNotAlphaNum, kNotAlpha};
bool trim (CharGroup mode = kSpace); ///< Trim lead/trail.
void removeChars (CharGroup mode = kSpace); ///< Removes all of group.
bool removeChars8 (const char8* which); ///< Remove all occurrences of each char in 'which'
bool removeChars16 (const char16* which); ///< Remove all occurrences of each char in 'which'
inline bool removeChars8 (const char8 which) {char8 str[] = {which, 0}; return removeChars8 (str); }
inline bool removeChars16 (const char16 which) {char16 str[] = {which, 0}; return removeChars16 (str); }
inline bool removeChars (const char8* which) {return removeChars8 (which);}
inline bool removeChars (const char16* which) {return removeChars16 (which);}
inline bool removeChars (const char8 which) {return removeChars8 (which);}
inline bool removeChars (const char16 which) {return removeChars16 (which);}
bool removeSubString (const ConstString& subString, bool allOccurences = true);
//-------------------------------------------------------------------------
// print-------------------------------------------------------------------
String& printf (const char8* format, ...); ///< Print formatted data into string
String& printf (const char16* format, ...); ///< Print formatted data into string
String& vprintf (const char8* format, va_list args);
String& vprintf (const char16* format, va_list args);
//-------------------------------------------------------------------------
// numbers-----------------------------------------------------------------
String& printInt64 (int64 value);
/**
* @brief print a float into a string, trailing zeros will be trimmed
* @param value the floating value to be printed
* @param maxPrecision (optional) the max precision allowed for this, num of significant digits after the comma
* For instance printFloat (1.234, 2) => 1.23
* @return the resulting string.
*/
String& printFloat (double value, uint32 maxPrecision = 6);
/** Increment the trailing number if present else start with minNumber, width specifies the string width format (width 2 for number 3 is 03),
applyOnlyFormat set to true will only format the string to the given width without incrementing the founded trailing number */
bool incrementTrailingNumber (uint32 width = 2, tchar separator = STR (' '), uint32 minNumber = 1, bool applyOnlyFormat = false);
//-------------------------------------------------------------------------
// conversion--------------------------------------------------------------
bool fromVariant (const FVariant& var); ///< Assigns string from FVariant
void toVariant (FVariant& var) const;
bool fromAttributes (IAttributes* a, IAttrID attrID); ///< Assigns string from FAttributes
bool toAttributes (IAttributes* a, IAttrID attrID);
void swapContent (String& s); ///< Swaps ownership of the strings pointed to
void take (String& str); ///< Take ownership of the string of 'str'
void take (void* _buffer, bool wide); ///< Take ownership of buffer
void* pass ();
void passToVariant (FVariant& var); ///< Pass ownership of buffer to Variant - sets Variant ownership
void toLower (uint32 index); ///< Lower case the character.
void toLower (); ///< Lower case the string.
void toUpper (uint32 index); ///< Upper case the character.
void toUpper (); ///< Upper case the string.
unsigned char* toPascalString (unsigned char* buf); ///< Pascal string conversion
const String& fromPascalString (const unsigned char* buf); ///< Pascal string conversion
bool toWideString (uint32 sourceCodePage = kCP_Default); ///< Converts to wide string according to sourceCodePage
bool toMultiByte (uint32 destCodePage = kCP_Default);
void fromUTF8 (const char8* utf8String); ///< Assigns from UTF8 string
bool normalize (UnicodeNormalization = kUnicodeNormC); ///< On PC only kUnicodeNormC is working
#if SMTG_OS_WINDOWS
String (const wchar_t* str, int32 length = -1, bool isTerminated = true) : String (wscast (str), length, isTerminated) {}
String& operator= (const wchar_t* str) {return String::operator= (wscast (str)); }
#endif
#if SMTG_OS_MACOS
virtual bool fromCFStringRef (const void*, uint32 encoding = 0xFFFF); ///< CFString conversion
#endif
//-------------------------------------------------------------------------
//-----------------------------------------------------------------------------
protected:
bool resize (uint32 newSize, bool wide, bool fill = false);
private:
bool _toWideString (const char8* src, int32 length, uint32 sourceCodePage = kCP_Default);
void tryFreeBuffer ();
bool checkToMultiByte (uint32 destCodePage = kCP_Default) const; // to remove debug code from inline - const_cast inside!!!
};
// String memory allocation macros
#define NEWSTR8(len) ((char8*)::malloc(len)) // len includes trailing zero
#define NEWSTR16(len) ((char16*)::malloc(2*(len)))
#define DELETESTR8(p) (::free((char*)(p))) // cast to strip const
#define DELETESTR16(p) (::free((char16*)(p)))
// String concatenation functions.
inline String operator+ (const ConstString& s1, const ConstString& s2) {return String (s1).append (s2);}
inline String operator+ (const ConstString& s1, const char8* s2) {return String (s1).append (s2);}
inline String operator+ (const ConstString& s1, const char16* s2) {return String (s1).append (s2);}
inline String operator+ (const char8* s1, const ConstString& s2) {return String (s1).append (s2);}
inline String operator+ (const char16* s1, const ConstString& s2) {return String (s1).append (s2);}
inline String operator+ (const ConstString& s1, const String& s2) {return String (s1).append (s2);}
inline String operator+ (const String& s1, const ConstString& s2) {return String (s1).append (s2);}
inline String operator+ (const String& s1, const String& s2) {return String (s1).append (s2);}
inline String operator+ (const String& s1, const char8* s2) {return String (s1).append (s2);}
inline String operator+ (const String& s1, const char16* s2) {return String (s1).append (s2);}
inline String operator+ (const char8* s1, const String& s2) {return String (s1).append (s2);}
inline String operator+ (const char16* s1, const String& s2) {return String (s1).append (s2);}
//-----------------------------------------------------------------------------
// ConstString
//-----------------------------------------------------------------------------
inline const tchar* ConstString::text () const
{
#ifdef UNICODE
return text16 ();
#else
return text8 ();
#endif
}
//-----------------------------------------------------------------------------
inline const char8* ConstString::text8 () const
{
return (!isWide && buffer8) ? buffer8: kEmptyString8;
}
//-----------------------------------------------------------------------------
inline const char16* ConstString::text16 () const
{
return (isWide && buffer16) ? buffer16 : kEmptyString16;
}
//-----------------------------------------------------------------------------
inline char8 ConstString::getChar8 (uint32 index) const
{
if (index < len && buffer8 && !isWide)
return buffer8[index];
return 0;
}
//-----------------------------------------------------------------------------
inline char16 ConstString::getChar16 (uint32 index) const
{
if (index < len && buffer16 && isWide)
return buffer16[index];
return 0;
}
//-----------------------------------------------------------------------------
inline tchar ConstString::getChar (uint32 index) const
{
#ifdef UNICODE
return getChar16 (index);
#else
return getChar8 (index);
#endif
}
//-----------------------------------------------------------------------------
inline tchar ConstString::getCharAt (uint32 index) const
{
#ifdef UNICODE
if (isWide)
return getChar16 (index);
#endif
return static_cast<tchar> (getChar8 (index));
}
//-----------------------------------------------------------------------------
inline int64 ConstString::getNumber () const
{
int64 tmp = 0;
scanInt64 (tmp);
return tmp;
}
//-----------------------------------------------------------------------------
inline bool ConstString::scanInt32_8 (const char8* text, int32& value, bool scanToEnd)
{
int64 tmp;
if (scanInt64_8 (text, tmp, scanToEnd))
{
value = (int32)tmp;
return true;
}
return false;
}
//-----------------------------------------------------------------------------
inline bool ConstString::scanInt32_16 (const char16* text, int32& value, bool scanToEnd)
{
int64 tmp;
if (scanInt64_16 (text, tmp, scanToEnd))
{
value = (int32)tmp;
return true;
}
return false;
}
//-----------------------------------------------------------------------------
inline bool ConstString::scanInt32 (const tchar* text, int32& value, bool scanToEnd)
{
int64 tmp;
if (scanInt64 (text, tmp, scanToEnd))
{
value = (int32)tmp;
return true;
}
return false;
}
//-----------------------------------------------------------------------------
inline bool ConstString::scanUInt32_8 (const char8* text, uint32& value, bool scanToEnd)
{
uint64 tmp;
if (scanUInt64_8 (text, tmp, scanToEnd))
{
value = (uint32)tmp;
return true;
}
return false;
}
//-----------------------------------------------------------------------------
inline bool ConstString::scanUInt32_16 (const char16* text, uint32& value, bool scanToEnd)
{
uint64 tmp;
if (scanUInt64_16 (text, tmp, scanToEnd))
{
value = (uint32)tmp;
return true;
}
return false;
}
//-----------------------------------------------------------------------------
inline bool ConstString::scanUInt32 (const tchar* text, uint32& value, bool scanToEnd)
{
uint64 tmp;
if (scanUInt64 (text, tmp, scanToEnd))
{
value = (uint32)tmp;
return true;
}
return false;
}
//-----------------------------------------------------------------------------
inline const char8* String::text8 () const
{
if (isWide && !isEmpty ())
checkToMultiByte (); // this should be avoided, since it can lead to information loss
return ConstString::text8 ();
}
//-----------------------------------------------------------------------------
inline const char16* String::text16 () const
{
if (!isWide && !isEmpty ())
{
const_cast<String&> (*this).toWideString ();
}
return ConstString::text16 ();
}
//-----------------------------------------------------------------------------
inline char8 String::getChar8 (uint32 index) const
{
if (isWide && !isEmpty ())
checkToMultiByte (); // this should be avoided, since it can lead to information loss
return ConstString::getChar8 (index);
}
//-----------------------------------------------------------------------------
inline char16 String::getChar16 (uint32 index) const
{
if (!isWide && !isEmpty ())
{
const_cast<String&> (*this).toWideString ();
}
return ConstString::getChar16 (index);
}
//-----------------------------------------------------------------------------
inline bool operator< (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) < 0) ? true : false;}
inline bool operator<= (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) <= 0) ? true : false;}
inline bool operator> (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) > 0) ? true : false;}
inline bool operator>= (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) >= 0) ? true : false;}
inline bool operator== (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) == 0) ? true : false;}
inline bool operator!= (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) != 0) ? true : false;}
inline bool operator< (const ConstString& s1, const char8* s2) {return (s1.compare (s2) < 0) ? true : false;}
inline bool operator<= (const ConstString& s1, const char8* s2) {return (s1.compare (s2) <= 0) ? true : false;}
inline bool operator> (const ConstString& s1, const char8* s2) {return (s1.compare (s2) > 0) ? true : false;}
inline bool operator>= (const ConstString& s1, const char8* s2) {return (s1.compare (s2) >= 0) ? true : false;}
inline bool operator== (const ConstString& s1, const char8* s2) {return (s1.compare (s2) == 0) ? true : false;}
inline bool operator!= (const ConstString& s1, const char8* s2) {return (s1.compare (s2) != 0) ? true : false;}
inline bool operator< (const char8* s1, const ConstString& s2) {return (s2.compare (s1) > 0) ? true : false;}
inline bool operator<= (const char8* s1, const ConstString& s2) {return (s2.compare (s1) >= 0) ? true : false;}
inline bool operator> (const char8* s1, const ConstString& s2) {return (s2.compare (s1) < 0) ? true : false;}
inline bool operator>= (const char8* s1, const ConstString& s2) {return (s2.compare (s1) <= 0) ? true : false;}
inline bool operator== (const char8* s1, const ConstString& s2) {return (s2.compare (s1) == 0) ? true : false;}
inline bool operator!= (const char8* s1, const ConstString& s2) {return (s2.compare (s1) != 0) ? true : false;}
inline bool operator< (const ConstString& s1, const char16* s2) {return (s1.compare (s2) < 0) ? true : false;}
inline bool operator<= (const ConstString& s1, const char16* s2) {return (s1.compare (s2) <= 0) ? true : false;}
inline bool operator> (const ConstString& s1, const char16* s2) {return (s1.compare (s2) > 0) ? true : false;}
inline bool operator>= (const ConstString& s1, const char16* s2) {return (s1.compare (s2) >= 0) ? true : false;}
inline bool operator== (const ConstString& s1, const char16* s2) {return (s1.compare (s2) == 0) ? true : false;}
inline bool operator!= (const ConstString& s1, const char16* s2) {return (s1.compare (s2) != 0) ? true : false;}
inline bool operator< (const char16* s1, const ConstString& s2) {return (s2.compare (s1) > 0) ? true : false;}
inline bool operator<= (const char16* s1, const ConstString& s2) {return (s2.compare (s1) >= 0) ? true : false;}
inline bool operator> (const char16* s1, const ConstString& s2) {return (s2.compare (s1) < 0) ? true : false;}
inline bool operator>= (const char16* s1, const ConstString& s2) {return (s2.compare (s1) <= 0) ? true : false;}
inline bool operator== (const char16* s1, const ConstString& s2) {return (s2.compare (s1) == 0) ? true : false;}
inline bool operator!= (const char16* s1, const ConstString& s2) {return (s2.compare (s1) != 0) ? true : false;}
// The following functions will only work with European Numbers!
// (e.g. Arabic, Tibetan, and Khmer digits are not supported)
extern int32 strnatcmp8 (const char8* s1, const char8* s2, bool caseSensitive = true);
extern int32 strnatcmp16 (const char16* s1, const char16* s2, bool caseSensitive = true);
inline int32 strnatcmp (const tchar* s1, const tchar* s2, bool caseSensitive = true)
{
#ifdef UNICODE
return strnatcmp16 (s1, s2, caseSensitive);
#else
return strnatcmp8 (s1, s2, caseSensitive);
#endif
}
//-----------------------------------------------------------------------------
/** StringObject implements IStringResult and IString methods.
It can therefore be exchanged with other Steinberg objects using one or both of these
interfaces.
\see String, ConstString
*/
//-----------------------------------------------------------------------------
class StringObject : public FObject, public String, public IStringResult, public IString
{
public:
//-----------------------------------------------------------------------------
StringObject () {}
StringObject (const char16* str, int32 n = -1, bool isTerminated = true) : String (str, n, isTerminated) {}
StringObject (const char8* str, int32 n = -1, bool isTerminated = true) : String (str, n, isTerminated) {}
StringObject (const StringObject& str, int32 n = -1) : String (str, n) {}
StringObject (const String& str, int32 n = -1) : String (str, n) {}
StringObject (const FVariant& var) : String (var) {}
using String::operator=;
// IStringResult ----------------------------------------------------------
void PLUGIN_API setText (const char8* text) SMTG_OVERRIDE;
//-------------------------------------------------------------------------
// IString-----------------------------------------------------------------
void PLUGIN_API setText8 (const char8* text) SMTG_OVERRIDE;
void PLUGIN_API setText16 (const char16* text) SMTG_OVERRIDE;
const char8* PLUGIN_API getText8 () SMTG_OVERRIDE;
const char16* PLUGIN_API getText16 () SMTG_OVERRIDE;
void PLUGIN_API take (void* s, bool _isWide) SMTG_OVERRIDE;
bool PLUGIN_API isWideString () const SMTG_OVERRIDE;
//-------------------------------------------------------------------------
OBJ_METHODS (StringObject, FObject)
FUNKNOWN_METHODS2 (IStringResult, IString, FObject)
};
//------------------------------------------------------------------------
} // namespace Steinberg
+127
View File
@@ -0,0 +1,127 @@
//-------------------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/hexbinary.h
// Created by : Steinberg, 1/2012
// Description : HexBinary encoding and decoding
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// This Software Development Kit may not be distributed in parts or its entirety
// without prior written agreement by Steinberg Media Technologies GmbH.
// This SDK must not be used to re-engineer or manipulate any technology used
// in any Steinberg or Third-party application or software module,
// unless permitted by law.
// Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SDK IS PROVIDED BY STEINBERG MEDIA TECHNOLOGIES GMBH "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL STEINBERG MEDIA TECHNOLOGIES GMBH BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
/** @file base/source/hexbinary.h
HexBinary encoding and decoding. */
//----------------------------------------------------------------------------------
#pragma once
#include "base/source/fbuffer.h"
namespace Steinberg {
//------------------------------------------------------------------------------
namespace HexBinary
{
//------------------------------------------------------------------------------
/** convert the HexBinary input buffer to binary. Note that it is appended to the result buffer. */
//------------------------------------------------------------------------------
inline bool decode (const void* input, int32 inputSize, Buffer& result)
{
if ((inputSize & 1) == 1)
return false;
result.grow (result.getSize () + inputSize / 2);
const char8* ptr = (const char8*)input;
uint8 current = 0;
for (int32 i = 0; i < inputSize; i++, ptr++)
{
current *= 16;
if (*ptr >= 48 && *ptr <= 57) // 0, 1, 2, .., 9
{
current += *ptr - 48;
}
else if (*ptr >= 65 && *ptr <= 70) // A, B, .., F
{
current += *ptr - 55;
}
else if (*ptr >= 97 && *ptr <= 102) // a, b, .., f
{
current += *ptr - 87;
}
else
{
// malformed
return false;
}
if (i % 2)
{
if (result.put (current) == false)
return false;
current = 0;
}
}
return true;
}
//------------------------------------------------------------------------------
/** convert the binary input buffer to HexBinary. Note that it is appended to the result buffer. */
//------------------------------------------------------------------------------
inline bool encode (const void* input, int32 inputSize, Buffer& result)
{
result.grow (result.getSize () + inputSize * 2);
const char8* ptr = (const char8*)input;
for (int32 i = 0; i < inputSize; i++, ptr++)
{
char8 high = (*ptr & 0xF0) >> 4;
char8 low = (*ptr & 0x0F);
if (high > 9)
{
if (result.put ((char8)(high + 55)) == false)
return false;
}
else
{
if (result.put ((char8)(high + 48)) == false)
return false;
}
if (low > 9)
{
if (result.put ((char8)(low + 55)) == false)
return false;
}
else
{
if (result.put ((char8)(low + 48)) == false)
return false;
}
}
return true;
}
//------------------------------------------------------------------------
} // namespace HexBinary
} // namespace Steinberg
+358
View File
@@ -0,0 +1,358 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/timer.cpp
// Created by : Steinberg, 05/2006
// Description : Timer class for receiving triggers at regular intervals
//
//-----------------------------------------------------------------------------
// 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 "base/source/timer.h"
namespace Steinberg {
static bool timersEnabled = true;
//------------------------------------------------------------------------
DisableDispatchingTimers::DisableDispatchingTimers ()
{
oldState = timersEnabled;
timersEnabled = false;
}
//------------------------------------------------------------------------
DisableDispatchingTimers::~DisableDispatchingTimers ()
{
timersEnabled = oldState;
}
//------------------------------------------------------------------------
namespace SystemTime {
//------------------------------------------------------------------------
struct ZeroStartTicks
{
static const uint64 startTicks;
static int32 getTicks32 ()
{
return static_cast<int32> (SystemTime::getTicks64 () - startTicks);
}
};
const uint64 ZeroStartTicks::startTicks = SystemTime::getTicks64 ();
//------------------------------------------------------------------------
int32 getTicks ()
{
return ZeroStartTicks::getTicks32 ();
}
//------------------------------------------------------------------------
} // namespace SystemTime
} // namespace Steinberg
#if SMTG_OS_MACOS
#include <CoreFoundation/CoreFoundation.h>
#include <mach/mach_time.h>
#ifdef verify
#undef verify
#endif
namespace Steinberg {
namespace SystemTime {
//------------------------------------------------------------------------
struct MachTimeBase
{
private:
struct mach_timebase_info timebaseInfo;
MachTimeBase () { mach_timebase_info (&timebaseInfo); }
static const MachTimeBase& instance ()
{
static MachTimeBase gInstance;
return gInstance;
}
public:
static double getTimeNanos ()
{
const MachTimeBase& timeBase = instance ();
double absTime = static_cast<double> (mach_absolute_time ());
// nano seconds
double d = (absTime / timeBase.timebaseInfo.denom) * timeBase.timebaseInfo.numer;
return d;
}
};
/*
@return the current system time in milliseconds
*/
uint64 getTicks64 ()
{
return static_cast<uint64> (MachTimeBase::getTimeNanos () / 1000000.);
}
//------------------------------------------------------------------------
} // namespace SystemTime
//------------------------------------------------------------------------
class MacPlatformTimer : public Timer
{
public:
MacPlatformTimer (ITimerCallback* callback, uint32 milliseconds);
~MacPlatformTimer ();
void stop () override;
bool verify () const { return platformTimer != nullptr; }
static void timerCallback (CFRunLoopTimerRef timer, void* info);
protected:
CFRunLoopTimerRef platformTimer;
ITimerCallback* callback;
};
//------------------------------------------------------------------------
MacPlatformTimer::MacPlatformTimer (ITimerCallback* callback, uint32 milliseconds)
: platformTimer (nullptr), callback (callback)
{
if (callback)
{
CFRunLoopTimerContext timerContext = {};
timerContext.info = this;
platformTimer = CFRunLoopTimerCreate (
kCFAllocatorDefault, CFAbsoluteTimeGetCurrent () + milliseconds * 0.001,
milliseconds * 0.001f, 0, 0, timerCallback, &timerContext);
if (platformTimer)
CFRunLoopAddTimer (CFRunLoopGetMain (), platformTimer, kCFRunLoopCommonModes);
}
}
//------------------------------------------------------------------------
MacPlatformTimer::~MacPlatformTimer ()
{
stop ();
}
//------------------------------------------------------------------------
void MacPlatformTimer::stop ()
{
if (platformTimer)
{
CFRunLoopRemoveTimer (CFRunLoopGetMain (), platformTimer, kCFRunLoopCommonModes);
CFRelease (platformTimer);
platformTimer = nullptr;
}
}
//------------------------------------------------------------------------
void MacPlatformTimer::timerCallback (CFRunLoopTimerRef, void* info)
{
if (timersEnabled)
{
if (auto timer = (MacPlatformTimer*)info)
timer->callback->onTimer (timer);
}
}
//------------------------------------------------------------------------
Timer* Timer::create (ITimerCallback* callback, uint32 milliseconds)
{
auto timer = NEW MacPlatformTimer (callback, milliseconds);
if (timer->verify ())
return timer;
timer->release ();
return nullptr;
}
//------------------------------------------------------------------------
} // namespace Steinberg
#elif SMTG_OS_WINDOWS
#include <windows.h>
#include <algorithm>
#include <list>
namespace Steinberg {
namespace SystemTime {
//------------------------------------------------------------------------
/*
@return the current system time in milliseconds
*/
uint64 getTicks64 ()
{
#if defined(__MINGW32__)
return GetTickCount ();
#else
return GetTickCount64 ();
#endif
} // namespace SystemTime
} // namespace Steinberg
class WinPlatformTimer;
using WinPlatformTimerList = std::list<WinPlatformTimer*>;
//------------------------------------------------------------------------
// WinPlatformTimer
//------------------------------------------------------------------------
class WinPlatformTimer : public Timer
{
public:
//------------------------------------------------------------------------
WinPlatformTimer (ITimerCallback* callback, uint32 milliseconds);
~WinPlatformTimer () override;
void stop () override;
bool verify () const { return id != 0; }
//------------------------------------------------------------------------
private:
UINT_PTR id;
ITimerCallback* callback;
static void addTimer (WinPlatformTimer* t);
static void removeTimer (WinPlatformTimer* t);
static void CALLBACK TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
static WinPlatformTimerList* timers;
};
//------------------------------------------------------------------------
WinPlatformTimerList* WinPlatformTimer::timers = nullptr;
//------------------------------------------------------------------------
WinPlatformTimer::WinPlatformTimer (ITimerCallback* callback, uint32 milliseconds)
: callback (callback)
{
id = SetTimer (nullptr, 0, milliseconds, TimerProc);
if (id)
addTimer (this);
}
//------------------------------------------------------------------------
WinPlatformTimer::~WinPlatformTimer ()
{
stop ();
}
//------------------------------------------------------------------------
void WinPlatformTimer::addTimer (WinPlatformTimer* t)
{
if (timers == nullptr)
timers = NEW WinPlatformTimerList;
timers->push_back (t);
}
//------------------------------------------------------------------------
void WinPlatformTimer::removeTimer (WinPlatformTimer* t)
{
if (!timers)
return;
WinPlatformTimerList::iterator it = std::find (timers->begin (), timers->end (), t);
if (it != timers->end ())
timers->erase (it);
if (timers->empty ())
{
delete timers;
timers = nullptr;
}
}
//------------------------------------------------------------------------
void WinPlatformTimer::stop ()
{
if (!id)
return;
KillTimer (nullptr, id);
removeTimer (this);
id = 0;
}
//------------------------------------------------------------------------
void CALLBACK WinPlatformTimer::TimerProc (HWND /*hwnd*/, UINT /*uMsg*/, UINT_PTR idEvent,
DWORD /*dwTime*/)
{
if (timersEnabled && timers)
{
WinPlatformTimerList::const_iterator it = timers->cbegin ();
while (it != timers->cend ())
{
WinPlatformTimer* timer = *it;
if (timer->id == idEvent)
{
if (timer->callback)
timer->callback->onTimer (timer);
return;
}
++it;
}
}
}
//------------------------------------------------------------------------
Timer* Timer::create (ITimerCallback* callback, uint32 milliseconds)
{
auto* platformTimer = NEW WinPlatformTimer (callback, milliseconds);
if (platformTimer->verify ())
return platformTimer;
platformTimer->release ();
return nullptr;
}
//------------------------------------------------------------------------
} // namespace Steinberg
#elif SMTG_OS_LINUX
#include <cassert>
#include <time.h>
namespace Steinberg {
namespace SystemTime {
//------------------------------------------------------------------------
/*
@return the current system time in milliseconds
*/
uint64 getTicks64 ()
{
struct timespec ts;
clock_gettime (CLOCK_MONOTONIC, &ts);
return static_cast<uint64> (ts.tv_sec) * 1000 + static_cast<uint64> (ts.tv_nsec) / 1000000;
}
//------------------------------------------------------------------------
} // namespace SystemTime
static CreateTimerFunc createTimerFunc = nullptr;
//------------------------------------------------------------------------
void InjectCreateTimerFunction (CreateTimerFunc f)
{
createTimerFunc = f;
}
//------------------------------------------------------------------------
Timer* Timer::create (ITimerCallback* callback, uint32 milliseconds)
{
if (createTimerFunc)
return createTimerFunc (callback, milliseconds);
return nullptr;
}
//------------------------------------------------------------------------
} // namespace Steinberg
#endif
+162
View File
@@ -0,0 +1,162 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/timer.h
// Created by : Steinberg, 05/2006
// Description : Timer class for receiving tiggers at regular intervals
//
//-----------------------------------------------------------------------------
// 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 "fobject.h"
#include <limits>
#if SMTG_CPP17
#include <functional>
#endif
namespace Steinberg {
class Timer;
//------------------------------------------------------------------------
namespace SystemTime {
uint64 getTicks64 ();
inline uint64 getTicksDuration (uint64 old, uint64 now)
{
if (old > now)
return (std::numeric_limits<uint64>::max) () - old + now;
return now - old;
}
int32 getTicks (); ///< deprecated, use getTicks64 ()
//------------------------------------------------------------------------
} // namespace SystemTime
//------------------------------------------------------------------------
/** @class ITimerCallback
Implement this callback interface to receive triggers from a timer.
Note: This interface is intended as a mix-in class and therefore does not provide ref-counting.
@see Timer */
class ITimerCallback
{
public:
virtual ~ITimerCallback () {}
/** This method is called at the end of each interval.
\param timer The timer which calls. */
virtual void onTimer (Timer* timer) = 0;
};
template <typename Call>
ITimerCallback* newTimerCallback (const Call& call)
{
struct Callback : public ITimerCallback
{
Callback (const Call& call) : call (call) {}
void onTimer (Timer* timer) SMTG_OVERRIDE { call (timer); }
Call call;
};
return NEW Callback (call);
}
#if SMTG_CPP17
//------------------------------------------------------------------------
/** @class TimerCallback
*
* a timer callback object using a funtion for the timer call
*/
struct TimerCallback final : ITimerCallback
{
using CallbackFunc = std::function<void (Timer*)>;
TimerCallback (CallbackFunc&& f) : f (std::move (f)) {}
TimerCallback (const CallbackFunc& f) : f (f) {}
void onTimer (Timer* timer) override { f (timer); }
private:
CallbackFunc f;
};
#endif // SMTG_CPP17
// -----------------------------------------------------------------
/** @class Timer
Timer is a class that allows you to receive triggers at regular intervals.
Note: The timer class is an abstract base class with (hidden) platform specific subclasses.
Usage:
@code
class TimerReceiver : public FObject, public ITimerCallback
{
...
virtual void onTimer (Timer* timer)
{
// do stuff
}
...
};
TimerReceiver* receiver = new TimerReceiver ();
Timer* myTimer = Timer::create (receiver, 100); // interval: every 100ms
...
...
if (myTimer)
myTimer->release ();
if (receiver)
receiver->release ();
@endcode
@see ITimerCallback
*/
class Timer : public FObject
{
public:
/** Create a timer with a given interval
\param callback The receiver of the timer calls.
\param intervalMilliseconds The timer interval in milliseconds.
\return The created timer if any, callers owns the timer. The timer starts immediately.
*/
static Timer* create (ITimerCallback* callback, uint32 intervalMilliseconds);
virtual void stop () = 0; ///< Stop the timer.
};
// -----------------------------------------------------------------
/** @class DisableDispatchingTimers
Disables dispatching of timers for the live time of this object
*/
class DisableDispatchingTimers
{
public:
DisableDispatchingTimers ();
~DisableDispatchingTimers ();
private:
bool oldState;
};
#if SMTG_OS_LINUX
using CreateTimerFunc = Timer* (*)(ITimerCallback* callback, uint32 intervalMilliseconds);
void InjectCreateTimerFunction (CreateTimerFunc f);
#endif
//------------------------------------------------------------------------
} // namespace Steinberg
+720
View File
@@ -0,0 +1,720 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/updatehandler.cpp
// Created by : Steinberg, 2008
// Description :
//
//-----------------------------------------------------------------------------
// 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 "base/source/updatehandler.h"
#include "base/source/classfactoryhelpers.h"
#include "base/source/fstring.h"
#if SMTG_CPP11_STDLIBSUPPORT
#include <unordered_map>
#else
#include <map>
#endif
#include <deque>
#include <vector>
#include <algorithm>
#define NON_EXISTING_DEPENDENCY_CHECK 0 // not yet
#define CLASS_NAME_TRACKED DEVELOPMENT
using Steinberg::Base::Thread::FGuard;
namespace Steinberg {
DEF_CLASS_IID (IUpdateManager)
namespace Update {
const uint32 kHashSize = (1 << 8); // must be power of 2 (16 bytes * 256 == 4096)
const uint32 kMapSize = 1024 * 10;
//------------------------------------------------------------------------
inline uint32 hashPointer (void* p)
{
return (uint32)((uint64 (p) >> 12) & (kHashSize - 1));
}
//------------------------------------------------------------------------
inline IPtr<FUnknown> getUnknownBase (FUnknown* unknown)
{
FUnknown* result = nullptr;
if (unknown)
{
if (unknown->queryInterface (FObject::iid, (void**)&result) != kResultTrue)
unknown->queryInterface (FUnknown::iid, (void**)&result);
}
return owned (result);
}
#if CLASS_NAME_TRACKED
//------------------------------------------------------------------------
struct Dependency
{
Dependency (FUnknown* o, IDependent* d)
: obj (o), dep (d), objClass (nullptr), depClass (nullptr)
{
}
inline bool operator== (const Dependency& d) const { return obj == d.obj; }
inline bool operator!= (const Dependency& d) const { return obj != d.obj; }
inline bool operator< (const Dependency& d) const { return obj < d.obj; }
inline bool operator> (const Dependency& d) const { return obj > d.obj; }
FUnknown* obj;
IDependent* dep;
FClassID objClass;
FClassID depClass;
};
#endif
//------------------------------------------------------------------------
struct DeferedChange
{
DeferedChange (FUnknown* o, int32 m = 0) : obj (o), msg (m) {}
~DeferedChange () {}
DeferedChange (const DeferedChange& r) : obj (r.obj), msg (r.msg) {}
inline bool operator== (const DeferedChange& d) const { return obj == d.obj; }
inline bool operator!= (const DeferedChange& d) const { return obj != d.obj; }
FUnknown* obj;
int32 msg;
};
//------------------------------------------------------------------------
struct UpdateData
{
UpdateData (FUnknown* o, IDependent** d, uint32 c)
: obj (o), dependents (d), count (c)
{
}
FUnknown* obj;
IDependent** dependents;
uint32 count;
bool operator== (const UpdateData& d) const
{
return d.obj == obj && d.dependents == dependents;
}
};
//------------------------------------------------------------------------
using DeferedChangeList = std::deque<DeferedChange>;
using DeferedChangeListIterConst = DeferedChangeList::const_iterator;
using DeferedChangeListIter = DeferedChangeList::iterator;
using UpdateDataList = std::deque<UpdateData>;
using UpdateDataListIterConst = UpdateDataList::const_iterator;
#if CLASS_NAME_TRACKED
using DependentList = std::vector<Dependency>;
#else
typedef std::vector<IDependent*> DependentList;
#endif
using DependentListIter = DependentList::iterator;
using DependentListIterConst = DependentList::const_iterator;
#if SMTG_CPP11_STDLIBSUPPORT
using DependentMap = std::unordered_map<const FUnknown*, DependentList>;
#else
typedef std::map<const FUnknown*, DependentList> DependentMap;
#endif
using DependentMapIter = DependentMap::iterator;
using DependentMapIterConst = DependentMap::const_iterator;
struct Table
{
DependentMap depMap[kHashSize];
DeferedChangeList defered;
UpdateDataList updateData;
};
//------------------------------------------------------------------------
void updateDone (FUnknown* unknown, int32 message)
{
if (message != IDependent::kDestroyed)
{
FObject* obj = FObject::unknownToObject (unknown);
if (obj)
obj->updateDone (message);
}
}
} // namespace Update
//------------------------------------------------------------------------
static int32 countEntries (Update::DependentMap& map)
{
int32 total = 0;
Update::DependentMapIterConst iterMap = map.begin ();
while (iterMap != map.end ())
{
const Update::DependentList& list = iterMap->second;
Update::DependentListIterConst iterList = list.begin ();
while (iterList != list.end ())
{
total++;
++iterList;
}
++iterMap;
}
return total;
}
//------------------------------------------------------------------------
UpdateHandler::UpdateHandler ()
{
table = NEW Update::Table;
if (FObject::getUpdateHandler () == nullptr)
FObject::setUpdateHandler (this);
}
//------------------------------------------------------------------------
UpdateHandler::~UpdateHandler ()
{
if (FObject::getUpdateHandler () == this)
FObject::setUpdateHandler (nullptr);
delete table;
table = nullptr;
}
//------------------------------------------------------------------------
tresult PLUGIN_API UpdateHandler::addDependent (FUnknown* u, IDependent* _dependent)
{
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
if (!unknown || !_dependent)
return kResultFalse;
FGuard guard (lock);
#if CLASS_NAME_TRACKED
Update::Dependency dependent (unknown, _dependent);
FObject* obj = FObject::unknownToObject (unknown);
if (obj)
dependent.objClass = obj->isA ();
obj = FObject::unknownToObject (_dependent);
if (obj)
dependent.depClass = obj->isA ();
#else
IDependent* dependent = _dependent;
#endif
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
Update::DependentMapIter it = map.find (unknown);
if (it == map.end ())
{
Update::DependentList list;
list.push_back (dependent);
map[unknown] = list;
}
else
{
(*it).second.push_back (dependent);
}
return kResultTrue;
}
//------------------------------------------------------------------------
tresult PLUGIN_API UpdateHandler::removeDependent (FUnknown* u, IDependent* dependent)
{
size_t eraseCount;
return removeDependent (u, dependent, eraseCount);
}
//------------------------------------------------------------------------
tresult PLUGIN_API UpdateHandler::removeDependent (FUnknown* u, IDependent* dependent, size_t& eraseCount)
{
eraseCount = 0;
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
if (unknown == nullptr && dependent == nullptr)
return kResultFalse;
FGuard guard (lock);
Update::UpdateDataListIterConst iter = table->updateData.begin ();
while (iter != table->updateData.end ())
{
if ((*iter).obj == unknown || unknown == nullptr)
{
for (uint32 count = 0; count < (*iter).count; count++)
{
if ((*iter).dependents[count] == dependent)
(*iter).dependents[count] = nullptr;
}
}
++iter;
}
// Remove all objects for the given dependent
if (unknown == nullptr)
{
for (uint32 j = 0; j < Update::kHashSize; j++)
{
Update::DependentMap& map = table->depMap[j];
Update::DependentMapIter iterMap = map.begin ();
while (iterMap != map.end ())
{
Update::DependentList& list = (*iterMap).second;
Update::DependentListIter iterList = list.begin ();
bool listIsEmpty = false;
while (iterList != list.end ())
{
#if CLASS_NAME_TRACKED
if ((*iterList).dep == dependent)
#else
if ((*iterList) == dependent)
#endif
{
eraseCount = list.size ();
if (list.size () == 1u)
{
listIsEmpty = true;
break;
}
iterList = list.erase (iterList);
}
else
{
++iterList;
}
}
if (listIsEmpty)
iterMap = map.erase (iterMap);
else
++iterMap;
}
}
}
else
{
bool mustFlush = true;
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
Update::DependentMapIter iterList = map.find (unknown);
#if NON_EXISTING_DEPENDENCY_CHECK
SMTG_ASSERT (iterList != map.end () && "ERROR: Trying to remove a non existing dependency!")
#endif
if (iterList != map.end ())
{
if (dependent == nullptr) // Remove all dependents of object
{
eraseCount = iterList->second.size ();
map.erase (iterList);
}
else // Remove one dependent
{
Update::DependentList& dependentlist = (*iterList).second;
Update::DependentListIter iterDependentlist = dependentlist.begin ();
while (iterDependentlist != dependentlist.end ())
{
#if CLASS_NAME_TRACKED
if ((*iterDependentlist).dep == dependent)
#else
if ((*iterDependentlist) == dependent)
#endif
{
iterDependentlist = dependentlist.erase (iterDependentlist);
eraseCount++;
if (dependentlist.empty ())
{
map.erase (iterList);
break;
}
}
else
{
++iterDependentlist;
mustFlush = false;
}
}
}
}
if (mustFlush)
cancelUpdates (unknown);
}
return kResultTrue;
}
//------------------------------------------------------------------------
tresult UpdateHandler::doTriggerUpdates (FUnknown* u, int32 message, bool suppressUpdateDone)
{
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
if (!unknown)
return kResultFalse;
// to avoid crashes due to stack overflow, we reduce the amount of memory reserved for the
// dependents
IDependent* smallDependents[Update::kMapSize / 10]; // 8kB for x64
IDependent** dependents = smallDependents;
int32 maxDependents = Update::kMapSize / 10;
int32 count = 0;
{
FGuard guard (lock); // scope for lock
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
Update::DependentMapIterConst iterList = map.find (unknown);
if (iterList != map.end ())
{
const Update::DependentList& dependentlist = (*iterList).second;
Update::DependentListIterConst iterDependentlist = dependentlist.begin ();
while (iterDependentlist != dependentlist.end ())
{
#if CLASS_NAME_TRACKED
dependents[count] = (*iterDependentlist).dep;
#else
dependents[count] = *iterDependentlist;
#endif
count++;
if (count >= maxDependents)
{
if (dependents == smallDependents)
{
dependents = NEW IDependent*[Update::kMapSize];
memcpy (dependents, smallDependents, count * sizeof (dependents[0]));
maxDependents = Update::kMapSize;
}
else
{
SMTG_WARNING ("Dependency overflow")
break;
}
}
++iterDependentlist;
}
}
// push update data on the stack
if (count > 0)
{
Update::UpdateData data (unknown, dependents, count);
table->updateData.push_back (data);
}
} // end scope
int32 i = 0;
while (i < count)
{
if (dependents[i])
dependents[i]->update (unknown, message);
i++;
}
if (dependents != smallDependents)
delete[] dependents;
// remove update data from the stack
if (count > 0)
{
FGuard guard (lock);
table->updateData.pop_back ();
}
// send update done message
if (suppressUpdateDone == false)
Update::updateDone (unknown, message);
return count > 0 ? kResultTrue : kResultFalse; // Object was found and has been updated
}
//------------------------------------------------------------------------
tresult PLUGIN_API UpdateHandler::triggerUpdates (FUnknown* u, int32 message)
{
return doTriggerUpdates (u, message, false);
}
//------------------------------------------------------------------------
tresult PLUGIN_API UpdateHandler::deferUpdates (FUnknown* u, int32 message)
{
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
if (!unknown)
return kResultFalse;
FGuard guard (lock);
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
Update::DependentMapIterConst iterList = map.find (unknown);
bool hasDependency = (iterList != map.end ());
if (hasDependency == false)
{
Update::updateDone (unknown, message);
return kResultTrue;
}
bool found = false;
Update::DeferedChangeListIterConst iter = table->defered.begin ();
while (iter != table->defered.end ())
{
if ((*iter).obj == unknown && (*iter).msg == message)
{
found = true;
break;
}
++iter;
}
if (!found)
{
Update::DeferedChange change (unknown, message);
table->defered.push_back (change);
}
return kResultTrue;
}
//------------------------------------------------------------------------
tresult PLUGIN_API UpdateHandler::triggerDeferedUpdates (FUnknown* unknown)
{
Update::DeferedChangeList deferedAgain;
if (!unknown)
{
while (table->defered.empty () == false)
{
// Remove first from queue
lock.lock ();
FUnknown* obj = table->defered.front ().obj;
int32 msg = table->defered.front ().msg;
table->defered.pop_front ();
// check if this object is currently being updated. in this case, defer update again...
bool canSignal = true;
Update::UpdateDataListIterConst iter = table->updateData.begin ();
while (iter != table->updateData.end ())
{
if ((*iter).obj == obj)
{
canSignal = false;
break;
}
++iter;
}
lock.unlock ();
if (canSignal)
{
triggerUpdates (obj, msg);
}
else
{
Update::DeferedChange change (obj, msg);
deferedAgain.push_back (change);
}
}
}
else
{
IPtr<FUnknown> object = Update::getUnknownBase (unknown);
Update::DeferedChange tmp (object);
while (true)
{
lock.lock ();
Update::DeferedChangeListIter it =
std::find (table->defered.begin (), table->defered.end (), tmp);
if (it == table->defered.end ())
{
lock.unlock ();
return kResultTrue;
}
if ((*it).obj != nullptr)
{
int32 msg = (*it).msg;
table->defered.erase (it);
// check if this object is currently being updated. in this case, defer update
// again...
bool canSignal = true;
Update::UpdateDataListIterConst iter = table->updateData.begin ();
while (iter != table->updateData.end ())
{
if ((*iter).obj == object)
{
canSignal = false;
break;
}
++iter;
}
lock.unlock ();
if (canSignal)
{
triggerUpdates (object, msg);
}
else
{
Update::DeferedChange change (object, msg);
deferedAgain.push_back (change);
}
}
}
}
if (deferedAgain.empty () == false)
{
FGuard guard (lock);
Update::DeferedChangeListIterConst iter = deferedAgain.begin ();
while (iter != deferedAgain.end ())
{
table->defered.push_back (*iter);
++iter;
}
}
return kResultTrue;
}
//------------------------------------------------------------------------
tresult PLUGIN_API UpdateHandler::cancelUpdates (FUnknown* u)
{
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
if (!unknown)
return kResultFalse;
FGuard guard (lock);
Update::DeferedChange change (unknown, 0);
while (true)
{
auto iter = std::find (table->defered.begin (), table->defered.end (), change);
if (iter != table->defered.end ())
table->defered.erase (iter);
else
break;
}
return kResultTrue;
}
//------------------------------------------------------------------------
size_t UpdateHandler::countDependencies (FUnknown* object)
{
FGuard guard (lock);
uint32 res = 0;
IPtr<FUnknown> unknown = Update::getUnknownBase (object);
if (unknown)
{
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
Update::DependentMapIter iterList = map.find (unknown);
if (iterList != map.end ())
return iterList->second.size ();
}
else
{
for (uint32 j = 0; j < Update::kHashSize; j++)
{
Update::DependentMap& map = table->depMap[j];
res += countEntries (map);
}
}
return res;
}
#if DEVELOPMENT
//------------------------------------------------------------------------
bool UpdateHandler::checkDeferred (FUnknown* object)
{
IPtr<FUnknown> unknown = Update::getUnknownBase (object);
FGuard guard (lock);
Update::DeferedChange tmp (unknown);
Update::DeferedChangeListIterConst it =
std::find (table->defered.begin (), table->defered.end (), tmp);
if (it != table->defered.end ())
return true;
return false;
}
//------------------------------------------------------------------------
bool UpdateHandler::hasDependencies (FUnknown* u)
{
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
if (!unknown)
return false;
FGuard guard (lock);
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
Update::DependentMapIterConst iterList = map.find (unknown);
bool hasDependency = (iterList != map.end ());
return hasDependency;
}
//------------------------------------------------------------------------
void UpdateHandler::printForObject (FObject* obj) const
{
IPtr<FUnknown> unknown = Update::getUnknownBase (obj);
if (!unknown)
return;
FUnknownPtr<IDependent> dep (obj);
bool header = false;
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
Update::DependentMapIterConst iterList = map.begin ();
while (iterList != map.end ())
{
const Update::DependentList& dependentlist = (*iterList).second;
Update::DependentListIterConst iterDependentlist = dependentlist.begin ();
while (iterDependentlist != dependentlist.end ())
{
#if CLASS_NAME_TRACKED
if ((*iterList).first == unknown || (*iterDependentlist).dep == dep.getInterface ())
{
if (!header)
{
FDebugPrint ("Dependencies for object %8" FORMAT_INT64A " %s\n", (uint64)obj,
obj->isA ());
header = true;
}
FDebugPrint ("%s %8" FORMAT_INT64A "\n <- %s %8" FORMAT_INT64A "\n",
(*iterDependentlist).depClass, (uint64) (*iterDependentlist).dep,
(*iterDependentlist).objClass, (uint64) ((*iterList).first));
}
#else
if ((*iterList).first == unknown || (*iterDependentlist) == dep.getInterface ())
{
if (!header)
{
FDebugPrint ("Dependencies for object %8" FORMAT_INT64A " %s\n", (uint64)obj,
obj->isA ());
header = true;
}
FDebugPrint ("%8" FORMAT_INT64A "\n <- %8" FORMAT_INT64A "\n",
(uint64) (*iterDependentlist), (uint64) ((*iterList).first));
}
#endif
++iterDependentlist;
}
++iterList;
}
}
#endif
//------------------------------------------------------------------------
} // namespace Steinberg
+130
View File
@@ -0,0 +1,130 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/source/updatehandler.h
// Created by : Steinberg, 2008
// Description :
//
//-----------------------------------------------------------------------------
// 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 "base/source/fobject.h"
#include "base/thread/include/flock.h"
#include "pluginterfaces/base/iupdatehandler.h"
namespace Steinberg {
/// @cond ignore
namespace Update { struct Table; }
/// @endcond
//------------------------------------------------------------------------
/** Handle Send and Cancel pending message for a given object*/
//------------------------------------------------------------------------
class IUpdateManager : public FUnknown
{
public:
//------------------------------------------------------------------------
/** cancel pending messages send by \param object or by any if object is 0 */
virtual tresult PLUGIN_API cancelUpdates (FUnknown* object) = 0;
/** send pending messages send by \param object or by any if object is 0 */
virtual tresult PLUGIN_API triggerDeferedUpdates (FUnknown* object = nullptr) = 0;
static const FUID iid;
};
DECLARE_CLASS_IID (IUpdateManager, 0x030B780C, 0xD6E6418D, 0x8CE00BC2, 0x09C834D4)
//------------------------------------------------------------------------------
/**
UpdateHandler implements IUpdateManager and IUpdateHandler to handle dependencies
between objects to store and forward messages to dependent objects.
This implementation is thread save, so objects can send message, add or remove
dependents from different threads.
Do do so it uses mutex, so be aware of locking.
*/
//------------------------------------------------------------------------------
class UpdateHandler : public FObject, public IUpdateHandler, public IUpdateManager
{
public:
//------------------------------------------------------------------------------
UpdateHandler ();
~UpdateHandler () SMTG_OVERRIDE;
using FObject::addDependent;
using FObject::removeDependent;
using FObject::deferUpdate;
// IUpdateHandler
//private:
friend class FObject;
/** register \param dependent to get messages from \param object */
tresult PLUGIN_API addDependent (FUnknown* object, IDependent* dependent) SMTG_OVERRIDE;
/** unregister \param dependent to get no messages from \param object */
tresult PLUGIN_API removeDependent (FUnknown* object, IDependent* dependent, size_t& earseCount);
tresult PLUGIN_API removeDependent (FUnknown* object,
IDependent* dependent) SMTG_OVERRIDE;
public:
/** send \param message to all dependents of \param object immediately */
tresult PLUGIN_API triggerUpdates (FUnknown* object, int32 message) SMTG_OVERRIDE;
/** send \param message to all dependents of \param object when idle */
tresult PLUGIN_API deferUpdates (FUnknown* object, int32 message) SMTG_OVERRIDE;
// IUpdateManager
/** cancel pending messages send by \param object or by any if object is 0 */
tresult PLUGIN_API cancelUpdates (FUnknown* object) SMTG_OVERRIDE;
/** send pending messages send by \param object or by any if object is 0 */
tresult PLUGIN_API triggerDeferedUpdates (FUnknown* object = nullptr) SMTG_OVERRIDE;
/// @cond ignore
// obsolete functions kept for compatibility
void checkUpdates (FObject* object = nullptr)
{
triggerDeferedUpdates (object ? object->unknownCast () : nullptr);
}
void flushUpdates (FObject* object)
{
if (object)
cancelUpdates (object->unknownCast ());
}
void deferUpdate (FObject* object, int32 message)
{
if (object)
deferUpdates (object->unknownCast (), message);
}
void signalChange (FObject* object, int32 message, bool suppressUpdateDone = false)
{
if (object)
doTriggerUpdates (object->unknownCast (), message, suppressUpdateDone);
}
#if DEVELOPMENT
bool checkDeferred (FUnknown* object);
bool hasDependencies (FUnknown* object);
void printForObject (FObject* object) const;
#endif
/// @endcond
size_t countDependencies (FUnknown* object = nullptr);
OBJ_METHODS (UpdateHandler, FObject)
FUNKNOWN_METHODS2 (IUpdateHandler, IUpdateManager, FObject)
SINGLETON (UpdateHandler)
//------------------------------------------------------------------------------
private:
tresult doTriggerUpdates (FUnknown* object, int32 message, bool suppressUpdateDone);
Steinberg::Base::Thread::FLock lock;
Update::Table* table = nullptr;
};
//------------------------------------------------------------------------
} // namespace Steinberg
+104
View File
@@ -0,0 +1,104 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/thread/include/fcondition.h
// Created by : Steinberg, 1995
// Description : the threads and locks and signals...
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
//----------------------------------------------------------------------------------
/** @file base/thread/include/fcondition.h
signal. */
/** @defgroup baseThread Thread Handling */
//----------------------------------------------------------------------------------
#pragma once
#include "pluginterfaces/base/ftypes.h"
#if SMTG_PTHREADS
#include <pthread.h>
#endif
//------------------------------------------------------------------------
namespace Steinberg {
namespace Base {
namespace Thread {
//------------------------------------------------------------------------
/** FCondition - wraps the signal and wait calls in win32
@ingroup baseThread */
//------------------------------------------------------------------------
class FCondition
{
public:
//------------------------------------------------------------------------
/** Condition constructor.
* @param name name of condition
*/
FCondition (const char8* name = nullptr /* "FCondition" */ );
/** Condition destructor.
*/
~FCondition ();
/** Signals one thread.
*/
void signal ();
/** Signals all threads.
*/
void signalAll ();
/** Waits for condition.
*/
void wait ();
/** Waits for condition with timeout
* @param timeout time out in milliseconds
* @return false if timed out
*/
bool waitTimeout (int32 timeout = -1);
/** Resets condition.
*/
void reset ();
#if SMTG_OS_WINDOWS
/** Gets condition handle.
* @return handle
*/
void* getHandle () { return event; }
#endif
//------------------------------------------------------------------------
private:
#if SMTG_PTHREADS
pthread_mutex_t mutex; ///< Mutex object
pthread_cond_t cond; ///< Condition object
int32 state; ///< Use to hold the state of the signal
int32 waiters; ///< Number of waiters
#if DEVELOPMENT
int32 waits; ///< Waits count
int32 signalCount; ///< Signals count
#endif
#elif SMTG_OS_WINDOWS
void* event; ///< Event handle
#endif
};
//------------------------------------------------------------------------
} // namespace Thread
} // namespace Base
} // namespace Steinberg
+165
View File
@@ -0,0 +1,165 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/thread/include/flock.h
// Created by : Steinberg, 1995
// Description : locks
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
//----------------------------------------------------------------------------------
/** @file base/thread/include/flock.h
Locks. */
/** @defgroup baseLocks Locks */
//----------------------------------------------------------------------------------
#pragma once
#include "base/source/fobject.h"
#include "pluginterfaces/base/ftypes.h"
#if SMTG_PTHREADS
#include <pthread.h>
#elif SMTG_OS_WINDOWS
struct CRITSECT // CRITICAL_SECTION
{
void* DebugInfo; // PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
Steinberg::int32 LockCount; // LONG LockCount;
Steinberg::int32 RecursionCount; // LONG RecursionCount;
void* OwningThread; // HANDLE OwningThread
void* LockSemaphore; // HANDLE LockSemaphore
Steinberg::int32 SpinCount; // ULONG_PTR SpinCount
};
#endif
namespace Steinberg {
namespace Base {
namespace Thread {
//------------------------------------------------------------------------
/** Lock interface declaration.
@ingroup baseLocks */
//------------------------------------------------------------------------
struct ILock
{
//------------------------------------------------------------------------
virtual ~ILock () {}
/** Enables lock. */
virtual void lock () = 0;
/** Disables lock. */
virtual void unlock () = 0;
/** Tries to disable lock. */
virtual bool trylock () = 0;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
/** FLock declaration.
@ingroup baseLocks */
//------------------------------------------------------------------------
class FLock : public ILock
{
public:
//------------------------------------------------------------------------
/** Lock constructor.
* @param name lock name
*/
FLock (const char8* name = "FLock");
/** Lock destructor. */
~FLock () SMTG_OVERRIDE;
//-- ILock -----------------------------------------------------------
void lock () SMTG_OVERRIDE;
void unlock () SMTG_OVERRIDE;
bool trylock () SMTG_OVERRIDE;
//------------------------------------------------------------------------
protected:
#if SMTG_PTHREADS
pthread_mutex_t mutex; ///< Mutex object
#elif SMTG_OS_WINDOWS
CRITSECT section; ///< Critical section object
#endif
};
//------------------------------------------------------------------------
/** FLockObj declaration. Reference counted lock
@ingroup baseLocks */
//------------------------------------------------------------------------
class FLockObject : public FObject, public FLock
{
public:
OBJ_METHODS (FLockObject, FObject)
};
//------------------------------------------------------------------------
/** FGuard - automatic object for locks.
@ingroup baseLocks */
//------------------------------------------------------------------------
class FGuard
{
public:
//------------------------------------------------------------------------
/** FGuard constructor.
* @param _lock guard this lock
*/
FGuard (ILock& _lock) : lock (_lock) { lock.lock (); }
/** FGuard destructor. */
~FGuard () { lock.unlock (); }
//------------------------------------------------------------------------
private:
ILock& lock; ///< guarded lock
};
//------------------------------------------------------------------------
/** Conditional Guard - Locks only if valid lock is passed.
@ingroup baseLocks */
//------------------------------------------------------------------------
class FConditionalGuard
{
public:
//------------------------------------------------------------------------
/** FConditionGuard constructor.
* @param _lock guard this lock
*/
FConditionalGuard (FLock* _lock) : lock (_lock)
{
if (lock)
lock->lock ();
}
/** FConditionGuard destructor. */
~FConditionalGuard ()
{
if (lock)
lock->unlock ();
}
//------------------------------------------------------------------------
private:
FLock* lock; ///< guarded lock
};
//------------------------------------------------------------------------
} // namespace Thread
} // namespace Base
} // namespace Steinberg
+259
View File
@@ -0,0 +1,259 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/thread/source/fcondition.cpp
// Created by : Steinberg, 1995
// Description : signals...
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#define DEBUG_LOCK 0
#include "base/thread/include/fcondition.h"
#include "base/source/fdebug.h"
#include <climits>
#include <cstdlib>
//------------------------------------------------------------------------
#if SMTG_PTHREADS
//------------------------------------------------------------------------
#if __MACH__
extern "C" {
#include <mach/clock.h>
#include <sched.h>
#include <mach/mach_init.h>
#include <mach/task.h>
#include <mach/task_policy.h>
#include <mach/thread_act.h>
#include <mach/semaphore.h>
#include <mach/thread_policy.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <unistd.h>
}
#include <dlfcn.h>
#else
#include <fcntl.h>
#endif
#include <errno.h>
#if SMTG_OS_MACOS
#include <TargetConditionals.h>
#if !SMTG_OS_IOS
#include <CoreServices/CoreServices.h>
#endif
#endif
#include <sys/time.h>
//------------------------------------------------------------------------
#elif SMTG_OS_WINDOWS
#include <windows.h>
#endif
namespace Steinberg {
namespace Base {
namespace Thread {
//------------------------------------------------------------------------
/** FCondition CTOR.
* @param name - can be used to set the name of the event.
*/
FCondition::FCondition (const char8* name)
{
#if SMTG_PTHREADS
(void)name; // unused
pthread_mutex_init (&mutex, 0);
pthread_cond_init (&cond, 0);
state = 0;
waiters = 0;
#if DEVELOPMENT
waits = 0;
signalCount = 0;
#endif
#elif SMTG_OS_WINDOWS
// use name if existing
event = CreateEventA (nullptr, FALSE, FALSE, name);
#endif
}
//------------------------------------------------------------------------
FCondition::~FCondition ()
{
#if SMTG_PTHREADS
pthread_mutex_destroy (&mutex);
pthread_cond_destroy (&cond);
#elif SMTG_OS_WINDOWS
CloseHandle (event);
#endif
}
//------------------------------------------------------------------------
void FCondition::signal ()
{
#if SMTG_PTHREADS
pthread_mutex_lock (&mutex);
state = 1;
#if DEVELOPMENT
signalCount++;
#endif
pthread_cond_signal (&cond);
pthread_mutex_unlock (&mutex);
#elif SMTG_OS_WINDOWS
BOOL result = PulseEvent (event);
if (!result)
{
SMTG_PRINTSYSERROR;
}
#endif
}
//------------------------------------------------------------------------
void FCondition::signalAll ()
{
#if SMTG_PTHREADS
pthread_mutex_lock (&mutex);
state = waiters + 1;
#if DEVELOPMENT
signalCount++;
#endif
pthread_cond_broadcast (&cond);
pthread_mutex_unlock (&mutex);
#elif SMTG_OS_WINDOWS
BOOL result = SetEvent (event);
if (!result)
{
SMTG_PRINTSYSERROR;
}
#endif
}
//------------------------------------------------------------------------
void FCondition::wait ()
{
#if SMTG_PTHREADS
pthread_mutex_lock (&mutex);
#if DEVELOPMENT
waits++;
#endif
waiters++;
while (!state)
pthread_cond_wait (&cond, &mutex);
if (--waiters == 0)
state = 0;
else
--state;
pthread_mutex_unlock (&mutex);
#elif SMTG_OS_WINDOWS
WaitForSingleObject (event, INFINITE);
#endif
}
//------------------------------------------------------------------------
bool FCondition::waitTimeout (int32 milliseconds)
{
#if SMTG_PTHREADS
// this is the implementation running on mac (2018-07-18)
if (milliseconds == -1)
{ // infinite timeout
wait ();
return true;
}
struct timespec time;
#if __MACH__
// this is the implementation running on mac (2018-07-18)
time.tv_sec = milliseconds / 1000;
time.tv_nsec = 1000000 * (milliseconds - (time.tv_sec * 1000));
pthread_mutex_lock (&mutex);
#if DEVELOPMENT
waits++;
#endif
// this is the implementation running on mac (2018-07-18)
waiters++;
bool result = true;
while (!state)
{
int32 err = pthread_cond_timedwait_relative_np (&cond, &mutex, &time);
if (err == ETIMEDOUT)
{
result = false;
break;
}
else
result = true;
}
if (--waiters == 0)
state = 0;
else
--state;
pthread_mutex_unlock (&mutex);
return result;
#else
// dead code? not compiled in unit test and sequencer (2018-07-18)
clock_gettime (CLOCK_REALTIME, &time);
time.tv_nsec += milliseconds * 1000; // ?????????
pthread_mutex_lock (&mutex);
bool result = false;
if (pthread_cond_timedwait (&cond, &mutex, &time) == 0)
result = true;
pthread_mutex_unlock (&mutex);
return result;
#endif
#elif SMTG_OS_WINDOWS
if (milliseconds == -1)
milliseconds = INFINITE;
DWORD result = WaitForSingleObject (event, milliseconds);
return result == WAIT_TIMEOUT ? false : true;
#endif
#if !SMTG_OS_WINDOWS
// WARNING ("Return false on time out not implemented!")
return true;
#endif
}
//------------------------------------------------------------------------
void FCondition::reset ()
{
#if SMTG_OS_WINDOWS
ResetEvent (event);
#elif SMTG_PTHREADS
state = 0;
#endif
}
//------------------------------------------------------------------------
} // namespace Thread
} // namespace Base
} // namespace Steinberg
+126
View File
@@ -0,0 +1,126 @@
//------------------------------------------------------------------------
// Project : SDK Base
// Version : 1.0
//
// Category : Helpers
// Filename : base/thread/source/flock.cpp
// Created by : Steinberg, 1995
// Description : Locks
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#define DEBUG_LOCK 0
#include "base/thread/include/flock.h"
#include "base/source/fdebug.h"
//------------------------------------------------------------------------
#if SMTG_OS_WINDOWS
//------------------------------------------------------------------------
#ifndef WINVER
#define WINVER 0x0500
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT WINVER
#endif
#include <windows.h>
#include <objbase.h>
#define INIT_CS(cs) \
InitializeCriticalSection ((LPCRITICAL_SECTION)&cs);
#endif // SMTG_OS_WINDOWS
namespace Steinberg {
namespace Base {
namespace Thread {
//------------------------------------------------------------------------
// FLock implementation
//------------------------------------------------------------------------
FLock::FLock (const char8* /*name*/)
{
#if SMTG_PTHREADS
pthread_mutexattr_t mutexAttr;
pthread_mutexattr_init (&mutexAttr);
pthread_mutexattr_settype (&mutexAttr, PTHREAD_MUTEX_RECURSIVE);
if (pthread_mutex_init (&mutex, &mutexAttr) != 0)
{SMTG_WARNING("mutex_init failed")}
pthread_mutexattr_destroy (&mutexAttr);
#elif SMTG_OS_WINDOWS
INIT_CS (section)
#else
#warning implement FLock!
#endif
}
//------------------------------------------------------------------------
FLock::~FLock ()
{
#if SMTG_PTHREADS
pthread_mutex_destroy (&mutex);
#elif SMTG_OS_WINDOWS
DeleteCriticalSection ((LPCRITICAL_SECTION)&section);
#endif
}
//------------------------------------------------------------------------
void FLock::lock ()
{
#if DEBUG_LOCK
FDebugPrint ("FLock::lock () %x\n", this);
#endif
#if SMTG_PTHREADS
pthread_mutex_lock (&mutex);
#elif SMTG_OS_WINDOWS
EnterCriticalSection ((LPCRITICAL_SECTION)&section);
#endif
}
//------------------------------------------------------------------------
void FLock::unlock ()
{
#if DEBUG_LOCK
FDebugPrint ("FLock::unlock () %x\n", this);
#endif
#if SMTG_PTHREADS
pthread_mutex_unlock (&mutex);
#elif SMTG_OS_WINDOWS
LeaveCriticalSection ((LPCRITICAL_SECTION)&section);
#endif
}
//------------------------------------------------------------------------
bool FLock::trylock ()
{
#if SMTG_PTHREADS
return pthread_mutex_trylock (&mutex) == 0;
#elif SMTG_OS_WINDOWS
return TryEnterCriticalSection ((LPCRITICAL_SECTION)&section) != 0 ? true : false;
#else
return false;
#endif
}
//------------------------------------------------------------------------
} // namespace Thread
} // namespace Base
} // namespace Steinberg
+24
View File
@@ -0,0 +1,24 @@
//-----------------------------------------------------------------------------
MIT License
Copyright (c) 2025, Steinberg Media Technologies GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
//---------------------------------------------------------------------------------
+88
View File
@@ -0,0 +1,88 @@
# Welcome to VST 3 SDK cmake
This repository contains Steinberg's [cmake modules](https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html) and template files which can be used to create **VST 3** plug-ins for platforms like Windows, macOS, iOS and Linux.
For more information about cmake visit [cmake.org](https:://www.cmake.org/).
## Dependency map
In order to build a plug-in successfully, it only needs to link to ```sdk``` library. [VSTGUI](https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/VSTGUI.html) is optional and can be used by linking to ```vstgui_support```.
The following figure shows the dependency map by using AGain, [EditorHost](https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/EditorHost.html) and [VST3Inspector](https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/VST3Inspector.html):
```tree
again
+-- sdk
| +-- sdk_common
| +-- base
| +-- pluginterfaces
|
+-- vstgui_support
+-- base
+-- vstgui_uidescription
+-- vstgui
```
```tree
editorhost
+-- sdk_hosting
+-- sdk_common
+-- base
+-- pluginterfaces
```
```tree
VST3Inspector
+-- vstgui_uidescription
| +-- vstgui
+-- vstgui_standalone
+-- vstgui
```
## Naming conventions and guidelines
Steinberg module, macro, function and variable names have the prefix ```SMTG_``` or ```smtg_``` in order to avoid name clashes.
### File namings
Steinberg module names are written in camel case and have the prefix ```SMTG_```.
Examples:
```c
SMTG_AddVST3Library.cmake
SMTG_DetectPlatform.cmake
SMTG_ConfigureCmakeGenerator.cmake
```
### Macro and function namings
Steinberg macro and function names are written in lower case and have the prefix ```smtg_``` followed by a verb.
Examples:
```c
smtg_detect_platform
smtg_configure_cmake_generator
smtg_setup_symbol_visibility
smtg_detect_xcode_version
```
### Variable namings
Steinberg variable names are written in upper case and have the prefix ```SMTG_```.
Examples:
```c
SMTG_PLUGIN_BINARY_DIR
SMTG_PLUGIN_EXTENSION
SMTG_PLUGIN_PACKAGE_NAME
```
## License & Usage guidelines
More details can be found at [www.steinberg.net/sdklicenses_vst3](http://www.steinberg.net/sdklicenses_vst3)
----
Return to [VST 3 SDK](https://github.com/steinbergmedia/vst3sdk)
@@ -0,0 +1,37 @@
#------------------------------------------------------------------------
function(setupAaxSupport)
# AAX SDK Location
if(SMTG_MAC OR SMTG_WIN)
if("${SMTG_AAX_SDK_PATH}" STREQUAL "")
# Check if the AAX SDK is next to the vst3sdk folder:
set(AAX_SDK_PATH ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../../external.avid.aax)
if(NOT EXISTS "${AAX_SDK_PATH}/Interfaces/AAX.h")
# Check if the AAX SDK is in the vst3sdk folder:
set(AAX_SDK_PATH ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../external.avid.aax)
if(NOT EXISTS "${AAX_SDK_PATH}/Interfaces/AAX.h")
set(AAX_SDK_PATH "")
endif()
endif()
if(NOT "${AAX_SDK_PATH}" STREQUAL "")
get_filename_component(AAX_SDK_PATH "${AAX_SDK_PATH}" ABSOLUTE)
endif()
set(SMTG_AAX_SDK_PATH "${AAX_SDK_PATH}" CACHE PATH "Here you can define where to find the AAX SDK" FORCE)
else()
set(AAX_SDK_PATH "${SMTG_AAX_SDK_PATH}")
if(NOT IS_ABSOLUTE ${AAX_SDK_PATH})
get_filename_component(AAX_SDK_PATH "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../${AAX_SDK_PATH}" ABSOLUTE)
endif()
if(NOT EXISTS "${AAX_SDK_PATH}/Interfaces/AAX.h")
message(FATAL_ERROR "[SMTG] SMTG_AAX_SDK_PATH is set but does not point to an expected location!")
else()
set(SMTG_AAX_SDK_PATH "${AAX_SDK_PATH}" CACHE PATH "Here you can define where to find the AAX SDK" FORCE)
endif()
endif()
if(EXISTS "${SMTG_AAX_SDK_PATH}")
message(STATUS "[SMTG] SMTG_AAX_SDK_PATH is set to: " ${SMTG_AAX_SDK_PATH})
else()
message(STATUS "[SMTG] SMTG_AAX_SDK_PATH is not set. If you need it, please download the AAX SDK!")
endif()
endif(SMTG_MAC OR SMTG_WIN)
endfunction(setupAaxSupport)
@@ -0,0 +1,73 @@
#------------------------------------------------------------------------
# Includes
#------------------------------------------------------------------------
include(SMTG_AddSMTGLibrary)
#------------------------------------------------------------------------
# Returns the Windows architecture.
#
# This name will be used as a folder name inside the Plug-in package.
# The variable SMTG_WIN_ARCHITECTURE_NAME will be set.
# @param target The target to which SMTG_WIN_ARCHITECTURE_NAME will be added.
function(smtg_target_set_aax_win_architecture_name target)
if(${GENERATOR_PLATFORM} MATCHES "win32")
set(WIN_ARCHITECTURE_NAME "win32")
else()
set(WIN_ARCHITECTURE_NAME "x64")
endif()
set_target_properties(${target}
PROPERTIES
SMTG_WIN_ARCHITECTURE_NAME ${WIN_ARCHITECTURE_NAME}
)
endfunction(smtg_target_set_aax_win_architecture_name)
#------------------------------------------------------------------------
# Adds a AAX target.
#
# @param target The target to which a AAX Plug-in will be added.
# @param pkg_name name of the created package
# for example:
# smtg_add_aaxplugin_with_pkgname(${target} "A Gain" ${again_sources})
function(smtg_add_aaxplugin_with_pkgname target pkg_name)
add_library(${target} MODULE ${ARGN})
smtg_target_set_aax_win_architecture_name(${target})
smtg_target_make_plugin_package(${target} ${pkg_name} aaxplugin)
# smtg_dump_plugin_package_variables(${target})
if(SMTG_MAC AND XCODE)
# disable automatic signing for AAX
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
)
endif(SMTG_MAC AND XCODE)
endfunction(smtg_add_aaxplugin_with_pkgname)
#------------------------------------------------------------------------
# Adds a AAX target.
#
# @param target The target to which a AAX Plug-in will be added.
# @param PACKAGE_NAME <Name> The name of the package [optional] if not present
# @param SOURCES_LIST <sources> List of sources to add to target project [mandatory when PACKAGE_NAME is used]
# for example:
# smtg_add_aaxplugin(${target} PACKAGE_NAME "A Gain" SOURCES_LIST ${again_sources})
# or
# smtg_add_aaxplugin(${target} ${again_sources})
function(smtg_add_aaxplugin target)
set(oneValueArgs PACKAGE_NAME)
set(sourcesArgs SOURCES_LIST)
cmake_parse_arguments(PARSE_ARGV 0 PARAMS "${options}" "${oneValueArgs}" "${sourcesArgs}")
set(SOURCES "${PARAMS_SOURCES_LIST}")
if(SOURCES STREQUAL "")
set(SOURCES ${ARGN})
endif()
set(pkg_name "${PARAMS_PACKAGE_NAME}")
if(pkg_name STREQUAL "")
set(pkg_name ${target})
endif()
smtg_add_aaxplugin_with_pkgname(${target} ${pkg_name} ${SOURCES})
endfunction(smtg_add_aaxplugin)
@@ -0,0 +1,39 @@
#------------------------------------------------------------------------
# Includes
#------------------------------------------------------------------------
include(SMTG_Platform_Windows)
# Use by default SMTG_ as prefix for ASSERT,...
option(SMTG_RENAME_ASSERT "Rename ASSERT to SMTG_ASSERT" ON)
# Logging
option(SMTG_ENABLE_TARGET_VARS_LOG "Enable Target variables Logging" OFF)
# Create Bundle on Windows for the Plug-ins
if(SMTG_WIN)
option(SMTG_CREATE_BUNDLE_FOR_WINDOWS "Create Bundle on Windows for the Plug-ins (New since VST 3.6.10!)" ON)
endif(SMTG_WIN)
# Specific Windows Stuff
# Create Symbolic Link for the Plug-ins
if(SMTG_WIN)
set(DEF_OPT_LINK ON) # be sure to start visual with admin right or adapt the user Group Policy when enabling this
else()
set(DEF_OPT_LINK ON)
endif(SMTG_WIN)
option(SMTG_CREATE_PLUGIN_LINK "Create symbolic link for each Plug-in (you need to have the Administrator right on Windows! or change the Local Group Policy to allow create symbolic links)" ${DEF_OPT_LINK})
# Specific Mac Stuff
if(SMTG_MAC)
if(DEFINED SMTG_IOS_DEVELOPMENT_TEAM)
set(DEF_OPT_BUILD_IOS ON)
else()
set(DEF_OPT_BUILD_IOS OFF)
endif()
option(SMTG_ENABLE_IOS_TARGETS "Enable building iOS targets" ${DEF_OPT_BUILD_IOS})
set(SMTG_CODE_SIGN_IDENTITY_MAC "Apple Development" CACHE STRING "macOS Code Sign Identity")
set(SMTG_CODE_SIGN_IDENTITY_IOS "Apple Development" CACHE STRING "iOS Code Sign Identity")
endif(SMTG_MAC)
@@ -0,0 +1,641 @@
#-------------------------------------------------------------------------------
# Includes
#-------------------------------------------------------------------------------
include(CMakePrintHelpers)
include(SMTG_UniversalBinary)
include(SMTG_CodeSign)
include(SMTG_SetDebugExecutable)
include(SMTG_AddCommonOptions)
# Customize output location for binaries by setting SMTG_CUSTOM_BINARY_LOCATION via command line
# cmd: cmake -GXcode -DSMTG_CUSTOM_BINARY_LOCATION="MyPath"
set(SMTG_CUSTOM_BINARY_LOCATION "" CACHE PATH "Customize output location for binaries")
# define the C++ standard version to use for plugins
set(SMTG_CXX_STANDARD "" CACHE STRING "C++ standard version used for plugins: 14, 17, 20, 23")
#------------------------------------------------------------------------
# Returns the windows architecture.
#
# This name will be used as a folder name inside the Plug-in package.
# The variable SMTG_WIN_ARCHITECTURE_NAME will be set.
function(smtg_target_set_vst_win_architecture_name target)
if(SMTG_WIN)
if(DEFINED CMAKE_GENERATOR_PLATFORM AND CMAKE_GENERATOR_PLATFORM)
string(TOLOWER ${CMAKE_GENERATOR_PLATFORM} GENERATOR_PLATFORM)
elseif(DEFINED CMAKE_MODULE_LINKER_FLAGS AND CMAKE_MODULE_LINKER_FLAGS)
string(TOLOWER ${CMAKE_MODULE_LINKER_FLAGS} GENERATOR_PLATFORM)
endif()
if(${GENERATOR_PLATFORM} MATCHES "arm64ec")
set(WIN_ARCHITECTURE_NAME "arm64ec")
elseif(${GENERATOR_PLATFORM} MATCHES "arm64")
set(WIN_ARCHITECTURE_NAME "arm64")
elseif(${GENERATOR_PLATFORM} MATCHES "arm")
set(WIN_ARCHITECTURE_NAME "arm")
elseif(${GENERATOR_PLATFORM} MATCHES "win32")
set(WIN_ARCHITECTURE_NAME "x86")
else()
set(WIN_ARCHITECTURE_NAME "x86_64")
endif()
set(WIN_ARCHITECTURE_NAME ${WIN_ARCHITECTURE_NAME}-win)
set_target_properties(${target}
PROPERTIES
SMTG_WIN_ARCHITECTURE_NAME ${WIN_ARCHITECTURE_NAME}
)
endif(SMTG_WIN)
endfunction(smtg_target_set_vst_win_architecture_name)
#------------------------------------------------------------------------
# Prints out all relevant properties of a target for debugging.
#
# @param target The target whose properties will be printed.
function(smtg_target_dump_plugin_package_variables target)
cmake_print_properties(
TARGETS
${target}
PROPERTIES
SMTG_PLUGIN_PACKAGE_NAME
SMTG_PLUGIN_BINARY_DIR
SMTG_PLUGIN_EXTENSION
LIBRARY_OUTPUT_DIRECTORY
SMTG_PLUGIN_PACKAGE_PATH
SMTG_PLUGIN_PACKAGE_CONTENTS
SMTG_PLUGIN_PACKAGE_RESOURCES
SMTG_PLUGIN_PACKAGE_SNAPSHOTS
SMTG_WIN_ARCHITECTURE_NAME
)
endfunction(smtg_target_dump_plugin_package_variables)
#------------------------------------------------------------------------
# Strips all symbols on linux
#
# @param target The target whose build symbols will be stripped
function(smtg_target_strip_symbols target)
add_custom_command(
TARGET ${target} POST_BUILD
COMMAND ${CMAKE_STRIP} $ENV{CROSS_COMPILE} --strip-debug --strip-unneeded $<TARGET_FILE:${target}>
)
endfunction(smtg_target_strip_symbols)
#------------------------------------------------------------------------
#! smtg_target_strip_symbols_with_dbg : Strips all symbols on and creates debug file on Linux
#
# @param target The target whose build symbols will be stripped
function(smtg_target_strip_symbols_with_dbg target)
add_custom_command(
TARGET ${target} POST_BUILD
# Create a target.so.dbg file with debug information
COMMAND ${CMAKE_OBJECT_COPY} $ENV{CROSS_COMPILE}objcopy --only-keep-debug $<TARGET_FILE:${target}> $<TARGET_FILE:${target}>.dbg
COMMAND ${CMAKE_STRIP} $ENV{CROSS_COMPILE} --strip-debug --strip-unneeded $<TARGET_FILE:${target}>
COMMAND ${CMAKE_OBJECT_COPY} $ENV{CROSS_COMPILE}objcopy --add-gnu-debuglink=$<TARGET_FILE:${target}>.dbg $<TARGET_FILE:${target}>
)
endfunction(smtg_target_strip_symbols_with_dbg)
#------------------------------------------------------------------------
# Creates a symlink to the targets output resp Plug-in.
#
# A symlink to the output Plug-in will be created as a post build step.
#
# @param target The target whose output is the symlink's source.
function(smtg_target_create_link_to_plugin target destination)
if(${destination} STREQUAL "")
message(FATAL_ERROR "[SMTG] no destination defined!")
endif()
get_target_property(PLUGIN_PACKAGE_NAME ${target} SMTG_PLUGIN_PACKAGE_NAME)
get_target_property(TARGET_SOURCE ${target} SMTG_PLUGIN_PACKAGE_PATH)
set(TARGET_DESTINATION ${destination})
if(SMTG_WIN)
get_target_property(PLUGIN_BINARY_DIR ${target} SMTG_PLUGIN_BINARY_DIR)
file(TO_CMAKE_PATH "${TARGET_DESTINATION}/${PLUGIN_PACKAGE_NAME}" SRC_NATIVE_PATH)
file(TO_CMAKE_PATH "${PLUGIN_BINARY_DIR}/Debug/${PLUGIN_PACKAGE_NAME}" TARGET_DESTINATION_DEBUG)
file(TO_CMAKE_PATH "${PLUGIN_BINARY_DIR}/Release/${PLUGIN_PACKAGE_NAME}" TARGET_DESTINATION_RELEASE)
add_custom_command(
TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo [SMTG] Delete previous link...
COMMAND ${CMAKE_COMMAND} -E rm -rf "${SRC_NATIVE_PATH}"
COMMAND ${CMAKE_COMMAND} -E echo [SMTG] Creation of the new link...
COMMAND ${CMAKE_COMMAND} -E create_symlink
"$<$<CONFIG:Debug>:${TARGET_DESTINATION_DEBUG}>"
"$<$<CONFIG:Release>:${TARGET_DESTINATION_RELEASE}>"
"${SRC_NATIVE_PATH}"
COMMAND ${CMAKE_COMMAND} -E echo [SMTG] Finished.
)
else()
set(PLUGIN_TARGET_DESTINATION ${TARGET_DESTINATION}/${PLUGIN_PACKAGE_NAME})
add_custom_command(
TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "${TARGET_DESTINATION}"
COMMAND ${CMAKE_COMMAND} -E echo [SMTG] Delete previous link...
COMMAND rm -rf "${PLUGIN_TARGET_DESTINATION}"
COMMAND ${CMAKE_COMMAND} -E echo [SMTG] Create new symlink...
COMMAND ln -sv "${TARGET_SOURCE}" "${PLUGIN_TARGET_DESTINATION}"
COMMAND ${CMAKE_COMMAND} -E echo [SMTG] Finished.
)
endif(SMTG_WIN)
endfunction(smtg_target_create_link_to_plugin)
#------------------------------------------------------------------------
# Customizes folder icon on windows
#
# Customizes folder icon on windows by copying desktop.ini and PlugIn.ico into the package.
#
# @param target The target whose folder icon will be customized.
function(smtg_target_add_folder_icon target icon)
set(DESKTOP_INI_PATH ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../templates/desktop.ini.in)
get_target_property(PLUGIN_PACKAGE_PATH ${target} SMTG_PLUGIN_PACKAGE_PATH)
add_custom_command(
TARGET ${target} POST_BUILD
COMMENT "[SMTG] Copy PlugIn.ico and desktop.ini and change their attributes."
COMMAND ${CMAKE_COMMAND} -E copy
${icon}
${PLUGIN_PACKAGE_PATH}/PlugIn.ico
COMMAND ${CMAKE_COMMAND} -E copy
${DESKTOP_INI_PATH}
${PLUGIN_PACKAGE_PATH}/desktop.ini
COMMAND attrib +s ${PLUGIN_PACKAGE_PATH}/desktop.ini
COMMAND attrib +s ${PLUGIN_PACKAGE_PATH}/PlugIn.ico
COMMAND attrib +s ${PLUGIN_PACKAGE_PATH}
)
endfunction(smtg_target_add_folder_icon)
#------------------------------------------------------------------------
# Adds the Plug-in's main entry point.
#
# The variable public_sdk_SOURCE_DIR needs to be specified.
#
# @param target The target to which the main entry point will be added.
function(smtg_target_add_library_main target)
if(public_sdk_SOURCE_DIR)
if(SMTG_MAC)
target_sources (${target}
PRIVATE
${public_sdk_SOURCE_DIR}/source/main/macmain.cpp
)
elseif(SMTG_WIN)
target_sources (${target}
PRIVATE
${public_sdk_SOURCE_DIR}/source/main/dllmain.cpp
)
elseif(SMTG_LINUX)
target_sources (${target}
PRIVATE
${public_sdk_SOURCE_DIR}/source/main/linuxmain.cpp
)
endif(SMTG_MAC)
endif(public_sdk_SOURCE_DIR)
endfunction(smtg_target_add_library_main)
#------------------------------------------------------------------------
# Returns the linux architecture name.
#
# This name will be used as a folder name inside the Plug-in package.
# The variable LINUX_ARCHITECTURE_NAME will be set.
function(smtg_get_linux_architecture_name)
if(ANDROID)
set(ARCHITECTURE ${CMAKE_ANDROID_ARCH_ABI})
set(LINUX_ARCHITECTURE_NAME ${ARCHITECTURE}-android PARENT_SCOPE)
else()
# Check if we are cross-compiling for a different architecture
if(NOT $ENV{CROSS_COMPILE} STREQUAL "")
string(REGEX MATCH "^[A-Z|a-z|0-9|_]*-" CROSS_COMPILE_PREFIX $ENV{CROSS_COMPILE})
# Strip trailing - from regex result
string(LENGTH ${CROSS_COMPILE_PREFIX} CROSS_COMPILE_PREFIX_LEN)
math(EXPR CROSS_COMPILE_PREFIX_LEN "${CROSS_COMPILE_PREFIX_LEN} -1")
string(SUBSTRING ${CROSS_COMPILE_PREFIX} 0 ${CROSS_COMPILE_PREFIX_LEN} ARCHITECTURE)
else()
EXECUTE_PROCESS(
COMMAND uname -m
COMMAND tr -d '\n'
OUTPUT_VARIABLE ARCHITECTURE
)
endif()
set(LINUX_ARCHITECTURE_NAME ${ARCHITECTURE}-linux PARENT_SCOPE)
endif(ANDROID)
endfunction(smtg_get_linux_architecture_name)
#------------------------------------------------------------------------
# Fatal error if PROJECT_VERSION is not defined
#
function(smtg_target_check_project_version target)
if(NOT PROJECT_VERSION)
# See: https://cmake.org/cmake/help/latest/variable/PROJECT_VERSION.html
message(FATAL_ERROR
"[SMTG] PROJECT_VERSION is not defined for target: \"${target}\". "
"To fix this, set the VERSION option of the most recent call of "
"the cmake project() command e.g. project(myPlugin VERSION 1.0.0)"
)
endif()
endfunction()
#------------------------------------------------------------------------
# Prepare the target to build a Plug-in package.
#
# @param target The target whose output will be put into a package.
# @param extension The package's extension
function(smtg_target_make_plugin_package target pkg_name extension)
smtg_target_check_project_version("${target}")
if(${pkg_name} STREQUAL "")
set(pkg_name ${target})
endif()
set(pkg_extension ${extension})
if(SMTG_WIN)
if(${extension} STREQUAL "bundle")
set(extension dll)
if(NOT SMTG_CREATE_BUNDLE_FOR_WINDOWS)
set(pkg_extension dll)
endif(NOT SMTG_CREATE_BUNDLE_FOR_WINDOWS)
endif()
endif(SMTG_WIN)
string(TOUPPER ${extension} PLUGIN_EXTENSION_UPPER)
if(SMTG_CUSTOM_BINARY_LOCATION)
set(SMTG_PLUGIN_BINARY_LOCATION ${SMTG_CUSTOM_BINARY_LOCATION})
else()
set(SMTG_PLUGIN_BINARY_LOCATION ${CMAKE_BINARY_DIR})
endif(SMTG_CUSTOM_BINARY_LOCATION)
set_target_properties(${target}
PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${SMTG_PLUGIN_BINARY_LOCATION}/${PLUGIN_EXTENSION_UPPER}
SMTG_PLUGIN_BINARY_DIR ${SMTG_PLUGIN_BINARY_LOCATION}/${PLUGIN_EXTENSION_UPPER}
SMTG_PLUGIN_EXTENSION ${extension}
SMTG_PLUGIN_PACKAGE_NAME ${pkg_name}.${pkg_extension}
OUTPUT_NAME ${pkg_name}
SMTG_PLUGIN_PACKAGE_CONTENTS Contents
SMTG_PLUGIN_PACKAGE_RESOURCES Contents/Resources
SMTG_PLUGIN_PACKAGE_SNAPSHOTS Snapshots
)
get_target_property(PLUGIN_BINARY_DIR ${target} SMTG_PLUGIN_BINARY_DIR)
get_target_property(PLUGIN_EXTENSION ${target} SMTG_PLUGIN_EXTENSION)
get_target_property(PLUGIN_PACKAGE_NAME ${target} SMTG_PLUGIN_PACKAGE_NAME)
smtg_target_add_library_main(${target})
if(SMTG_CXX_STANDARD)
target_compile_features(${target}
PRIVATE
cxx_std_${SMTG_CXX_STANDARD}
)
endif(SMTG_CXX_STANDARD)
if(SMTG_MAC)
set_target_properties(${target}
PROPERTIES
BUNDLE TRUE
)
if(XCODE)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE YES
XCODE_ATTRIBUTE_WRAPPER_EXTENSION ${PLUGIN_EXTENSION}
XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS YES
XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT $<$<CONFIG:Debug>:dwarf>$<$<CONFIG:Release>:dwarf-with-dsym>
XCODE_ATTRIBUTE_DEPLOYMENT_POSTPROCESSING $<$<CONFIG:Debug>:NO>$<$<CONFIG:Release>:YES>
)
if(SMTG_CUSTOM_BINARY_LOCATION)
set_target_properties(${target}
PROPERTIES
SMTG_PLUGIN_PACKAGE_PATH ${PLUGIN_BINARY_DIR}/${PLUGIN_PACKAGE_NAME}
)
else()
set_target_properties(${target}
PROPERTIES
SMTG_PLUGIN_PACKAGE_PATH ${PLUGIN_BINARY_DIR}/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>/${PLUGIN_PACKAGE_NAME}
)
endif(SMTG_CUSTOM_BINARY_LOCATION)
else()
set_target_properties(${target}
PROPERTIES
BUNDLE_EXTENSION ${PLUGIN_EXTENSION}
LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_BINARY_DIR}/${CMAKE_BUILD_TYPE}
SMTG_PLUGIN_PACKAGE_PATH ${PLUGIN_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${PLUGIN_PACKAGE_NAME}
)
endif(XCODE)
target_link_libraries(${target}
PRIVATE
"-framework CoreFoundation"
)
smtg_target_setup_universal_binary(${target})
smtg_target_codesign(${target} ${SMTG_IOS_DEVELOPMENT_TEAM} "${SMTG_CODE_SIGN_IDENTITY_MAC}")
elseif(SMTG_WIN)
if(SMTG_CUSTOM_BINARY_LOCATION)
set(PLUGIN_PACKAGE_PATH ${PLUGIN_BINARY_DIR}/${PLUGIN_PACKAGE_NAME})
else()
set(PLUGIN_PACKAGE_PATH ${PLUGIN_BINARY_DIR}/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>/${PLUGIN_PACKAGE_NAME})
endif(SMTG_CUSTOM_BINARY_LOCATION)
set_target_properties(${target}
PROPERTIES
SUFFIX .${PLUGIN_EXTENSION}
SMTG_PLUGIN_PACKAGE_PATH ${PLUGIN_PACKAGE_PATH}
)
if(MSVC)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set_target_properties(${target}
PROPERTIES
LINK_FLAGS /EXPORT:GetPluginFactory
)
endif()
endif(MSVC)
if(MINGW) # no "lib" prefix for MinGw
set_target_properties(${target}
PROPERTIES
PREFIX ""
)
endif(MINGW)
# In order not to have the PDB inside the Plug-in package in release builds,
# we specify a different location (only for MSVC).
if(MSVC)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(WIN_PDB WIN_PDB32)
else()
set(WIN_PDB WIN_PDB64)
endif()
set_target_properties(${target}
PROPERTIES
PDB_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${WIN_PDB}
)
endif(MSVC)
# Create Bundle on Windows
if(SMTG_CREATE_BUNDLE_FOR_WINDOWS)
get_target_property(WIN_ARCHITECTURE_NAME ${target} SMTG_WIN_ARCHITECTURE_NAME)
# When using LIBRARY_OUTPUT_DIRECTORY, cmake adds another /Debug resp. /Release folder at the end of the path.
# In order to prevent cmake from doing that we set LIBRARY_OUTPUT_DIRECTORY_DEBUG and LIBRARY_OUTPUT_DIRECTORY_RELEASE
# (or LIBRARY_OUTPUT_DIRECTORY_${CONFIG_UPPERCASE}) directly.
get_target_property(PLUGIN_PACKAGE_CONTENTS ${target} SMTG_PLUGIN_PACKAGE_CONTENTS)
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG_UPPER)
if(SMTG_CUSTOM_BINARY_LOCATION)
set_target_properties(${target}
PROPERTIES
LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG_UPPER} ${PLUGIN_BINARY_DIR}/${PLUGIN_PACKAGE_NAME}/${PLUGIN_PACKAGE_CONTENTS}/${WIN_ARCHITECTURE_NAME}
)
else()
set_target_properties(${target}
PROPERTIES
LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG_UPPER} ${PLUGIN_BINARY_DIR}/${OUTPUTCONFIG}/${PLUGIN_PACKAGE_NAME}/${PLUGIN_PACKAGE_CONTENTS}/${WIN_ARCHITECTURE_NAME}
)
endif(SMTG_CUSTOM_BINARY_LOCATION)
endforeach()
if(EXISTS ${SMTG_PACKAGE_ICON_PATH})
smtg_target_add_folder_icon(${target} ${SMTG_PACKAGE_ICON_PATH})
endif()
else()
# Do not create a "MyPlugin.vst3/Contents/Resources" folder when SMTG_CREATE_BUNDLE_FOR_WINDOWS is NOT set!
set_target_properties(${target}
PROPERTIES
SMTG_DISABLE_CREATE_RESOURCE_FOLDER 1
)
endif(SMTG_CREATE_BUNDLE_FOR_WINDOWS)
# Disable warning LNK4221: "This object file does not define any previously undefined public symbols...".
# Enable "Generate Debug Information" in release config by setting "/Zi" and "/DEBUG" flags.
if(MSVC)
target_compile_options(${target}
PRIVATE
/wd4221
$<$<CONFIG:RELEASE>:/Zi>
)
set_property(TARGET ${target}
APPEND PROPERTY
LINK_FLAGS_RELEASE /DEBUG
)
endif(MSVC)
elseif(SMTG_LINUX)
smtg_get_linux_architecture_name() # Sets var LINUX_ARCHITECTURE_NAME
message(STATUS "[SMTG] Linux architecture name is ${LINUX_ARCHITECTURE_NAME}.")
get_target_property(PLUGIN_PACKAGE_CONTENTS ${target} SMTG_PLUGIN_PACKAGE_CONTENTS)
set_target_properties(${target}
PROPERTIES
PREFIX ""
LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${PLUGIN_PACKAGE_NAME}/${PLUGIN_PACKAGE_CONTENTS}/${LINUX_ARCHITECTURE_NAME}
SMTG_PLUGIN_PACKAGE_PATH ${PLUGIN_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${PLUGIN_PACKAGE_NAME}
)
# Strip symbols in Release config
if(${CMAKE_BUILD_TYPE} MATCHES Release)
smtg_target_strip_symbols(${target})
elseif(${CMAKE_BUILD_TYPE} MATCHES RelWithDebInfo)
smtg_target_strip_symbols_with_dbg(${target})
endif()
endif(SMTG_MAC)
smtg_target_create_resources_folder(${target})
endfunction(smtg_target_make_plugin_package)
#------------------------------------------------------------------------
# Create "Resources" folder for a target
#
# @param target cmake target
function(smtg_target_create_resources_folder target)
get_target_property(DISABLE_CREATE_RESOURCE_FOLDER ${target} SMTG_DISABLE_CREATE_RESOURCE_FOLDER)
if(DEFINED DISABLE_CREATE_RESOURCE_FOLDER AND DISABLE_CREATE_RESOURCE_FOLDER EQUAL 1)
return()
endif()
get_target_property(PLUGIN_PACKAGE_PATH ${target} SMTG_PLUGIN_PACKAGE_PATH)
get_target_property(PLUGIN_PACKAGE_RESOURCES ${target} SMTG_PLUGIN_PACKAGE_RESOURCES)
set(resources_folder "${PLUGIN_PACKAGE_PATH}/${PLUGIN_PACKAGE_RESOURCES}")
add_custom_command(
TARGET ${target} PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "${resources_folder}"
)
endfunction()
#------------------------------------------------------------------------
# Adds a resource for a target
#
# The resource which gets copied into the targets Resource Bundle directory.
#
# @param target cmake target
# @param input_file resource file
# @param ARGV2 destination subfolder inside the Resource folder [optional]
function(smtg_target_add_plugin_resource target input_file)
if(SMTG_LINUX OR (SMTG_WIN AND SMTG_CREATE_BUNDLE_FOR_WINDOWS))
get_target_property(PLUGIN_PACKAGE_PATH ${target} SMTG_PLUGIN_PACKAGE_PATH)
get_target_property(PLUGIN_PACKAGE_RESOURCES ${target} SMTG_PLUGIN_PACKAGE_RESOURCES)
set(destination_folder "${PLUGIN_PACKAGE_PATH}/${PLUGIN_PACKAGE_RESOURCES}")
set(destination_sourcegroup "${PLUGIN_PACKAGE_RESOURCES}")
if(ARGC GREATER 2 AND ARGV2)
set(destination_folder "${destination_folder}/${ARGV2}")
set(destination_sourcegroup "${destination_sourcegroup}/${ARGV2}")
endif()
# Make the incoming path absolute.
get_filename_component(absolute_input_file_path "${input_file}" ABSOLUTE)
# Extract the filename and its extension
get_filename_component(file_name_with_extension "${input_file}" NAME)
# Create absolute output file path
set(absolute_output_file_path "${destination_folder}/${file_name_with_extension}")
# Add the file as a source to the target inside their corresponding folders
source_group("${destination_sourcegroup}" FILES ${input_file})
target_sources(${target}
PRIVATE
${input_file}
)
# CMAKE_VS_MSBUILD_COMMAND is not defined when using "-G Ninja" generator but resolves to msbuild.exe when using "-G Visual Studio..."
if(CMAKE_VS_MSBUILD_COMMAND)
# Hacky workaround: replace all SMTG_PLUGIN_PACKAGE_NAME (e.g. again.vst3)
# occurences by a MSVS macro $(TargetFileName). Using the cmake only approach does not work.
get_target_property(PLUGIN_PACKAGE_NAME ${target} SMTG_PLUGIN_PACKAGE_NAME)
string(REPLACE "${PLUGIN_PACKAGE_NAME}" "$(TargetFileName)" absolute_output_file_path ${absolute_output_file_path})
endif()
# Create a custom build tool for the specific file
add_custom_command(
OUTPUT "${absolute_output_file_path}"
MAIN_DEPENDENCY "${absolute_input_file_path}"
COMMAND ${CMAKE_COMMAND}
-E copy_if_different
"${absolute_input_file_path}"
"${absolute_output_file_path}"
COMMAND ${CMAKE_COMMAND}
-E echo
"[SMTG] Copied ${absolute_input_file_path} to ${absolute_output_file_path}"
)
elseif(SMTG_MAC)
target_sources(${target}
PRIVATE
${input_file}
)
set(destination_folder "Resources")
if(ARGC GREATER 2 AND ARGV2)
set(destination_folder "${destination_folder}/${ARGV2}")
endif()
set_source_files_properties(${input_file}
PROPERTIES
MACOSX_PACKAGE_LOCATION "${destination_folder}"
)
endif(SMTG_LINUX OR (SMTG_WIN AND SMTG_CREATE_BUNDLE_FOR_WINDOWS))
endfunction(smtg_target_add_plugin_resource)
#------------------------------------------------------------------------
# Adds multiple snapshots to target.
#
# Usage:
# smtg_target_add_plugin_snapshots (target
# RESOURCES
# bitmap0.png
# bitmap1.png
# )
# This adds both bitmaps to <Bundle>/Resources/Snapshots
#
# @param target The target to which the resources will be added.
function(smtg_target_add_plugin_snapshots target)
cmake_parse_arguments(
PARSED_ARGS # Prefix of output variables e.g. PARSED_ARGS_RESOURCES
"" # List of names for boolean arguments
"" # List of names for mono-valued arguments
"RESOURCES" # List of names for multi-valued arguments resp. lists
${ARGN} # Arguments of the function to parse
)
get_target_property(PLUGIN_PACKAGE_SNAPSHOTS ${target} SMTG_PLUGIN_PACKAGE_SNAPSHOTS)
foreach(rsrc ${PARSED_ARGS_RESOURCES})
smtg_target_add_plugin_resource (${target} ${rsrc} ${PLUGIN_PACKAGE_SNAPSHOTS})
endforeach()
endfunction(smtg_target_add_plugin_snapshots)
#------------------------------------------------------------------------
# Adds multiple resources to target.
#
# Usage:
# smtg_target_add_plugin_resources (target
# RESOURCES
# bitmap0.png
# bitmap1.png
# OUTPUT_SUBDIRECTORY
# Graphics
# )
# This adds both bitmaps to <Bundle>/Resources/Graphics
#
# @param target The target to which the resources will be added.
function(smtg_target_add_plugin_resources target)
cmake_parse_arguments(
PARSED_ARGS # Prefix of output variables e.g. PARSED_ARGS_RESOURCES
"" # List of names for boolean arguments
"OUTPUT_SUBDIRECTORY" # List of names for mono-valued arguments
"RESOURCES" # List of names for multi-valued arguments resp. lists
${ARGN} # Arguments of the function to parse
)
foreach(rsrc ${PARSED_ARGS_RESOURCES})
smtg_target_add_plugin_resource (${target} ${rsrc} ${PARSED_ARGS_OUTPUT_SUBDIRECTORY})
endforeach()
endfunction(smtg_target_add_plugin_resources)
#------------------------------------------------------------------------
# Deprecated since 3.7.4 -----------------------------
function(smtg_add_folder_icon target icon)
message(DEPRECATION "[SMTG] Use smtg_target_add_folder_icon instead of smtg_add_folder_icon")
smtg_target_add_folder_icon (${target} ${icon})
endfunction(smtg_add_folder_icon)
# Deprecated since 3.7.4 -----------------------------
function(smtg_create_link_to_plugin target)
message(DEPRECATION "[SMTG] Use smtg_target_create_link_to_plugin instead of smtg_create_link_to_plugin")
smtg_get_default_plugin_path()
smtg_target_create_link_to_plugin(${target} ${SMTG_PLUGIN_TARGET_DEFAULT_PATH})
endfunction(smtg_create_link_to_plugin)
# Deprecated since 3.7.4 -----------------------------
function(smtg_make_plugin_package target pkg_name extension)
message(DEPRECATION "[SMTG] Use smtg_target_make_plugin_package instead of smtg_make_plugin_package")
smtg_target_make_plugin_package (${target} ${pkg_name} ${extension})
endfunction(smtg_make_plugin_package)
# Deprecated since 3.7.4 -----------------------------
function(smtg_strip_symbols target)
message(DEPRECATION "[SMTG] Use smtg_target_strip_symbols instead of smtg_strip_symbols")
smtg_target_strip_symbols (${target})
endfunction(smtg_strip_symbols)
# Deprecated since 3.7.4 -----------------------------
function(smtg_add_library_main target)
message(DEPRECATION "[SMTG] Use smtg_target_add_library_main instead of smtg_add_library_main")
smtg_target_add_library_main (${target})
endfunction(smtg_add_library_main)
# Deprecated since 3.7.4 -----------------------------
function(smtg_strip_symbols_with_dbg target)
message(DEPRECATION "[SMTG] Use smtg_target_strip_symbols_with_dbg instead of smtg_strip_symbols_with_dbg")
smtg_target_strip_symbols_with_dbg (${target})
endfunction(smtg_strip_symbols_with_dbg)
# Deprecated since 3.7.4 -----------------------------
function(smtg_dump_plugin_package_variables target)
message(DEPRECATION "[SMTG] Use smtg_target_dump_plugin_package_variables instead of smtg_dump_plugin_package_variables")
smtg_target_dump_plugin_package_variables (${target})
endfunction(smtg_dump_plugin_package_variables)
# Deprecated since 3.7.4 -----------------------------
function(smtg_add_plugin_resource target input_file)
message(DEPRECATION "[SMTG] Use smtg_target_add_plugin_resource instead of smtg_add_plugin_resource")
smtg_target_add_plugin_resource (${target} ${input_file})
endfunction(smtg_add_plugin_resource)
# Deprecated since 3.7.4 -----------------------------
function(smtg_add_plugin_snapshot target snapshot)
message(DEPRECATION "[SMTG] Use smtg_target_add_plugin_snapshots instead of smtg_add_plugin_snapshot")
smtg_target_add_plugin_snapshots (${target}
RESOURCES
${snapshot}
)
endfunction(smtg_add_plugin_snapshot)
@@ -0,0 +1,13 @@
#------------------------------------------------------------------------
# add every sub directory of the current source dir if it contains a CMakeLists.txt
function(smtg_add_subdirectories)
file(GLOB subDirectories RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *)
foreach(dir ${subDirectories})
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${dir}/CMakeLists.txt")
add_subdirectory(${dir})
endif()
endif()
endforeach(dir)
endfunction(smtg_add_subdirectories)
@@ -0,0 +1,151 @@
include(SMTG_Bundle)
include(SMTG_UniversalBinary)
include(SMTG_CodeSign)
if(XCODE AND SMTG_ENABLE_AUV2_BUILDS)
set(SMTG_AUV2_FOLDER FOLDER "AudioUnit V2")
#------------------------------------------------------------------------
# Add an AudioUnit Version 2 target for macOS
# @param target target name
# @param BUNDLE_NAME name of the bundle
# @param BUNDLE_IDENTIFIER bundle identifier
# @param INFO_PLIST_TEMPLATE the info.plist file containing the needed AudioUnit keys
# @param VST3_PLUGIN_TARGET the vst3 plugin target
#------------------------------------------------------------------------
function(smtg_target_add_auv2 target)
set(oneValueArgs
BUNDLE_NAME
BUNDLE_IDENTIFIER
INFO_PLIST_TEMPLATE
VST3_PLUGIN_TARGET
)
cmake_parse_arguments(ARG "" "${oneValueArgs}" "" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "[SMTG] The following parameters are unrecognized: ${ARG_UNPARSED_ARGUMENTS}")
endif(ARG_UNPARSED_ARGUMENTS)
if(ARG_KEYWORDS_MISSING_VALUES)
message(FATAL_ERROR "[SMTG] The following parameter values are missing: ${ARG_KEYWORDS_MISSING_VALUES}")
endif(ARG_KEYWORDS_MISSING_VALUES)
foreach(ARG_NAME ${oneValueArgs})
set(tmp ARG_${ARG_NAME})
if(NOT ${tmp})
message(FATAL_ERROR "[SMTG] Missing ${ARG_NAME} argument and value")
endif()
endforeach()
string(TIMESTAMP CocoaIdStamp "%Y%j%H%M%S")
string(MAKE_C_IDENTIFIER "SMTG_AUCocoaUIBase_${ARG_BUNDLE_NAME}${CocoaIdStamp}" SMTG_AUCocoaUIBase_CLASS_NAME)
add_library(${target} MODULE
${public_sdk_SOURCE_DIR}/source/vst/auwrapper/aucocoaview.mm
${public_sdk_SOURCE_DIR}/source/vst/auwrapper/aucocoaview.h
${public_sdk_SOURCE_DIR}/source/vst/auwrapper/auwrapper.mm
${public_sdk_SOURCE_DIR}/source/vst/auwrapper/auwrapper.h
${public_sdk_SOURCE_DIR}/source/vst/auwrapper/NSDataIBStream.mm
${public_sdk_SOURCE_DIR}/source/vst/auwrapper/NSDataIBStream.h
)
smtg_target_setup_universal_binary(${target})
smtg_target_codesign(${target} ${SMTG_IOS_DEVELOPMENT_TEAM} "${SMTG_CODE_SIGN_IDENTITY_MAC}")
target_compile_features(${target}
PUBLIC
cxx_std_17
)
target_compile_definitions(${target}
PRIVATE
SMTG_AUCocoaUIBase_CLASS_NAME=${SMTG_AUCocoaUIBase_CLASS_NAME}
CA_USE_AUDIO_PLUGIN_ONLY=0 # TODO: If true will let instruments fail validation
)
target_link_libraries(${target}
PRIVATE
sdk_hosting
"-framework AudioUnit"
"-framework CoreMIDI"
"-framework AudioToolbox"
"-framework CoreFoundation"
"-framework Carbon"
"-framework Cocoa"
"-framework CoreAudio"
)
if(NOT ${SMTG_COREAUDIO_SDK_PATH} STREQUAL "")
target_sources(${target}
PRIVATE
"${public_sdk_SOURCE_DIR}/source/vst/auwrapper/ausdk.mm"
)
target_include_directories(${target}
PRIVATE
"${SMTG_COREAUDIO_SDK_PATH}/**"
)
elseif(NOT ${SMTG_AUDIOUNIT_SDK_PATH} STREQUAL "")
target_compile_definitions(${target}
PRIVATE
SMTG_AUWRAPPER_USES_AUSDK
)
## Adding the xcodeproj will crash Xcode when closing and reopening the cmake generated project
# target_sources(${target} PRIVATE "${SMTG_AUDIOUNIT_SDK_PATH}/AudioUnitSDK.xcodeproj")
target_include_directories(${target}
PRIVATE
"${SMTG_AUDIOUNIT_SDK_PATH}/include/**"
)
add_custom_command(TARGET ${target}
PRE_BUILD
COMMAND "xcodebuild" -project "${SMTG_AUDIOUNIT_SDK_PATH}/AudioUnitSDK.xcodeproj" -target AudioUnitSDK build -configuration Release SYMROOT=${CMAKE_BINARY_DIR}/AudioUnitSDK/
)
target_link_libraries(${target}
PRIVATE
"${CMAKE_BINARY_DIR}/AudioUnitSDK/Release/libAudioUnitSDK.a"
)
endif()
smtg_target_set_bundle(${target}
INFOPLIST ${ARG_INFO_PLIST_TEMPLATE}
EXTENSION component
)
set(VST3_OUTPUT_DIR ${CMAKE_BINARY_DIR}/VST3)
set(outputdir ${VST3_OUTPUT_DIR}/$<CONFIG>)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE "YES"
XCODE_ATTRIBUTE_PRODUCT_NAME "${ARG_BUNDLE_NAME}"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER ${ARG_BUNDLE_IDENTIFIER}
LIBRARY_OUTPUT_DIRECTORY ${VST3_OUTPUT_DIR}
${SMTG_AUV2_FOLDER}
)
add_dependencies(${target} ${ARG_VST3_PLUGIN_TARGET})
add_custom_command(TARGET ${target} POST_BUILD
COMMAND /bin/mkdir "-p" ${outputdir}/${ARG_BUNDLE_NAME}.component/Contents/Resources
COMMAND /bin/rm "-f" "${outputdir}/${ARG_BUNDLE_NAME}.component/Contents/Resources/plugin.vst3"
COMMAND /bin/ln "-svfF" "${outputdir}/$<TARGET_FILE_NAME:${ARG_VST3_PLUGIN_TARGET}>.vst3" "${outputdir}/${ARG_BUNDLE_NAME}.component/Contents/Resources/plugin.vst3"
COMMAND /bin/rm "-rf" "~/Library/Audio/Plug-Ins/Components/${ARG_BUNDLE_NAME}.component"
COMMAND /bin/cp "-rpf" "${outputdir}/${ARG_BUNDLE_NAME}.component" "~/Library/Audio/Plug-Ins/Components/"
BYPRODUCTS "~/Library/Audio/Plug-Ins/Components/${ARG_BUNDLE_NAME}.component"
)
smtg_target_add_custom_codesign_post_build_step(
TARGET
"${target}"
IDENTITY
${SMTG_CODE_SIGN_IDENTITY_MAC}
PATH
"~/Library/Audio/Plug-Ins/Components/${ARG_BUNDLE_NAME}.component"
FLAGS
--timestamp
)
endfunction(smtg_target_add_auv2)
else()
message("[SMTG] * To add an AudioUnit v2 target, you need to use the Xcode generator and set SMTG_COREAUDIO_SDK_PATH to the path of your installation of the CoreAudio SDK!")
endif(XCODE AND SMTG_ENABLE_AUV2_BUILDS)
@@ -0,0 +1,227 @@
#------------------------------------------------------------------------
# Includes
#------------------------------------------------------------------------
include(SMTG_CodeSign)
if(SMTG_MAC)
if(XCODE)
set(SMTG_AUV3_FOLDER FOLDER "AudioUnit V3")
set(auv3_wrapper_macos_sources
${public_sdk_SOURCE_DIR}/source/vst/auv3wrapper/AUv3WrappermacOS/main.mm
)
set(auv3_wrapper_macosextension_sources
${public_sdk_SOURCE_DIR}/source/vst/auv3wrapper/Shared/AUv3WrapperFactory.mm
)
set(auv3_wrapper_ios_sources
)
set(auv3_wrapper_iosextension_sources
${public_sdk_SOURCE_DIR}/source/vst/auv3wrapper/Shared/AUv3WrapperFactory.mm
)
#------------------------------------------------------------------------
# Add a AudioUnit Version 3 App target for macOS
# @param target target name
# @param BuildTarget must be either "macOS" or "iOS"
# @param OutputName Output App name
# @param BundleID Bundle Identifier
# @param AudioUnitConfigHeader configuration header
# @param EntitlementFile Code sign entitlements file
# @param AppSources Application Sources
# @param AppUIResources Application UI Resources
# @param AppInfoPlist Info.plist for the application
# @param ExtensionInfoPlist Info.plist for the app-extension
# @param vst3_plugin_target the vst3 plugin target
#------------------------------------------------------------------------
function(smtg_add_auv3_app target BuildTarget OutputName BundleID AudioUnitConfigHeader EntitlementFile AppSources AppUIResources AppInfoPlist ExtensionInfoPlist vst3_plugin_target)
if(BuildTarget STREQUAL macOS)
set(macOS TRUE)
elseif(BuildTarget STREQUAL iOS)
set(iOS TRUE)
else()
message(FATAL_ERROR "[SMTG] BuildTarget must be macOS or iOS not ${BuildTarget}")
endif()
if(macOS)
set(link_frameworks
"-framework Accelerate"
"-framework AppKit"
"-framework AudioToolbox"
"-framework AVFoundation"
"-framework CoreAudioKit"
"-framework OpenGL"
"-framework QuartzCore"
"-framework CoreMIDI"
)
set(app-extension-target ${target}_appextension_macos)
set(app-target ${target})
set(app-extension-sources ${auv3_wrapper_macosextension_sources})
set(auwrapper-sources ${auv3_wrapper_macos_sources} ${AppSources})
set(auwrapper-lib auv3_wrapper_macos)
else()
set(link_frameworks
"-framework UIKit"
"-framework CoreAudioKit"
"-framework AudioToolbox"
"-framework CoreGraphics"
"-framework QuartzCore"
"-framework CoreText"
"-framework Accelerate"
"-framework AVFoundation"
"-framework ImageIO"
"-framework MobileCoreServices"
"-framework MediaPlayer"
"-framework CoreMIDI"
)
set(app-extension-target ${target}_appextension_ios)
set(app-target ${target})
set(app-extension-sources ${auv3_wrapper_iosextension_sources})
set(auwrapper-sources ${AppSources})
set(auwrapper-lib auv3_wrapper_ios)
endif(macOS)
set(auwrapper-xib-resources ${AppUIResources})
get_filename_component(AudioUnitConfig ${AudioUnitConfigHeader} ABSOLUTE)
get_filename_component(AppInfoPlist ${AppInfoPlist} ABSOLUTE)
get_filename_component(ExtensionInfoPlist ${ExtensionInfoPlist} ABSOLUTE)
get_filename_component(EntitlementFile ${EntitlementFile} ABSOLUTE)
# app-extension
add_executable(${app-extension-target} ${app-extension-sources})
target_compile_features(${app-extension-target}
PUBLIC
cxx_std_17
)
target_link_libraries(${app-extension-target}
PRIVATE
${auwrapper-lib}
${link_frameworks}
)
add_dependencies(${app-extension-target} "${vst3_plugin_target}")
set_target_properties(${app-extension-target}
PROPERTIES
# BUNDLE YES
# MACOSX_BUNDLE TRUE
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER ${BundleID}.appex
XCODE_ATTRIBUTE_INFOPLIST_PREFIX_HEADER ${AudioUnitConfig}
XCODE_ATTRIBUTE_GCC_PREFIX_HEADER ${AudioUnitConfig}
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES
XCODE_ATTRIBUTE_WRAPPER_EXTENSION appex
XCODE_PRODUCT_TYPE com.apple.product-type.app-extension
${SMTG_AUV3_FOLDER}
)
smtg_target_set_bundle(${app-extension-target} INFOPLIST "${ExtensionInfoPlist}" PREPROCESS)
# application
add_executable(${app-target} ${auwrapper-sources} ${auwrapper-xib-resources})
target_compile_features(${app-target}
PUBLIC
cxx_std_17
)
target_link_libraries(${app-target}
PRIVATE
${auwrapper-lib}
${link_frameworks}
)
add_dependencies(${app-target} "${app-extension-target}")
set_target_properties(${app-target}
PROPERTIES
RESOURCE "${auwrapper-xib-resources}"
MACOSX_BUNDLE TRUE
OUTPUT_NAME "${OutputName}"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER ${BundleID}
XCODE_ATTRIBUTE_INFOPLIST_PREFIX_HEADER ${AudioUnitConfig}
XCODE_ATTRIBUTE_GCC_PREFIX_HEADER ${AudioUnitConfig}
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES
${SMTG_AUV3_FOLDER}
)
smtg_target_set_bundle(${app-target} INFOPLIST "${AppInfoPlist}" PREPROCESS)
get_target_property(PLUGIN_PACKAGE_PATH ${vst3_plugin_target} SMTG_PLUGIN_PACKAGE_PATH)
if(macOS)
add_custom_command(
TARGET ${app-extension-target} POST_BUILD
COMMENT "[SMTG] Copy VST3 plugin into App-Extension"
COMMAND rm -Rf
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/$<TARGET_FILE_NAME:${app-extension-target}>.appex/Contents/PlugIns/plugin.vst3"
COMMAND ${CMAKE_COMMAND} -E make_directory
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/$<TARGET_FILE_NAME:${app-extension-target}>.appex/Contents/PlugIns/plugin.vst3"
COMMAND /bin/cp -a -v
"${PLUGIN_PACKAGE_PATH}/"
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/$<TARGET_FILE_NAME:${app-extension-target}>.appex/Contents/PlugIns/plugin.vst3/"
)
add_custom_command(
TARGET ${app-target} POST_BUILD
COMMENT "[SMTG] Copy App-Extension into Application"
COMMAND rm -Rf
"$<TARGET_BUNDLE_CONTENT_DIR:${app-target}>/PlugIns/auv3.appex"
COMMAND ${CMAKE_COMMAND} -E make_directory
"$<TARGET_BUNDLE_CONTENT_DIR:${app-target}>/PlugIns/auv3.appex"
COMMAND /bin/cp -a -v
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/$<TARGET_FILE_NAME:${app-extension-target}>.appex/"
"$<TARGET_BUNDLE_CONTENT_DIR:${app-target}>/PlugIns/auv3.appex/"
)
smtg_target_codesign(${app-target} ${SMTG_IOS_DEVELOPMENT_TEAM} "${SMTG_CODE_SIGN_IDENTITY_MAC}")
smtg_target_codesign(${app-extension-target} ${SMTG_IOS_DEVELOPMENT_TEAM} "${SMTG_CODE_SIGN_IDENTITY_MAC}")
set_target_properties(${app-extension-target}
PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${EntitlementFile}"
)
else()
add_custom_command(
TARGET ${app-extension-target} POST_BUILD
COMMENT "[SMTG] Copy VST3 plugin into App-Extension"
COMMAND rm -Rf
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/$<TARGET_FILE_NAME:${app-extension-target}>.appex/PlugIns/plugin.vst3"
COMMAND ${CMAKE_COMMAND} -E make_directory
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/$<TARGET_FILE_NAME:${app-extension-target}>.appex/PlugIns/plugin.vst3"
COMMAND /bin/cp -a -v
"${PLUGIN_PACKAGE_PATH}/"
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/$<TARGET_FILE_NAME:${app-extension-target}>.appex/PlugIns/plugin.vst3/"
)
add_custom_command(
TARGET ${app-target} POST_BUILD
COMMENT "[SMTG] Copy App-Extension into Application"
COMMAND rm -Rf
"$<TARGET_BUNDLE_DIR:${app-target}>/PlugIns/auv3.appex"
COMMAND ${CMAKE_COMMAND} -E make_directory
"$<TARGET_BUNDLE_DIR:${app-target}>/PlugIns/auv3.appex"
COMMAND /bin/cp -a -v
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/$<TARGET_FILE_NAME:${app-extension-target}>.appex/"
"$<TARGET_BUNDLE_DIR:${app-target}>/PlugIns/auv3.appex/"
)
smtg_target_set_platform_ios(${app-target})
smtg_target_set_platform_ios(${app-extension-target})
smtg_target_codesign(${app-target} ${SMTG_IOS_DEVELOPMENT_TEAM} "${SMTG_CODE_SIGN_IDENTITY_IOS}")
smtg_target_codesign(${app-extension-target} ${SMTG_IOS_DEVELOPMENT_TEAM} "${SMTG_CODE_SIGN_IDENTITY_IOS}")
set_target_properties(${app-target}
PROPERTIES
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
)
set_target_properties(${app-extension-target}
PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${EntitlementFile}"
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
)
endif(macOS)
set(AUV3_APP_TARGET ${app-target} PARENT_SCOPE)
set(AUV3_EXTENSION_TARGET ${app-extension-target} PARENT_SCOPE)
endfunction(smtg_add_auv3_app)
# Deprecated since 3.7.4 -----------------------------
function(smtg_add_auv3 target BuildTarget OutputName BundleID AudioUnitConfigHeader EntitlementFile AppSources AppUIResources AppInfoPlist ExtensionInfoPlist vst3_plugin_target)
message(DEPRECATION "[SMTG] Use smtg_add_auv3_app instead of smtg_add_auv3")
smtg_add_auv3_app (${target} ${BuildTarget} ${OutputName} ${BundleID} ${AudioUnitConfigHeader} ${EntitlementFile} ${AppSources} ${AppUIResources} ${AppInfoPlist} ${ExtensionInfoPlist} ${vst3_plugin_target})
endfunction(smtg_add_auv3)
endif(XCODE)
endif(SMTG_MAC)
@@ -0,0 +1,314 @@
#------------------------------------------------------------------------
# Includes
#------------------------------------------------------------------------
include(SMTG_AddSMTGLibrary)
set(SMTG_RUN_VST_VALIDATOR_DEFAULT ON)
set(SMTG_CREATE_MODULE_INFO_DEFAULT ON)
# Run the Validator after each new compilation of VST3 Plug-ins
option(SMTG_RUN_VST_VALIDATOR "Run VST validator on VST3 Plug-ins" ${SMTG_RUN_VST_VALIDATOR_DEFAULT})
# Create the moduleinfo.json file after building
option(SMTG_CREATE_MODULE_INFO "Create the moduleinfo.json file" ${SMTG_CREATE_MODULE_INFO_DEFAULT})
#------------------------------------------------------------------------
# Runs the validator on a VST3 target.
#
# The validator will be run on the target as a post build step.
#
# @param target The target which the validator will validate.
function(smtg_target_run_vst_validator target)
if(TARGET validator)
message(STATUS "[SMTG] Setup running validator for ${target}")
add_dependencies(${target} validator)
if(SMTG_WIN AND NOT SMTG_CREATE_BUNDLE_FOR_WINDOWS)
set(TARGET_PATH $<TARGET_FILE:${target}>)
add_custom_command(
TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo [SMTG] Validator started...
COMMAND
$<TARGET_FILE:validator>
"${TARGET_PATH}"
WORKING_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
COMMAND ${CMAKE_COMMAND} -E echo [SMTG] Validator finished.
)
else()
get_target_property(PLUGIN_PACKAGE_PATH ${target} SMTG_PLUGIN_PACKAGE_PATH)
add_custom_command(
TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo [SMTG] Validator started...
COMMAND
$<TARGET_FILE:validator>
$<$<CONFIG:Debug>:${PLUGIN_PACKAGE_PATH}>
$<$<CONFIG:Release>:${PLUGIN_PACKAGE_PATH}>
WORKING_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
COMMAND ${CMAKE_COMMAND} -E echo [SMTG] Validator finished.
)
endif()
endif(TARGET validator)
endfunction(smtg_target_run_vst_validator)
#------------------------------------------------------------------------
# Runs the moduleinfotool on a VST3 target.
#
# The moduleinfotool will be run on the target as a post build step and
# generates a moduleinfo.json file inside the VST 3 bundle.
#
# @param target The target for which the moduleinfotool will create the file.
# @param MODULEINFO_COMPATIBILITY <Path> The path to the compatibility json file [optional]
function(smtg_target_create_module_info_file target)
set(oneValueArgs MODULEINFO_COMPATIBILITY)
cmake_parse_arguments(PARSE_ARGV 1 PARAMS "" "${oneValueArgs}" "")
if(NOT SMTG_CREATE_MODULE_INFO)
return()
endif()
if(SMTG_WIN AND NOT SMTG_CREATE_BUNDLE_FOR_WINDOWS)
message(WARNING "[SMTG] No moduleinfo.json file for ${target} generated. Consider to enable SMTG_CREATE_BUNDLE_FOR_WINDOWS.")
return()
endif()
message(STATUS "[SMTG] Setup running moduleinfotool for ${target}")
add_dependencies(${target} moduleinfotool)
get_target_property(PLUGIN_PACKAGE_PATH ${target} SMTG_PLUGIN_PACKAGE_PATH)
set(SMTG_MODULEINFO_PATH_INSIDE_BUNDLE Contents/Resources/moduleinfo.json)
if(DEFINED PARAMS_MODULEINFO_COMPATIBILITY)
add_custom_command(
TARGET ${target} POST_BUILD
COMMAND
$<TARGET_FILE:moduleinfotool> -create -version ${PROJECT_VERSION}
-path "${PLUGIN_PACKAGE_PATH}"
-compat "${CMAKE_CURRENT_SOURCE_DIR}/${PARAMS_MODULEINFO_COMPATIBILITY}"
-output "${PLUGIN_PACKAGE_PATH}/${SMTG_MODULEINFO_PATH_INSIDE_BUNDLE}"
WORKING_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
)
else()
add_custom_command(
TARGET ${target} POST_BUILD
COMMAND
$<TARGET_FILE:moduleinfotool> -create -version ${PROJECT_VERSION}
-path "${PLUGIN_PACKAGE_PATH}"
-output "${PLUGIN_PACKAGE_PATH}/${SMTG_MODULEINFO_PATH_INSIDE_BUNDLE}"
WORKING_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
)
endif()
if(SMTG_MAC)
add_custom_command(
TARGET ${target} POST_BUILD
COMMAND
codesign -f -s "-" -v "${PLUGIN_PACKAGE_PATH}/${SMTG_MODULEINFO_PATH_INSIDE_BUNDLE}"
WORKING_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
)
endif()
endfunction()
#------------------------------------------------------------------------
# Set SMTG_PLUGIN_TARGET_PATH to default VST3 Path
function(smtg_get_vst3_path)
# here you can define the VST3 Plug-ins folder (it will be created), SMTG_PLUGIN_TARGET_DEFAULT_PATH will be set
smtg_get_default_vst3_path()
set(SMTG_PLUGIN_TARGET_USER_PATH "" CACHE PATH "Here you can redefine the VST3 Plug-ins folder")
if(NOT ${SMTG_PLUGIN_TARGET_USER_PATH} STREQUAL "")
set(PLUGIN_TARGET_PATH ${SMTG_PLUGIN_TARGET_USER_PATH})
else()
set(PLUGIN_TARGET_PATH ${SMTG_PLUGIN_TARGET_DEFAULT_PATH})
endif()
if(NOT ${PLUGIN_TARGET_PATH} STREQUAL "" AND SMTG_CREATE_PLUGIN_LINK)
if(NOT EXISTS ${PLUGIN_TARGET_PATH})
message(STATUS "[SMTG] Create folder: " ${PLUGIN_TARGET_PATH})
if(SMTG_WIN)
smtg_create_directory_as_admin_win(${PLUGIN_TARGET_PATH})
else()
file(MAKE_DIRECTORY ${PLUGIN_TARGET_PATH})
endif(SMTG_WIN)
endif(NOT EXISTS ${PLUGIN_TARGET_PATH})
endif(NOT ${PLUGIN_TARGET_PATH} STREQUAL "" AND SMTG_CREATE_PLUGIN_LINK)
if(EXISTS ${PLUGIN_TARGET_PATH})
message(STATUS "[SMTG] SMTG_PLUGIN_TARGET_PATH is set to: " ${PLUGIN_TARGET_PATH})
else()
message(STATUS "[SMTG] SMTG_PLUGIN_TARGET_PATH is not set!")
endif(EXISTS ${PLUGIN_TARGET_PATH})
set(SMTG_PLUGIN_TARGET_PATH ${PLUGIN_TARGET_PATH} PARENT_SCOPE)
endfunction(smtg_get_vst3_path)
#------------------------------------------------------------------------
# Adds a VST3 target.
#
# @param target The target to which a VST3 Plug-in will be added.
# @param pkg_name name of the created package
# @param MODULEINFO_COMPATIBILITY <path> The path to the compatibility json file [optional]
function(smtg_add_vst3plugin_with_pkgname target pkg_name)
#message(STATUS "[SMTG] target is ${target}")
#message(STATUS "[SMTG] pkg_name is ${pkg_name}")
set(oneValueArgs MODULEINFO_COMPATIBILITY)
set(sourcesArgs SOURCES_LIST)
cmake_parse_arguments(PARSE_ARGV 2 PARAMS "" "${oneValueArgs}" "${sourcesArgs}")
#message(STATUS "[SMTG] PARAMS_UNPARSED_ARGUMENTS is ${PARAMS_UNPARSED_ARGUMENTS}")
#message(STATUS "[SMTG] PARAMS_MODULEINFO_COMPATIBILITY is ${PARAMS_MODULEINFO_COMPATIBILITY}")
#message(STATUS "[SMTG] PARAMS_SOURCES_LIST is ${PARAMS_SOURCES_LIST}")
if(NOT EXISTS ${SMTG_PACKAGE_ICON_PATH})
set(SMTG_PACKAGE_ICON_PATH ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../templates/VST_Logo_Steinberg.ico)
endif()
#message(STATUS "[SMTG] SMTG_PACKAGE_ICON_PATH is ${SMTG_PACKAGE_ICON_PATH}")
if(DEFINED PARAMS_SOURCES_LIST)
set(SOURCES "${PARAMS_SOURCES_LIST}")
else()
set(SOURCES "${PARAMS_UNPARSED_ARGUMENTS}")
endif()
add_library(${target} MODULE "${SOURCES}")
smtg_target_set_vst_win_architecture_name(${target})
smtg_target_make_plugin_package(${target} ${pkg_name} vst3)
####################
# Workaround for Xcode 15 not allowing to add adhoc_codesign linker setting
####################
if(SMTG_MAC AND XCODE_VERSION VERSION_GREATER_EQUAL 15)
get_target_property(PLUGIN_PACKAGE_PATH ${target} SMTG_PLUGIN_PACKAGE_PATH)
add_custom_command(
TARGET ${target} POST_BUILD
COMMENT "[SMTG] Adhoc codesign workaround for Xcode 15"
COMMAND codesign --force --verbose --sign -
"${PLUGIN_PACKAGE_PATH}"
)
endif()
if(SMTG_ENABLE_TARGET_VARS_LOG)
smtg_target_dump_plugin_package_variables(${target})
endif(SMTG_ENABLE_TARGET_VARS_LOG)
if(DEFINED PARAMS_MODULEINFO_COMPATIBILITY)
smtg_target_create_module_info_file(${target} MODULEINFO_COMPATIBILITY "${PARAMS_MODULEINFO_COMPATIBILITY}")
else()
smtg_target_create_module_info_file(${target})
endif()
if(SMTG_RUN_VST_VALIDATOR)
smtg_target_run_vst_validator(${target})
endif(SMTG_RUN_VST_VALIDATOR)
if(SMTG_CREATE_PLUGIN_LINK)
smtg_get_vst3_path()
smtg_target_create_link_to_plugin(${target} ${SMTG_PLUGIN_TARGET_PATH})
endif(SMTG_CREATE_PLUGIN_LINK)
endfunction(smtg_add_vst3plugin_with_pkgname)
#------------------------------------------------------------------------
# Adds a VST3 target.
#
# @param target The target to which a VST3 Plug-in will be added.
# @param PACKAGE_NAME <Name> The name of the package [optional] if not present
# @param MODULEINFO_COMPATIBILITY <path> The path to the compatibility json file [optional]
# @param SOURCES_LIST <sources> List of sources to add to target project [mandatory when PACKAGE_NAME is used]
# for example:
# smtg_add_vst3plugin(${target} PACKAGE_NAME "A Gain" SOURCES_LIST ${again_sources})
# smtg_add_vst3plugin(${target} PACKAGE_NAME "A Gain" MODULEINFO_COMPATIBILITY compat.json SOURCES_LIST ${again_sources})
# or
# smtg_add_vst3plugin(${target} ${again_sources})
function(smtg_add_vst3plugin target)
set(oneValueArgs PACKAGE_NAME MODULEINFO_COMPATIBILITY)
set(sourcesArgs SOURCES_LIST)
cmake_parse_arguments(PARSE_ARGV 1 PARAMS "${options}" "${oneValueArgs}" "${sourcesArgs}")
#message(STATUS "[SMTG] PARAMS_UNPARSED_ARGUMENTS is ${PARAMS_UNPARSED_ARGUMENTS}")
#message(STATUS "[SMTG] PARAMS_PACKAGE_NAME is ${PARAMS_PACKAGE_NAME}")
#message(STATUS "[SMTG] PARAMS_SOURCES is ${PARAMS_SOURCES_NAME}")
#message(STATUS "[SMTG] PARAMS_MODULEINFO_COMPATIBILITY is ${PARAMS_MODULEINFO_COMPATIBILITY}")
set(SOURCES "${PARAMS_SOURCES_LIST}")
if(SOURCES STREQUAL "")
set(SOURCES ${PARAMS_UNPARSED_ARGUMENTS})
endif()
set(pkg_name "${PARAMS_PACKAGE_NAME}")
if(pkg_name STREQUAL "")
set(pkg_name ${target})
endif()
#message(STATUS "[SMTG] target is ${target}.")
#message(STATUS "[SMTG] pkg_name is ${pkg_name}.")
#message(STATUS "[SMTG] SOURCES is ${SOURCES}.")
if(DEFINED PARAMS_MODULEINFO_COMPATIBILITY)
set(SMTG_MODULEINFO_COMPATIBILITY "${PARAMS_MODULEINFO_COMPATIBILITY}")
smtg_add_vst3plugin_with_pkgname(${target} ${pkg_name} MODULEINFO_COMPATIBILITY "${SMTG_MODULEINFO_COMPATIBILITY}" SOURCES_LIST ${SOURCES})
else()
smtg_add_vst3plugin_with_pkgname(${target} ${pkg_name} ${SOURCES})
endif()
endfunction(smtg_add_vst3plugin)
#------------------------------------------------------------------------
# Adds a VST3 target for iOS
#
# @param sign_identity which code signing identity to use
# @param target The target to which a VST3 Plug-in will be added.
function(smtg_add_ios_vst3plugin target sign_identity pkg_name)
if(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
add_library(${target} MODULE ${ARGN})
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${SMTG_CODE_SIGN_IDENTITY_IOS}"
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
SMTG_DISABLE_CREATE_RESOURCE_FOLDER 1
)
if(SMTG_IOS_DEVELOPMENT_TEAM)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${SMTG_IOS_DEVELOPMENT_TEAM}
)
endif(SMTG_IOS_DEVELOPMENT_TEAM)
smtg_target_make_plugin_package(${target} ${pkg_name} vst3)
if(SMTG_ENABLE_TARGET_VARS_LOG)
smtg_target_dump_plugin_package_variables(${target})
endif(SMTG_ENABLE_TARGET_VARS_LOG)
smtg_target_set_platform_ios(${target})
get_target_property(PLUGIN_PACKAGE_PATH ${target} SMTG_PLUGIN_PACKAGE_PATH)
add_custom_command(
TARGET ${target} POST_BUILD
COMMENT "[SMTG] Codesign"
COMMAND codesign --force --verbose --sign "${sign_identity}"
"${PLUGIN_PACKAGE_PATH}"
)
endif(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
endfunction(smtg_add_ios_vst3plugin)
#------------------------------------------------------------------------
# Deprecated since 3.7.4 -----------------------------
function(smtg_run_vst_validator target)
message(DEPRECATION "[SMTG] Use smtg_target_run_vst_validator instead of smtg_run_vst_validator")
smtg_target_run_vst_validator (${target})
endfunction(smtg_run_vst_validator)
# Deprecated since 3.7.4 -----------------------------
function(smtg_add_vst3_resource target input_file)
message(DEPRECATION "[SMTG] Use smtg_target_add_plugin_resources instead of smtg_add_vst3_resource")
smtg_target_add_plugin_resources (${target}
RESOURCES
${input_file}
)
endfunction(smtg_add_vst3_resource)
# Deprecated since 3.7.4 -----------------------------
function(smtg_add_vst3_snapshot target snapshot)
message(DEPRECATION "[SMTG] Use smtg_target_add_plugin_snapshots instead of smtg_add_vst3_snapshot")
smtg_target_add_plugin_snapshots (${target}
RESOURCES
${snapshot}
)
endfunction(smtg_add_vst3_snapshot)
@@ -0,0 +1,7 @@
#-------------------------------------------------------------------------------
# Includes
#-------------------------------------------------------------------------------
include(SMTG_SetupVST3LibraryDefaultPath)
include(SMTG_AddCommonOptions)
+170
View File
@@ -0,0 +1,170 @@
include(CMakeParseArguments)
#[=======================================================================[.md:
Configures the macOS bundle
The usual usage is:
```cmake
smtg_target_set_bundle(yourplugin
BUNDLE_IDENTIFIER "com.yourcompany.vst3.yourplugin"
COMPANY_NAME "yourplugin"
)
```
#]=======================================================================]
function(smtg_target_set_bundle target)
if(NOT SMTG_MAC)
return()
endif(NOT SMTG_MAC)
set(options
PREPROCESS
)
set(oneValueArgs
EXTENSION
INFOPLIST
INFOPLIST_IN
BUNDLE_IDENTIFIER
COMPANY_NAME
)
set(multiValueArgs
RESOURCES
PREPROCESSOR_FLAGS
)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "[SMTG] The following parameters are unrecognized: ${ARG_UNPARSED_ARGUMENTS}")
endif(ARG_UNPARSED_ARGUMENTS)
# Adding the bundle resources to the target sources creates a warning, see https://cmake.org/Bug/view.php?id=15272
target_sources(${target}
PRIVATE
${ARG_RESOURCES}
)
get_target_property(type ${target} TYPE)
if(type STREQUAL MODULE_LIBRARY)
set_target_properties(${target}
PROPERTIES
BUNDLE TRUE
)
elseif(type STREQUAL EXECUTABLE)
set_target_properties(${target}
PROPERTIES
MACOSX_BUNDLE TRUE
)
endif()
if(ARG_EXTENSION)
if(XCODE)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_WRAPPER_EXTENSION ${ARG_EXTENSION}
)
else()
set_target_properties(${target}
PROPERTIES
BUNDLE_EXTENSION ${ARG_EXTENSION}
)
endif(XCODE)
endif(ARG_EXTENSION)
if(ARG_RESOURCES)
set_source_files_properties(${ARG_RESOURCES}
PROPERTIES
MACOSX_PACKAGE_LOCATION Resources
)
endif(ARG_RESOURCES)
if(ARG_INFOPLIST AND XCODE)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_INFOPLIST_FILE "${ARG_INFOPLIST}"
)
if(ARG_PREPROCESS)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_INFOPLIST_PREPROCESS "YES"
)
endif(ARG_PREPROCESS)
if(ARG_PREPROCESSOR_FLAGS)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_INFOPLIST_OTHER_PREPROCESSOR_FLAGS "${ARG_PREPROCESSOR_FLAGS}"
)
endif(ARG_PREPROCESSOR_FLAGS)
elseif(XCODE)
# Build Copyright string:
string(TIMESTAMP BUNDLE_INFO_STRING_YEAR "%Y")
set(BUNDLE_COPYRIGHT "© ${BUNDLE_INFO_STRING_YEAR} ${ARG_COMPANY_NAME}.")
# Check for custom info.plist template:
if(ARG_INFOPLIST_IN)
# dest Info.plist.in template file in cmake format
# see: https://duckduckgo.com/?q=MACOSX_BUNDLE_INFO_PLIST
set(SMTG_BUNDLE_INFO_PLIST "${PROJECT_BINARY_DIR}/smtg_mac/Info.plist.in")
# Configure SMTG_BUNDLE_INFO_PLIST to cmake MACOSX_BUNDLE_INFO_PLIST template
# Use @VAR@ for variables not defined in MACOSX_BUNDLE_INFO_PLIST
configure_file("${ARG_INFOPLIST_IN}" "${SMTG_BUNDLE_INFO_PLIST}" @ONLY)
set_target_properties(${smtg_target}
PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${SMTG_BUNDLE_INFO_PLIST}
)
endif()
set_target_properties(${target}
PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER ${ARG_BUNDLE_IDENTIFIER}
MACOSX_BUNDLE_COPYRIGHT ${BUNDLE_COPYRIGHT}
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
MACOSX_BUNDLE_LONG_VERSION_STRING ${PROJECT_VERSION}
MACOSX_BUNDLE_INFO_STRING ${PROJECT_VERSION}
)
endif()
if(ARG_BUNDLE_IDENTIFIER)
if(XCODE)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${ARG_BUNDLE_IDENTIFIER}"
)
endif(XCODE)
endif(ARG_BUNDLE_IDENTIFIER)
endfunction()
#[=======================================================================[.md:
Creates the file projectversion.h and adds the directory as an
include directory.
#]=======================================================================]
function(smtg_target_configure_version_file target)
set(SMTG_PROJECT_VERSION "")
if(NOT "${PROJECT_VERSION_MAJOR}" STREQUAL "")
string(APPEND SMTG_PROJECT_VERSION "${PROJECT_VERSION_MAJOR}")
endif()
if(NOT "${PROJECT_VERSION_MINOR}" STREQUAL "")
string(APPEND SMTG_PROJECT_VERSION ".${PROJECT_VERSION_MINOR}")
endif()
if(NOT "${PROJECT_VERSION_PATCH}" STREQUAL "")
string(APPEND SMTG_PROJECT_VERSION ".${PROJECT_VERSION_PATCH}")
endif()
configure_file(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../templates/projectversion.h.in projectversion.h)
target_include_directories(${target}
PUBLIC
"${PROJECT_BINARY_DIR}"
)
endfunction()
#[=======================================================================[.md:
Deprecated since 3.7.4
#]=======================================================================]
function(smtg_set_bundle target)
message(DEPRECATION "[SMTG] Use smtg_target_set_bundle instead of smtg_set_bundle")
smtg_target_set_bundle (${target})
endfunction()
+86
View File
@@ -0,0 +1,86 @@
if(XCODE)
option(SMTG_DISABLE_CODE_SIGNING "Disable All Code Signing" OFF)
set(SMTG_XCODE_OTHER_CODE_SIGNING_FLAGS "--timestamp" CACHE STRING "Other code signing flags [Xcode]")
option(SMTG_XCODE_MANUAL_CODE_SIGN_STYLE "Manual Xcode sign style" OFF)
endif()
#------------------------------------------------------------------------
function(smtg_target_codesign target)
if(XCODE AND (NOT SMTG_DISABLE_CODE_SIGNING))
if(ARGC GREATER 2)
set(team "${ARGV1}")
set(identity "${ARGV2}")
message(STATUS "[SMTG] Codesign ${target} with team '${team}' and identity '${identity}'")
set(SMTG_CODESIGN_ATTRIBUTES
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${team}"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${identity}"
)
else()
message(STATUS "[SMTG] Codesign ${target} for local machine only")
set(SMTG_CODESIGN_ATTRIBUTES
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-"
)
endif(ARGC GREATER 2)
if(SMTG_XCODE_OTHER_CODE_SIGNING_FLAGS)
set(SMTG_CODESIGN_ATTRIBUTES
${SMTG_CODESIGN_ATTRIBUTES}
XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "${SMTG_XCODE_OTHER_CODE_SIGNING_FLAGS}"
)
endif()
message(DEBUG "[SMTG] Code Sign Attributes: ${SMTG_CODESIGN_ATTRIBUTES}")
set_target_properties(${target}
PROPERTIES
${SMTG_CODESIGN_ATTRIBUTES}
)
if(SMTG_XCODE_MANUAL_CODE_SIGN_STYLE)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Manual"
)
endif(SMTG_XCODE_MANUAL_CODE_SIGN_STYLE)
if(SMTG_MAC AND (XCODE_VERSION VERSION_GREATER_EQUAL 12))
# make sure that the executable is signed before cmake post build commands are run as the
# Xcode code-sign step is run after the post build commands are run which would prevent
# using the target output on system where everything needs to be code-signed.
target_link_options(${target}
PRIVATE
LINKER:-adhoc_codesign
)
endif()
endif(XCODE AND (NOT SMTG_DISABLE_CODE_SIGNING))
endfunction(smtg_target_codesign)
#------------------------------------------------------------------------
function(smtg_target_add_custom_codesign_post_build_step)
if(XCODE AND (NOT SMTG_DISABLE_CODE_SIGNING))
set(mono_args PATH TARGET IDENTITY)
cmake_parse_arguments(PARSE_ARGV 0
PARSED_ARGS # Prefix of output variables e.g. PARSED_ARGS_RESOURCES
"" # List of names for boolean arguments
"${mono_args}" # List of names for mono-valued arguments
"FLAGS" # List of names for multi-valued arguments resp. lists
)
if(NOT PARSED_ARGS_TARGET)
message(FATAL_ERROR "Need TARGET argument")
endif()
if(NOT PARSED_ARGS_PATH)
message(FATAL_ERROR "Need PATH argument")
endif()
if(PARSED_ARGS_IDENTITY)
set(identity "${PARSED_ARGS_IDENTITY}")
else()
set(identity "-")
endif()
add_custom_command(TARGET ${PARSED_ARGS_TARGET} POST_BUILD
COMMAND /usr/bin/codesign -v -s "${identity}" --force ${PARSED_ARGS_FLAGS} "${PARSED_ARGS_PATH}"
)
endif()
endfunction(smtg_target_add_custom_codesign_post_build_step)
#------------------------------------------------------------------------
# Deprecated since 3.7.4 -----------------------------
function(smtg_codesign_target target)
message(DEPRECATION "[SMTG] Use smtg_target_codesign instead of smtg_codesign_target")
smtg_target_codesign (${target})
endfunction(smtg_codesign_target)
@@ -0,0 +1,49 @@
#------------------------------------------------------------------------
# Specify Output directories
#
# XCode is creating the "Debug/Release" folder on its own and does not need to be added.
macro(smtg_specify_output_directories)
if(SMTG_WIN OR (SMTG_MAC AND CMAKE_GENERATOR STREQUAL Xcode))
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
else ()
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}")
endif(SMTG_WIN OR (SMTG_MAC AND CMAKE_GENERATOR STREQUAL Xcode))
endmacro(smtg_specify_output_directories)
#------------------------------------------------------------------------
# Specify build types
#
# Specifies what build types (configurations) will be available.
macro(smtg_specify_build_types)
set(CMAKE_CONFIGURATION_TYPES "Debug;Release")
# This variable is only meaningful to single-configuration generators (such as make and Ninja).
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type")
endmacro(smtg_specify_build_types)
#------------------------------------------------------------------------
# Group predefined cmake projects
#
# Put predefined targets like "ALL_BUILD" and "ZERO_CHECK" into a separate folder within the IDE.
macro(smtg_group_predefined_cmake_projects)
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER Predefined)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
endmacro(smtg_group_predefined_cmake_projects)
#------------------------------------------------------------------------
# Configure CMake generator
macro(smtg_configure_cmake_generator)
smtg_specify_output_directories()
smtg_specify_build_types()
smtg_group_predefined_cmake_projects()
# Generates a compile_commands.json file containing the exact compiler calls.
# (This option is implemented only by Makefile Generators and the Ninja. It
# is ignored on other generators.)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE STRING "Generate compile commands" FORCE)
endmacro(smtg_configure_cmake_generator)
@@ -0,0 +1,82 @@
#------------------------------------------------------------------------
function(smtg_private_setup_audiounit_sdk)
if("${SMTG_AUDIOUNIT_SDK_PATH}" STREQUAL "")
# Check if the AudioUnit SDK is next to the vst3sdk folder:
set(AUDIOUNIT_SDK_PATH ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../../AudioUnitSDK)
if(NOT EXISTS "${AUDIOUNIT_SDK_PATH}/AudioUnitSDK.xcodeproj")
# Check if the AudioUnit SDK is in the vst3sdk folder:
set(AUDIOUNIT_SDK_PATH ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../external.apple.audiounitsdk)
if(NOT EXISTS "${AUDIOUNIT_SDK_PATH}/AudioUnitSDK.xcodeproj")
set(AUDIOUNIT_SDK_PATH "")
endif()
endif()
if(NOT "${AUDIOUNIT_SDK_PATH}" STREQUAL "")
get_filename_component(AUDIOUNIT_SDK_PATH "${AUDIOUNIT_SDK_PATH}" ABSOLUTE)
endif()
set(SMTG_AUDIOUNIT_SDK_PATH "${AUDIOUNIT_SDK_PATH}" CACHE PATH "Path to the AudioUnit SDK" FORCE)
elseif(NOT "${SMTG_AUDIOUNIT_SDK_PATH}" STREQUAL "")
set(AUDIOUNIT_SDK_PATH "${SMTG_AUDIOUNIT_SDK_PATH}")
if(NOT IS_ABSOLUTE ${AUDIOUNIT_SDK_PATH})
get_filename_component(AUDIOUNIT_SDK_PATH "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../${AUDIOUNIT_SDK_PATH}" ABSOLUTE)
endif()
if(NOT EXISTS "${AUDIOUNIT_SDK_PATH}/AudioUnitSDK.xcodeproj")
message(FATAL_ERROR "[SMTG] SMTG_AUDIOUNIT_SDK_PATH is set but does not point to an expected location!")
else()
set(SMTG_AUDIOUNIT_SDK_PATH "${AUDIOUNIT_SDK_PATH}" CACHE PATH "Path to the AudioUnit SDK" FORCE)
endif()
endif()
if(EXISTS "${SMTG_AUDIOUNIT_SDK_PATH}")
message(STATUS "[SMTG] SMTG_AUDIOUNIT_SDK_PATH is set to: " ${SMTG_AUDIOUNIT_SDK_PATH})
option(SMTG_ENABLE_AUV2_BUILDS "Enable AUv2 Builds" ON)
endif()
endfunction(smtg_private_setup_audiounit_sdk)
#------------------------------------------------------------------------
function(smtg_private_setup_coreaudio_sdk)
if("${SMTG_COREAUDIO_SDK_PATH}" STREQUAL "")
# Check if the CoreAudio SDK is next to the vst3sdk folder:
set(COREAUDIO_SDK_PATH ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../../CoreAudio)
if(NOT EXISTS "${COREAUDIO_SDK_PATH}/AudioUnits/AUPublic/AUBase/AUBase.cpp")
# Check if the CoreAudio SDK is in the vst3sdk folder:
set(COREAUDIO_SDK_PATH ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../external.apple.coreaudio)
if(NOT EXISTS "${COREAUDIO_SDK_PATH}/AudioUnits/AUPublic/AUBase/AUBase.cpp")
set(COREAUDIO_SDK_PATH "")
endif()
endif()
if(NOT "${COREAUDIO_SDK_PATH}" STREQUAL "")
get_filename_component(COREAUDIO_SDK_PATH "${COREAUDIO_SDK_PATH}" ABSOLUTE)
endif()
set(SMTG_COREAUDIO_SDK_PATH "${COREAUDIO_SDK_PATH}" CACHE PATH "Here you can define where to find the COREAUDIO SDK" FORCE)
else()
set(COREAUDIO_SDK_PATH "${SMTG_COREAUDIO_SDK_PATH}")
if(NOT IS_ABSOLUTE ${COREAUDIO_SDK_PATH})
get_filename_component(COREAUDIO_SDK_PATH "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../${COREAUDIO_SDK_PATH}" ABSOLUTE)
endif()
if(NOT EXISTS "${COREAUDIO_SDK_PATH}/AudioUnits/AUPublic/AUBase/AUBase.cpp")
message(FATAL_ERROR "[SMTG] SMTG_COREAUDIO_SDK_PATH is set but does not point to an expected location!")
else()
set(SMTG_COREAUDIO_SDK_PATH "${COREAUDIO_SDK_PATH}" CACHE PATH "Here you can define where to find the COREAUDIO SDK" FORCE)
endif()
endif()
if(EXISTS "${SMTG_COREAUDIO_SDK_PATH}")
message(STATUS "[SMTG] SMTG_COREAUDIO_SDK_PATH is set to: " ${SMTG_COREAUDIO_SDK_PATH})
option(SMTG_ENABLE_AUV2_BUILDS "Enable AUv2 Builds" ON)
endif()
endfunction(smtg_private_setup_coreaudio_sdk)
#------------------------------------------------------------------------
function(setupCoreAudioSupport)
if(SMTG_MAC AND XCODE)
set(SMTG_IOS_DEVELOPMENT_TEAM "" CACHE STRING "Needed for building the InterAppAudio and AUv3 examples for iOS")
smtg_private_setup_audiounit_sdk()
if(NOT SMTG_ENABLE_AUV2_BUILDS)
smtg_private_setup_coreaudio_sdk()
endif()
if("${SMTG_AUDIOUNIT_SDK_PATH}" STREQUAL "" AND "${SMTG_COREAUDIO_SDK_PATH}" STREQUAL "")
message(STATUS "[SMTG] Neither SMTG_AUDIOUNIT_SDK_PATH nor SMTG_COREAUDIO_SDK_PATH is set. This is needed to build AudioUnit Version 2 plug-ins.")
endif()
endif()
endfunction(setupCoreAudioSupport)
@@ -0,0 +1,48 @@
# Custom target in order to get all cmake modules into a VST3 project.
add_custom_target(cmake_modules
SOURCES
${CMAKE_CURRENT_LIST_FILE}
${CMAKE_CURRENT_LIST_DIR}/SMTG_AddCommonOptions.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_AddSMTGLibrary.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_AddSubDirectories.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_Bundle.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_CodeSign.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_ConfigureCmakeGenerator.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_DetectPlatform.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_ExportedSymbols.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_GenerateSourceGroups.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_Global.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_PlatformIOS.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_PlatformToolset.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_Platform_Windows.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_PrefixHeader.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_SetDebugExecutable.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_UniversalBinary.cmake
)
if(VST_SDK)
add_custom_target(cmake_VST_modules
SOURCES
${CMAKE_CURRENT_LIST_DIR}/SMTG_AAXSupport.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_AddAAXLibrary.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_AddVST3AuV3.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_AddVST3Library.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_AddVST3Options.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_CoreAudioSupport.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_ExportedSymbols.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_FindJack.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_SetupVST3LibraryDefaultPath.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_VST3_SDK.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_VstGuiSupport.cmake
)
endif(VST_SDK)
if(SKI_SDK)
add_custom_target(cmake_SKI_modules
SOURCES
${CMAKE_CURRENT_LIST_DIR}/SMTG_AddComponentLibrary.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_AddComponentOptions.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_SKI_SDK.cmake
${CMAKE_CURRENT_LIST_DIR}/SMTG_SetupComponentLibraryDefaultPath.cmake
)
endif(SKI_SDK)
@@ -0,0 +1,62 @@
# Detect the platform which cmake builds for.
#
# Needed for check_language(CXX)
include(CheckLanguage)
# The detected platform var is stored within the internal cache of cmake in order to make it
# available globally.
set(SMTG_PLATFORM_DETECTION_COMMENT "The platform which was detected by SMTG")
#------------------------------------------------------------------------
# Detect the Platform
#
macro(smtg_detect_platform)
if(APPLE)
set(SMTG_MAC TRUE CACHE INTERNAL ${SMTG_PLATFORM_DETECTION_COMMENT})
elseif(UNIX OR ANDROID_PLATFORM)
set(SMTG_LINUX TRUE CACHE INTERNAL ${SMTG_PLATFORM_DETECTION_COMMENT})
elseif(WIN32)
set(SMTG_WIN TRUE CACHE INTERNAL ${SMTG_PLATFORM_DETECTION_COMMENT})
endif(APPLE)
endmacro(smtg_detect_platform)
#------------------------------------------------------------------------
# Check if c++ compiler is available
# Handling cmake issue: https://gitlab.kitware.com/cmake/cmake/-/issues/20890
function(smtg_check_language_cxx)
message(STATUS "[SMTG] Check C++ compiler")
check_language(CXX)
if(NOT CMAKE_CXX_COMPILER)
if(SMTG_MAC)
execute_process(COMMAND xcode-select -p OUTPUT_VARIABLE _xcode ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
cmake_path(SET _xcode NORMALIZE "${_xcode}/../..")
string(FIND "${_xcode}" " " _pos)
if(_pos GREATER "-1")
message(FATAL_ERROR "[SMTG] Spaces in Xcode path are not supported by cmake: \"${_xcode}\"" )
endif()
endif()
endif()
endfunction()
#------------------------------------------------------------------------
# Detect the default Xcode Version
#
macro(smtg_detect_xcode_version)
if(SMTG_MAC)
# Check if CXX compiler is available
smtg_check_language_cxx()
if(NOT DEFINED ENV{XCODE_VERSION})
# find out Xcode version if not set by cmake
execute_process(COMMAND xcodebuild -version OUTPUT_VARIABLE XCODE_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX MATCH "Xcode [0-9\\.]+" XCODE_VERSION "${XCODE_VERSION}")
string(REGEX REPLACE "Xcode ([0-9\\.]+)" "\\1" XCODE_VERSION "${XCODE_VERSION}")
endif()
if(XCODE_VERSION VERSION_LESS "9")
message(FATAL_ERROR "[SMTG] XCode 9 or newer is required")
endif()
message(STATUS "[SMTG] Building with Xcode version: ${XCODE_VERSION}")
if(NOT DEFINED ENV{SDKROOT})
execute_process(COMMAND xcrun --sdk macosx --show-sdk-path OUTPUT_VARIABLE CMAKE_OSX_SYSROOT OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
endif(SMTG_MAC)
endmacro(smtg_detect_xcode_version)
@@ -0,0 +1,40 @@
#------------------------------------------------------------------------
# Setup symbol visibility
#
# Puts symbol visibility to default hidden.
macro(smtg_setup_symbol_visibility)
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
endmacro(smtg_setup_symbol_visibility)
#------------------------------------------------------------------------
# Set exported symbols
#
# Specifies the exported symbols by file.
function(smtg_target_set_exported_symbols target exported_symbols_file)
if(MSVC)
set_target_properties(${target}
PROPERTIES
LINK_FLAGS "/DEF:\"${exported_symbols_file}\""
)
elseif(XCODE)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_EXPORTED_SYMBOLS_FILE "${exported_symbols_file}"
)
elseif(NOT MINGW)
set_target_properties(${target}
PROPERTIES
LINK_FLAGS "-exported_symbols_list \"${exported_symbols_file}\""
)
endif(MSVC)
endfunction(smtg_target_set_exported_symbols)
#------------------------------------------------------------------------
# Deprecated since 3.7.4 -----------------------------
function(smtg_set_exported_symbols target exported_symbols_file)
message(DEPRECATION "[SMTG] Use smtg_target_set_exported_symbols instead of smtg_set_exported_symbols")
smtg_target_set_exported_symbols (${target} ${exported_symbols_file})
endfunction(smtg_set_exported_symbols)
+61
View File
@@ -0,0 +1,61 @@
# - Try to find Jack Audio Libraries
# libjack; libjackserver;
# Once done this will define
# LIBJACK_FOUND - System has libjack.so
# LIBJACK_INCLUDE_DIRS - The jack.h include directories
# LIBJACK_LIBRARIES - The libraries needed to use jack
# Install jack on Ubuntu: apt-get install libjack-jackd2-dev
# Add user to audio group: usermod -a -G audio <yourUserName>
# Install jack on Windows: winget install Jackaudio.JACK2
# Install jack on macOS: brew install jack
#------------------------------------------------------------------------
# Uncomment to see all locations/paths which are searched
# set(CMAKE_FIND_DEBUG_MODE TRUE)
if(NOT PROJECT_NAME)
message(FATAL_ERROR "[SMTG] Only include SMTG_FindJack AFTER the root \"project(...)\" call is done!")
endif()
find_path(LIBJACK_INCLUDE_DIR
NAMES
jack/jack.h
PATH_SUFFIXES
JACK2/include
)
find_library(LIBJACK_libjack_LIBRARY
NAMES
libjack64
libjack
jack
PATH_SUFFIXES
JACK2/lib
)
find_library(LIBJACK_libjackserver_LIBRARY
NAMES
libjackserver64
libjackserver
jackserver
PATH_SUFFIXES
JACK2/lib
)
# For debugging
# message(STATUS "LIBJACK_libjackserver_LIBRARY ${LIBJACK_libjackserver_LIBRARY}")
# message(STATUS "LIBJACK_libjack_LIBRARY ${LIBJACK_libjack_LIBRARY}")
# message(STATUS "LIBJACK_INCLUDE_DIR ${LIBJACK_INCLUDE_DIR}")
set(LIBJACK_LIBRARIES ${LIBJACK_libjack_LIBRARY} ${LIBJACK_libjackserver_LIBRARY})
set(LIBJACK_LIBRARY ${LIBJACK_LIBRARIES})
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBJACK_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(LIBJACK DEFAULT_MSG
LIBJACK_LIBRARIES LIBJACK_INCLUDE_DIR)
@@ -0,0 +1,28 @@
#------------------------------------------------------------------------
# Generate Source Groups
#------------------------------------------------------------------------
#------------------------------------------------------------------------
function(smtg_generate_source_groups root)
foreach(source ${ARGN})
set(path ${source})
string(REGEX REPLACE "${root}/" "" path "${path}")
string(REGEX REPLACE "[\\\\/][^\\\\/]*$" "" path "${path}")
string(REGEX REPLACE "^[\\\\/]" "" path "${path}")
string(REGEX REPLACE "\\.\\.[\\\\/]" "" path "${path}")
string(REGEX REPLACE "/" "\\\\\\\\" path "${path}")
source_group(${path} FILES ${source})
endforeach()
endfunction(smtg_generate_source_groups)
#------------------------------------------------------------------------
function(smtg_target_generate_source_groups target)
get_target_property(_source_list ${target} SOURCES)
foreach(_source IN ITEMS ${_source_list})
get_filename_component(_source_path "${_source}" PATH)
string(REPLACE "/" "\\" _source_path_msvc "${_source_path}")
source_group("${_source_path_msvc}" FILES "${_source}")
endforeach()
endfunction(smtg_target_generate_source_groups)
+41
View File
@@ -0,0 +1,41 @@
#------------------------------------------------------------------------
# Includes
#------------------------------------------------------------------------
include(SMTG_DetectPlatform)
include(SMTG_ConfigureCmakeGenerator)
include(SMTG_ExportedSymbols)
# Check for in-source build directory.
#
# In order not to pollute the source directory, using a separate build directory is mandatory.
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR OR EXISTS "${CMAKE_BINARY_DIR}/CMakeLists.txt")
message(SEND_ERROR "[SMTG] In-source builds are not allowed. Please create a separate build directory and run 'cmake /path/to/folder [options]' there.")
message(FATAL_ERROR "[SMTG] You can remove the file \"CMakeCache.txt\" and directory \"CMakeFiles\" in ${CMAKE_SOURCE_DIR}.")
endif()
#------------------------------------------------------------------------
# Global setup functions/macros
#
# Call macros/functions which setup the SDK's basics.
smtg_detect_platform()
smtg_configure_cmake_generator()
smtg_detect_xcode_version()
#------------------------------------------------------------------------
# Enable VST3 SDK
#
# This macro should be called from a 3rd party's plug-in CMakeLists.txt file.
macro(smtg_enable_vst3_sdk)
smtg_configure_cmake_generator()
smtg_setup_platform_toolset()
smtg_setup_symbol_visibility()
# Needs to bet set for 'smtg_add_library_main' function.
if(DEFINED vst3sdk_SOURCE_DIR)
set(public_sdk_SOURCE_DIR ${vst3sdk_SOURCE_DIR}/public.sdk)
else ()
get_target_property(public_sdk_SOURCE_DIR sdk SOURCE_DIR)
set(public_sdk_SOURCE_DIR ${public_sdk_SOURCE_DIR}/public.sdk)
endif()
endmacro(smtg_enable_vst3_sdk)
@@ -0,0 +1,41 @@
#------------------------------------------------------------------------
# Platform
#------------------------------------------------------------------------
#------------------------------------------------------------------------
function(smtg_target_set_platform_ios target)
if(NOT SMTG_MAC)
message(FATAL_ERROR "[SMTG] smtg_target_set_platform_ios only works on macOS, use it in an if(SMTG_MAC) block")
endif(NOT SMTG_MAC)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "12.0"
XCODE_ATTRIBUTE_SDKROOT "iphoneos"
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
XCODE_ATTRIBUTE_SUPPORTS_MACCATALYST "NO"
)
endfunction(smtg_target_set_platform_ios)
#------------------------------------------------------------------------
# Deprecated since 3.7.4 -----------------------------
function(smtg_set_platform_ios target)
message(DEPRECATION "[SMTG] Use smtg_target_set_platform_ios instead of smtg_set_platform_ios")
smtg_target_set_platform_ios (${target})
endfunction(smtg_set_platform_ios)
#------------------------------------------------------------------------
function(smtg_create_ios_target_from_target target)
set(ios_target ${target}_ios)
get_target_property(SOURCES_OF_TARGET ${target} SOURCES)
add_library(${ios_target}
STATIC
${SOURCES_OF_TARGET}
)
smtg_target_set_platform_ios(${ios_target})
target_compile_features(${ios_target}
PUBLIC
cxx_std_17
)
endfunction()
@@ -0,0 +1,123 @@
if(SMTG_WIN)
option(SMTG_USE_STATIC_CRT "use static CRuntime on Windows (option /MT)" OFF)
endif(SMTG_WIN)
#------------------------------------------------------------------------
# setup the platform toolset (compiler options)
macro(smtg_setup_platform_toolset)
# deprecated
if(SMTG_RENAME_ASSERT)
add_compile_options(-DSMTG_RENAME_ASSERT=1)
endif()
# Add colors to clang output when using Ninja
# See: https://github.com/ninja-build/ninja/wiki/FAQ
if(UNIX AND CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_GENERATOR STREQUAL "Ninja")
add_compile_options(-fcolor-diagnostics)
endif()
#------------
option(SMTG_ENABLE_ADDRESS_SANITIZER "Enable Address Sanitizer" OFF)
if(SMTG_LINUX)
if(SMTG_ENABLE_ADDRESS_SANITIZER)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES};ASan")
add_compile_options($<$<CONFIG:ASan>:-DDEVELOPMENT=1>)
add_compile_options($<$<CONFIG:ASan>:-fsanitize=address>)
add_compile_options($<$<CONFIG:ASan>:-DVSTGUI_LIVE_EDITING=1>)
add_compile_options($<$<CONFIG:ASan>:-g>)
add_compile_options($<$<CONFIG:ASan>:-O0>)
set(ASAN_LIBRARY asan)
link_libraries($<$<CONFIG:ASan>:${ASAN_LIBRARY}>)
endif()
set(common_linker_flags "-Wl,--no-undefined")
set(CMAKE_MODULE_LINKER_FLAGS "${common_linker_flags}" CACHE STRING "Module Library Linker Flags")
set(CMAKE_SHARED_LINKER_FLAGS "${common_linker_flags}" CACHE STRING "Shared Library Linker Flags")
endif(SMTG_LINUX)
#------------
if(UNIX)
if(XCODE)
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
add_compile_options(-Winconsistent-missing-override) # Suggest override when missing
add_compile_options(-Werror=return-type)
add_compile_options(-ffast-math -ffp-contract=fast)
if(SMTG_ENABLE_ADDRESS_SANITIZER)
set(CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER ON)
set(CMAKE_XCODE_GENERATE_SCHEME ON)
endif(SMTG_ENABLE_ADDRESS_SANITIZER)
else()
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wsuggest-override) # Suggest override when missing
endif()
if(SMTG_MAC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-multichar")
if(ANDROID)
set(CMAKE_ANDROID_STL_TYPE c++_static)
link_libraries(dl)
else()
link_libraries(stdc++fs pthread dl)
endif(ANDROID)
endif(SMTG_MAC)
endif(XCODE)
#------------
elseif(SMTG_WIN)
if(MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-multichar")
set(common_linker_flags "-Wl,--no-undefined")
set(CMAKE_MODULE_LINKER_FLAGS "${common_linker_flags}" CACHE STRING "Module Library Linker Flags")
set(CMAKE_SHARED_LINKER_FLAGS "${common_linker_flags}" CACHE STRING "Shared Library Linker Flags")
else()
add_definitions(-D_UNICODE)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) # Eliminate deprecation warnings for less secure functions (strcpy...)
add_compile_options(/W3) # Baseline reasonable warnings
add_compile_options(/Zc:__cplusplus) # __cplusplus should denote the c++ standard
add_compile_options(/fp:fast) # Floating Point Model
add_compile_options($<$<CONFIG:Release>:/Oi>) # Enable Intrinsic Functions (Yes)
add_compile_options($<$<CONFIG:Release>:/Ot>) # Favor Size Or Speed (Favor fast code)
add_compile_options($<$<CONFIG:Release>:/GF>) # Enable String Pooling
add_compile_options($<$<CONFIG:Release>:/EHa>) # Enable C++ Exceptions
add_compile_options($<$<CONFIG:Release>:/Oy>) # Omit Frame Pointers
#add_compile_options($<$<CONFIG:Release>:/Ox>) # Optimization (/O2: Maximise Speed /0x: Full Optimization)
add_compile_options(/MP) # Multi-processor Compilation
add_compile_options(/wd6031) # Return value ignored
add_compile_options(/wd6308) # Realloc may return null pointer
add_compile_options(/wd6330) # Incorrect type passed as parameter in call to function
add_compile_options(/wd6385) # Invalid data
add_compile_options(/wd6386) # Buffer overrun
add_compile_options(/wd28125) # The function must be called from within a try/except block
add_compile_options(/wd28251) # Inconsistent annotation for function
#add_definitions("/analyze") # Enable Code Analyze
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
if(DEFINED CMAKE_GENERATOR_PLATFORM AND CMAKE_GENERATOR_PLATFORM)
string(TOLOWER ${CMAKE_GENERATOR_PLATFORM} GENERATOR_PLATFORM)
endif()
if(${GENERATOR_PLATFORM} MATCHES "arm*")
add_compile_options($<$<CONFIG:Debug>:/Zi>) # Program Database
add_compile_options($<$<CONFIG:Debug>:/EHsc>) # Enable C++ Exceptions
add_compile_options(/wd4103) # Alignment changed after including header
else()
if(SMTG_ENABLE_ADDRESS_SANITIZER)
add_compile_options($<$<CONFIG:Debug>:/fsanitize=address>) # Enable Address Sanitizer
add_link_options($<$<CONFIG:Debug>:/INCREMENTAL:NO>) # Enable Incremental Linking
else()
add_compile_options($<$<CONFIG:Debug>:/ZI>) # Program Database for Edit And Continue
endif()
endif()
if(SMTG_USE_STATIC_CRT)
add_compile_options($<$<CONFIG:Debug>:/MTd>) # Runtime Library: /MTd = MultiThreaded Debug Runtime
add_compile_options($<$<CONFIG:Release>:/MT>) # Runtime Library: /MT = MultiThreaded Runtime
else()
add_compile_options($<$<CONFIG:Debug>:/MDd>) # Runtime Library: /MDd = MultiThreadedDLL Debug Runtime
add_compile_options($<$<CONFIG:Release>:/MD>) # Runtime Library: /MD = MultiThreadedDLL Runtime
endif(SMTG_USE_STATIC_CRT)
endif(MINGW)
endif(UNIX)
endmacro(smtg_setup_platform_toolset)
@@ -0,0 +1,34 @@
#------------------------------------------------------------------------
# Create a given Directory with Admin permission on Windows
function(smtg_create_directory_as_admin_win directory_name)
if(NOT SMTG_WIN)
message(FATAL_ERROR "[SMTG] smtg_create_directory_as_admin only works on Windows, use it in an if(SMTG_WIN) block")
endif()
if(EXISTS ${directory_name})
return()
endif()
set(TMPDIR "$ENV{TEMP}")
if(NOT EXISTS ${TMPDIR})
set(TMPDIR "$ENV{TMPDIR}")
endif()
message(STATUS "[SMTG] TMPDIR is set to: " ${TMPDIR})
if(NOT EXISTS ${TMPDIR})
message(FATAL_ERROR "[SMTG] smtg_create_directory_as_admin does find TEMP Folder!")
endif()
# create the bat creating the Directory
set(TMPFILE ${TMPDIR}\\smtg_mkdir_windows_as_admin.bat)
file(WRITE ${TMPFILE} "md \"${directory_name}\"")
execute_process(
COMMAND
msg * /time:60 /w VST 3 SDK: In order to create the subDirectory:\n\"${directory_name}\"\nyou will need to provide Administrator permission!
)
# execute with powershell the bat file
set(RUNAS "-Verb runAs")
execute_process(
COMMAND
powershell.exe Start-Process ${TMPFILE} ${RUNAS}
)
endfunction(smtg_create_directory_as_admin_win)
@@ -0,0 +1,21 @@
#------------------------------------------------------------------------
# Prefix Header
#------------------------------------------------------------------------
#------------------------------------------------------------------------
function(smtg_target_set_prefix_header target header precompile)
if(MSVC)
elseif(XCODE)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${header}"
XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "${precompile}"
)
else()
target_compile_options(${target}
PRIVATE
-include "${header}"
)
endif(MSVC)
endfunction(smtg_target_set_prefix_header)
@@ -0,0 +1,37 @@
#------------------------------------------------------------------------
function(smtg_target_set_debug_executable target executable)
if(CMAKE_GENERATOR STREQUAL Xcode)
set_target_properties(${target}
PROPERTIES
XCODE_GENERATE_SCHEME YES
XCODE_SCHEME_EXECUTABLE "${executable}"
)
if(ARGC GREATER 2 AND ARGV2)
set_target_properties(${target}
PROPERTIES
XCODE_SCHEME_ARGUMENTS "${ARGV2}"
)
endif()
endif()
if(MSVC)
set_target_properties(${target}
PROPERTIES
VS_DEBUGGER_COMMAND "${executable}"
)
if(ARGC GREATER 2 AND ARGV2)
set_target_properties(${target}
PROPERTIES
VS_DEBUGGER_COMMAND_ARGUMENTS "${ARGV2}"
)
endif()
endif(MSVC)
endfunction(smtg_target_set_debug_executable)
#------------------------------------------------------------------------
# Deprecated since 3.7.4 -----------------------------
function(smtg_set_debug_executable target executable)
message(DEPRECATION "[SMTG] Use smtg_target_set_debug_executable instead of smtg_set_debug_executable")
smtg_target_set_debug_executable (${target} ${executable})
endfunction(smtg_set_debug_executable)
@@ -0,0 +1,50 @@
if(SMTG_WIN)
option(SMTG_PLUGIN_TARGET_USER_PROGRAM_FILES_COMMON "use FOLDERID_UserProgramFilesCommon as VST3 target path" ON)
endif(SMTG_WIN)
#------------------------------------------------------------------------
# VST3 Folder (following the specification)
function(smtg_get_default_vst3_path)
if(SMTG_WIN)
set(win64Found "1")
if(NOT ${CMAKE_GENERATOR_PLATFORM} STREQUAL "")
string(FIND ${CMAKE_GENERATOR_PLATFORM} x64 win64Found)
if(${win64Found} EQUAL -1)
string(FIND ${CMAKE_GENERATOR_PLATFORM} ARM64 win64Found)
endif()
elseif(${CMAKE_GENERATOR} STREQUAL "Visual Studio 15 2017" OR
${CMAKE_GENERATOR} STREQUAL "Visual Studio 14 2015" OR
${CMAKE_GENERATOR} STREQUAL "Visual Studio 12 2013" OR
${CMAKE_GENERATOR} STREQUAL "Visual Studio 11 2012" OR
${CMAKE_GENERATOR} STREQUAL "Visual Studio 10 2010" OR
${CMAKE_GENERATOR} STREQUAL "Visual Studio 9 2008")
set(win64Found "-1")
else()
string(FIND ${CMAKE_GENERATOR} Win32 win32Found)
if(NOT ${win32Found} EQUAL -1)
set(win64Found "-1")
endif()
endif()
if(${win64Found} EQUAL -1) # for 32bits OS
if(EXISTS "$ENV{PROGRAMFILES} (x86)")
set(SMTG_PLUGIN_TARGET_DEFAULT_PATH "$ENV{PROGRAMFILES} (x86)\\Common Files\\VST3" PARENT_SCOPE)
else()
set(SMTG_PLUGIN_TARGET_DEFAULT_PATH "$ENV{PROGRAMFILES}\\Common Files\\VST3" PARENT_SCOPE)
endif()
else() # for 64bits OS
#FOLDERID_UserProgramFilesCommon
if(SMTG_PLUGIN_TARGET_USER_PROGRAM_FILES_COMMON)
set(SMTG_PLUGIN_TARGET_DEFAULT_PATH "$ENV{LOCALAPPDATA}\\Programs\\Common\\VST3" PARENT_SCOPE)
else()
set(SMTG_PLUGIN_TARGET_DEFAULT_PATH "$ENV{CommonProgramW6432}\\VST3" PARENT_SCOPE)
endif(SMTG_PLUGIN_TARGET_USER_PROGRAM_FILES_COMMON)
endif()
elseif(SMTG_MAC)
set(SMTG_PLUGIN_TARGET_DEFAULT_PATH "$ENV{HOME}/Library/Audio/Plug-Ins/VST3" PARENT_SCOPE)
elseif(SMTG_LINUX)
set(SMTG_PLUGIN_TARGET_DEFAULT_PATH "$ENV{HOME}/.vst3" PARENT_SCOPE)
else()
message(FATAL_ERROR "[SMTG] unknown platform")
endif(SMTG_WIN)
endfunction(smtg_get_default_vst3_path)
@@ -0,0 +1,45 @@
if(SMTG_MAC)
if(XCODE_VERSION VERSION_GREATER_EQUAL 12)
option(SMTG_BUILD_UNIVERSAL_BINARY "Build universal binary (x86_64 & arm64)" ON)
elseif(XCODE_VERSION VERSION_LESS 10)
option(SMTG_BUILD_UNIVERSAL_BINARY "Build universal binary (32 & 64 bit)" OFF)
else()
# Xcode 10 and 11 can only build x86_64 for macOS
set(SMTG_BUILD_UNIVERSAL_BINARY 0)
endif()
endif(SMTG_MAC)
#------------------------------------------------------------------------
# smtg_target_setup_universal_binary
#------------------------------------------------------------------------
function(smtg_target_setup_universal_binary target)
if(SMTG_MAC)
if(SMTG_BUILD_UNIVERSAL_BINARY)
if(XCODE_VERSION VERSION_GREATER_EQUAL 12)
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_OSX_ARCHITECTURES "x86_64;arm64;arm64e"
XCODE_ATTRIBUTE_ARCHS "$(ARCHS_STANDARD_64_BIT)"
)
else()
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_OSX_ARCHITECTURES "x86_64;i386"
XCODE_ATTRIBUTE_ARCHS "$(ARCHS_STANDARD_32_64_BIT)"
)
endif()
set_target_properties(${target}
PROPERTIES
XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "$<$<CONFIG:Debug>:YES>$<$<CONFIG:Release>:NO>"
)
endif(SMTG_BUILD_UNIVERSAL_BINARY)
endif(SMTG_MAC)
endfunction(smtg_target_setup_universal_binary)
#------------------------------------------------------------------------
# Deprecated since 3.7.4 -----------------------------
function(smtg_setup_universal_binary target)
message(DEPRECATION "[SMTG] Use smtg_target_setup_universal_binary instead of smtg_setup_universal_binary")
smtg_target_setup_universal_binary (${target})
endfunction(smtg_setup_universal_binary)
+394
View File
@@ -0,0 +1,394 @@
#------------------------------------------------------------------------
# Includes
#------------------------------------------------------------------------
include(SMTG_Global)
include(SMTG_AddVST3Library)
include(SMTG_Bundle)
include(SMTG_ExportedSymbols)
include(SMTG_PrefixHeader)
include(SMTG_PlatformIOS)
include(SMTG_PlatformToolset)
include(SMTG_CoreAudioSupport)
include(SMTG_AAXSupport)
include(SMTG_VstGuiSupport)
include(SMTG_UniversalBinary)
include(SMTG_AddVST3Options)
#------------------------------------------------------------------------
function(smtg_create_lib_base_target)
add_library(base
STATIC
${SDK_ROOT}/base/source/baseiids.cpp
${SDK_ROOT}/base/source/classfactoryhelpers.h
${SDK_ROOT}/base/source/fbuffer.cpp
${SDK_ROOT}/base/source/fbuffer.h
${SDK_ROOT}/base/source/fcleanup.h
${SDK_ROOT}/base/source/fcommandline.h
${SDK_ROOT}/base/source/fdebug.cpp
${SDK_ROOT}/base/source/fdebug.h
${SDK_ROOT}/base/source/fdynlib.cpp
${SDK_ROOT}/base/source/fdynlib.h
${SDK_ROOT}/base/source/fobject.cpp
${SDK_ROOT}/base/source/fobject.h
${SDK_ROOT}/base/source/fstreamer.cpp
${SDK_ROOT}/base/source/fstreamer.h
${SDK_ROOT}/base/source/fstring.cpp
${SDK_ROOT}/base/source/fstring.h
${SDK_ROOT}/base/source/timer.cpp
${SDK_ROOT}/base/source/timer.h
${SDK_ROOT}/base/source/updatehandler.cpp
${SDK_ROOT}/base/source/updatehandler.h
${SDK_ROOT}/base/thread/include/fcondition.h
${SDK_ROOT}/base/thread/include/flock.h
${SDK_ROOT}/base/thread/source/fcondition.cpp
${SDK_ROOT}/base/thread/source/flock.cpp
)
target_include_directories(base
PUBLIC
${SDK_ROOT}
)
# Compiler switches are PUBLIC and will be populated.
target_compile_options(base
PUBLIC
"$<$<CONFIG:Debug>:-DDEVELOPMENT=1>"
"$<$<CONFIG:Release>:-DRELEASE=1>"
"$<$<CONFIG:RelWithDebInfo>:-DRELEASE=1>"
)
target_compile_features(base
PUBLIC
cxx_std_17
)
if(MSVC)
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /IGNORE:4221")
endif(MSVC)
smtg_target_setup_universal_binary(base)
# iOS target
if(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
smtg_create_ios_target_from_target(base)
set_target_properties(base_ios
PROPERTIES
${SDK_IDE_LIBS_FOLDER}
)
# Compiler switches are PUBLIC and will be populated.
target_compile_options(base_ios
PUBLIC
"$<$<CONFIG:Debug>:-DDEVELOPMENT=1>"
"$<$<CONFIG:Release>:-DRELEASE=1>"
"$<$<CONFIG:RelWithDebInfo>:-DRELEASE=1>"
)
endif(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
endfunction()
#------------------------------------------------------------------------
function(smtg_create_pluginterfaces_target)
add_library(pluginterfaces
STATIC
${SDK_ROOT}/pluginterfaces/base/conststringtable.cpp
${SDK_ROOT}/pluginterfaces/base/conststringtable.h
${SDK_ROOT}/pluginterfaces/base/coreiids.cpp
${SDK_ROOT}/pluginterfaces/base/falignpop.h
${SDK_ROOT}/pluginterfaces/base/falignpush.h
${SDK_ROOT}/pluginterfaces/base/fplatform.h
${SDK_ROOT}/pluginterfaces/base/fstrdefs.h
${SDK_ROOT}/pluginterfaces/base/ftypes.h
${SDK_ROOT}/pluginterfaces/base/funknown.cpp
${SDK_ROOT}/pluginterfaces/base/funknown.h
${SDK_ROOT}/pluginterfaces/base/funknownimpl.h
${SDK_ROOT}/pluginterfaces/base/futils.h
${SDK_ROOT}/pluginterfaces/base/fvariant.h
${SDK_ROOT}/pluginterfaces/base/geoconstants.h
${SDK_ROOT}/pluginterfaces/base/ibstream.h
${SDK_ROOT}/pluginterfaces/base/icloneable.h
${SDK_ROOT}/pluginterfaces/base/ierrorcontext.h
${SDK_ROOT}/pluginterfaces/base/ipersistent.h
${SDK_ROOT}/pluginterfaces/base/ipluginbase.h
${SDK_ROOT}/pluginterfaces/base/istringresult.h
${SDK_ROOT}/pluginterfaces/base/iupdatehandler.h
${SDK_ROOT}/pluginterfaces/base/keycodes.h
${SDK_ROOT}/pluginterfaces/base/pluginbasefwd.h
${SDK_ROOT}/pluginterfaces/base/smartpointer.h
${SDK_ROOT}/pluginterfaces/base/typesizecheck.h
${SDK_ROOT}/pluginterfaces/base/ucolorspec.h
${SDK_ROOT}/pluginterfaces/base/ustring.cpp
${SDK_ROOT}/pluginterfaces/base/ustring.h
${SDK_ROOT}/pluginterfaces/gui/iplugview.h
${SDK_ROOT}/pluginterfaces/gui/iplugviewcontentscalesupport.h
${SDK_ROOT}/pluginterfaces/vst/ivstattributes.h
${SDK_ROOT}/pluginterfaces/vst/ivstaudioprocessor.h
${SDK_ROOT}/pluginterfaces/vst/ivstautomationstate.h
${SDK_ROOT}/pluginterfaces/vst/ivstchannelcontextinfo.h
${SDK_ROOT}/pluginterfaces/vst/ivstcomponent.h
${SDK_ROOT}/pluginterfaces/vst/ivstcontextmenu.h
${SDK_ROOT}/pluginterfaces/vst/ivsteditcontroller.h
${SDK_ROOT}/pluginterfaces/vst/ivstevents.h
${SDK_ROOT}/pluginterfaces/vst/ivstdataexchange.h
${SDK_ROOT}/pluginterfaces/vst/ivsthostapplication.h
${SDK_ROOT}/pluginterfaces/vst/ivstinterappaudio.h
${SDK_ROOT}/pluginterfaces/vst/ivstmessage.h
${SDK_ROOT}/pluginterfaces/vst/ivstmidicontrollers.h
${SDK_ROOT}/pluginterfaces/vst/ivstmidilearn.h
${SDK_ROOT}/pluginterfaces/vst/ivstnoteexpression.h
${SDK_ROOT}/pluginterfaces/vst/ivstparameterchanges.h
${SDK_ROOT}/pluginterfaces/vst/ivstparameterfunctionname.h
${SDK_ROOT}/pluginterfaces/vst/ivstphysicalui.h
${SDK_ROOT}/pluginterfaces/vst/ivstpluginterfacesupport.h
${SDK_ROOT}/pluginterfaces/vst/ivstplugview.h
${SDK_ROOT}/pluginterfaces/vst/ivstprefetchablesupport.h
${SDK_ROOT}/pluginterfaces/vst/ivstprocesscontext.h
${SDK_ROOT}/pluginterfaces/vst/ivstremapparamid.h
${SDK_ROOT}/pluginterfaces/vst/ivstrepresentation.h
${SDK_ROOT}/pluginterfaces/vst/ivstunits.h
${SDK_ROOT}/pluginterfaces/vst/vstpresetkeys.h
${SDK_ROOT}/pluginterfaces/vst/vstpshpack4.h
${SDK_ROOT}/pluginterfaces/vst/vstspeaker.h
${SDK_ROOT}/pluginterfaces/vst/vsttypes.h
)
# check for C11 atomic header
include(CheckSourceCompiles)
set(SMTG_CHECK_STDATOMIC_H_SRC
"#include <stdatomic.h>
int main () {
atomic_int_least32_t value = 0;
atomic_fetch_add (&value, 1);
return 0;
}"
)
#set(CMAKE_REQUIRED_QUIET 1)
check_source_compiles(CXX "${SMTG_CHECK_STDATOMIC_H_SRC}" SMTG_USE_STDATOMIC_H)
if(SMTG_USE_STDATOMIC_H)
target_compile_definitions(pluginterfaces
PRIVATE
"SMTG_USE_STDATOMIC_H=${SMTG_USE_STDATOMIC_H}"
)
endif(SMTG_USE_STDATOMIC_H)
target_include_directories(pluginterfaces
PUBLIC
${SDK_ROOT}
)
target_compile_features(pluginterfaces
PUBLIC
cxx_std_17
)
smtg_target_setup_universal_binary(pluginterfaces)
# iOS target
if(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
smtg_create_ios_target_from_target(pluginterfaces)
set_target_properties(pluginterfaces_ios
PROPERTIES
${SDK_IDE_LIBS_FOLDER}
)
endif()
endfunction()
#------------------------------------------------------------------------
function(smtg_create_public_sdk_common_target)
add_library(sdk_common
STATIC
${SDK_ROOT}/public.sdk/source/common/commoniids.cpp
${SDK_ROOT}/public.sdk/source/common/commonstringconvert.cpp
${SDK_ROOT}/public.sdk/source/common/commonstringconvert.h
${SDK_ROOT}/public.sdk/source/common/openurl.cpp
${SDK_ROOT}/public.sdk/source/common/openurl.h
${SDK_ROOT}/public.sdk/source/common/systemclipboard.h
${SDK_ROOT}/public.sdk/source/common/systemclipboard_linux.cpp
${SDK_ROOT}/public.sdk/source/common/systemclipboard_win32.cpp
${SDK_ROOT}/public.sdk/source/common/threadchecker.h
${SDK_ROOT}/public.sdk/source/common/threadchecker_linux.cpp
${SDK_ROOT}/public.sdk/source/common/threadchecker_win32.cpp
${SDK_ROOT}/public.sdk/source/common/readfile.cpp
${SDK_ROOT}/public.sdk/source/common/readfile.h
${SDK_ROOT}/public.sdk/source/vst/vstpresetfile.cpp
${SDK_ROOT}/public.sdk/source/vst/vstpresetfile.h
)
if(SMTG_MAC)
target_sources(sdk_common
PRIVATE
${SDK_ROOT}/public.sdk/source/common/threadchecker_mac.mm
${SDK_ROOT}/public.sdk/source/common/systemclipboard_mac.mm
)
endif(SMTG_MAC)
# add dependencies
target_link_libraries(sdk_common
PUBLIC
base
pluginterfaces
)
target_include_directories(sdk_common
PUBLIC
${SDK_ROOT}
)
smtg_target_setup_universal_binary(sdk_common)
if(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
smtg_create_ios_target_from_target(sdk_common)
set_target_properties(sdk_common_ios
PROPERTIES
${SDK_IDE_LIBS_FOLDER}
)
target_link_libraries(sdk_common_ios
PUBLIC
base_ios
pluginterfaces_ios
)
endif()
endfunction()
#------------------------------------------------------------------------
function(smtg_create_public_sdk_target)
add_library(sdk
STATIC
${SDK_ROOT}/public.sdk/source/common/pluginview.cpp
${SDK_ROOT}/public.sdk/source/common/pluginview.h
${SDK_ROOT}/public.sdk/source/main/pluginfactory.cpp
${SDK_ROOT}/public.sdk/source/main/pluginfactory.h
${SDK_ROOT}/public.sdk/source/main/pluginfactory_constexpr.h
${SDK_ROOT}/public.sdk/source/main/moduleinit.cpp
${SDK_ROOT}/public.sdk/source/main/moduleinit.h
${SDK_ROOT}/public.sdk/source/vst/utility/alignedalloc.h
${SDK_ROOT}/public.sdk/source/vst/utility/audiobuffers.h
${SDK_ROOT}/public.sdk/source/vst/utility/dataexchange.cpp
${SDK_ROOT}/public.sdk/source/vst/utility/dataexchange.h
${SDK_ROOT}/public.sdk/source/vst/utility/memoryibstream.h
${SDK_ROOT}/public.sdk/source/vst/utility/processcontextrequirements.h
${SDK_ROOT}/public.sdk/source/vst/utility/processdataslicer.h
${SDK_ROOT}/public.sdk/source/vst/utility/ringbuffer.h
${SDK_ROOT}/public.sdk/source/vst/utility/rttransfer.h
${SDK_ROOT}/public.sdk/source/vst/utility/sampleaccurate.h
${SDK_ROOT}/public.sdk/source/vst/utility/stringconvert.cpp
${SDK_ROOT}/public.sdk/source/vst/utility/stringconvert.h
${SDK_ROOT}/public.sdk/source/vst/utility/systemtime.h
${SDK_ROOT}/public.sdk/source/vst/utility/systemtime.cpp
${SDK_ROOT}/public.sdk/source/vst/utility/testing.cpp
${SDK_ROOT}/public.sdk/source/vst/utility/testing.h
${SDK_ROOT}/public.sdk/source/vst/utility/vst2persistence.h
${SDK_ROOT}/public.sdk/source/vst/utility/vst2persistence.cpp
${SDK_ROOT}/public.sdk/source/vst/vstaudioeffect.cpp
${SDK_ROOT}/public.sdk/source/vst/vstaudioeffect.h
${SDK_ROOT}/public.sdk/source/vst/vstbus.cpp
${SDK_ROOT}/public.sdk/source/vst/vstbus.h
${SDK_ROOT}/public.sdk/source/vst/vstbypassprocessor.h
${SDK_ROOT}/public.sdk/source/vst/vstcomponent.cpp
${SDK_ROOT}/public.sdk/source/vst/vstcomponent.h
${SDK_ROOT}/public.sdk/source/vst/vstcomponentbase.cpp
${SDK_ROOT}/public.sdk/source/vst/vstcomponentbase.h
${SDK_ROOT}/public.sdk/source/vst/vsteditcontroller.cpp
${SDK_ROOT}/public.sdk/source/vst/vsteditcontroller.h
${SDK_ROOT}/public.sdk/source/vst/vsteventshelper.h
${SDK_ROOT}/public.sdk/source/vst/vsthelpers.h
${SDK_ROOT}/public.sdk/source/vst/vstinitiids.cpp
${SDK_ROOT}/public.sdk/source/vst/vstnoteexpressiontypes.cpp
${SDK_ROOT}/public.sdk/source/vst/vstnoteexpressiontypes.h
${SDK_ROOT}/public.sdk/source/vst/vstparameters.cpp
${SDK_ROOT}/public.sdk/source/vst/vstparameters.h
${SDK_ROOT}/public.sdk/source/vst/vstrepresentation.cpp
${SDK_ROOT}/public.sdk/source/vst/vstrepresentation.h
)
target_compile_features(sdk
PUBLIC
cxx_std_17
)
# add dependencies
target_link_libraries(sdk
PUBLIC
sdk_common
)
target_include_directories(sdk
PUBLIC
${SDK_ROOT}
)
smtg_target_setup_universal_binary(sdk)
get_target_property(sdk_SOURCES sdk SOURCES)
# iOS target
if(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
smtg_create_ios_target_from_target(sdk)
set_target_properties(sdk_ios
PROPERTIES
${SDK_IDE_LIBS_FOLDER}
)
target_link_libraries(sdk_ios
PUBLIC
sdk_common_ios
)
endif(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
endfunction()
#------------------------------------------------------------------------
function(smtg_create_public_sdk_hosting_target)
add_library(sdk_hosting
STATIC
${SDK_ROOT}/public.sdk/source/vst/hosting/connectionproxy.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/connectionproxy.h
${SDK_ROOT}/public.sdk/source/vst/hosting/eventlist.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/eventlist.h
${SDK_ROOT}/public.sdk/source/vst/hosting/hostclasses.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/hostclasses.h
${SDK_ROOT}/public.sdk/source/vst/hosting/module.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/module.h
${SDK_ROOT}/public.sdk/source/vst/hosting/parameterchanges.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/parameterchanges.h
${SDK_ROOT}/public.sdk/source/vst/hosting/pluginterfacesupport.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/pluginterfacesupport.h
${SDK_ROOT}/public.sdk/source/vst/hosting/processdata.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/processdata.h
${SDK_ROOT}/public.sdk/source/vst/utility/optional.h
${SDK_ROOT}/public.sdk/source/vst/utility/stringconvert.cpp
${SDK_ROOT}/public.sdk/source/vst/utility/stringconvert.h
${SDK_ROOT}/public.sdk/source/vst/utility/uid.h
${SDK_ROOT}/public.sdk/source/vst/utility/versionparser.h
${SDK_ROOT}/public.sdk/source/vst/vstinitiids.cpp
)
# add dependencies
target_link_libraries(sdk_hosting
PUBLIC
sdk_common
)
target_include_directories(sdk_hosting
PUBLIC
${SDK_ROOT}
)
smtg_target_setup_universal_binary(sdk_hosting)
# iOS target for hosting
if(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
smtg_create_ios_target_from_target(sdk_hosting)
set_target_properties(sdk_hosting_ios
PROPERTIES
${SDK_IDE_LIBS_FOLDER}
)
target_link_libraries(sdk_hosting_ios
PUBLIC
sdk_common_ios
)
target_include_directories(sdk_hosting_ios
PUBLIC
${SDK_ROOT}
)
endif(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
endfunction()
@@ -0,0 +1,127 @@
#------------------------------------------------------------------------
macro(smtg_add_vstgui_subdirectory vstgui_SOURCE_DIR)
set(VSTGUI_DISABLE_UNITTESTS 1)
set(VSTGUI_STANDALONE_EXAMPLES OFF)
set(VSTGUI_STANDALONE ON)
set(VSTGUI_TOOLS OFF)
add_subdirectory(${vstgui_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/VSTGUI.build)
endmacro()
macro(smtg_target_setup_vstgui_deprecated_methods target)
if(VSTGUI_ENABLE_DEPRECATED_METHODS)
target_compile_definitions(${target}
PUBLIC
VSTGUI_ENABLE_DEPRECATED_METHODS=1
)
else()
target_compile_definitions(${target}
PUBLIC
VSTGUI_ENABLE_DEPRECATED_METHODS=0
)
endif()
endmacro()
macro(smtg_target_prepare_bundle target)
target_compile_definitions(${target}
PUBLIC
SMTG_MODULE_IS_BUNDLE=1
)
target_sources(${target}
PRIVATE
${public_sdk_SOURCE_DIR}/source/vst/vstgui_win32_bundle_support.cpp
${public_sdk_SOURCE_DIR}/source/vst/vstgui_win32_bundle_support.h
)
endmacro()
#[=======================================================================[.txt:
Adds VSTGUI support.
Usage:
smtg_enable_vstgui_support(VSTGUI_SOURCE_DIR "<path-to-the-vstgui-source-folder>")
Exports:
smtg_enable_vstgui_support exports "<path-to-the-vstgui-source-folder>"
as SMTG_VSTGUI_SOURCE_DIR to its parent scope.
Deprecation:
The usage wihout parameters is depricated.
SMTG_VSTGUI_ROOT is exported for compatibility reasons and is also depricated.
Replace "${SMTG_VSTGUI_ROOT}/vstgui4" with "${SMTG_VSTGUI_SOURCE_DIR}".
The export of "${SMTG_VSTGUI_ROOT}" may be removed in future SDK versions.
#]=======================================================================]
function(smtg_enable_vstgui_support)
if(${ARGC} GREATER 0)
set(options)
set(oneValueArgs VSTGUI_SOURCE_DIR)
set(multiValueArgs)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "[SMTG] The following parameters are unrecognized: ${ARG_UNPARSED_ARGUMENTS}")
endif()
get_filename_component(vstgui_root "${ARG_VSTGUI_SOURCE_DIR}" DIRECTORY)
set(SMTG_VSTGUI_ROOT "${vstgui_root}" PARENT_SCOPE)
set(vstgui_source_dir "${ARG_VSTGUI_SOURCE_DIR}")
else()
# See function documentation for more information.
message(DEPRECATION "[SMTG] Use smtg_enable_vstgui_support(VSTGUI_SOURCE_DIR \"<vstgui-source-folder>\") "
"instead of set(SMTG_VSTGUI_ROOT \"<parrent-of-vstgui-source-dir>\") and smtg_enable_vstgui_support()")
set(vstgui_source_dir "${SMTG_VSTGUI_ROOT}/vstgui4")
endif()
# Export SMTG_VSTGUI_SOURCE_DIR to parent scope
set(SMTG_VSTGUI_SOURCE_DIR "${vstgui_source_dir}" PARENT_SCOPE)
message(STATUS "[SMTG] SMTG_VSTGUI_SOURCE_DIR is set to: ${vstgui_source_dir}")
smtg_add_vstgui_subdirectory(${vstgui_source_dir})
add_library(vstgui_support
STATIC
${vstgui_source_dir}/vstgui/plugin-bindings/vst3groupcontroller.cpp
${vstgui_source_dir}/vstgui/plugin-bindings/vst3groupcontroller.h
${vstgui_source_dir}/vstgui/plugin-bindings/vst3padcontroller.cpp
${vstgui_source_dir}/vstgui/plugin-bindings/vst3padcontroller.h
${vstgui_source_dir}/vstgui/plugin-bindings/vst3editor.cpp
${vstgui_source_dir}/vstgui/plugin-bindings/vst3editor.h
${public_sdk_SOURCE_DIR}/source/vst/vstguieditor.cpp
)
target_link_libraries(vstgui_support
PUBLIC
base
vstgui
vstgui_uidescription
)
target_include_directories(vstgui_support
PUBLIC
${vstgui_source_dir}
)
target_compile_definitions(vstgui_support
PUBLIC
$<$<CONFIG:Debug>:VSTGUI_LIVE_EDITING>
)
smtg_target_setup_vstgui_deprecated_methods(vstgui_support)
smtg_target_setup_universal_binary(vstgui_support)
smtg_target_setup_universal_binary(vstgui)
smtg_target_setup_universal_binary(vstgui_uidescription)
if(SMTG_WIN AND SMTG_CREATE_BUNDLE_FOR_WINDOWS)
smtg_target_prepare_bundle(vstgui_support)
endif()
if(SMTG_LINUX)
target_sources(vstgui_support
PRIVATE
${public_sdk_SOURCE_DIR}/source/vst/vstgui_linux_runloop_support.cpp
${public_sdk_SOURCE_DIR}/source/vst/vstgui_linux_runloop_support.h
)
endif()
endfunction()
Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

+2
View File
@@ -0,0 +1,2 @@
[.ShellClassInfo]
IconResource=PlugIn.ico,0
@@ -0,0 +1,55 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : cmake
// Filename : cmake/templates/projectversion.h.in
// Created by : Steinberg, 03/2022
// Description : cmake template file to generate the projectversion.h
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2022, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------
#pragma once
#define MAJOR_VERSION_STR "@PROJECT_VERSION_MAJOR@"
#define MAJOR_VERSION_INT @PROJECT_VERSION_MAJOR@
#define SUB_VERSION_STR "@PROJECT_VERSION_MINOR@"
#define SUB_VERSION_INT @PROJECT_VERSION_MINOR@
#define RELEASE_NUMBER_STR "@PROJECT_VERSION_PATCH@"
#define RELEASE_NUMBER_INT @PROJECT_VERSION_PATCH@
#define BUILD_NUMBER_STR "@PROJECT_VERSION_TWEAK@" // Build number to be sure that each result could identified.
#define BUILD_NUMBER_INT @PROJECT_VERSION_TWEAK@
// Version possibly with build number (example "1.0.3.342")
#define FULL_VERSION_STR "@PROJECT_VERSION@"
// Version without build number (example "1.0.3")
#define VERSION_STR "@SMTG_PROJECT_VERSION@"
+24
View File
@@ -0,0 +1,24 @@
//-----------------------------------------------------------------------------
MIT License
Copyright (c) 2025, Steinberg Media Technologies GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
//---------------------------------------------------------------------------------
+12
View File
@@ -0,0 +1,12 @@
# Welcome to VST 3 SDK Doc
* Check the **VST 3 API** online documentation created from this github project under: [steinbergmedia.github.io/vst3_doc](https://steinbergmedia.github.io/vst3_doc)
* Check the **VST 3 SDK** online documentation under: [steinbergmedia.github.io/vst3_dev_portal](https://steinbergmedia.github.io/vst3_dev_portal/pages/index.html)
## License & Usage guidelines
More details are found at [www.steinberg.net/sdklicenses_vst3](http://www.steinberg.net/sdklicenses_vst3)
----
Return to [VST 3 SDK](https://github.com/steinbergmedia/vst3sdk)
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 116.2 74.7" style="enable-background:new 0 0 116.2 74.7;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;}
.st1{fill:#FFFFFF;}
.st2{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
.st3{fill:#1A1A18;}
</style>
<g>
<g>
<rect x="1.2" y="0.7" class="st0" width="113.9" height="73"/>
<path class="st1" d="M114.6,1.2v71.9H1.8V1.2H114.6 M115.7,0.1h-1.1H1.8H0.7v1.1v71.9v1.1h1.1h112.8h1.1v-1.1V1.2V0.1L115.7,0.1z"
/>
</g>
<g>
<path class="st1" d="M20.6,58.5c-0.4,0.9-1.6,3.3-4.7,3.3c-2.6,0-5.1-1.7-5.1-5.8c0-2.4,1.4-5.6,5.1-5.6c2.8,0,3.9,1.8,4.4,3.3
l-2,0.5c-0.1-1.2-1.1-2-2.3-2c-1.8,0-3,1.3-3,3.8c0,1.5,0.6,3.8,3,3.8c1.4,0,2.3-1.1,2.6-2.2L20.6,58.5z"/>
<path class="st1" d="M27.1,50.4c3.3,0,5.2,2.7,5.2,5.6c0,2.5-1.3,5.8-5.2,5.8c-3.2,0-5.2-2.6-5.2-5.7C21.9,53,23.9,50.4,27.1,50.4
z M27.1,59.9c1.6,0,3.1-1.2,3.1-3.7c0-1.9-1-3.9-3.2-3.9c-1.8,0-3.1,1.4-3.1,3.8C24,57.8,24.8,59.9,27.1,59.9z"/>
<path class="st1" d="M42.2,61.5c0-0.3,0.2-8.9,0.2-8.9l-2.3,8.9h-1.8l-2.3-8.9c0,0,0.2,8.5,0.2,8.9h-2V50.7h2.9l2.1,8l2.1-8h2.9
v10.8H42.2z"/>
<path class="st1" d="M51.5,50.7c2.2,0,3.8,1.4,3.8,3.6c0,2-1.1,3.5-4,3.5h-2.1v3.7h-2V50.7H51.5z M49.3,56.2h1.8
c1.4,0,2.2-0.7,2.2-1.9c0-1.7-1.4-1.8-2.4-1.8h-1.5V56.2z"/>
<path class="st1" d="M62.9,61.5l-0.6-2.1h-4.1l-0.6,2.1h-2.2L59,50.7h2.3L65,61.5H62.9z M60.2,52.7l-1.5,5h3L60.2,52.7z"/>
<path class="st1" d="M69.2,52.5v9h-2v-9h-2.9v-1.8h8v1.8H69.2z"/>
<path class="st1" d="M73.8,61.5V50.7h2v10.8H73.8z"/>
<path class="st1" d="M83.7,50.7c2.3,0,3.3,1.3,3.3,2.7c0,0.9-0.5,2.1-1.8,2.2c1,0.2,2.3,1,2.3,2.9c0,1.5-0.9,3.1-3.6,3.1h-5V50.7
H83.7z M80.9,55.1h2c0.9,0,2-0.3,2-1.4c0-1.1-1.1-1.3-1.9-1.3h-2.1V55.1z M80.9,59.8h2.7c1.4,0,1.9-0.7,1.9-1.5
c0-1.5-1.5-1.7-2.3-1.7h-2.3V59.8z"/>
<path class="st1" d="M90.1,61.5V50.7h2v9h4.3v1.8H90.1z"/>
<path class="st1" d="M97.7,61.5V50.7h7.7v1.8h-5.7v2.5h5.2v1.7h-5.2v2.9h6.1v1.8H97.7z"/>
</g>
<path class="st2" d="M69.6,19h36.2l0.1,6.4h-1.7c-0.6-2.2-2.2-3.7-4.9-4.4c-1.5-0.4-3.8-0.7-6.8-0.7v16c0,1.1,0.4,1.6,1.1,1.9
c0.8,0.4,2.4,0.4,4.8,0.4v1.4H77.1v-1.4c2.3,0,3.9-0.2,4.7-0.5c0.8-0.4,1.2-0.7,1.2-1.8v-16c-2.9,0-5.2,0.3-6.7,0.7
c-2.9,0.8-4.5,2.3-4.9,4.4c-0.5,0-1.7,0-1.7,0L69.6,19z"/>
<g>
<path class="st2" d="M41.2,29.8l3.3,0.4l0.1,0.1c1.3,2.7,3.4,4.8,6.3,6c2.9,1.3,6.3,1.9,10.1,1.9c3.7,0,6.3-0.4,7.8-1.3
c1.5-0.8,2.2-1.7,2.2-2.6c0-1-0.8-1.9-2.3-2.5c-1.1-0.5-3.3-1.1-6.5-1.8l-5.3-1.2c-5.2-1.2-9-2.4-11.1-3.6
c-2.2-1.2-3.3-2.8-3.3-4.6c0-1.9,1.5-3.7,4.4-5.4c2.9-1.6,7.3-2.4,13.2-2.4c3,0,5.9,0.2,8.7,0.6c1.8,0.3,4.3,0.6,4.8,0.6
c1.1,0,1.5-0.2,1.7-0.3c0.3-0.2,0.6-0.5,0.8-0.9l0.1-0.1h2.8v8.7H76l-0.1-0.1c-1.1-1.9-3-3.5-5.7-4.8c-2.7-1.4-6-2-9.8-2
c-2.7,0-4.9,0.3-6.4,1c-1.5,0.6-2.2,1.4-2.2,2.3c0,1.1,0.7,1.9,2.1,2.5c1.5,0.6,4.8,1.5,9.8,2.6l6.1,1.4c2.7,0.6,4.9,1.3,6.5,2.1
c3.1,1.5,4.7,3.3,4.7,5.4c0,2-1.7,3.9-5,5.6c-3.2,1.7-8.5,2.6-15.6,2.6c-1.6,0-3.3-0.1-5-0.2c-1.7-0.1-3.4-0.4-5-0.6l-1.6-0.3
c-0.4,0-0.7-0.1-1-0.1c-0.3,0-0.6-0.1-0.9-0.1c-0.8,0-1.3,0.1-1.6,0.3c-0.3,0.2-0.5,0.5-0.8,0.9L44.4,40l-3.2,0V29.8z"/>
<path class="st3" d="M78.4,13.1v8.2h-2.3c-1.1-1.9-3-3.5-5.7-4.9c-2.7-1.4-6-2.1-9.9-2.1c-2.8,0-4.9,0.3-6.5,1
c-1.6,0.7-2.4,1.5-2.4,2.5c0,1.2,0.8,2.1,2.3,2.7c1.5,0.6,4.8,1.5,9.9,2.6l6.1,1.4c2.7,0.6,4.9,1.3,6.5,2.1c3,1.4,4.5,3.2,4.5,5.2
c0,1.9-1.6,3.7-4.9,5.4c-3.2,1.7-8.4,2.5-15.5,2.5c-1.6,0-3.3-0.1-5-0.2c-1.7-0.1-3.3-0.3-5-0.6l-1.6-0.3c-0.4,0-0.7-0.1-1.1-0.1
c-0.3,0-0.6-0.1-0.9-0.1c-0.8,0-1.4,0.1-1.7,0.3c-0.3,0.2-0.6,0.5-0.8,1l-2.9,0v-9.7l2.9,0.4c1.3,2.8,3.4,4.9,6.4,6.1
c3,1.3,6.3,1.9,10.1,1.9c3.7,0,6.3-0.4,7.9-1.3c1.6-0.9,2.3-1.8,2.3-2.8c0-1.1-0.8-2-2.5-2.8c-1.1-0.5-3.3-1.1-6.5-1.8l-5.3-1.2
c-5.2-1.2-8.9-2.4-11.1-3.6c-2.1-1.2-3.2-2.6-3.2-4.4c0-1.8,1.4-3.6,4.2-5.2c2.9-1.6,7.2-2.4,13.1-2.4c3,0,5.9,0.2,8.6,0.6
c2.8,0.4,4.4,0.6,4.8,0.6c0.9,0,1.5-0.1,1.9-0.3c0.3-0.2,0.6-0.6,0.8-1H78.4 M78.8,12.6h-0.5H76h-0.3l-0.1,0.2
c-0.2,0.3-0.4,0.6-0.7,0.8c-0.1,0.1-0.5,0.3-1.6,0.3c-0.5,0-3.7-0.5-4.7-0.6c-2.8-0.4-5.7-0.6-8.7-0.6c-5.9,0-10.4,0.8-13.3,2.5
c-3,1.7-4.5,3.5-4.5,5.6c0,1.9,1.2,3.5,3.5,4.8c2.2,1.2,5.9,2.4,11.2,3.6l5.3,1.2c3.2,0.7,5.4,1.3,6.5,1.8
c1.4,0.6,2.2,1.4,2.2,2.3c0,0.8-0.7,1.6-2.1,2.4c-1.5,0.8-4.1,1.2-7.7,1.2c-3.7,0-7.1-0.6-10-1.9C48,35,46,33,44.7,30.3L44.6,30
l-0.3,0l-2.9-0.4L41,29.6v0.5v9.7v0.5l0.5,0l2.9,0l0.3,0l0.1-0.2c0.2-0.4,0.4-0.6,0.7-0.8c0.1-0.1,0.5-0.3,1.5-0.3
c0.2,0,0.5,0,0.8,0.1c0.3,0,0.7,0.1,1.1,0.1l1.6,0.3c1.6,0.3,3.3,0.5,5,0.6c1.7,0.1,3.4,0.2,5,0.2c7.2,0,12.5-0.9,15.8-2.6
c3.4-1.8,5.1-3.7,5.1-5.8c0-2.2-1.6-4.1-4.8-5.6c-1.6-0.8-3.9-1.5-6.6-2.1l-6.1-1.4c-5-1.1-8.3-2-9.8-2.6c-1.3-0.5-2-1.3-2-2.2
c0-0.8,0.7-1.5,2.1-2.1c1.5-0.7,3.7-1,6.4-1c3.8,0,7.1,0.7,9.7,2c2.7,1.3,4.5,2.9,5.6,4.7l0.1,0.2h0.3h2.3h0.5v-0.5v-8.2V12.6
L78.8,12.6z"/>
</g>
<g>
<g>
<path class="st2" d="M28.6,40.6L13.5,22.9c-0.6-0.7-1.2-1.2-1.8-1.5c-0.6-0.3-2.3-0.5-3.8-0.5l-0.2,0v-1.4h21v1.5l-0.2,0
c-2.1,0.1-3.4,0.2-4.1,0.3c-0.7,0.1-0.7,0.4-0.7,0.7c0,0.1,0,0.3,0,0.4c0,0.1,0.1,0.2,0.2,0.3l8.8,10.8h0.1l7.6-9.9
c0.2-0.2,0.3-0.4,0.4-0.6c0.2-0.3,0.3-0.6,0.3-0.8c0-0.3-0.1-0.7-0.8-0.8c-0.6-0.1-2-0.2-4-0.3l-0.2,0v-1.5h13.8v1.4l-0.2,0
c-1.5,0.1-3.4,0.3-4,0.6c-0.7,0.3-1.3,0.9-2,1.7L30.4,40.6H28.6z"/>
<path class="st3" d="M49.8,19.7v1c-1.4,0.1-3.4,0.3-4.1,0.6c-0.7,0.3-1.4,0.9-2.1,1.8L30.3,40.4h-1.6L13.6,22.7
c-0.6-0.7-1.2-1.2-1.9-1.5c-0.6-0.3-2.5-0.5-3.9-0.6v-1h20.5v1c-2.1,0.1-3.5,0.2-4.1,0.3c-0.6,0.1-0.9,0.4-0.9,0.9
c0,0.1,0,0.3,0.1,0.4c0.1,0.1,0.2,0.3,0.3,0.4l8.9,10.9H33l7.7-9.9c0.2-0.2,0.3-0.4,0.5-0.7c0.2-0.4,0.3-0.7,0.3-0.9
c0-0.6-0.3-0.9-1-1c-0.6-0.1-2-0.3-4-0.3v-1H49.8 M50.3,19.2h-0.5H36.5H36v0.5v1v0.5l0.5,0c2,0.1,3.3,0.2,3.9,0.3
C41,21.6,41,21.8,41,22c0,0.1,0,0.3-0.3,0.7c-0.1,0.2-0.3,0.4-0.4,0.6L32.8,33l-8.7-10.6c-0.1-0.1-0.2-0.2-0.2-0.3
c0-0.1,0-0.2,0-0.3c0-0.1,0-0.3,0.5-0.4c0.6-0.1,1.9-0.2,4-0.3l0.5,0v-0.5v-1v-0.5h-0.5H7.9H7.4v0.5v1v0.4l0.4,0
c1.7,0.1,3.2,0.3,3.7,0.5c0.6,0.3,1.2,0.8,1.7,1.4l15.1,17.6l0.1,0.2h0.2h1.6h0.2l0.1-0.2L44,23.3c0.6-0.8,1.3-1.3,1.9-1.6
c0.5-0.3,2.1-0.5,3.9-0.6l0.4,0v-0.4v-1V19.2L50.3,19.2z"/>
</g>
</g>
<g>
<path class="st1" d="M105.6,14.9c-2.4,0-4.4-2-4.4-4.4s2-4.4,4.4-4.4c2.4,0,4.4,2,4.4,4.3C110.1,12.9,108.2,14.9,105.6,14.9z
M105.6,6.4c-2.2,0-4,1.8-4,4s1.7,4,4,4c2.2,0,4-1.8,4-3.9C109.6,8.2,107.9,6.4,105.6,6.4z M105.5,7.6c1.4,0,2,0.5,2,1.6
c0,0.9-0.4,1.3-1.2,1.6l1.3,2.4h-1l-1.2-2.3h-0.7v2.3h-0.9V7.6H105.5z M104.8,10.1h0.7c0.8,0,1.1-0.3,1.1-0.9
c0-0.6-0.4-0.9-1.2-0.9h-0.6V10.1z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 116.2 74.7" style="enable-background:new 0 0 116.2 74.7;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#030304;stroke:#FFFFFF;stroke-width:0.7418;stroke-miterlimit:10;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
.st2{fill:#030304;}
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#030304;}
.st4{fill:#FFFFFF;}
</style>
<g>
<rect x="1.8" y="0.6" class="st0" width="112.8" height="73.7"/>
</g>
<rect x="3.6" y="2.7" class="st1" width="109.2" height="69.5"/>
<g>
<path class="st2" d="M20.3,58c-0.4,0.9-1.6,3.3-4.7,3.3c-2.6,0-5.1-1.7-5.1-5.8c0-2.4,1.4-5.6,5.1-5.6c2.8,0,3.9,1.8,4.4,3.3
l-2,0.5c-0.1-1.2-1.1-2-2.3-2c-1.8,0-3,1.3-3,3.8c0,1.5,0.6,3.8,3,3.8c1.4,0,2.3-1.1,2.6-2.2L20.3,58z"/>
<path class="st2" d="M26.8,49.9c3.3,0,5.2,2.7,5.2,5.6c0,2.5-1.3,5.8-5.2,5.8c-3.2,0-5.2-2.6-5.2-5.7
C21.6,52.4,23.6,49.9,26.8,49.9z M26.8,59.4c1.6,0,3.1-1.2,3.1-3.7c0-1.9-1-3.9-3.2-3.9c-1.8,0-3.1,1.4-3.1,3.8
C23.7,57.2,24.5,59.4,26.8,59.4z"/>
<path class="st2" d="M41.9,61c0-0.3,0.2-8.9,0.2-8.9L39.8,61h-1.8l-2.3-8.9c0,0,0.2,8.5,0.2,8.9h-2V50.2h2.9l2.1,8l2.1-8h2.9V61
H41.9z"/>
<path class="st2" d="M51.2,50.2c2.2,0,3.8,1.4,3.8,3.6c0,2-1.1,3.5-4,3.5H49V61h-2V50.2H51.2z M49,55.7h1.8c1.4,0,2.2-0.7,2.2-1.9
c0-1.7-1.4-1.8-2.4-1.8H49V55.7z"/>
<path class="st2" d="M62.6,61l-0.6-2.1h-4.1L57.3,61h-2.2l3.7-10.8H61L64.7,61H62.6z M59.9,52.1l-1.5,5h3L59.9,52.1z"/>
<path class="st2" d="M68.9,52v9h-2v-9H64v-1.8h8V52H68.9z"/>
<path class="st2" d="M73.5,61V50.2h2V61H73.5z"/>
<path class="st2" d="M83.4,50.2c2.3,0,3.3,1.3,3.3,2.7c0,0.9-0.5,2.1-1.8,2.2c1,0.2,2.3,1,2.3,2.9c0,1.5-0.9,3.1-3.6,3.1h-5V50.2
H83.4z M80.6,54.5h2c0.9,0,2-0.3,2-1.4c0-1.1-1.1-1.3-1.9-1.3h-2.1V54.5z M80.6,59.3h2.7c1.4,0,1.9-0.7,1.9-1.5
c0-1.5-1.5-1.7-2.3-1.7h-2.3V59.3z"/>
<path class="st2" d="M89.8,61V50.2h2v9h4.3V61H89.8z"/>
<path class="st2" d="M97.4,61V50.2h7.7V52h-5.7v2.5h5.2v1.7h-5.2v2.9h6.1V61H97.4z"/>
</g>
<path class="st3" d="M69.3,18.5h36.2l0.1,6.4h-1.7c-0.6-2.2-2.2-3.7-4.9-4.4c-1.5-0.4-3.8-0.7-6.8-0.7v16c0,1.1,0.4,1.6,1.1,1.9
c0.8,0.4,2.4,0.4,4.8,0.4v1.4H76.8V38c2.3,0,3.9-0.2,4.7-0.5c0.8-0.4,1.2-0.7,1.2-1.8v-16c-2.9,0-5.2,0.3-6.7,0.7
c-2.9,0.8-4.5,2.3-4.9,4.4c-0.5,0-1.7,0-1.7,0L69.3,18.5z"/>
<g>
<path class="st3" d="M40.9,29.3l3.3,0.4l0.1,0.1c1.3,2.7,3.4,4.8,6.3,6c2.9,1.3,6.3,1.9,10.1,1.9c3.7,0,6.3-0.4,7.8-1.3
c1.5-0.8,2.2-1.7,2.2-2.6c0-1-0.8-1.9-2.3-2.5c-1.1-0.5-3.3-1.1-6.5-1.8l-5.3-1.2c-5.2-1.2-9-2.4-11.1-3.6C43.1,23.5,42,22,42,20.2
c0-1.9,1.5-3.7,4.4-5.4c2.9-1.6,7.3-2.4,13.2-2.4c3,0,5.9,0.2,8.7,0.6c1.8,0.3,4.3,0.6,4.8,0.6c1.1,0,1.5-0.2,1.7-0.3
c0.3-0.2,0.6-0.5,0.8-0.9l0.1-0.1h2.8V21h-2.6l-0.1-0.1c-1.1-1.9-3-3.5-5.7-4.8c-2.7-1.4-6-2-9.8-2c-2.7,0-4.9,0.3-6.4,1
c-1.5,0.6-2.2,1.4-2.2,2.3c0,1.1,0.7,1.9,2.1,2.5c1.5,0.6,4.8,1.5,9.8,2.6l6.1,1.4c2.7,0.6,4.9,1.3,6.5,2.1
c3.1,1.5,4.7,3.3,4.7,5.4c0,2-1.7,3.9-5,5.6c-3.2,1.7-8.5,2.6-15.6,2.6c-1.6,0-3.3-0.1-5-0.2c-1.7-0.1-3.4-0.4-5-0.6l-1.6-0.3
c-0.4,0-0.7-0.1-1-0.1c-0.3,0-0.6-0.1-0.9-0.1c-0.8,0-1.3,0.1-1.6,0.3c-0.3,0.2-0.5,0.5-0.8,0.9l-0.1,0.1l-3.2,0V29.3z"/>
<path class="st4" d="M78.1,12.6v8.2h-2.3c-1.1-1.9-3-3.5-5.7-4.9c-2.7-1.4-6-2.1-9.9-2.1c-2.8,0-4.9,0.3-6.5,1
c-1.6,0.7-2.4,1.5-2.4,2.5c0,1.2,0.8,2.1,2.3,2.7c1.5,0.6,4.8,1.5,9.9,2.6l6.1,1.4c2.7,0.6,4.9,1.3,6.5,2.1c3,1.4,4.5,3.2,4.5,5.2
c0,1.9-1.6,3.7-4.9,5.4c-3.2,1.7-8.4,2.5-15.5,2.5c-1.6,0-3.3-0.1-5-0.2c-1.7-0.1-3.3-0.3-5-0.6l-1.6-0.3c-0.4,0-0.7-0.1-1.1-0.1
c-0.3,0-0.6-0.1-0.9-0.1c-0.8,0-1.4,0.1-1.7,0.3c-0.3,0.2-0.6,0.5-0.8,1l-2.9,0v-9.7l2.9,0.4c1.3,2.8,3.4,4.9,6.4,6.1
c3,1.3,6.3,1.9,10.1,1.9c3.7,0,6.3-0.4,7.9-1.3c1.6-0.9,2.3-1.8,2.3-2.8c0-1.1-0.8-2-2.5-2.8c-1.1-0.5-3.3-1.1-6.5-1.8l-5.3-1.2
c-5.2-1.2-8.9-2.4-11.1-3.6c-2.1-1.2-3.2-2.6-3.2-4.4c0-1.8,1.4-3.6,4.2-5.2c2.9-1.6,7.2-2.4,13.1-2.4c3,0,5.9,0.2,8.6,0.6
c2.8,0.4,4.4,0.6,4.8,0.6c0.9,0,1.5-0.1,1.9-0.3c0.3-0.2,0.6-0.6,0.8-1H78.1 M78.5,12.1h-0.5h-2.4h-0.3l-0.1,0.2
c-0.2,0.3-0.4,0.6-0.7,0.8c-0.1,0.1-0.5,0.3-1.6,0.3c-0.5,0-3.7-0.5-4.7-0.6c-2.8-0.4-5.7-0.6-8.7-0.6c-5.9,0-10.4,0.8-13.3,2.5
c-3,1.7-4.5,3.5-4.5,5.6c0,1.9,1.2,3.5,3.5,4.8c2.2,1.2,5.9,2.4,11.2,3.6l5.3,1.2c3.2,0.7,5.4,1.3,6.5,1.8c1.4,0.6,2.2,1.4,2.2,2.3
c0,0.8-0.7,1.6-2.1,2.4c-1.5,0.8-4.1,1.2-7.7,1.2c-3.7,0-7.1-0.6-10-1.9c-2.8-1.2-4.9-3.2-6.1-5.9l-0.1-0.2l-0.3,0l-2.9-0.4
L40.7,29v0.5v9.7v0.5l0.5,0l2.9,0l0.3,0l0.1-0.2c0.2-0.4,0.4-0.6,0.7-0.8c0.1-0.1,0.5-0.3,1.5-0.3c0.2,0,0.5,0,0.8,0.1
c0.3,0,0.7,0.1,1.1,0.1l1.6,0.3c1.6,0.3,3.3,0.5,5,0.6c1.7,0.1,3.4,0.2,5,0.2c7.2,0,12.5-0.9,15.8-2.6c3.4-1.8,5.1-3.7,5.1-5.8
c0-2.2-1.6-4.1-4.8-5.6c-1.6-0.8-3.9-1.5-6.6-2.1l-6.1-1.4c-5-1.1-8.3-2-9.8-2.6c-1.3-0.5-2-1.3-2-2.2c0-0.8,0.7-1.5,2.1-2.1
c1.5-0.7,3.7-1,6.4-1c3.8,0,7.1,0.7,9.7,2c2.7,1.3,4.5,2.9,5.6,4.7l0.1,0.2h0.3h2.3h0.5v-0.5v-8.2V12.1L78.5,12.1z"/>
</g>
<g>
<g>
<path class="st3" d="M28.3,40.1L13.2,22.4c-0.6-0.7-1.2-1.2-1.8-1.5c-0.6-0.3-2.3-0.5-3.8-0.5l-0.2,0v-1.4h21v1.5l-0.2,0
c-2.1,0.1-3.4,0.2-4.1,0.3c-0.7,0.1-0.7,0.4-0.7,0.7c0,0.1,0,0.3,0,0.4c0,0.1,0.1,0.2,0.2,0.3l8.8,10.8h0.1l7.6-9.9
c0.2-0.2,0.3-0.4,0.4-0.6c0.2-0.3,0.3-0.6,0.3-0.8c0-0.3-0.1-0.7-0.8-0.8c-0.6-0.1-2-0.2-4-0.3l-0.2,0v-1.5h13.8v1.4l-0.2,0
c-1.5,0.1-3.4,0.3-4,0.6c-0.7,0.3-1.3,0.9-2,1.7L30.1,40.1H28.3z"/>
<path class="st4" d="M49.5,19.1v1c-1.4,0.1-3.4,0.3-4.1,0.6c-0.7,0.3-1.4,0.9-2.1,1.8L30,39.8h-1.6L13.3,22.2
c-0.6-0.7-1.2-1.2-1.9-1.5c-0.6-0.3-2.5-0.5-3.9-0.6v-1h20.5v1c-2.1,0.1-3.5,0.2-4.1,0.3c-0.6,0.1-0.9,0.4-0.9,0.9
c0,0.1,0,0.3,0.1,0.4c0.1,0.1,0.2,0.3,0.3,0.4L32.4,33h0.3l7.7-9.9c0.2-0.2,0.3-0.4,0.5-0.7c0.2-0.4,0.3-0.7,0.3-0.9
c0-0.6-0.3-0.9-1-1c-0.6-0.1-2-0.3-4-0.3v-1H49.5 M50,18.7h-0.5H36.2h-0.5v0.5v1v0.5l0.5,0c2,0.1,3.3,0.2,3.9,0.3
c0.6,0.1,0.6,0.4,0.6,0.6c0,0.1,0,0.3-0.3,0.7c-0.1,0.2-0.3,0.4-0.4,0.6l-7.5,9.7l-8.7-10.6c-0.1-0.1-0.2-0.2-0.2-0.3
c0-0.1,0-0.2,0-0.3c0-0.1,0-0.3,0.5-0.4c0.6-0.1,1.9-0.2,4-0.3l0.5,0v-0.5v-1v-0.5h-0.5H7.6H7.1v0.5v1v0.4l0.4,0
c1.7,0.1,3.2,0.3,3.7,0.5c0.6,0.3,1.2,0.8,1.7,1.4l15.1,17.6l0.1,0.2h0.2H30h0.2l0.1-0.2l13.4-17.3c0.6-0.8,1.3-1.3,1.9-1.6
c0.5-0.3,2.1-0.5,3.9-0.6l0.4,0v-0.4v-1V18.7L50,18.7z"/>
</g>
</g>
<g>
<path class="st2" d="M106,14c-2.4,0-4.4-2-4.4-4.4s2-4.4,4.4-4.4c2.4,0,4.4,2,4.4,4.3C110.4,12.1,108.5,14,106,14z M106,5.6
c-2.2,0-4,1.8-4,4s1.7,4,4,4c2.2,0,4-1.8,4-3.9C110,7.4,108.3,5.6,106,5.6z M105.9,6.8c1.4,0,2,0.5,2,1.6c0,0.9-0.4,1.3-1.2,1.6
l1.3,2.4h-1l-1.2-2.3h-0.7v2.3h-0.9V6.8H105.9z M105.1,9.3h0.7c0.8,0,1.1-0.3,1.1-0.9c0-0.6-0.4-0.9-1.2-0.9h-0.6V9.3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

@@ -0,0 +1,204 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 116.2 107.7" style="enable-background:new 0 0 116.2 107.7;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:none;stroke:#000000;stroke-width:0.8877;stroke-miterlimit:10;}
.st2{fill:#FFFFFF;}
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
</style>
<rect x="2.1" y="1.3" class="st0" width="112.8" height="71.9"/>
<g>
<rect x="2.1" y="1.3" class="st1" width="112.8" height="105.5"/>
</g>
<g>
<path class="st2" d="M20.9,58.6c-0.4,0.9-1.6,3.3-4.7,3.3c-2.6,0-5.1-1.7-5.1-5.8c0-2.4,1.4-5.6,5.1-5.6c2.8,0,3.9,1.8,4.4,3.3
l-2,0.5c-0.1-1.2-1.1-2-2.3-2c-1.8,0-3,1.3-3,3.8c0,1.5,0.6,3.8,3,3.8c1.4,0,2.3-1.1,2.6-2.2L20.9,58.6z"/>
<path class="st2" d="M27.4,50.5c3.3,0,5.2,2.7,5.2,5.6c0,2.5-1.3,5.8-5.2,5.8c-3.2,0-5.2-2.6-5.2-5.7C22.2,53,24.2,50.5,27.4,50.5z
M27.4,60c1.6,0,3.1-1.2,3.1-3.7c0-1.9-1-3.9-3.2-3.9c-1.8,0-3.1,1.4-3.1,3.8C24.2,57.8,25.1,60,27.4,60z"/>
<path class="st2" d="M42.5,61.6c0-0.3,0.2-8.9,0.2-8.9l-2.3,8.9h-1.8l-2.3-8.9c0,0,0.2,8.5,0.2,8.9h-2V50.8h2.9l2.1,8l2.1-8h2.9
v10.8H42.5z"/>
<path class="st2" d="M51.8,50.8c2.2,0,3.8,1.4,3.8,3.6c0,2-1.1,3.5-4,3.5h-2.1v3.7h-2V50.8H51.8z M49.6,56.3h1.8
c1.4,0,2.2-0.7,2.2-1.9c0-1.7-1.4-1.8-2.4-1.8h-1.5V56.3z"/>
<path class="st2" d="M63.2,61.6l-0.6-2.1h-4.1l-0.6,2.1h-2.2l3.7-10.8h2.3l3.7,10.8H63.2z M60.5,52.7l-1.5,5h3L60.5,52.7z"/>
<path class="st2" d="M69.5,52.6v9h-2v-9h-2.9v-1.8h8v1.8H69.5z"/>
<path class="st2" d="M74.1,61.6V50.8h2v10.8H74.1z"/>
<path class="st2" d="M84,50.8c2.3,0,3.3,1.3,3.3,2.7c0,0.9-0.5,2.1-1.8,2.2c1,0.2,2.3,1,2.3,2.9c0,1.5-0.9,3.1-3.6,3.1h-5V50.8H84z
M81.2,55.1h2c0.9,0,2-0.3,2-1.4c0-1.1-1.1-1.3-1.9-1.3h-2.1V55.1z M81.2,59.9h2.7c1.4,0,1.9-0.7,1.9-1.5c0-1.5-1.5-1.7-2.3-1.7
h-2.3V59.9z"/>
<path class="st2" d="M90.4,61.6V50.8h2v9h4.3v1.8H90.4z"/>
<path class="st2" d="M98,61.6V50.8h7.7v1.8H100v2.5h5.2v1.7H100v2.9h6.1v1.8H98z"/>
</g>
<path class="st3" d="M69.9,19.1h36.2l0.1,6.4h-1.7c-0.6-2.2-2.2-3.7-4.9-4.4c-1.5-0.4-3.8-0.7-6.8-0.7v16c0,1.1,0.4,1.6,1.1,1.9
c0.8,0.4,2.4,0.4,4.8,0.4V40H77.4v-1.4c2.3,0,3.9-0.2,4.7-0.5c0.8-0.4,1.2-0.7,1.2-1.8v-16c-2.9,0-5.2,0.3-6.7,0.7
c-2.9,0.8-4.5,2.3-4.9,4.4c-0.5,0-1.7,0-1.7,0L69.9,19.1z"/>
<g>
<path class="st3" d="M41.5,29.9l3.3,0.4l0.1,0.1c1.3,2.7,3.4,4.8,6.3,6c2.9,1.3,6.3,1.9,10.1,1.9c3.7,0,6.3-0.4,7.8-1.3
c1.5-0.8,2.2-1.7,2.2-2.6c0-1-0.8-1.9-2.3-2.5c-1.1-0.5-3.3-1.1-6.5-1.8L57,28.9c-5.2-1.2-9-2.4-11.1-3.6c-2.2-1.2-3.3-2.8-3.3-4.6
c0-1.9,1.5-3.7,4.4-5.4c2.9-1.6,7.3-2.4,13.2-2.4c3,0,5.9,0.2,8.7,0.6c1.8,0.3,4.3,0.6,4.8,0.6c1.1,0,1.5-0.2,1.7-0.3
c0.3-0.2,0.6-0.5,0.8-0.9l0.1-0.1h2.8v8.7h-2.6l-0.1-0.1c-1.1-1.8-3-3.5-5.7-4.8c-2.7-1.4-6-2-9.8-2c-2.7,0-4.9,0.3-6.4,1
C52.8,16.3,52,17.1,52,18c0,1.1,0.7,1.9,2.1,2.5c1.5,0.6,4.8,1.5,9.8,2.6l6.1,1.4c2.7,0.6,4.9,1.3,6.5,2.1c3.1,1.5,4.7,3.3,4.7,5.4
c0,2-1.7,3.9-5,5.6c-3.2,1.7-8.5,2.6-15.6,2.6c-1.6,0-3.3-0.1-5-0.2c-1.7-0.1-3.4-0.4-5-0.6L49.1,39c-0.4,0-0.7-0.1-1-0.1
c-0.3,0-0.6-0.1-0.9-0.1c-0.8,0-1.3,0.1-1.6,0.3c-0.3,0.2-0.5,0.5-0.8,0.9l-0.1,0.1l-3.2,0V29.9z"/>
<path d="M78.7,13.2v8.2h-2.3c-1.1-1.9-3-3.5-5.7-4.9c-2.7-1.4-6-2.1-9.9-2.1c-2.8,0-4.9,0.3-6.5,1c-1.6,0.7-2.4,1.5-2.4,2.5
c0,1.2,0.8,2.1,2.3,2.7c1.5,0.6,4.8,1.5,9.9,2.6l6.1,1.4c2.7,0.6,4.9,1.3,6.5,2.1c3,1.4,4.5,3.2,4.5,5.2c0,1.9-1.6,3.7-4.9,5.4
c-3.2,1.7-8.4,2.5-15.5,2.5c-1.6,0-3.3-0.1-5-0.2c-1.7-0.1-3.3-0.3-5-0.6l-1.6-0.3c-0.4,0-0.7-0.1-1.1-0.1c-0.3,0-0.6-0.1-0.9-0.1
c-0.8,0-1.4,0.1-1.7,0.3c-0.3,0.2-0.6,0.5-0.8,1l-2.9,0v-9.7l2.9,0.4c1.3,2.8,3.4,4.9,6.4,6.1c3,1.3,6.3,1.9,10.1,1.9
c3.7,0,6.3-0.4,7.9-1.3c1.6-0.9,2.3-1.8,2.3-2.8c0-1.1-0.8-2-2.5-2.8c-1.1-0.5-3.3-1.1-6.5-1.8l-5.3-1.2c-5.2-1.2-8.9-2.4-11.1-3.6
c-2.1-1.2-3.2-2.6-3.2-4.4c0-1.8,1.4-3.6,4.2-5.2c2.9-1.6,7.2-2.4,13.1-2.4c3,0,5.9,0.2,8.6,0.6c2.8,0.4,4.4,0.6,4.8,0.6
c0.9,0,1.5-0.1,1.9-0.3c0.3-0.2,0.6-0.6,0.8-1H78.7 M79.1,12.7h-0.5h-2.4H76L75.8,13c-0.2,0.3-0.4,0.6-0.7,0.8
C75,13.9,74.6,14,73.6,14c-0.5,0-3.7-0.5-4.7-0.6c-2.8-0.4-5.7-0.6-8.7-0.6c-5.9,0-10.4,0.8-13.3,2.5c-3,1.7-4.5,3.5-4.5,5.6
c0,1.9,1.2,3.5,3.5,4.8C48,26.7,51.7,28,57,29.2l5.3,1.2c3.2,0.7,5.4,1.3,6.5,1.8c1.4,0.6,2.2,1.4,2.2,2.3c0,0.8-0.7,1.6-2.1,2.4
c-1.5,0.8-4.1,1.2-7.7,1.2c-3.7,0-7.1-0.6-10-1.9C48.3,35,46.3,33,45,30.4l-0.1-0.2l-0.3,0l-2.9-0.4l-0.5-0.1v0.5v9.7v0.5l0.5,0
l2.9,0l0.3,0l0.1-0.2c0.2-0.4,0.4-0.6,0.7-0.8c0.1-0.1,0.5-0.3,1.5-0.3c0.2,0,0.5,0,0.8,0.1c0.3,0,0.7,0.1,1.1,0.1l1.6,0.3
c1.6,0.3,3.3,0.5,5,0.6c1.7,0.1,3.4,0.2,5,0.2c7.2,0,12.5-0.9,15.8-2.6c3.4-1.8,5.1-3.7,5.1-5.8c0-2.2-1.6-4.1-4.8-5.6
c-1.6-0.8-3.9-1.5-6.6-2.1L64,22.8c-5-1.1-8.3-2-9.8-2.6c-1.3-0.5-2-1.3-2-2.2c0-0.8,0.7-1.5,2.1-2.1c1.5-0.7,3.7-1,6.4-1
c3.8,0,7.1,0.7,9.7,2c2.7,1.3,4.5,2.9,5.6,4.7l0.1,0.2h0.3h2.3h0.5v-0.5v-8.2V12.7L79.1,12.7z"/>
</g>
<g>
<g>
<path class="st3" d="M28.9,40.7L13.8,23c-0.6-0.7-1.2-1.2-1.8-1.5C11.4,21.2,9.6,21,8.2,21l-0.2,0v-1.4h21V21l-0.2,0
c-2.1,0.1-3.5,0.2-4.1,0.3C24,21.4,24,21.7,24,21.9c0,0.1,0,0.3,0,0.4c0,0.1,0.1,0.2,0.2,0.3l8.8,10.8h0.1l7.6-9.9
c0.2-0.2,0.3-0.4,0.4-0.6c0.3-0.4,0.3-0.7,0.3-0.8c0-0.3-0.1-0.7-0.8-0.8c-0.6-0.1-2-0.2-4-0.3l-0.2,0v-1.5h13.8v1.4l-0.2,0
c-1.5,0.1-3.4,0.3-4,0.6c-0.7,0.3-1.3,0.9-2,1.7L30.7,40.7H28.9z"/>
<path d="M50.1,19.7v1c-1.4,0.1-3.4,0.3-4.1,0.6c-0.7,0.3-1.4,0.9-2.1,1.8L30.6,40.4H29L13.9,22.8c-0.6-0.7-1.2-1.2-1.9-1.5
c-0.6-0.3-2.5-0.5-3.9-0.6v-1h20.5v1c-2.1,0.1-3.5,0.2-4.1,0.3c-0.6,0.1-0.9,0.4-0.9,0.9c0,0.1,0,0.3,0.1,0.4
c0.1,0.1,0.2,0.3,0.3,0.4L33,33.6h0.3l7.7-9.9c0.2-0.2,0.3-0.4,0.5-0.7c0.2-0.4,0.3-0.7,0.3-0.9c0-0.6-0.3-0.9-1-1
c-0.6-0.1-2-0.3-4-0.3v-1H50.1 M50.6,19.3h-0.5H36.8h-0.5v0.5v1v0.5l0.5,0c2,0.1,3.3,0.2,3.9,0.3c0.6,0.1,0.6,0.4,0.6,0.6
c0,0.1,0,0.3-0.3,0.7c-0.1,0.2-0.3,0.4-0.4,0.6l-7.5,9.7l-8.7-10.6c-0.1-0.1-0.2-0.2-0.2-0.3c0-0.1,0-0.2,0-0.3
c0-0.1,0-0.3,0.5-0.4c0.6-0.1,1.9-0.2,4-0.3l0.5,0v-0.5v-1v-0.5h-0.5H8.2H7.7v0.5v1v0.4l0.4,0c1.7,0.1,3.2,0.3,3.7,0.5
c0.6,0.3,1.2,0.8,1.7,1.4l15.1,17.6l0.1,0.2H29h1.6h0.2l0.1-0.2l13.4-17.3c0.6-0.8,1.3-1.3,1.9-1.6c0.5-0.3,2.1-0.5,3.9-0.6l0.4,0
v-0.4v-1V19.3L50.6,19.3z"/>
</g>
</g>
<g>
<path d="M14.7,87.2h-0.5l-1.2-7.3h0.5l1,6.3l1.1-6.3H16L14.7,87.2z"/>
<path d="M17.4,84.8v0.6c0,0.6,0,0.9,0.2,1.1c0.2,0.3,0.6,0.4,0.9,0.4c0.7,0,0.9-0.5,0.9-1.2c0-0.8-0.2-1.1-1.1-2
c-0.8-0.8-1.3-1.3-1.3-2.3c0-0.6,0.1-1.6,1.4-1.6c1.3,0,1.4,1,1.4,1.7V82h-0.5v-0.7c0-0.4,0-1.1-0.9-1.1c-0.6,0-0.9,0.4-0.9,1.1
s0.1,1,1.2,2.1c0.8,0.8,1.1,1.2,1.1,2.1c0,0.7-0.1,1.7-1.5,1.7c-0.9,0-1.5-0.4-1.5-1.5v-1H17.4z"/>
<path d="M22.3,80.3v6.9h-0.5v-6.9h-1.3v-0.5h3.1v0.5H22.3z"/>
<path d="M26.4,81.3v-0.8h0.4v0.8H26.4z M26.4,87.2V82h0.4v5.2H26.4z"/>
<path d="M28.2,85.3v0.5c0,0.3,0,1,0.8,1c0.4,0,0.8-0.2,0.8-0.9c0-0.5-0.1-0.7-0.9-1.3c-0.6-0.5-0.9-0.8-0.9-1.6
c0-0.4,0.1-1.1,1.1-1.1c1.1,0,1.1,0.8,1.1,1.2v0.4h-0.4v-0.4c0-0.6-0.2-0.8-0.6-0.8c-0.6,0-0.7,0.4-0.7,0.7c0,0.5,0,0.6,1,1.4
c0.5,0.4,0.8,0.7,0.8,1.4c0,0.8-0.3,1.3-1.2,1.3c-1.1,0-1.2-0.6-1.2-1.5v-0.4H28.2z"/>
<path d="M35.7,87.2c-0.4,0-0.6-0.1-0.7-0.4c-0.2,0.1-0.5,0.4-1,0.4c-0.7,0-1-0.6-1-1.2c0-1.5,1.4-1.6,2-2.2v-0.7
c0-0.4-0.1-0.7-0.6-0.7c-0.5,0-0.7,0.3-0.7,1v0.3h-0.4v-0.3c0-1,0.4-1.4,1.2-1.4c0.7,0,1.1,0.4,1.1,1.1v3.6c0,0.2,0.1,0.2,0.3,0.2
L35.7,87.2L35.7,87.2z M35,84.3c-0.3,0.2-0.6,0.3-0.9,0.5c-0.5,0.3-0.7,0.6-0.7,1.2c0,0.2,0,0.8,0.7,0.8c0.4,0,0.7-0.2,0.9-0.5
V84.3z"/>
<path d="M39.1,82v0.9c0.2-0.6,0.7-0.9,1.1-1.1v0.6c-0.1,0-0.3,0.1-0.4,0.2c-0.4,0.2-0.6,0.8-0.7,0.9v3.7h-0.4V82H39.1z"/>
<path d="M43.2,86c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3h-2v1.3
c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V86z M42.7,83.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5V83.2z"
/>
<path d="M46.6,87.6c0,0.9-0.6,1.3-1.3,1.3c-0.4,0-0.9-0.1-1-0.5c-0.1-0.1-0.1-0.3-0.1-0.6h0.4c0,0,0,0.2,0.1,0.4
c0.2,0.3,0.6,0.3,0.6,0.3c0.1,0,0.8-0.1,0.8-0.8v-0.9c-0.1,0.1-0.4,0.5-0.9,0.5c-0.7,0-1-0.6-1-1.2v-2.9c0-0.9,0.5-1.2,1.1-1.2
c0.5,0,0.8,0.3,0.9,0.5V82h0.4V87.6z M46.2,83c-0.1-0.4-0.4-0.7-0.8-0.7c-0.6,0-0.7,0.5-0.7,0.9v2.6c0,0.7,0.3,0.9,0.7,0.9
c0.3,0,0.7-0.2,0.8-0.8V83z"/>
<path d="M47.8,81.3v-0.8h0.4v0.8H47.8z M47.8,87.2V82h0.4v5.2H47.8z"/>
<path d="M49.6,85.3v0.5c0,0.3,0,1,0.8,1c0.4,0,0.8-0.2,0.8-0.9c0-0.5-0.1-0.7-0.9-1.3c-0.6-0.5-0.9-0.8-0.9-1.6
c0-0.4,0.1-1.1,1.1-1.1c1.1,0,1.1,0.8,1.1,1.2v0.4h-0.4v-0.4c0-0.6-0.2-0.8-0.6-0.8c-0.6,0-0.7,0.4-0.7,0.7c0,0.5,0,0.6,1,1.4
c0.5,0.4,0.8,0.7,0.8,1.4c0,0.8-0.3,1.3-1.2,1.3c-1.1,0-1.2-0.6-1.2-1.5v-0.4H49.6z"/>
<path d="M52.1,82h0.6v-1.4h0.4V82h0.8v0.4h-0.8v4.1c0,0.3,0.3,0.3,0.4,0.3c0.1,0,0.3,0,0.4,0v0.4c-0.2,0-0.3,0-0.5,0
c-0.6,0-0.8-0.2-0.8-0.6v-4.2h-0.6V82z"/>
<path d="M56.9,86c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3h-2v1.3
c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V86z M56.5,83.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5V83.2z"
/>
<path d="M58.4,82v0.9c0.2-0.6,0.7-0.9,1.1-1.1v0.6c-0.1,0-0.3,0.1-0.4,0.2c-0.4,0.2-0.6,0.8-0.7,0.9v3.7H58V82H58.4z"/>
<path d="M62.6,86c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3h-2v1.3
c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V86z M62.1,83.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5V83.2z"
/>
<path d="M65.6,87.2v-0.6c-0.1,0.2-0.4,0.6-1,0.6c-0.5,0-1-0.3-1-1.2v-2.8c0-0.9,0.5-1.3,1.1-1.3c0.6,0,0.8,0.4,0.9,0.5v-2.6H66v7.3
H65.6z M65.6,83.3c-0.1-0.5-0.3-0.9-0.8-0.9c-0.5,0-0.7,0.4-0.7,0.8v2.7c0,0.3,0.1,0.9,0.7,0.9c0.4,0,0.7-0.4,0.8-0.8V83.3z"/>
<path d="M68.8,82h0.6v-1.4h0.4V82h0.8v0.4h-0.8v4.1c0,0.3,0.3,0.3,0.4,0.3c0.1,0,0.3,0,0.4,0v0.4c-0.2,0-0.3,0-0.5,0
c-0.6,0-0.8-0.2-0.8-0.6v-4.2h-0.6V82z"/>
<path d="M71.7,82v0.9c0.2-0.6,0.7-0.9,1.1-1.1v0.6c-0.1,0-0.3,0.1-0.4,0.2c-0.4,0.2-0.6,0.8-0.7,0.9v3.7h-0.4V82H71.7z"/>
<path d="M76,87.2c-0.4,0-0.6-0.1-0.7-0.4c-0.2,0.1-0.5,0.4-1,0.4c-0.7,0-1-0.6-1-1.2c0-1.5,1.4-1.6,2-2.2v-0.7
c0-0.4-0.1-0.7-0.6-0.7c-0.5,0-0.7,0.3-0.7,1v0.3h-0.4v-0.3c0-1,0.4-1.4,1.2-1.4c0.8,0,1.1,0.4,1.1,1.1v3.6c0,0.2,0.1,0.2,0.3,0.2
L76,87.2L76,87.2z M75.3,84.3c-0.3,0.2-0.6,0.3-0.9,0.5c-0.5,0.3-0.7,0.6-0.7,1.2c0,0.2,0,0.8,0.7,0.8c0.4,0,0.7-0.2,0.9-0.5V84.3z
"/>
<path d="M78.9,87.2v-0.6c-0.1,0.2-0.4,0.6-1,0.6c-0.5,0-1-0.3-1-1.2v-2.8c0-0.9,0.5-1.3,1.1-1.3c0.6,0,0.8,0.4,0.9,0.5v-2.6h0.4
v7.3H78.9z M78.8,83.3c-0.1-0.5-0.3-0.9-0.8-0.9c-0.5,0-0.7,0.4-0.7,0.8v2.7c0,0.3,0.1,0.9,0.7,0.9c0.4,0,0.8-0.4,0.8-0.8V83.3z"/>
<path d="M82.8,86c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3h-2v1.3
c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V86z M82.3,83.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5V83.2z"
/>
<path d="M87.8,87.2v-4c0-0.5-0.1-0.9-0.7-0.9c-0.4,0-0.7,0.3-0.9,0.6v4.2h-0.4V83c0-0.5-0.2-0.7-0.7-0.7c-0.5,0-0.8,0.4-0.8,0.6
v4.3h-0.4V82h0.4v0.4c0.1-0.2,0.5-0.5,1-0.5c0.6,0,0.8,0.4,0.9,0.6c0.1-0.2,0.4-0.6,1.1-0.6c0.5,0,1,0.3,1,1.2v4.2H87.8z"/>
<path d="M91.8,87.2c-0.4,0-0.6-0.1-0.7-0.4c-0.2,0.1-0.5,0.4-1,0.4c-0.7,0-1-0.6-1-1.2c0-1.5,1.4-1.6,2-2.2v-0.7
c0-0.4-0.1-0.7-0.6-0.7c-0.5,0-0.7,0.3-0.7,1v0.3h-0.4v-0.3c0-1,0.4-1.4,1.2-1.4c0.7,0,1.1,0.4,1.1,1.1v3.6c0,0.2,0.1,0.2,0.3,0.2
L91.8,87.2L91.8,87.2z M91.2,84.3c-0.3,0.2-0.6,0.3-0.9,0.5c-0.5,0.3-0.7,0.6-0.7,1.2c0,0.2,0,0.8,0.7,0.8c0.4,0,0.7-0.2,0.9-0.5
V84.3z"/>
<path d="M93.2,82v0.9c0.2-0.6,0.7-0.9,1.1-1.1v0.6c-0.1,0-0.3,0.1-0.4,0.2c-0.4,0.2-0.6,0.8-0.7,0.9v3.7h-0.4V82H93.2z"/>
<path d="M97.1,87.2l-1.1-2.8l-0.5,0.8v1.9H95v-7.3h0.4v4.6l1.5-2.5h0.5l-1.2,2l1.3,3.2H97.1z"/>
<path d="M102.7,85.8c0,1-0.6,1.4-1.2,1.4c-0.7,0-1.2-0.4-1.2-1.1v-2.9c0-0.6,0.3-1.3,1.3-1.3c0.8,0,1.2,0.5,1.2,1.3V85.8z
M102.3,83.3c0-0.4-0.1-0.9-0.7-0.9c-0.7,0-0.8,0.5-0.8,1v2.6c0,0.6,0.3,0.8,0.8,0.8c0.7,0,0.8-0.6,0.8-0.9V83.3z"/>
<path d="M103.4,82h0.6v-1.3c0-0.4,0.2-0.8,0.9-0.8c0.1,0,0.2,0,0.3,0v0.4c0,0-0.1,0-0.2,0c-0.3,0-0.6,0.1-0.6,0.6V82h0.6v0.4h-0.7
v4.8H104v-4.8h-0.6V82z"/>
<path d="M7.5,96.8v0.6c0,0.6,0,0.9,0.2,1.1c0.2,0.3,0.6,0.4,0.9,0.4c0.7,0,0.9-0.5,0.9-1.2c0-0.8-0.2-1.1-1.1-2
c-0.8-0.8-1.3-1.3-1.3-2.3c0-0.6,0.1-1.6,1.4-1.6c1.3,0,1.4,1,1.4,1.7V94H9.4v-0.7c0-0.4,0-1.1-0.9-1.1c-0.6,0-0.9,0.4-0.9,1.1
s0.1,1,1.2,2.1c0.8,0.8,1.1,1.2,1.1,2.1c0,0.7-0.1,1.7-1.5,1.7c-0.9,0-1.5-0.4-1.5-1.5v-1H7.5z"/>
<path d="M10.5,94H11v-1.4h0.4V94h0.8v0.4h-0.8v4.1c0,0.3,0.3,0.3,0.4,0.3c0.1,0,0.3,0,0.4,0v0.4c-0.2,0-0.3,0-0.5,0
c-0.6,0-0.8-0.2-0.8-0.6v-4.2h-0.6V94z"/>
<path d="M15.3,98.1c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3h-2V98
c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V98.1z M14.8,95.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5V95.2
z"/>
<path d="M16.3,93.4v-0.8h0.4v0.8H16.3z M16.3,99.2V94h0.4v5.2H16.3z"/>
<path d="M19.9,99.2v-4.1c0-0.4-0.1-0.8-0.6-0.8c-0.4,0-0.7,0.2-0.9,0.7v4.3H18V94h0.4v0.5c0.3-0.5,0.8-0.6,1-0.6c0.4,0,1,0.2,1,1.1
v4.2H19.9z"/>
<path d="M21.5,91.9H22v2.6c0.3-0.4,0.7-0.5,1-0.5c0.9,0,1,0.8,1,1.3V98c0,0.5-0.3,1.2-1.1,1.2c-0.1,0-0.6,0-0.8-0.5v0.4h-0.5V91.9z
M22,97.8c0,0.9,0.6,1,0.8,1c0.5,0,0.7-0.4,0.7-1v-2.6c0-0.2,0-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9V97.8z"/>
<path d="M27.4,98.1c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3h-2V98
c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V98.1z M26.9,95.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5V95.2
z"/>
<path d="M28.9,94v0.9c0.2-0.6,0.7-0.9,1.1-1.1v0.6c-0.1,0-0.3,0.1-0.4,0.2c-0.4,0.2-0.6,0.8-0.7,0.9v3.7h-0.4V94H28.9z"/>
<path d="M33.1,99.6c0,0.9-0.6,1.3-1.3,1.3c-0.4,0-0.9-0.1-1-0.5c-0.1-0.1-0.1-0.3-0.1-0.6h0.4c0,0,0,0.2,0.1,0.4
c0.2,0.3,0.6,0.3,0.6,0.3c0.1,0,0.8-0.1,0.8-0.8v-0.9c-0.1,0.1-0.4,0.5-0.9,0.5c-0.7,0-1-0.6-1-1.2v-2.9c0-0.9,0.5-1.2,1.1-1.2
c0.5,0,0.8,0.3,0.9,0.5V94h0.4V99.6z M32.6,95.1c-0.1-0.4-0.4-0.7-0.8-0.7c-0.6,0-0.7,0.5-0.7,0.9v2.6c0,0.7,0.3,0.9,0.7,0.9
c0.3,0,0.7-0.2,0.8-0.8V95.1z"/>
<path d="M39.9,99.2c0-0.5,0-5.1,0-6.8l-1.3,6.8h-0.5l-1.3-6.8v6.8h-0.5c0-0.5,0.1-7.3,0.1-7.3h0.7l1.2,6.3l1.2-6.3h0.7
c0,0.8,0.1,7.3,0.1,7.3H39.9z"/>
<path d="M43.9,98.1c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3h-2V98
c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V98.1z M43.5,95.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5V95.2
z"/>
<path d="M46.9,99.2v-0.6c-0.1,0.2-0.4,0.6-1,0.6c-0.5,0-1-0.3-1-1.2v-2.8c0-0.9,0.5-1.3,1.1-1.3c0.6,0,0.8,0.4,0.9,0.5v-2.6h0.4
v7.3H46.9z M46.9,95.3c-0.1-0.5-0.3-0.9-0.8-0.9c-0.5,0-0.7,0.4-0.7,0.8V98c0,0.3,0.1,0.9,0.7,0.9c0.4,0,0.7-0.4,0.8-0.8V95.3z"/>
<path d="M48.5,93.4v-0.8H49v0.8H48.5z M48.5,99.2V94H49v5.2H48.5z"/>
<path d="M52.6,99.2c-0.4,0-0.6-0.1-0.7-0.4c-0.2,0.1-0.5,0.4-1,0.4c-0.7,0-1-0.6-1-1.2c0-1.5,1.4-1.6,2-2.2v-0.7
c0-0.4-0.1-0.7-0.6-0.7c-0.5,0-0.7,0.3-0.7,1v0.3h-0.4v-0.3c0-1,0.4-1.4,1.2-1.4c0.7,0,1.1,0.4,1.1,1.1v3.6c0,0.2,0.1,0.2,0.3,0.2
L52.6,99.2L52.6,99.2z M52,96.3c-0.3,0.2-0.6,0.3-0.9,0.5c-0.5,0.3-0.7,0.6-0.7,1.2c0,0.2,0,0.8,0.7,0.8c0.4,0,0.7-0.2,0.9-0.5
V96.3z"/>
<path d="M56.9,92.3v6.9h-0.5v-6.9h-1.3v-0.5h3.1v0.5H56.9z"/>
<path d="M60.6,98.1c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3h-2V98
c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V98.1z M60.2,95.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5V95.2
z"/>
<path d="M64.1,97.9c0,0.8-0.3,1.4-1.3,1.4c-0.9,0-1.2-0.7-1.2-1.3v-2.6c0-1,0.5-1.3,1.2-1.3c0.8,0,1.2,0.5,1.2,1.4v0.5h-0.4v-0.4
c0-0.5-0.1-1.1-0.8-1.1c-0.7,0-0.8,0.6-0.8,1v2.3c0,0.5,0,1.2,0.8,1.2c0.6,0,0.7-0.5,0.7-0.9v-0.8h0.5V97.9z"/>
<path d="M67,99.2v-3.9c0-0.5-0.1-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.7v4.2h-0.4v-7.3h0.4v2.5c0.1-0.1,0.4-0.5,0.9-0.5
c0.4,0,1,0.2,1,1.1v4.2H67z"/>
<path d="M70.6,99.2v-4.1c0-0.4-0.1-0.8-0.6-0.8c-0.4,0-0.7,0.2-0.9,0.7v4.3h-0.4V94h0.4v0.5c0.3-0.5,0.8-0.6,1-0.6
c0.4,0,1,0.2,1,1.1v4.2H70.6z"/>
<path d="M74.6,97.9c0,1-0.6,1.4-1.2,1.4c-0.7,0-1.2-0.4-1.2-1.1v-2.9c0-0.6,0.3-1.3,1.3-1.3c0.8,0,1.2,0.5,1.2,1.3V97.9z
M74.1,95.3c0-0.4-0.1-0.9-0.7-0.9c-0.7,0-0.8,0.5-0.8,1V98c0,0.6,0.3,0.8,0.8,0.8c0.7,0,0.8-0.6,0.8-0.9V95.3z"/>
<path d="M75.6,99.2v-7.3h0.4v7.3H75.6z"/>
<path d="M79.7,97.9c0,1-0.6,1.4-1.2,1.4c-0.7,0-1.2-0.4-1.2-1.1v-2.9c0-0.6,0.3-1.3,1.3-1.3c0.8,0,1.2,0.5,1.2,1.3V97.9z
M79.2,95.3c0-0.4-0.1-0.9-0.7-0.9c-0.7,0-0.8,0.5-0.8,1V98c0,0.6,0.3,0.8,0.8,0.8c0.7,0,0.8-0.6,0.8-0.9V95.3z"/>
<path d="M83.2,99.6c0,0.9-0.6,1.3-1.3,1.3c-0.4,0-0.9-0.1-1-0.5c-0.1-0.1-0.1-0.3-0.1-0.6h0.4c0,0,0,0.2,0.1,0.4
c0.2,0.3,0.6,0.3,0.6,0.3c0.1,0,0.8-0.1,0.8-0.8v-0.9c-0.1,0.1-0.4,0.5-0.9,0.5c-0.8,0-1-0.6-1-1.2v-2.9c0-0.9,0.5-1.2,1.1-1.2
c0.5,0,0.8,0.3,0.9,0.5V94h0.4V99.6z M82.8,95.1c-0.1-0.4-0.4-0.7-0.8-0.7c-0.6,0-0.7,0.5-0.7,0.9v2.6c0,0.7,0.3,0.9,0.7,0.9
c0.3,0,0.7-0.2,0.8-0.8V95.1z"/>
<path d="M84.4,93.4v-0.8h0.4v0.8H84.4z M84.4,99.2V94h0.4v5.2H84.4z"/>
<path d="M88.3,98.1c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3h-2V98
c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V98.1z M87.9,95.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5V95.2
z"/>
<path d="M89.6,97.4v0.5c0,0.3,0,1,0.8,1c0.4,0,0.8-0.2,0.8-0.9c0-0.5-0.1-0.7-0.9-1.3c-0.6-0.5-0.9-0.8-0.9-1.6
c0-0.4,0.1-1.1,1.1-1.1c1.1,0,1.1,0.8,1.1,1.2v0.4h-0.4v-0.4c0-0.6-0.2-0.8-0.6-0.8c-0.6,0-0.7,0.4-0.7,0.7c0,0.5,0,0.6,1,1.4
c0.5,0.4,0.8,0.7,0.8,1.4c0,0.8-0.3,1.3-1.2,1.3c-1.1,0-1.2-0.6-1.2-1.5v-0.4H89.6z"/>
<path d="M97.2,99.2v-0.6c-0.1,0.2-0.5,0.7-1.2,0.7c-0.4,0-0.9-0.2-1.1-0.6c-0.2-0.4-0.3-0.7-0.3-1.4v-3.9c0-1,0.4-1.6,1.5-1.6
c1.1,0,1.4,0.7,1.4,1.3v1.1h-0.5v-0.9c0-0.6-0.1-1.1-1-1.1c-0.8,0-1,0.6-1,1.2v3.8c0,0.6,0,0.9,0.1,1.2c0.1,0.2,0.3,0.5,0.8,0.5
c0.7,0,1-0.8,1-1.2v-1.3H96v-0.4h1.6v3.4H97.2z"/>
<path d="M102.7,99.2v-4c0-0.5-0.1-0.9-0.7-0.9c-0.4,0-0.7,0.3-0.9,0.6v4.2h-0.4v-4.2c0-0.5-0.2-0.7-0.7-0.7c-0.5,0-0.8,0.4-0.8,0.6
v4.3h-0.4V94h0.4v0.4c0.1-0.2,0.5-0.5,1-0.5c0.6,0,0.8,0.4,0.9,0.6c0.1-0.2,0.4-0.6,1.1-0.6c0.5,0,1,0.3,1,1.2v4.2H102.7z"/>
<path d="M104.3,91.9h0.4v2.6c0.3-0.4,0.7-0.5,1-0.5c0.9,0,1,0.8,1,1.3V98c0,0.5-0.3,1.2-1.1,1.2c-0.1,0-0.6,0-0.8-0.5v0.4h-0.5
V91.9z M104.8,97.8c0,0.9,0.6,1,0.8,1c0.5,0,0.7-0.4,0.7-1v-2.6c0-0.2,0-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9V97.8z"/>
<path d="M110.2,99.2v-3.4h-1.8v3.4h-0.5v-7h0.5v3.1h1.8v-3.1h0.5v7H110.2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

@@ -0,0 +1,215 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 116.2 107.7" style="enable-background:new 0 0 116.2 107.7;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#030304;stroke:#FFFFFF;stroke-width:0.8877;stroke-miterlimit:10;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
.st2{fill:#030304;}
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#030304;}
.st4{fill:#FFFFFF;}
</style>
<g>
<rect x="1.8" y="1.2" class="st0" width="112.8" height="105.5"/>
</g>
<rect x="3.6" y="3" class="st1" width="109.2" height="69.5"/>
<g>
<path class="st2" d="M20.3,58.5c-0.4,0.9-1.6,3.3-4.7,3.3c-2.6,0-5.1-1.7-5.1-5.8c0-2.4,1.4-5.6,5.1-5.6c2.8,0,3.9,1.8,4.4,3.3
l-2,0.5c-0.1-1.2-1.1-2-2.3-2c-1.8,0-3,1.3-3,3.8c0,1.5,0.6,3.8,3,3.8c1.4,0,2.3-1.1,2.6-2.2L20.3,58.5z"/>
<path class="st2" d="M26.8,50.4c3.3,0,5.2,2.7,5.2,5.6c0,2.5-1.3,5.8-5.2,5.8c-3.2,0-5.2-2.6-5.2-5.7C21.6,53,23.6,50.4,26.8,50.4z
M26.8,59.9c1.6,0,3.1-1.2,3.1-3.7c0-1.9-1-3.9-3.2-3.9c-1.8,0-3.1,1.4-3.1,3.8C23.7,57.8,24.5,59.9,26.8,59.9z"/>
<path class="st2" d="M41.9,61.5c0-0.3,0.2-8.9,0.2-8.9l-2.3,8.9h-1.8l-2.3-8.9c0,0,0.2,8.5,0.2,8.9h-2V50.7h2.9l2.1,8l2.1-8h2.9
v10.8H41.9z"/>
<path class="st2" d="M51.2,50.7c2.2,0,3.8,1.4,3.8,3.6c0,2-1.1,3.5-4,3.5H49v3.7h-2V50.7H51.2z M49,56.2h1.8c1.4,0,2.2-0.7,2.2-1.9
c0-1.7-1.4-1.8-2.4-1.8H49V56.2z"/>
<path class="st2" d="M62.6,61.5l-0.6-2.1h-4.1l-0.6,2.1h-2.2l3.7-10.8H61l3.7,10.8H62.6z M59.9,52.7l-1.5,5h3L59.9,52.7z"/>
<path class="st2" d="M68.9,52.5v9h-2v-9H64v-1.8h8v1.8H68.9z"/>
<path class="st2" d="M73.5,61.5V50.7h2v10.8H73.5z"/>
<path class="st2" d="M83.4,50.7c2.3,0,3.3,1.3,3.3,2.7c0,0.9-0.5,2.1-1.8,2.2c1,0.2,2.3,1,2.3,2.9c0,1.5-0.9,3.1-3.6,3.1h-5V50.7
H83.4z M80.6,55.1h2c0.9,0,2-0.3,2-1.4c0-1.1-1.1-1.3-1.9-1.3h-2.1V55.1z M80.6,59.8h2.7c1.4,0,1.9-0.7,1.9-1.5
c0-1.5-1.5-1.7-2.3-1.7h-2.3V59.8z"/>
<path class="st2" d="M89.8,61.5V50.7h2v9h4.3v1.8H89.8z"/>
<path class="st2" d="M97.4,61.5V50.7h7.7v1.8h-5.7v2.5h5.2v1.7h-5.2v2.9h6.1v1.8H97.4z"/>
</g>
<path class="st3" d="M69.3,19h36.2l0.1,6.4h-1.7c-0.6-2.2-2.2-3.7-4.9-4.4c-1.5-0.4-3.8-0.7-6.8-0.7v16c0,1.1,0.4,1.6,1.1,1.9
c0.8,0.4,2.4,0.4,4.8,0.4v1.4H76.8v-1.4c2.3,0,3.9-0.2,4.7-0.5c0.8-0.4,1.2-0.7,1.2-1.8v-16c-2.9,0-5.2,0.3-6.7,0.7
c-2.9,0.8-4.5,2.3-4.9,4.4c-0.5,0-1.7,0-1.7,0L69.3,19z"/>
<g>
<path class="st3" d="M40.9,29.8l3.3,0.4l0.1,0.1c1.3,2.7,3.4,4.8,6.3,6c2.9,1.3,6.3,1.9,10.1,1.9c3.6,0,6.3-0.4,7.8-1.3
c1.5-0.8,2.2-1.7,2.2-2.6c0-1-0.8-1.9-2.3-2.5c-1.1-0.5-3.3-1.1-6.5-1.8l-5.3-1.2c-5.2-1.2-9-2.4-11.1-3.6C43.1,24,42,22.5,42,20.7
c0-1.9,1.5-3.7,4.4-5.4c2.9-1.6,7.3-2.4,13.2-2.4c3,0,5.9,0.2,8.7,0.6c1.8,0.3,4.3,0.6,4.8,0.6c1.1,0,1.5-0.2,1.7-0.3
c0.3-0.2,0.6-0.5,0.8-0.9l0.1-0.1h2.8v8.7h-2.6l-0.1-0.1c-1.1-1.8-3-3.5-5.7-4.8c-2.7-1.4-6-2-9.8-2c-2.7,0-4.9,0.3-6.4,1
c-1.5,0.6-2.2,1.4-2.2,2.3c0,1.1,0.7,1.9,2.1,2.5c1.5,0.6,4.8,1.5,9.8,2.6l6.1,1.4c2.7,0.6,4.9,1.3,6.5,2.1
c3.1,1.5,4.7,3.3,4.7,5.4c0,2-1.7,3.9-5,5.6C72.4,39.2,67.2,40,60,40c-1.6,0-3.3-0.1-5-0.2c-1.7-0.1-3.4-0.4-5-0.6l-1.6-0.3
c-0.4,0-0.7-0.1-1-0.1c-0.3,0-0.6-0.1-0.9-0.1c-0.8,0-1.3,0.1-1.6,0.3c-0.3,0.2-0.5,0.5-0.8,0.9L44.1,40l-3.2,0V29.8z"/>
<path class="st4" d="M78.1,13.1v8.2h-2.3c-1.1-1.9-3-3.5-5.7-4.9c-2.7-1.4-6-2.1-9.9-2.1c-2.8,0-4.9,0.3-6.5,1
c-1.6,0.7-2.4,1.5-2.4,2.5c0,1.2,0.8,2.1,2.3,2.7c1.5,0.6,4.8,1.5,9.9,2.6l6.1,1.4c2.7,0.6,4.9,1.3,6.5,2.1c3,1.4,4.5,3.2,4.5,5.2
c0,1.9-1.6,3.7-4.9,5.4c-3.2,1.7-8.4,2.5-15.5,2.5c-1.6,0-3.3-0.1-5-0.2c-1.7-0.1-3.3-0.3-5-0.6l-1.6-0.3c-0.4,0-0.7-0.1-1.1-0.1
c-0.3,0-0.6-0.1-0.9-0.1c-0.8,0-1.4,0.1-1.7,0.3c-0.3,0.2-0.6,0.5-0.8,1l-2.9,0v-9.7l2.9,0.4c1.3,2.8,3.4,4.9,6.4,6.1
c3,1.3,6.3,1.9,10.1,1.9c3.7,0,6.3-0.4,7.9-1.3c1.6-0.9,2.3-1.8,2.3-2.8c0-1.1-0.8-2-2.5-2.8c-1.1-0.5-3.3-1.1-6.5-1.8l-5.3-1.2
c-5.2-1.2-8.9-2.4-11.1-3.6c-2.1-1.2-3.2-2.6-3.2-4.4c0-1.8,1.4-3.6,4.2-5.2c2.9-1.6,7.2-2.4,13.1-2.4c3,0,5.9,0.2,8.6,0.6
c2.8,0.4,4.4,0.6,4.8,0.6c0.9,0,1.5-0.1,1.9-0.3c0.3-0.2,0.6-0.6,0.8-1H78.1 M78.5,12.6h-0.5h-2.4h-0.3l-0.1,0.2
c-0.2,0.3-0.4,0.6-0.7,0.8c-0.1,0.1-0.5,0.3-1.6,0.3c-0.5,0-3.7-0.5-4.7-0.6c-2.8-0.4-5.7-0.6-8.7-0.6c-5.9,0-10.4,0.8-13.3,2.5
c-3,1.7-4.5,3.5-4.5,5.6c0,1.9,1.2,3.5,3.5,4.8c2.2,1.2,5.9,2.4,11.2,3.6l5.3,1.2c3.2,0.7,5.4,1.3,6.5,1.8c1.4,0.6,2.2,1.4,2.2,2.3
c0,0.8-0.7,1.6-2.1,2.4c-1.5,0.8-4.1,1.2-7.7,1.2c-3.7,0-7.1-0.6-10-1.9c-2.8-1.2-4.9-3.2-6.1-5.9L44.3,30l-0.3,0l-2.9-0.4
l-0.5-0.1v0.5v9.7v0.5l0.5,0l2.9,0l0.3,0l0.1-0.2c0.2-0.4,0.4-0.6,0.7-0.8c0.1-0.1,0.5-0.3,1.5-0.3c0.2,0,0.5,0,0.8,0.1
c0.3,0,0.7,0.1,1.1,0.1l1.6,0.3c1.6,0.3,3.3,0.5,5,0.6c1.7,0.1,3.4,0.2,5,0.2c7.2,0,12.5-0.9,15.8-2.6c3.4-1.8,5.1-3.7,5.1-5.8
c0-2.2-1.6-4.1-4.8-5.6c-1.6-0.8-3.9-1.5-6.6-2.1l-6.1-1.4c-5-1.1-8.3-2-9.8-2.6c-1.3-0.5-2-1.3-2-2.2c0-0.8,0.7-1.5,2.1-2.1
c1.5-0.7,3.7-1,6.4-1c3.8,0,7.1,0.7,9.7,2c2.7,1.3,4.5,2.9,5.6,4.7l0.1,0.2h0.3h2.3h0.5v-0.5v-8.2V12.6L78.5,12.6z"/>
</g>
<g>
<g>
<path class="st3" d="M28.3,40.6L13.2,22.9c-0.6-0.7-1.2-1.2-1.8-1.5c-0.6-0.3-2.3-0.5-3.8-0.5l-0.2,0v-1.4h21v1.5l-0.2,0
c-2.1,0.1-3.4,0.1-4.1,0.3c-0.7,0.1-0.7,0.4-0.7,0.7c0,0.1,0,0.3,0,0.4c0,0.1,0.1,0.2,0.2,0.3l8.8,10.8h0.1l7.6-9.9
c0.2-0.2,0.3-0.4,0.4-0.6c0.3-0.4,0.3-0.7,0.3-0.8c0-0.3-0.1-0.7-0.8-0.8c-0.6-0.1-2-0.2-4-0.3l-0.2,0v-1.5h13.8v1.4l-0.2,0
c-1.5,0.1-3.4,0.3-4,0.6c-0.7,0.3-1.3,0.9-2,1.7L30.1,40.6H28.3z"/>
<path class="st4" d="M49.5,19.7v1c-1.4,0.1-3.4,0.3-4.1,0.6c-0.7,0.3-1.4,0.9-2.1,1.8L30,40.4h-1.6L13.3,22.7
c-0.6-0.7-1.2-1.2-1.9-1.5c-0.6-0.3-2.5-0.5-3.9-0.6v-1h20.5v1c-2.1,0.1-3.5,0.2-4.1,0.3c-0.6,0.1-0.9,0.4-0.9,0.9
c0,0.1,0,0.3,0.1,0.4c0.1,0.1,0.2,0.3,0.3,0.4l8.9,10.9h0.3l7.7-9.9c0.2-0.2,0.3-0.4,0.5-0.7c0.2-0.4,0.3-0.7,0.3-0.9
c0-0.6-0.3-0.9-1-1c-0.6-0.1-2-0.3-4-0.3v-1H49.5 M50,19.2h-0.5H36.2h-0.5v0.5v1v0.5l0.5,0c2,0.1,3.3,0.2,3.9,0.3
c0.6,0.1,0.6,0.4,0.6,0.6c0,0.1,0,0.3-0.3,0.7c-0.1,0.2-0.3,0.4-0.4,0.6L32.5,33l-8.7-10.6c-0.1-0.1-0.2-0.2-0.2-0.3
c0-0.1,0-0.2,0-0.3c0-0.1,0-0.3,0.5-0.4c0.6-0.1,1.9-0.2,4-0.3l0.5,0v-0.5v-1v-0.5h-0.5H7.6H7.1v0.5v1v0.4l0.4,0
c1.7,0.1,3.2,0.3,3.7,0.5c0.6,0.3,1.2,0.8,1.7,1.4l15.1,17.6l0.1,0.2h0.2H30h0.2l0.1-0.2l13.4-17.3c0.6-0.8,1.3-1.3,1.9-1.6
c0.5-0.3,2.1-0.5,3.9-0.6l0.4,0v-0.4v-1V19.2L50,19.2z"/>
</g>
</g>
<g>
<path class="st4" d="M14.1,87.1h-0.5l-1.2-7.3h0.5l1,6.3l1.1-6.3h0.5L14.1,87.1z"/>
<path class="st4" d="M16.8,84.7v0.6c0,0.6,0,0.9,0.2,1.1c0.2,0.3,0.6,0.4,0.9,0.4c0.7,0,0.9-0.5,0.9-1.2c0-0.8-0.2-1.1-1.1-2
c-0.8-0.8-1.3-1.3-1.3-2.3c0-0.6,0.1-1.6,1.4-1.6c1.3,0,1.4,1,1.4,1.7v0.5h-0.5v-0.7c0-0.4,0-1.1-0.9-1.1c-0.6,0-0.9,0.4-0.9,1.1
s0.1,1,1.2,2.1c0.8,0.8,1.1,1.2,1.1,2.1c0,0.7-0.1,1.7-1.5,1.7c-0.9,0-1.5-0.4-1.5-1.5v-1H16.8z"/>
<path class="st4" d="M21.7,80.2v6.9h-0.5v-6.9h-1.3v-0.5H23v0.5H21.7z"/>
<path class="st4" d="M25.8,81.3v-0.8h0.4v0.8H25.8z M25.8,87.1v-5.2h0.4v5.2H25.8z"/>
<path class="st4" d="M27.6,85.3v0.5c0,0.3,0,1,0.8,1c0.4,0,0.8-0.2,0.8-0.9c0-0.5-0.1-0.7-0.9-1.3c-0.6-0.5-0.9-0.8-0.9-1.6
c0-0.4,0.1-1.1,1.1-1.1c1.1,0,1.1,0.8,1.1,1.2v0.4h-0.4v-0.4c0-0.6-0.2-0.8-0.6-0.8c-0.6,0-0.7,0.4-0.7,0.7c0,0.5,0,0.6,1,1.4
c0.5,0.4,0.8,0.7,0.8,1.4c0,0.8-0.3,1.3-1.2,1.3c-1.1,0-1.2-0.6-1.2-1.5v-0.4H27.6z"/>
<path class="st4" d="M35.1,87.1c-0.4,0-0.6-0.1-0.7-0.4c-0.2,0.1-0.5,0.4-1,0.4c-0.7,0-1-0.6-1-1.2c0-1.5,1.4-1.6,2-2.2V83
c0-0.4-0.1-0.7-0.6-0.7c-0.5,0-0.7,0.3-0.7,1v0.3h-0.4v-0.3c0-1,0.4-1.4,1.2-1.4c0.7,0,1.1,0.4,1.1,1.1v3.6c0,0.2,0.1,0.2,0.3,0.2
L35.1,87.1L35.1,87.1z M34.4,84.2c-0.3,0.2-0.6,0.3-0.9,0.5c-0.5,0.3-0.7,0.6-0.7,1.2c0,0.2,0,0.8,0.7,0.8c0.4,0,0.7-0.2,0.9-0.5
V84.2z"/>
<path class="st4" d="M38.5,81.9v0.9c0.2-0.6,0.7-0.9,1.1-1.1v0.6c-0.1,0-0.3,0.1-0.4,0.2c-0.4,0.2-0.6,0.8-0.7,0.9v3.7H38v-5.2
H38.5z"/>
<path class="st4" d="M42.6,85.9c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4
v1.3h-2v1.3c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V85.9z M42.1,83.1c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9
v1h1.5V83.1z"/>
<path class="st4" d="M46,87.5c0,0.9-0.6,1.3-1.3,1.3c-0.4,0-0.9-0.1-1-0.5c-0.1-0.1-0.1-0.3-0.1-0.6H44c0,0,0,0.2,0.1,0.4
c0.2,0.3,0.6,0.3,0.6,0.3c0.1,0,0.8-0.1,0.8-0.8v-0.9c-0.1,0.1-0.4,0.5-0.9,0.5c-0.7,0-1-0.6-1-1.2V83c0-0.9,0.5-1.2,1.1-1.2
c0.5,0,0.8,0.3,0.9,0.5v-0.4H46V87.5z M45.6,83c-0.1-0.4-0.4-0.7-0.8-0.7c-0.6,0-0.7,0.5-0.7,0.9v2.6c0,0.7,0.3,0.9,0.7,0.9
c0.3,0,0.7-0.2,0.8-0.8V83z"/>
<path class="st4" d="M47.2,81.3v-0.8h0.4v0.8H47.2z M47.2,87.1v-5.2h0.4v5.2H47.2z"/>
<path class="st4" d="M49,85.3v0.5c0,0.3,0,1,0.8,1c0.4,0,0.8-0.2,0.8-0.9c0-0.5-0.1-0.7-0.9-1.3c-0.6-0.5-0.9-0.8-0.9-1.6
c0-0.4,0.1-1.1,1.1-1.1c1.1,0,1.1,0.8,1.1,1.2v0.4h-0.4v-0.4c0-0.6-0.2-0.8-0.6-0.8c-0.6,0-0.7,0.4-0.7,0.7c0,0.5,0,0.6,1,1.4
c0.5,0.4,0.8,0.7,0.8,1.4c0,0.8-0.3,1.3-1.2,1.3c-1.1,0-1.2-0.6-1.2-1.5v-0.4H49z"/>
<path class="st4" d="M51.5,81.9h0.6v-1.4h0.4v1.4h0.8v0.4h-0.8v4.1c0,0.3,0.3,0.3,0.4,0.3c0.1,0,0.3,0,0.4,0v0.4
c-0.2,0-0.3,0-0.5,0c-0.6,0-0.8-0.2-0.8-0.6v-4.2h-0.6V81.9z"/>
<path class="st4" d="M56.3,85.9c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4
v1.3h-2v1.3c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V85.9z M55.9,83.1c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9
v1h1.5V83.1z"/>
<path class="st4" d="M57.8,81.9v0.9c0.2-0.6,0.7-0.9,1.1-1.1v0.6c-0.1,0-0.3,0.1-0.4,0.2c-0.4,0.2-0.6,0.8-0.7,0.9v3.7h-0.4v-5.2
H57.8z"/>
<path class="st4" d="M62,85.9c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3
h-2v1.3c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4H62V85.9z M61.5,83.1c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1
h1.5V83.1z"/>
<path class="st4" d="M65,87.1v-0.6c-0.1,0.2-0.4,0.6-1,0.6c-0.5,0-1-0.3-1-1.2v-2.8c0-0.9,0.5-1.3,1.1-1.3c0.6,0,0.8,0.4,0.9,0.5
v-2.6h0.4v7.3H65z M65,83.2c-0.1-0.5-0.3-0.9-0.8-0.9c-0.5,0-0.7,0.4-0.7,0.8v2.7c0,0.3,0.1,0.9,0.7,0.9c0.4,0,0.7-0.4,0.8-0.8
V83.2z"/>
<path class="st4" d="M68.2,81.9h0.6v-1.4h0.4v1.4H70v0.4h-0.8v4.1c0,0.3,0.3,0.3,0.4,0.3c0.1,0,0.3,0,0.4,0v0.4c-0.2,0-0.3,0-0.5,0
c-0.6,0-0.8-0.2-0.8-0.6v-4.2h-0.6V81.9z"/>
<path class="st4" d="M71.1,81.9v0.9c0.2-0.6,0.7-0.9,1.1-1.1v0.6c-0.1,0-0.3,0.1-0.4,0.2c-0.4,0.2-0.6,0.8-0.7,0.9v3.7h-0.4v-5.2
H71.1z"/>
<path class="st4" d="M75.4,87.1c-0.4,0-0.6-0.1-0.7-0.4c-0.2,0.1-0.5,0.4-1,0.4c-0.7,0-1-0.6-1-1.2c0-1.5,1.4-1.6,2-2.2V83
c0-0.4-0.1-0.7-0.6-0.7c-0.5,0-0.7,0.3-0.7,1v0.3h-0.4v-0.3c0-1,0.4-1.4,1.2-1.4c0.8,0,1.1,0.4,1.1,1.1v3.6c0,0.2,0.1,0.2,0.3,0.2
L75.4,87.1L75.4,87.1z M74.7,84.2c-0.3,0.2-0.6,0.3-0.9,0.5c-0.5,0.3-0.7,0.6-0.7,1.2c0,0.2,0,0.8,0.7,0.8c0.4,0,0.7-0.2,0.9-0.5
V84.2z"/>
<path class="st4" d="M78.3,87.1v-0.6c-0.1,0.2-0.4,0.6-1,0.6c-0.5,0-1-0.3-1-1.2v-2.8c0-0.9,0.5-1.3,1.1-1.3c0.6,0,0.8,0.4,0.9,0.5
v-2.6h0.4v7.3H78.3z M78.2,83.2c-0.1-0.5-0.3-0.9-0.8-0.9c-0.5,0-0.7,0.4-0.7,0.8v2.7c0,0.3,0.1,0.9,0.7,0.9c0.4,0,0.8-0.4,0.8-0.8
V83.2z"/>
<path class="st4" d="M82.2,85.9c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4
v1.3h-2v1.3c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V85.9z M81.7,83.1c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9
v1h1.5V83.1z"/>
<path class="st4" d="M87.2,87.1v-4c0-0.5-0.1-0.9-0.7-0.9c-0.4,0-0.7,0.3-0.9,0.6v4.2h-0.4V83c0-0.5-0.2-0.7-0.7-0.7
c-0.5,0-0.8,0.4-0.8,0.6v4.3h-0.4v-5.2h0.4v0.4c0.1-0.2,0.5-0.5,1-0.5c0.6,0,0.8,0.4,0.9,0.6c0.1-0.2,0.4-0.6,1.1-0.6
c0.5,0,1,0.3,1,1.2v4.2H87.2z"/>
<path class="st4" d="M91.2,87.1c-0.4,0-0.6-0.1-0.7-0.4c-0.2,0.1-0.5,0.4-1,0.4c-0.7,0-1-0.6-1-1.2c0-1.5,1.4-1.6,2-2.2V83
c0-0.4-0.1-0.7-0.6-0.7c-0.5,0-0.7,0.3-0.7,1v0.3h-0.4v-0.3c0-1,0.4-1.4,1.2-1.4c0.7,0,1.1,0.4,1.1,1.1v3.6c0,0.2,0.1,0.2,0.3,0.2
L91.2,87.1L91.2,87.1z M90.6,84.2c-0.3,0.2-0.6,0.3-0.9,0.5C89.2,85,89,85.3,89,85.9c0,0.2,0,0.8,0.7,0.8c0.4,0,0.7-0.2,0.9-0.5
V84.2z"/>
<path class="st4" d="M92.6,81.9v0.9c0.2-0.6,0.7-0.9,1.1-1.1v0.6c-0.1,0-0.3,0.1-0.4,0.2c-0.4,0.2-0.6,0.8-0.7,0.9v3.7h-0.4v-5.2
H92.6z"/>
<path class="st4" d="M96.5,87.1l-1.1-2.8l-0.5,0.8v1.9h-0.4v-7.3h0.4v4.6l1.5-2.5h0.5l-1.2,2l1.3,3.2H96.5z"/>
<path class="st4" d="M102.1,85.7c0,1-0.6,1.4-1.2,1.4c-0.7,0-1.2-0.4-1.2-1.1v-2.9c0-0.6,0.3-1.3,1.3-1.3c0.8,0,1.2,0.5,1.2,1.3
V85.7z M101.7,83.2c0-0.4-0.1-0.9-0.7-0.9c-0.7,0-0.8,0.5-0.8,1v2.6c0,0.6,0.3,0.8,0.8,0.8c0.7,0,0.8-0.6,0.8-0.9V83.2z"/>
<path class="st4" d="M102.8,81.9h0.6v-1.3c0-0.4,0.2-0.8,0.9-0.8c0.1,0,0.2,0,0.3,0v0.4c0,0-0.1,0-0.2,0c-0.3,0-0.6,0.1-0.6,0.6
v1.1h0.6v0.4h-0.7v4.8h-0.4v-4.8h-0.6V81.9z"/>
<path class="st4" d="M6.9,96.7v0.6c0,0.6,0,0.9,0.2,1.1c0.2,0.3,0.6,0.4,0.9,0.4c0.7,0,0.9-0.5,0.9-1.2c0-0.8-0.2-1.1-1.1-2
c-0.8-0.8-1.3-1.3-1.3-2.3c0-0.6,0.1-1.6,1.4-1.6c1.3,0,1.4,1,1.4,1.7v0.5H8.8v-0.7c0-0.4,0-1.1-0.9-1.1c-0.6,0-0.9,0.4-0.9,1.1
s0.1,1,1.2,2.1c0.8,0.8,1.1,1.2,1.1,2.1c0,0.7-0.1,1.7-1.5,1.7c-0.9,0-1.5-0.4-1.5-1.5v-1H6.9z"/>
<path class="st4" d="M9.9,93.9h0.6v-1.4h0.4v1.4h0.8v0.4h-0.8v4.1c0,0.3,0.3,0.3,0.4,0.3c0.1,0,0.3,0,0.4,0v0.4c-0.2,0-0.3,0-0.5,0
c-0.6,0-0.8-0.2-0.8-0.6v-4.2H9.9V93.9z"/>
<path class="st4" d="M14.7,98c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3
h-2v1.3c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V98z M14.2,95.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5
V95.2z"/>
<path class="st4" d="M15.7,93.3v-0.8h0.4v0.8H15.7z M15.7,99.2v-5.2h0.4v5.2H15.7z"/>
<path class="st4" d="M19.3,99.2V95c0-0.4-0.1-0.8-0.6-0.8c-0.4,0-0.7,0.2-0.9,0.7v4.3h-0.4v-5.2h0.4v0.5c0.3-0.5,0.8-0.6,1-0.6
c0.4,0,1,0.2,1,1.1v4.2H19.3z"/>
<path class="st4" d="M20.9,91.8h0.4v2.6c0.3-0.4,0.7-0.5,1-0.5c0.9,0,1,0.8,1,1.3v2.7c0,0.5-0.3,1.2-1.1,1.2c-0.1,0-0.6,0-0.8-0.5
v0.4h-0.5V91.8z M21.4,97.7c0,0.9,0.6,1,0.8,1c0.5,0,0.7-0.4,0.7-1v-2.6c0-0.2,0-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9V97.7z"/>
<path class="st4" d="M26.8,98c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3
h-2v1.3c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V98z M26.3,95.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5
V95.2z"/>
<path class="st4" d="M28.3,93.9v0.9c0.2-0.6,0.7-0.9,1.1-1.1v0.6c-0.1,0-0.3,0.1-0.4,0.2c-0.4,0.2-0.6,0.8-0.7,0.9v3.7h-0.4v-5.2
H28.3z"/>
<path class="st4" d="M32.5,99.5c0,0.9-0.6,1.3-1.3,1.3c-0.4,0-0.9-0.1-1-0.5c-0.1-0.1-0.1-0.3-0.1-0.6h0.4c0,0,0,0.2,0.1,0.4
c0.2,0.3,0.6,0.3,0.6,0.3c0.1,0,0.8-0.1,0.8-0.8v-0.9c-0.1,0.1-0.4,0.5-0.9,0.5c-0.7,0-1-0.6-1-1.2v-2.9c0-0.9,0.5-1.2,1.1-1.2
c0.5,0,0.8,0.3,0.9,0.5v-0.4h0.4V99.5z M32,95c-0.1-0.4-0.4-0.7-0.8-0.7c-0.6,0-0.7,0.5-0.7,0.9v2.6c0,0.7,0.3,0.9,0.7,0.9
c0.3,0,0.7-0.2,0.8-0.8V95z"/>
<path class="st4" d="M39.3,99.2c0-0.5,0-5.1,0-6.8L38,99.2h-0.5l-1.3-6.8v6.8h-0.5c0-0.5,0.1-7.3,0.1-7.3h0.7l1.2,6.3l1.2-6.3h0.7
c0,0.8,0.1,7.3,0.1,7.3H39.3z"/>
<path class="st4" d="M43.3,98c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3
h-2v1.3c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V98z M42.9,95.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5
V95.2z"/>
<path class="st4" d="M46.3,99.2v-0.6c-0.1,0.2-0.4,0.6-1,0.6c-0.5,0-1-0.3-1-1.2v-2.8c0-0.9,0.5-1.3,1.1-1.3c0.6,0,0.8,0.4,0.9,0.5
v-2.6h0.4v7.3H46.3z M46.3,95.3c-0.1-0.5-0.3-0.9-0.8-0.9c-0.5,0-0.7,0.4-0.7,0.8v2.7c0,0.3,0.1,0.9,0.7,0.9c0.4,0,0.7-0.4,0.8-0.8
V95.3z"/>
<path class="st4" d="M48,93.3v-0.8h0.4v0.8H48z M48,99.2v-5.2h0.4v5.2H48z"/>
<path class="st4" d="M52,99.2c-0.4,0-0.6-0.1-0.7-0.4c-0.2,0.1-0.5,0.4-1,0.4c-0.7,0-1-0.6-1-1.2c0-1.5,1.4-1.6,2-2.2V95
c0-0.4-0.1-0.7-0.6-0.7c-0.5,0-0.7,0.3-0.7,1v0.3h-0.4v-0.3c0-1,0.4-1.4,1.2-1.4c0.7,0,1.1,0.4,1.1,1.1v3.6c0,0.2,0.1,0.2,0.3,0.2
L52,99.2L52,99.2z M51.4,96.2c-0.3,0.2-0.6,0.3-0.9,0.5c-0.5,0.3-0.7,0.6-0.7,1.2c0,0.2,0,0.8,0.7,0.8c0.4,0,0.7-0.2,0.9-0.5V96.2z
"/>
<path class="st4" d="M56.3,92.3v6.9h-0.5v-6.9h-1.3v-0.5h3.1v0.5H56.3z"/>
<path class="st4" d="M60,98c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3
h-2v1.3c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4H60V98z M59.6,95.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5
V95.2z"/>
<path class="st4" d="M63.5,97.8c0,0.8-0.3,1.4-1.3,1.4c-0.9,0-1.2-0.7-1.2-1.3v-2.6c0-1,0.5-1.3,1.2-1.3c0.8,0,1.2,0.5,1.2,1.4v0.5
H63v-0.4c0-0.5-0.1-1.1-0.8-1.1c-0.7,0-0.8,0.6-0.8,1v2.3c0,0.5,0,1.2,0.8,1.2c0.6,0,0.7-0.5,0.7-0.9v-0.8h0.5V97.8z"/>
<path class="st4" d="M66.4,99.2v-3.9c0-0.5-0.1-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.7v4.2h-0.4v-7.3h0.4v2.5c0.1-0.1,0.4-0.5,0.9-0.5
c0.4,0,1,0.2,1,1.1v4.2H66.4z"/>
<path class="st4" d="M70,99.2V95c0-0.4-0.1-0.8-0.6-0.8c-0.4,0-0.7,0.2-0.9,0.7v4.3H68v-5.2h0.4v0.5c0.3-0.5,0.8-0.6,1-0.6
c0.4,0,1,0.2,1,1.1v4.2H70z"/>
<path class="st4" d="M74,97.8c0,1-0.6,1.4-1.2,1.4c-0.7,0-1.2-0.4-1.2-1.1v-2.9c0-0.6,0.3-1.3,1.3-1.3c0.8,0,1.2,0.5,1.2,1.3V97.8z
M73.5,95.2c0-0.4-0.1-0.9-0.7-0.9c-0.7,0-0.8,0.5-0.8,1v2.6c0,0.6,0.3,0.8,0.8,0.8c0.7,0,0.8-0.6,0.8-0.9V95.2z"/>
<path class="st4" d="M75,99.2v-7.3h0.4v7.3H75z"/>
<path class="st4" d="M79.1,97.8c0,1-0.6,1.4-1.2,1.4c-0.7,0-1.2-0.4-1.2-1.1v-2.9c0-0.6,0.3-1.3,1.3-1.3c0.8,0,1.2,0.5,1.2,1.3
V97.8z M78.6,95.2c0-0.4-0.1-0.9-0.7-0.9c-0.7,0-0.8,0.5-0.8,1v2.6c0,0.6,0.3,0.8,0.8,0.8c0.7,0,0.8-0.6,0.8-0.9V95.2z"/>
<path class="st4" d="M82.6,99.5c0,0.9-0.6,1.3-1.3,1.3c-0.4,0-0.9-0.1-1-0.5c-0.1-0.1-0.1-0.3-0.1-0.6h0.4c0,0,0,0.2,0.1,0.4
c0.2,0.3,0.6,0.3,0.6,0.3c0.1,0,0.8-0.1,0.8-0.8v-0.9c-0.1,0.1-0.4,0.5-0.9,0.5c-0.8,0-1-0.6-1-1.2v-2.9c0-0.9,0.5-1.2,1.1-1.2
c0.5,0,0.8,0.3,0.9,0.5v-0.4h0.4V99.5z M82.2,95c-0.1-0.4-0.4-0.7-0.8-0.7c-0.6,0-0.7,0.5-0.7,0.9v2.6c0,0.7,0.3,0.9,0.7,0.9
c0.3,0,0.7-0.2,0.8-0.8V95z"/>
<path class="st4" d="M83.8,93.3v-0.8h0.4v0.8H83.8z M83.8,99.2v-5.2h0.4v5.2H83.8z"/>
<path class="st4" d="M87.7,98c0,0.6-0.3,1.2-1.2,1.2c-0.7,0-1.2-0.4-1.2-1.2v-2.8c0-0.6,0.3-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.4v1.3
h-2v1.3c0,0.3,0.1,0.9,0.7,0.9c0.7,0,0.8-0.6,0.8-1.1v-0.4h0.4V98z M87.3,95.2c0-0.6-0.3-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9v1h1.5
V95.2z"/>
<path class="st4" d="M89,97.3v0.5c0,0.3,0,1,0.8,1c0.4,0,0.8-0.2,0.8-0.9c0-0.5-0.1-0.7-0.9-1.3c-0.6-0.5-0.9-0.8-0.9-1.6
c0-0.4,0.1-1.1,1.1-1.1c1.1,0,1.1,0.8,1.1,1.2v0.4h-0.4v-0.4c0-0.6-0.2-0.8-0.6-0.8c-0.6,0-0.7,0.4-0.7,0.7c0,0.5,0,0.6,1,1.4
c0.5,0.4,0.8,0.7,0.8,1.4c0,0.8-0.3,1.3-1.2,1.3c-1.1,0-1.2-0.6-1.2-1.5v-0.4H89z"/>
<path class="st4" d="M96.6,99.2v-0.6c-0.1,0.2-0.5,0.7-1.2,0.7c-0.4,0-0.9-0.2-1.1-0.6C94.1,98.3,94,98,94,97.3v-3.9
c0-1,0.4-1.6,1.5-1.6c1.1,0,1.4,0.7,1.4,1.3v1.1h-0.5v-0.9c0-0.6-0.1-1.1-1-1.1c-0.8,0-1,0.6-1,1.2v3.8c0,0.6,0,0.9,0.1,1.2
c0.1,0.2,0.3,0.5,0.8,0.5c0.7,0,1-0.8,1-1.2v-1.3h-1.1v-0.4H97v3.4H96.6z"/>
<path class="st4" d="M102.1,99.2v-4c0-0.5-0.1-0.9-0.7-0.9c-0.4,0-0.7,0.3-0.9,0.6v4.2h-0.4V95c0-0.5-0.2-0.7-0.7-0.7
c-0.5,0-0.8,0.4-0.8,0.6v4.3h-0.4v-5.2h0.4v0.4c0.1-0.2,0.5-0.5,1-0.5c0.6,0,0.8,0.4,0.9,0.6c0.1-0.2,0.4-0.6,1.1-0.6
c0.5,0,1,0.3,1,1.2v4.2H102.1z"/>
<path class="st4" d="M103.7,91.8h0.4v2.6c0.3-0.4,0.7-0.5,1-0.5c0.9,0,1,0.8,1,1.3v2.7c0,0.5-0.3,1.2-1.1,1.2c-0.1,0-0.6,0-0.8-0.5
v0.4h-0.5V91.8z M104.2,97.7c0,0.9,0.6,1,0.8,1c0.5,0,0.7-0.4,0.7-1v-2.6c0-0.2,0-0.9-0.7-0.9c-0.5,0-0.8,0.4-0.8,0.9V97.7z"/>
<path class="st4" d="M109.6,99.2v-3.4h-1.8v3.4h-0.5v-7h0.5v3.1h1.8v-3.1h0.5v7H109.6z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 908 B

+183
View File
@@ -0,0 +1,183 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Interface Technology Basics: Class List</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="smtg_extra.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Interface Technology Basics<span id="projectnumber">&#160;VST 3.8</span>
</div>
<div id="projectbrief">SDK for developing VST plug-in</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search',true);
$(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){initNavTree('annotated.html',''); initResizable(true); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="headertitle"><div class="title">Class List</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock">Here are the classes, structs, unions and interfaces with brief descriptions:</div><div class="directory">
<div class="levels">[detail level <span onclick="javascript:dynsection.toggleLevel(1);">1</span><span onclick="javascript:dynsection.toggleLevel(2);">2</span><span onclick="javascript:dynsection.toggleLevel(3);">3</span><span onclick="javascript:dynsection.toggleLevel(4);">4</span>]</div><table class="directory">
<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_0_" class="arrow" onclick="dynsection.toggleFolder('0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceSteinberg.html" target="_self">Steinberg</a></td><td class="desc">This header provides classes for working with <a class="el" href="classSteinberg_1_1FUnknown.html" title="The basic interface of all interfaces.">FUnknown</a> </td></tr>
<tr id="row_0_0_" class="odd"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_0_0_" class="arrow" onclick="dynsection.toggleFolder('0_0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceSteinberg_1_1FUnknownImpl.html" target="_self">FUnknownImpl</a></td><td class="desc"></td></tr>
<tr id="row_0_0_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span id="arr_0_0_0_" class="arrow" onclick="dynsection.toggleFolder('0_0_0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceSteinberg_1_1FUnknownImpl_1_1Detail.html" target="_self">Detail</a></td><td class="desc"></td></tr>
<tr id="row_0_0_0_0_" class="odd"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1FUnknownImpl_1_1Detail_1_1NonDestroyable.html" target="_self">NonDestroyable</a></td><td class="desc"></td></tr>
<tr id="row_0_0_0_1_" class="even"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1FUnknownImpl_1_1Detail_1_1QueryInterfaceEnd.html" target="_self">QueryInterfaceEnd</a></td><td class="desc"></td></tr>
<tr id="row_0_0_0_2_" class="odd"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1FUnknownImpl_1_1Detail_1_1RefCounted.html" target="_self">RefCounted</a></td><td class="desc">This struct implements reference counting for the <code><a class="el" href="namespaceSteinberg_1_1FUnknownImpl.html#aa97fe0c3b9d688a3e43da776dec431c6" title="This typedef provides the interface implementation.">U::Implements</a></code> template </td></tr>
<tr id="row_0_0_1_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1FUnknownImpl_1_1Destroyer.html" target="_self">Destroyer</a></td><td class="desc">Common destroyer policy for ski object instances </td></tr>
<tr id="row_0_0_2_" class="odd"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1FUnknownImpl_1_1Directly.html" target="_self">Directly</a></td><td class="desc">This struct is used to group a list of interfaces from which should be inherited and which should be available via the <code>queryInterface</code> method </td></tr>
<tr id="row_0_0_3_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1FUnknownImpl_1_1HideIIDBase.html" target="_self">HideIIDBase</a></td><td class="desc">A base class which hides the <a class="el" href="classSteinberg_1_1FUnknown.html#a07978c93295b03d09c4bc97aa12e9c60">FUnknown::iid</a> static var </td></tr>
<tr id="row_0_0_4_" class="odd"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1FUnknownImpl_1_1ImplementsImpl.html" target="_self">ImplementsImpl</a></td><td class="desc"></td></tr>
<tr id="row_0_0_5_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1FUnknownImpl_1_1ImplementsImpl_3_01Base_00_01Indirectly_3_01IndirectInterfaces9a4a5325b3bc049eba78ef3421c75dc0.html" target="_self">ImplementsImpl&lt; Base, Indirectly&lt; IndirectInterfaces... &gt;, Directly&lt; DirectInterfaces... &gt; &gt;</a></td><td class="desc"></td></tr>
<tr id="row_0_0_6_" class="odd"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1FUnknownImpl_1_1Indirectly.html" target="_self">Indirectly</a></td><td class="desc">This struct is used to group a list of interfaces from which should not be inherited but which should be available via the <code>queryInterface</code> method </td></tr>
<tr id="row_0_0_7_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1FUnknownImpl_1_1UID.html" target="_self">UID</a></td><td class="desc">This class provides a compile-time uid and enables interfaces to specify a <a class="el" href="structSteinberg_1_1FUnknownImpl_1_1UID.html" title="This class provides a compile-time uid and enables interfaces to specify a UID as a simple typedef.">UID</a> as a simple typedef </td></tr>
<tr id="row_0_1_" class="odd"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_0_1_" class="arrow" onclick="dynsection.toggleFolder('0_1_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceSteinberg_1_1Linux.html" target="_self">Linux</a></td><td class="desc"></td></tr>
<tr id="row_0_1_0_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1Linux_1_1IEventHandler.html" target="_self">IEventHandler</a></td><td class="desc"><a class="el" href="namespaceSteinberg_1_1Linux.html">Linux</a> event handler interface </td></tr>
<tr id="row_0_1_1_" class="odd"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1Linux_1_1IRunLoop.html" target="_self">IRunLoop</a></td><td class="desc"><a class="el" href="namespaceSteinberg_1_1Linux.html">Linux</a> host run loop interface </td></tr>
<tr id="row_0_1_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1Linux_1_1ITimerHandler.html" target="_self">ITimerHandler</a></td><td class="desc"><a class="el" href="namespaceSteinberg_1_1Linux.html">Linux</a> timer handler interface </td></tr>
<tr id="row_0_2_" class="odd"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_0_2_" class="arrow" onclick="dynsection.toggleFolder('0_2_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceSteinberg_1_1U.html" target="_self">U</a></td><td class="desc">Shortcut namespace for implementing <a class="el" href="classSteinberg_1_1FUnknown.html" title="The basic interface of all interfaces.">FUnknown</a> based objects </td></tr>
<tr id="row_0_2_0_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1U_1_1Directly.html" target="_self">Directly</a></td><td class="desc">This struct is used to group a list of interfaces from which should be inherited and which should be available via the <code>queryInterface</code> method </td></tr>
<tr id="row_0_2_1_" class="odd"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1U_1_1Indirectly.html" target="_self">Indirectly</a></td><td class="desc">This struct is used to group a list of interfaces from which should not be inherited but which should be available via the <code>queryInterface</code> method </td></tr>
<tr id="row_0_2_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1U_1_1UID.html" target="_self">UID</a></td><td class="desc">This class provides a compile-time uid and enables interfaces to specify a <a class="el" href="structSteinberg_1_1U_1_1UID.html" title="This class provides a compile-time uid and enables interfaces to specify a UID as a simple typedef.">UID</a> as a simple typedef </td></tr>
<tr id="row_0_3_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1ConstStringTable.html" target="_self">ConstStringTable</a></td><td class="desc">Constant unicode string table </td></tr>
<tr id="row_0_4_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1FReleaser.html" target="_self">FReleaser</a></td><td class="desc">Release an interface using automatic object (obsolete) </td></tr>
<tr id="row_0_5_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1FUID.html" target="_self">FUID</a></td><td class="desc">Handling 16 Byte Globally Unique Identifiers </td></tr>
<tr id="row_0_6_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1FUnknown.html" target="_self">FUnknown</a></td><td class="desc">The basic interface of all interfaces </td></tr>
<tr id="row_0_7_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1FUnknownPtr.html" target="_self">FUnknownPtr</a></td><td class="desc"><a class="el" href="classSteinberg_1_1FUnknownPtr.html" title="FUnknownPtr - automatic interface conversion and smart pointer in one.">FUnknownPtr</a> - automatic interface conversion and smart pointer in one </td></tr>
<tr id="row_0_8_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1FVariant.html" target="_self">FVariant</a></td><td class="desc">A Value of variable type </td></tr>
<tr id="row_0_9_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IAttributes.html" target="_self">IAttributes</a></td><td class="desc">Object Data Archive Interface </td></tr>
<tr id="row_0_10_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IAttributes2.html" target="_self">IAttributes2</a></td><td class="desc">Extended access to Attributes; supports Attribute retrieval via iteration </td></tr>
<tr id="row_0_11_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IBStream.html" target="_self">IBStream</a></td><td class="desc">Base class for streams </td></tr>
<tr id="row_0_12_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1ICloneable.html" target="_self">ICloneable</a></td><td class="desc">Interface allowing an object to be copied </td></tr>
<tr id="row_0_13_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IDependent.html" target="_self">IDependent</a></td><td class="desc">A dependent will get notified about changes of a model </td></tr>
<tr id="row_0_14_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IErrorContext.html" target="_self">IErrorContext</a></td><td class="desc">Interface for error handling </td></tr>
<tr id="row_0_15_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IPersistent.html" target="_self">IPersistent</a></td><td class="desc">Persistent Object Interface </td></tr>
<tr id="row_0_16_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IPlugFrame.html" target="_self">IPlugFrame</a></td><td class="desc">Callback interface passed to <a class="el" href="classSteinberg_1_1IPlugView.html" title="Plug-in definition of a view.">IPlugView</a> </td></tr>
<tr id="row_0_17_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IPluginBase.html" target="_self">IPluginBase</a></td><td class="desc">Basic interface to a plug-in component: <a class="el" href="classSteinberg_1_1IPluginBase.html" title="Basic interface to a plug-in component: IPluginBase.">IPluginBase</a> </td></tr>
<tr id="row_0_18_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IPluginCompatibility.html" target="_self">IPluginCompatibility</a></td><td class="desc">Optional interface to query the compatibility of the plug-ins classes </td></tr>
<tr id="row_0_19_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IPluginFactory.html" target="_self">IPluginFactory</a></td><td class="desc">Class factory that any plug-in defines for creating class instances: <a class="el" href="classSteinberg_1_1IPluginFactory.html" title="Class factory that any plug-in defines for creating class instances: IPluginFactory.">IPluginFactory</a> </td></tr>
<tr id="row_0_20_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IPluginFactory2.html" target="_self">IPluginFactory2</a></td><td class="desc">Version 2 of class factory supporting <a class="el" href="structSteinberg_1_1PClassInfo2.html" title="Version 2 of Basic Information about a class provided by the plug-in.">PClassInfo2</a>: <a class="el" href="classSteinberg_1_1IPluginFactory2.html" title="Version 2 of class factory supporting PClassInfo2: IPluginFactory2.">IPluginFactory2</a> </td></tr>
<tr id="row_0_21_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IPluginFactory3.html" target="_self">IPluginFactory3</a></td><td class="desc">Version 3 of class factory supporting <a class="el" href="structSteinberg_1_1PClassInfoW.html" title="Unicode Version of Basic Information about a class provided by the plug-in.">PClassInfoW</a>: <a class="el" href="classSteinberg_1_1IPluginFactory3.html" title="Version 3 of class factory supporting PClassInfoW: IPluginFactory3.">IPluginFactory3</a> </td></tr>
<tr id="row_0_22_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IPlugView.html" target="_self">IPlugView</a></td><td class="desc">Plug-in definition of a view </td></tr>
<tr id="row_0_23_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IPlugViewContentScaleSupport.html" target="_self">IPlugViewContentScaleSupport</a></td><td class="desc">Plug-in view content scale support </td></tr>
<tr id="row_0_24_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IPtr.html" target="_self">IPtr</a></td><td class="desc"><a class="el" href="classSteinberg_1_1IPtr.html" title="IPtr - Smart pointer template class.">IPtr</a> - Smart pointer template class </td></tr>
<tr id="row_0_25_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1ISizeableStream.html" target="_self">ISizeableStream</a></td><td class="desc">Stream with a size </td></tr>
<tr id="row_0_26_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IString.html" target="_self">IString</a></td><td class="desc">Interface to a string of variable size and encoding </td></tr>
<tr id="row_0_27_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IStringResult.html" target="_self">IStringResult</a></td><td class="desc">Interface to return an ascii string of variable size </td></tr>
<tr id="row_0_28_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1IUpdateHandler.html" target="_self">IUpdateHandler</a></td><td class="desc">Host implements dependency handling for plugins </td></tr>
<tr id="row_0_29_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1KeyCode.html" target="_self">KeyCode</a></td><td class="desc">Simple data-struct representing a key-stroke on the keyboard </td></tr>
<tr id="row_0_30_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1OPtr.html" target="_self">OPtr</a></td><td class="desc"><a class="el" href="classSteinberg_1_1OPtr.html" title="OPtr - &quot;owning&quot; smart pointer used for newly created FObjects.">OPtr</a> - "owning" smart pointer used for newly created FObjects </td></tr>
<tr id="row_0_31_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1PClassInfo.html" target="_self">PClassInfo</a></td><td class="desc">Basic Information about a class provided by the plug-in </td></tr>
<tr id="row_0_32_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1PClassInfo2.html" target="_self">PClassInfo2</a></td><td class="desc">Version 2 of Basic Information about a class provided by the plug-in </td></tr>
<tr id="row_0_33_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1PClassInfoW.html" target="_self">PClassInfoW</a></td><td class="desc">Unicode Version of Basic Information about a class provided by the plug-in </td></tr>
<tr id="row_0_34_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1PFactoryInfo.html" target="_self">PFactoryInfo</a></td><td class="desc">Basic Information about the class factory of the plug-in </td></tr>
<tr id="row_0_35_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1UString.html" target="_self">UString</a></td><td class="desc">UTF-16 string class without buffer management </td></tr>
<tr id="row_0_36_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classSteinberg_1_1UStringBuffer.html" target="_self">UStringBuffer</a></td><td class="desc">UTF-16 string with fixed buffer size </td></tr>
<tr id="row_0_37_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structSteinberg_1_1ViewRect.html" target="_self">ViewRect</a></td><td class="desc">Graphical rectangle structure </td></tr>
</table>
</div><!-- directory -->
</div><!-- contents -->
</div><!-- doc-content -->
<html>
<head>
<title>Empty</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Steinberg">
</head>
<body>
<br/>
<hr width="100%" size="2" align="left" />
<div align=right>
Copyright &copy;<span id="year"></span> <a href="http://www.steinberg.net" target="_blank"><u>Steinberg Media Technologies GmbH</u></a>.
All Rights Reserved. This documentation is under this <a href="http://www.steinberg.net/sdklicenses" target="_blank"><u>license</u></a>.
</div>
<script>
document.querySelector("#year").textContent = new Date().getFullYear();
</script>
</body>
</html>
+64
View File
@@ -0,0 +1,64 @@
var annotated_dup =
[
[ "Steinberg", "namespaceSteinberg.html", [
[ "FUnknownImpl", "namespaceSteinberg_1_1FUnknownImpl.html", [
[ "Detail", "namespaceSteinberg_1_1FUnknownImpl_1_1Detail.html", [
[ "NonDestroyable", "structSteinberg_1_1FUnknownImpl_1_1Detail_1_1NonDestroyable.html", "structSteinberg_1_1FUnknownImpl_1_1Detail_1_1NonDestroyable" ],
[ "QueryInterfaceEnd", "structSteinberg_1_1FUnknownImpl_1_1Detail_1_1QueryInterfaceEnd.html", "structSteinberg_1_1FUnknownImpl_1_1Detail_1_1QueryInterfaceEnd" ],
[ "RefCounted", "structSteinberg_1_1FUnknownImpl_1_1Detail_1_1RefCounted.html", "structSteinberg_1_1FUnknownImpl_1_1Detail_1_1RefCounted" ]
] ],
[ "Destroyer", "structSteinberg_1_1FUnknownImpl_1_1Destroyer.html", null ],
[ "Directly", "structSteinberg_1_1FUnknownImpl_1_1Directly.html", null ],
[ "HideIIDBase", "structSteinberg_1_1FUnknownImpl_1_1HideIIDBase.html", "structSteinberg_1_1FUnknownImpl_1_1HideIIDBase" ],
[ "ImplementsImpl", "classSteinberg_1_1FUnknownImpl_1_1ImplementsImpl.html", null ],
[ "ImplementsImpl< Base, Indirectly< IndirectInterfaces... >, Directly< DirectInterfaces... > >", "classSteinberg_1_1FUnknownImpl_1_1ImplementsImpl_3_01Base_00_01Indirectly_3_01IndirectInterfaces9a4a5325b3bc049eba78ef3421c75dc0.html", null ],
[ "Indirectly", "structSteinberg_1_1FUnknownImpl_1_1Indirectly.html", null ],
[ "UID", "structSteinberg_1_1FUnknownImpl_1_1UID.html", "structSteinberg_1_1FUnknownImpl_1_1UID" ]
] ],
[ "Linux", "namespaceSteinberg_1_1Linux.html", [
[ "IEventHandler", "classSteinberg_1_1Linux_1_1IEventHandler.html", "classSteinberg_1_1Linux_1_1IEventHandler" ],
[ "IRunLoop", "classSteinberg_1_1Linux_1_1IRunLoop.html", "classSteinberg_1_1Linux_1_1IRunLoop" ],
[ "ITimerHandler", "classSteinberg_1_1Linux_1_1ITimerHandler.html", "classSteinberg_1_1Linux_1_1ITimerHandler" ]
] ],
[ "U", "namespaceSteinberg_1_1U.html", [
[ "Directly", "structSteinberg_1_1U_1_1Directly.html", null ],
[ "Indirectly", "structSteinberg_1_1U_1_1Indirectly.html", null ],
[ "UID", "structSteinberg_1_1U_1_1UID.html", "structSteinberg_1_1U_1_1UID" ]
] ],
[ "ConstStringTable", "classSteinberg_1_1ConstStringTable.html", "classSteinberg_1_1ConstStringTable" ],
[ "FReleaser", "structSteinberg_1_1FReleaser.html", "structSteinberg_1_1FReleaser" ],
[ "FUID", "classSteinberg_1_1FUID.html", "classSteinberg_1_1FUID" ],
[ "FUnknown", "classSteinberg_1_1FUnknown.html", "classSteinberg_1_1FUnknown" ],
[ "FUnknownPtr", "classSteinberg_1_1FUnknownPtr.html", "classSteinberg_1_1FUnknownPtr" ],
[ "FVariant", "classSteinberg_1_1FVariant.html", "classSteinberg_1_1FVariant" ],
[ "IAttributes", "classSteinberg_1_1IAttributes.html", "classSteinberg_1_1IAttributes" ],
[ "IAttributes2", "classSteinberg_1_1IAttributes2.html", "classSteinberg_1_1IAttributes2" ],
[ "IBStream", "classSteinberg_1_1IBStream.html", "classSteinberg_1_1IBStream" ],
[ "ICloneable", "classSteinberg_1_1ICloneable.html", "classSteinberg_1_1ICloneable" ],
[ "IDependent", "classSteinberg_1_1IDependent.html", "classSteinberg_1_1IDependent" ],
[ "IErrorContext", "classSteinberg_1_1IErrorContext.html", "classSteinberg_1_1IErrorContext" ],
[ "IPersistent", "classSteinberg_1_1IPersistent.html", "classSteinberg_1_1IPersistent" ],
[ "IPlugFrame", "classSteinberg_1_1IPlugFrame.html", "classSteinberg_1_1IPlugFrame" ],
[ "IPluginBase", "classSteinberg_1_1IPluginBase.html", "classSteinberg_1_1IPluginBase" ],
[ "IPluginCompatibility", "classSteinberg_1_1IPluginCompatibility.html", "classSteinberg_1_1IPluginCompatibility" ],
[ "IPluginFactory", "classSteinberg_1_1IPluginFactory.html", "classSteinberg_1_1IPluginFactory" ],
[ "IPluginFactory2", "classSteinberg_1_1IPluginFactory2.html", "classSteinberg_1_1IPluginFactory2" ],
[ "IPluginFactory3", "classSteinberg_1_1IPluginFactory3.html", "classSteinberg_1_1IPluginFactory3" ],
[ "IPlugView", "classSteinberg_1_1IPlugView.html", "classSteinberg_1_1IPlugView" ],
[ "IPlugViewContentScaleSupport", "classSteinberg_1_1IPlugViewContentScaleSupport.html", "classSteinberg_1_1IPlugViewContentScaleSupport" ],
[ "IPtr", "classSteinberg_1_1IPtr.html", "classSteinberg_1_1IPtr" ],
[ "ISizeableStream", "classSteinberg_1_1ISizeableStream.html", "classSteinberg_1_1ISizeableStream" ],
[ "IString", "classSteinberg_1_1IString.html", "classSteinberg_1_1IString" ],
[ "IStringResult", "classSteinberg_1_1IStringResult.html", "classSteinberg_1_1IStringResult" ],
[ "IUpdateHandler", "classSteinberg_1_1IUpdateHandler.html", "classSteinberg_1_1IUpdateHandler" ],
[ "KeyCode", "structSteinberg_1_1KeyCode.html", "structSteinberg_1_1KeyCode" ],
[ "OPtr", "classSteinberg_1_1OPtr.html", "classSteinberg_1_1OPtr" ],
[ "PClassInfo", "structSteinberg_1_1PClassInfo.html", "structSteinberg_1_1PClassInfo" ],
[ "PClassInfo2", "structSteinberg_1_1PClassInfo2.html", "structSteinberg_1_1PClassInfo2" ],
[ "PClassInfoW", "structSteinberg_1_1PClassInfoW.html", "structSteinberg_1_1PClassInfoW" ],
[ "PFactoryInfo", "structSteinberg_1_1PFactoryInfo.html", "structSteinberg_1_1PFactoryInfo" ],
[ "UString", "classSteinberg_1_1UString.html", "classSteinberg_1_1UString" ],
[ "UStringBuffer", "classSteinberg_1_1UStringBuffer.html", "classSteinberg_1_1UStringBuffer" ],
[ "ViewRect", "structSteinberg_1_1ViewRect.html", "structSteinberg_1_1ViewRect" ]
] ]
];
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

@@ -0,0 +1,131 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Interface Technology Basics: Member List</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="smtg_extra.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Interface Technology Basics<span id="projectnumber">&#160;VST 3.8</span>
</div>
<div id="projectbrief">SDK for developing VST plug-in</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search',true);
$(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){initNavTree('classSteinberg_1_1ConstStringTable.html',''); initResizable(true); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="headertitle"><div class="title">ConstStringTable Member List</div></div>
</div><!--header-->
<div class="contents">
<p>This is the complete list of members for <a class="el" href="classSteinberg_1_1ConstStringTable.html">ConstStringTable</a>, including all inherited members.</p>
<table class="directory">
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1ConstStringTable.html#acf88e43da1b31d3d425c80d747bbb1a8">ConstStringTable</a>()</td><td class="entry"><a class="el" href="classSteinberg_1_1ConstStringTable.html">ConstStringTable</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1ConstStringTable.html#ad11982e5de305e29fd59bab3e197a4f2">getString</a>(const char8 *str) const</td><td class="entry"><a class="el" href="classSteinberg_1_1ConstStringTable.html">ConstStringTable</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1ConstStringTable.html#ae50b58af65ebbc7d1a035d88c520d7dd">getString</a>(const char8 str) const</td><td class="entry"><a class="el" href="classSteinberg_1_1ConstStringTable.html">ConstStringTable</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1ConstStringTable.html#a7ed68ef8938393b1fc911313db64c804">instance</a>()</td><td class="entry"><a class="el" href="classSteinberg_1_1ConstStringTable.html">ConstStringTable</a></td><td class="entry"><span class="mlabel">static</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1ConstStringTable.html#a99f647d997cd61d511fdf60560c5706b">~ConstStringTable</a>()</td><td class="entry"><a class="el" href="classSteinberg_1_1ConstStringTable.html">ConstStringTable</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
</table></div><!-- contents -->
</div><!-- doc-content -->
<html>
<head>
<title>Empty</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Steinberg">
</head>
<body>
<br/>
<hr width="100%" size="2" align="left" />
<div align=right>
Copyright &copy;<span id="year"></span> <a href="http://www.steinberg.net" target="_blank"><u>Steinberg Media Technologies GmbH</u></a>.
All Rights Reserved. This documentation is under this <a href="http://www.steinberg.net/sdklicenses" target="_blank"><u>license</u></a>.
</div>
<script>
document.querySelector("#year").textContent = new Date().getFullYear();
</script>
</body>
</html>
@@ -0,0 +1,273 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Interface Technology Basics: ConstStringTable Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="smtg_extra.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Interface Technology Basics<span id="projectnumber">&#160;VST 3.8</span>
</div>
<div id="projectbrief">SDK for developing VST plug-in</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search',true);
$(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){initNavTree('classSteinberg_1_1ConstStringTable.html',''); initResizable(true); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="summary">
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pub-static-methods">Static Public Member Functions</a> &#124;
<a href="#pro-methods">Protected Member Functions</a> &#124;
<a href="classSteinberg_1_1ConstStringTable-members.html">List of all members</a> </div>
<div class="headertitle"><div class="title">ConstStringTable Class Reference</div></div>
</div><!--header-->
<div class="contents">
<p>Constant unicode string table.
<a href="#details">More...</a></p>
<p><code>#include &lt;conststringtable.h&gt;</code></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:ad11982e5de305e29fd59bab3e197a4f2" id="r_ad11982e5de305e29fd59bab3e197a4f2"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="group__smtgtypedef.html#ga667a0a4e0cbcb3f3785984955e1fefd8">char16</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#ad11982e5de305e29fd59bab3e197a4f2">getString</a> (const <a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *str) const</td></tr>
<tr class="memdesc:ad11982e5de305e29fd59bab3e197a4f2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a <a class="el" href="group__smtgtypedef.html#ga667a0a4e0cbcb3f3785984955e1fefd8">char16</a> string of a ASCII string literal. <br /></td></tr>
<tr class="separator:ad11982e5de305e29fd59bab3e197a4f2"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae50b58af65ebbc7d1a035d88c520d7dd" id="r_ae50b58af65ebbc7d1a035d88c520d7dd"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__smtgtypedef.html#ga667a0a4e0cbcb3f3785984955e1fefd8">char16</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#ae50b58af65ebbc7d1a035d88c520d7dd">getString</a> (const <a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> str) const</td></tr>
<tr class="memdesc:ae50b58af65ebbc7d1a035d88c520d7dd"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a <a class="el" href="group__smtgtypedef.html#ga667a0a4e0cbcb3f3785984955e1fefd8">char16</a> character of a ASCII character. <br /></td></tr>
<tr class="separator:ae50b58af65ebbc7d1a035d88c520d7dd"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-static-methods" name="pub-static-methods"></a>
Static Public Member Functions</h2></td></tr>
<tr class="memitem:a7ed68ef8938393b1fc911313db64c804" id="r_a7ed68ef8938393b1fc911313db64c804"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="classSteinberg_1_1ConstStringTable.html">ConstStringTable</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a7ed68ef8938393b1fc911313db64c804">instance</a> ()</td></tr>
<tr class="separator:a7ed68ef8938393b1fc911313db64c804"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pro-methods" name="pro-methods"></a>
Protected Member Functions</h2></td></tr>
<tr class="memitem:acf88e43da1b31d3d425c80d747bbb1a8" id="r_acf88e43da1b31d3d425c80d747bbb1a8"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#acf88e43da1b31d3d425c80d747bbb1a8">ConstStringTable</a> ()</td></tr>
<tr class="separator:acf88e43da1b31d3d425c80d747bbb1a8"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a99f647d997cd61d511fdf60560c5706b" id="r_a99f647d997cd61d511fdf60560c5706b"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a99f647d997cd61d511fdf60560c5706b">~ConstStringTable</a> ()</td></tr>
<tr class="separator:a99f647d997cd61d511fdf60560c5706b"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>Constant unicode string table. </p>
<p>Used for conversion from ASCII string literals to <a class="el" href="group__smtgtypedef.html#ga667a0a4e0cbcb3f3785984955e1fefd8">char16</a>. </p>
</div><h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="acf88e43da1b31d3d425c80d747bbb1a8" name="acf88e43da1b31d3d425c80d747bbb1a8"></a>
<h2 class="memtitle"><span class="permalink"><a href="#acf88e43da1b31d3d425c80d747bbb1a8">&#9670;&#160;</a></span>ConstStringTable()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classSteinberg_1_1ConstStringTable.html">ConstStringTable</a> </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel protected">protected</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a99f647d997cd61d511fdf60560c5706b" name="a99f647d997cd61d511fdf60560c5706b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a99f647d997cd61d511fdf60560c5706b">&#9670;&#160;</a></span>~ConstStringTable()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">~<a class="el" href="classSteinberg_1_1ConstStringTable.html">ConstStringTable</a> </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel protected">protected</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a7ed68ef8938393b1fc911313db64c804" name="a7ed68ef8938393b1fc911313db64c804"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7ed68ef8938393b1fc911313db64c804">&#9670;&#160;</a></span>instance()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classSteinberg_1_1ConstStringTable.html">ConstStringTable</a> * instance </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel static">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="ad11982e5de305e29fd59bab3e197a4f2" name="ad11982e5de305e29fd59bab3e197a4f2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad11982e5de305e29fd59bab3e197a4f2">&#9670;&#160;</a></span>getString() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">const <a class="el" href="group__smtgtypedef.html#ga667a0a4e0cbcb3f3785984955e1fefd8">char16</a> * getString </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *</td> <td class="paramname"><span class="paramname"><em>str</em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Returns a <a class="el" href="group__smtgtypedef.html#ga667a0a4e0cbcb3f3785984955e1fefd8">char16</a> string of a ASCII string literal. </p>
</div>
</div>
<a id="ae50b58af65ebbc7d1a035d88c520d7dd" name="ae50b58af65ebbc7d1a035d88c520d7dd"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae50b58af65ebbc7d1a035d88c520d7dd">&#9670;&#160;</a></span>getString() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__smtgtypedef.html#ga667a0a4e0cbcb3f3785984955e1fefd8">char16</a> getString </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a></td> <td class="paramname"><span class="paramname"><em>str</em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Returns a <a class="el" href="group__smtgtypedef.html#ga667a0a4e0cbcb3f3785984955e1fefd8">char16</a> character of a ASCII character. </p>
</div>
</div>
</div><!-- contents -->
</div><!-- doc-content -->
<html>
<head>
<title>Empty</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Steinberg">
</head>
<body>
<br/>
<hr width="100%" size="2" align="left" />
<div align=right>
Copyright &copy;<span id="year"></span> <a href="http://www.steinberg.net" target="_blank"><u>Steinberg Media Technologies GmbH</u></a>.
All Rights Reserved. This documentation is under this <a href="http://www.steinberg.net/sdklicenses" target="_blank"><u>license</u></a>.
</div>
<script>
document.querySelector("#year").textContent = new Date().getFullYear();
</script>
</body>
</html>
@@ -0,0 +1,7 @@
var classSteinberg_1_1ConstStringTable =
[
[ "ConstStringTable", "classSteinberg_1_1ConstStringTable.html#acf88e43da1b31d3d425c80d747bbb1a8", null ],
[ "~ConstStringTable", "classSteinberg_1_1ConstStringTable.html#a99f647d997cd61d511fdf60560c5706b", null ],
[ "getString", "classSteinberg_1_1ConstStringTable.html#ad11982e5de305e29fd59bab3e197a4f2", null ],
[ "getString", "classSteinberg_1_1ConstStringTable.html#ae50b58af65ebbc7d1a035d88c520d7dd", null ]
];
@@ -0,0 +1,159 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Interface Technology Basics: Member List</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="smtg_extra.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Interface Technology Basics<span id="projectnumber">&#160;VST 3.8</span>
</div>
<div id="projectbrief">SDK for developing VST plug-in</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search',true);
$(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){initNavTree('classSteinberg_1_1FUID.html',''); initResizable(true); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="headertitle"><div class="title">FUID Member List</div></div>
</div><!--header-->
<div class="contents">
<p>This is the complete list of members for <a class="el" href="classSteinberg_1_1FUID.html">FUID</a>, including all inherited members.</p>
<table class="directory">
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a5831f7a540668b040269fcc4a4634a6c">data</a></td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#ad4ecb2d9af5f8cf17d6ec497f871f13a">from4Int</a>(uint32 d1, uint32 d2, uint32 d3, uint32 d4)</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a8124e38def2946aa169b72c0fdb115bb">fromRegistryString</a>(const char8 *string)</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a1e809eb52c1b13101a137f4f722d93ab">fromString</a>(const char8 *string)</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a23ebc24784d7e1065dd4685c348921d6">fromTUID</a>(const TUID uid)</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">static</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#aef4d827e945c171d056b9ed79a8964f8">FUID</a>()</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a29217891f71b9c22549ae79a894f480f">FUID</a>(uint32 l1, uint32 l2, uint32 l3, uint32 l4)</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a0404d1a9d834c21a3c91a2d9b8c1a361">FUID</a>(const FUID &amp;)</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a520fecef8e1598c4068262db433bef10">FUID</a>(const char(&amp;uid)[N])</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">explicit</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#aa854636edbaec64049039c593403bc70">generate</a>()</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a69634d019cd59e996d3e58b7c73d77b3">getLong1</a>() const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a2c9ff52f208fe256a9798bbcc00e1eac">getLong2</a>() const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#acf6839f0503110cef6b68d8ea88fc80b">getLong3</a>() const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#ae8f158cac1ea26a24ddc1a8ad22cb4b6">getLong4</a>() const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a5bc2a781be2586924afce4e4a4ea6697">isValid</a>() const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a4c6d5af58eee71460b173f2a3fc16e83af0e94a5c0c5e442c941dedb3488540dd">kCLASS_UID</a> enum value</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a4c6d5af58eee71460b173f2a3fc16e83a0645d915ab71dfc6a46b46b2e0437b01">kDECLARE_UID</a> enum value</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a4c6d5af58eee71460b173f2a3fc16e83a786d38db04f85fa7d41ffb4bfdb38283">kFUID</a> enum value</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a4c6d5af58eee71460b173f2a3fc16e83a9f131fba80cf6b9f835dbcd1893a8e2a">kINLINE_UID</a> enum value</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#afae4e80e8075a18550e4fc7133be806e">operator const TUID &amp;</a>() const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a50949c38f9edc20949dda2b2e9be0c20">operator!=</a>(const FUID &amp;f) const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a47e1a323874d7aeb090bb8b82ef1b9ce">operator&lt;</a>(const FUID &amp;f) const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#ac8fc81bf202c6eb2f5832bc9605bf0bc">operator=</a>(const FUID &amp;f)</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a5ad5c12f86e9e7ba00d880779d52d41c">operator==</a>(const FUID &amp;f) const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a455f8339a8295a98549aa87d3ee0c63a">print</a>(int32 style, char8 *string=nullptr, size_t stringBufferSize=0) const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a2e69817c730e10bae2a6d442eb32b9a7">String</a> typedef</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#af7f9ecc7a078e7ae6461165c94b2525f">to4Int</a>(uint32 &amp;d1, uint32 &amp;d2, uint32 &amp;d3, uint32 &amp;d4) const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#ab89459cc6a432d8ed103b5113a74cfc9">toRegistryString</a>(char8 *string) const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a9ee7f374796ccad9af741f533e79dbea">toString</a>(char8 *string) const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#af2e718c3b14a4a50caf23cadeebe862c">toTUID</a>(TUID result) const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#ada4c8b233567ae46549da9769a739f02">toTUID</a>() const</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a4c6d5af58eee71460b173f2a3fc16e83">UIDPrintStyle</a> enum name</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html#a55b6f76b0487f0ceb85525b05fa4009f">~FUID</a>()</td><td class="entry"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
</table></div><!-- contents -->
</div><!-- doc-content -->
<html>
<head>
<title>Empty</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Steinberg">
</head>
<body>
<br/>
<hr width="100%" size="2" align="left" />
<div align=right>
Copyright &copy;<span id="year"></span> <a href="http://www.steinberg.net" target="_blank"><u>Steinberg Media Technologies GmbH</u></a>.
All Rights Reserved. This documentation is under this <a href="http://www.steinberg.net/sdklicenses" target="_blank"><u>license</u></a>.
</div>
<script>
document.querySelector("#year").textContent = new Date().getFullYear();
</script>
</body>
</html>
@@ -0,0 +1,887 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Interface Technology Basics: FUID Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="smtg_extra.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Interface Technology Basics<span id="projectnumber">&#160;VST 3.8</span>
</div>
<div id="projectbrief">SDK for developing VST plug-in</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search',true);
$(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){initNavTree('classSteinberg_1_1FUID.html',''); initResizable(true); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="summary">
<a href="#pub-types">Public Types</a> &#124;
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pub-static-methods">Static Public Member Functions</a> &#124;
<a href="#pro-attribs">Protected Attributes</a> &#124;
<a href="classSteinberg_1_1FUID-members.html">List of all members</a> </div>
<div class="headertitle"><div class="title">FUID Class Reference<div class="ingroups"><a class="el" href="group__pluginBase.html">Basic Interfaces</a></div></div></div>
</div><!--header-->
<div class="contents">
<p>Handling 16 Byte Globally Unique Identifiers.
<a href="#details">More...</a></p>
<p><code>#include &lt;funknown.h&gt;</code></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-types" name="pub-types"></a>
Public Types</h2></td></tr>
<tr class="memitem:a4c6d5af58eee71460b173f2a3fc16e83" id="r_a4c6d5af58eee71460b173f2a3fc16e83"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a4c6d5af58eee71460b173f2a3fc16e83">UIDPrintStyle</a> { <a class="el" href="#a4c6d5af58eee71460b173f2a3fc16e83a9f131fba80cf6b9f835dbcd1893a8e2a">kINLINE_UID</a>
, <a class="el" href="#a4c6d5af58eee71460b173f2a3fc16e83a0645d915ab71dfc6a46b46b2e0437b01">kDECLARE_UID</a>
, <a class="el" href="#a4c6d5af58eee71460b173f2a3fc16e83a786d38db04f85fa7d41ffb4bfdb38283">kFUID</a>
, <a class="el" href="#a4c6d5af58eee71460b173f2a3fc16e83af0e94a5c0c5e442c941dedb3488540dd">kCLASS_UID</a>
}</td></tr>
<tr class="separator:a4c6d5af58eee71460b173f2a3fc16e83"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a2e69817c730e10bae2a6d442eb32b9a7" id="r_a2e69817c730e10bae2a6d442eb32b9a7"><td class="memItemLeft" align="right" valign="top">typedef <a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a2e69817c730e10bae2a6d442eb32b9a7">String</a>[33]</td></tr>
<tr class="separator:a2e69817c730e10bae2a6d442eb32b9a7"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:aef4d827e945c171d056b9ed79a8964f8" id="r_aef4d827e945c171d056b9ed79a8964f8"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#aef4d827e945c171d056b9ed79a8964f8">FUID</a> ()</td></tr>
<tr class="separator:aef4d827e945c171d056b9ed79a8964f8"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a29217891f71b9c22549ae79a894f480f" id="r_a29217891f71b9c22549ae79a894f480f"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a29217891f71b9c22549ae79a894f480f">FUID</a> (<a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> l1, <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> l2, <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> l3, <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> l4)</td></tr>
<tr class="separator:a29217891f71b9c22549ae79a894f480f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0404d1a9d834c21a3c91a2d9b8c1a361" id="r_a0404d1a9d834c21a3c91a2d9b8c1a361"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a0404d1a9d834c21a3c91a2d9b8c1a361">FUID</a> (const <a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp;)</td></tr>
<tr class="separator:a0404d1a9d834c21a3c91a2d9b8c1a361"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a55b6f76b0487f0ceb85525b05fa4009f" id="r_a55b6f76b0487f0ceb85525b05fa4009f"><td class="memItemLeft" align="right" valign="top">virtual&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a55b6f76b0487f0ceb85525b05fa4009f">~FUID</a> ()</td></tr>
<tr class="separator:a55b6f76b0487f0ceb85525b05fa4009f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa854636edbaec64049039c593403bc70" id="r_aa854636edbaec64049039c593403bc70"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#aa854636edbaec64049039c593403bc70">generate</a> ()</td></tr>
<tr class="memdesc:aa854636edbaec64049039c593403bc70"><td class="mdescLeft">&#160;</td><td class="mdescRight">Generates a new Unique Identifier (UID). <br /></td></tr>
<tr class="separator:aa854636edbaec64049039c593403bc70"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5bc2a781be2586924afce4e4a4ea6697" id="r_a5bc2a781be2586924afce4e4a4ea6697"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a5bc2a781be2586924afce4e4a4ea6697">isValid</a> () const</td></tr>
<tr class="memdesc:a5bc2a781be2586924afce4e4a4ea6697"><td class="mdescLeft">&#160;</td><td class="mdescRight">Checks if the UID data is valid. <br /></td></tr>
<tr class="separator:a5bc2a781be2586924afce4e4a4ea6697"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ac8fc81bf202c6eb2f5832bc9605bf0bc" id="r_ac8fc81bf202c6eb2f5832bc9605bf0bc"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#ac8fc81bf202c6eb2f5832bc9605bf0bc">operator=</a> (const <a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp;f)</td></tr>
<tr class="separator:ac8fc81bf202c6eb2f5832bc9605bf0bc"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5ad5c12f86e9e7ba00d880779d52d41c" id="r_a5ad5c12f86e9e7ba00d880779d52d41c"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a5ad5c12f86e9e7ba00d880779d52d41c">operator==</a> (const <a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp;f) const</td></tr>
<tr class="separator:a5ad5c12f86e9e7ba00d880779d52d41c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a47e1a323874d7aeb090bb8b82ef1b9ce" id="r_a47e1a323874d7aeb090bb8b82ef1b9ce"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a47e1a323874d7aeb090bb8b82ef1b9ce">operator&lt;</a> (const <a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp;f) const</td></tr>
<tr class="separator:a47e1a323874d7aeb090bb8b82ef1b9ce"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a50949c38f9edc20949dda2b2e9be0c20" id="r_a50949c38f9edc20949dda2b2e9be0c20"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a50949c38f9edc20949dda2b2e9be0c20">operator!=</a> (const <a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp;f) const</td></tr>
<tr class="separator:a50949c38f9edc20949dda2b2e9be0c20"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a69634d019cd59e996d3e58b7c73d77b3" id="r_a69634d019cd59e996d3e58b7c73d77b3"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a69634d019cd59e996d3e58b7c73d77b3">getLong1</a> () const</td></tr>
<tr class="separator:a69634d019cd59e996d3e58b7c73d77b3"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a2c9ff52f208fe256a9798bbcc00e1eac" id="r_a2c9ff52f208fe256a9798bbcc00e1eac"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a2c9ff52f208fe256a9798bbcc00e1eac">getLong2</a> () const</td></tr>
<tr class="separator:a2c9ff52f208fe256a9798bbcc00e1eac"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:acf6839f0503110cef6b68d8ea88fc80b" id="r_acf6839f0503110cef6b68d8ea88fc80b"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#acf6839f0503110cef6b68d8ea88fc80b">getLong3</a> () const</td></tr>
<tr class="separator:acf6839f0503110cef6b68d8ea88fc80b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae8f158cac1ea26a24ddc1a8ad22cb4b6" id="r_ae8f158cac1ea26a24ddc1a8ad22cb4b6"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#ae8f158cac1ea26a24ddc1a8ad22cb4b6">getLong4</a> () const</td></tr>
<tr class="separator:ae8f158cac1ea26a24ddc1a8ad22cb4b6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad4ecb2d9af5f8cf17d6ec497f871f13a" id="r_ad4ecb2d9af5f8cf17d6ec497f871f13a"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#ad4ecb2d9af5f8cf17d6ec497f871f13a">from4Int</a> (<a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> d1, <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> d2, <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> d3, <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> d4)</td></tr>
<tr class="separator:ad4ecb2d9af5f8cf17d6ec497f871f13a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af7f9ecc7a078e7ae6461165c94b2525f" id="r_af7f9ecc7a078e7ae6461165c94b2525f"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#af7f9ecc7a078e7ae6461165c94b2525f">to4Int</a> (<a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> &amp;d1, <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> &amp;d2, <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> &amp;d3, <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> &amp;d4) const</td></tr>
<tr class="separator:af7f9ecc7a078e7ae6461165c94b2525f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9ee7f374796ccad9af741f533e79dbea" id="r_a9ee7f374796ccad9af741f533e79dbea"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a9ee7f374796ccad9af741f533e79dbea">toString</a> (<a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *string) const</td></tr>
<tr class="memdesc:a9ee7f374796ccad9af741f533e79dbea"><td class="mdescLeft">&#160;</td><td class="mdescRight">Converts UID to a string. <br /></td></tr>
<tr class="separator:a9ee7f374796ccad9af741f533e79dbea"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1e809eb52c1b13101a137f4f722d93ab" id="r_a1e809eb52c1b13101a137f4f722d93ab"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a1e809eb52c1b13101a137f4f722d93ab">fromString</a> (const <a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *string)</td></tr>
<tr class="memdesc:a1e809eb52c1b13101a137f4f722d93ab"><td class="mdescLeft">&#160;</td><td class="mdescRight">Sets the UID data from a string. <br /></td></tr>
<tr class="separator:a1e809eb52c1b13101a137f4f722d93ab"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab89459cc6a432d8ed103b5113a74cfc9" id="r_ab89459cc6a432d8ed103b5113a74cfc9"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#ab89459cc6a432d8ed103b5113a74cfc9">toRegistryString</a> (<a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *string) const</td></tr>
<tr class="memdesc:ab89459cc6a432d8ed103b5113a74cfc9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Converts UID to a string in Microsoft(R) OLE format. <br /></td></tr>
<tr class="separator:ab89459cc6a432d8ed103b5113a74cfc9"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8124e38def2946aa169b72c0fdb115bb" id="r_a8124e38def2946aa169b72c0fdb115bb"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a8124e38def2946aa169b72c0fdb115bb">fromRegistryString</a> (const <a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *string)</td></tr>
<tr class="memdesc:a8124e38def2946aa169b72c0fdb115bb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Sets the UID data from a string in Microsoft(R) OLE format. <br /></td></tr>
<tr class="separator:a8124e38def2946aa169b72c0fdb115bb"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a455f8339a8295a98549aa87d3ee0c63a" id="r_a455f8339a8295a98549aa87d3ee0c63a"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a455f8339a8295a98549aa87d3ee0c63a">print</a> (<a class="el" href="group__smtgtypedef.html#gab7903878916593daecbeb95b98115ab0">int32</a> style, <a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *string=nullptr, size_t stringBufferSize=0) const</td></tr>
<tr class="memdesc:a455f8339a8295a98549aa87d3ee0c63a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prints the UID to a string (or debug output if string is NULL). <br /></td></tr>
<tr class="separator:a455f8339a8295a98549aa87d3ee0c63a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a520fecef8e1598c4068262db433bef10" id="r_a520fecef8e1598c4068262db433bef10"><td class="memTemplParams" colspan="2">template&lt;size_t N&gt; </td></tr>
<tr class="memitem:a520fecef8e1598c4068262db433bef10"><td class="memTemplItemLeft" align="right" valign="top">&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="#a520fecef8e1598c4068262db433bef10">FUID</a> (const <a class="el" href="group__smtgtypedef.html#gaa9eb7d301130a7771343735bef461579">char</a>(&amp;uid)[N])</td></tr>
<tr class="separator:a520fecef8e1598c4068262db433bef10"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af2e718c3b14a4a50caf23cadeebe862c" id="r_af2e718c3b14a4a50caf23cadeebe862c"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#af2e718c3b14a4a50caf23cadeebe862c">toTUID</a> (<a class="el" href="group__pluginBase.html#ga6935af93744bfe4ecc455f274ef1ec36">TUID</a> result) const</td></tr>
<tr class="separator:af2e718c3b14a4a50caf23cadeebe862c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:afae4e80e8075a18550e4fc7133be806e" id="r_afae4e80e8075a18550e4fc7133be806e"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#afae4e80e8075a18550e4fc7133be806e">operator const TUID &amp;</a> () const</td></tr>
<tr class="separator:afae4e80e8075a18550e4fc7133be806e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ada4c8b233567ae46549da9769a739f02" id="r_ada4c8b233567ae46549da9769a739f02"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="group__pluginBase.html#ga6935af93744bfe4ecc455f274ef1ec36">TUID</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#ada4c8b233567ae46549da9769a739f02">toTUID</a> () const</td></tr>
<tr class="separator:ada4c8b233567ae46549da9769a739f02"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-static-methods" name="pub-static-methods"></a>
Static Public Member Functions</h2></td></tr>
<tr class="memitem:a23ebc24784d7e1065dd4685c348921d6" id="r_a23ebc24784d7e1065dd4685c348921d6"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="classSteinberg_1_1FUID.html">FUID</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a23ebc24784d7e1065dd4685c348921d6">fromTUID</a> (const <a class="el" href="group__pluginBase.html#ga6935af93744bfe4ecc455f274ef1ec36">TUID</a> uid)</td></tr>
<tr class="separator:a23ebc24784d7e1065dd4685c348921d6"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pro-attribs" name="pro-attribs"></a>
Protected Attributes</h2></td></tr>
<tr class="memitem:a5831f7a540668b040269fcc4a4634a6c" id="r_a5831f7a540668b040269fcc4a4634a6c"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__pluginBase.html#ga6935af93744bfe4ecc455f274ef1ec36">TUID</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a5831f7a540668b040269fcc4a4634a6c">data</a></td></tr>
<tr class="separator:a5831f7a540668b040269fcc4a4634a6c"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>Handling 16 Byte Globally Unique Identifiers. </p>
<p>Each interface declares its identifier as static member inside the interface namespace (e.g. <a class="el" href="classSteinberg_1_1FUnknown.html#a07978c93295b03d09c4bc97aa12e9c60">FUnknown::iid</a>). </p>
</div><h2 class="groupheader">Member Typedef Documentation</h2>
<a id="a2e69817c730e10bae2a6d442eb32b9a7" name="a2e69817c730e10bae2a6d442eb32b9a7"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a2e69817c730e10bae2a6d442eb32b9a7">&#9670;&#160;</a></span>String</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">typedef <a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> String[33]</td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<h2 class="groupheader">Member Enumeration Documentation</h2>
<a id="a4c6d5af58eee71460b173f2a3fc16e83" name="a4c6d5af58eee71460b173f2a3fc16e83"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a4c6d5af58eee71460b173f2a3fc16e83">&#9670;&#160;</a></span>UIDPrintStyle</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">enum <a class="el" href="#a4c6d5af58eee71460b173f2a3fc16e83">UIDPrintStyle</a></td>
</tr>
</table>
</div><div class="memdoc">
<table class="fieldtable">
<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="a4c6d5af58eee71460b173f2a3fc16e83a9f131fba80cf6b9f835dbcd1893a8e2a" name="a4c6d5af58eee71460b173f2a3fc16e83a9f131fba80cf6b9f835dbcd1893a8e2a"></a>kINLINE_UID&#160;</td><td class="fielddoc"><p>"INLINE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)" </p>
</td></tr>
<tr><td class="fieldname"><a id="a4c6d5af58eee71460b173f2a3fc16e83a0645d915ab71dfc6a46b46b2e0437b01" name="a4c6d5af58eee71460b173f2a3fc16e83a0645d915ab71dfc6a46b46b2e0437b01"></a>kDECLARE_UID&#160;</td><td class="fielddoc"><p>"DECLARE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)" </p>
</td></tr>
<tr><td class="fieldname"><a id="a4c6d5af58eee71460b173f2a3fc16e83a786d38db04f85fa7d41ffb4bfdb38283" name="a4c6d5af58eee71460b173f2a3fc16e83a786d38db04f85fa7d41ffb4bfdb38283"></a>kFUID&#160;</td><td class="fielddoc"><p>"FUID (0x00000000, 0x00000000, 0x00000000, 0x00000000)" </p>
</td></tr>
<tr><td class="fieldname"><a id="a4c6d5af58eee71460b173f2a3fc16e83af0e94a5c0c5e442c941dedb3488540dd" name="a4c6d5af58eee71460b173f2a3fc16e83af0e94a5c0c5e442c941dedb3488540dd"></a>kCLASS_UID&#160;</td><td class="fielddoc"><p>"DECLARE_CLASS_IID (Interface, 0x00000000, 0x00000000, 0x00000000, 0x00000000)" </p>
</td></tr>
</table>
</div>
</div>
<h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="aef4d827e945c171d056b9ed79a8964f8" name="aef4d827e945c171d056b9ed79a8964f8"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aef4d827e945c171d056b9ed79a8964f8">&#9670;&#160;</a></span>FUID() <span class="overload">[1/4]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a> </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a29217891f71b9c22549ae79a894f480f" name="a29217891f71b9c22549ae79a894f480f"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a29217891f71b9c22549ae79a894f480f">&#9670;&#160;</a></span>FUID() <span class="overload">[2/4]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a> </td>
<td>(</td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a></td> <td class="paramname"><span class="paramname"><em>l1</em></span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a></td> <td class="paramname"><span class="paramname"><em>l2</em></span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a></td> <td class="paramname"><span class="paramname"><em>l3</em></span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a></td> <td class="paramname"><span class="paramname"><em>l4</em></span>&#160;)</td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a0404d1a9d834c21a3c91a2d9b8c1a361" name="a0404d1a9d834c21a3c91a2d9b8c1a361"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0404d1a9d834c21a3c91a2d9b8c1a361">&#9670;&#160;</a></span>FUID() <span class="overload">[3/4]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a> </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp;</td> <td class="paramname"><span class="paramname"><em>f</em></span></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a55b6f76b0487f0ceb85525b05fa4009f" name="a55b6f76b0487f0ceb85525b05fa4009f"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a55b6f76b0487f0ceb85525b05fa4009f">&#9670;&#160;</a></span>~FUID()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">virtual ~<a class="el" href="classSteinberg_1_1FUID.html">FUID</a> </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel inline">inline</span><span class="mlabel virtual">virtual</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a520fecef8e1598c4068262db433bef10" name="a520fecef8e1598c4068262db433bef10"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a520fecef8e1598c4068262db433bef10">&#9670;&#160;</a></span>FUID() <span class="overload">[4/4]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;size_t N&gt; </div>
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a> </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="group__smtgtypedef.html#gaa9eb7d301130a7771343735bef461579">char</a>(&amp;)</td> <td class="paramname"><span class="paramname"><em>uid</em></span>[N]</td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel inline">inline</span><span class="mlabel explicit">explicit</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="aa854636edbaec64049039c593403bc70" name="aa854636edbaec64049039c593403bc70"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa854636edbaec64049039c593403bc70">&#9670;&#160;</a></span>generate()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">bool generate </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Generates a new Unique Identifier (UID). </p>
<p>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. </p>
</div>
</div>
<a id="a5bc2a781be2586924afce4e4a4ea6697" name="a5bc2a781be2586924afce4e4a4ea6697"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a5bc2a781be2586924afce4e4a4ea6697">&#9670;&#160;</a></span>isValid()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">bool isValid </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Checks if the UID data is valid. </p>
<p>The default constructor initializes the memory with zeros. </p>
</div>
</div>
<a id="ac8fc81bf202c6eb2f5832bc9605bf0bc" name="ac8fc81bf202c6eb2f5832bc9605bf0bc"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac8fc81bf202c6eb2f5832bc9605bf0bc">&#9670;&#160;</a></span>operator=()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp; operator= </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp;</td> <td class="paramname"><span class="paramname"><em>f</em></span></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a5ad5c12f86e9e7ba00d880779d52d41c" name="a5ad5c12f86e9e7ba00d880779d52d41c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a5ad5c12f86e9e7ba00d880779d52d41c">&#9670;&#160;</a></span>operator==()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">bool operator== </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp;</td> <td class="paramname"><span class="paramname"><em>f</em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel inline">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a47e1a323874d7aeb090bb8b82ef1b9ce" name="a47e1a323874d7aeb090bb8b82ef1b9ce"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a47e1a323874d7aeb090bb8b82ef1b9ce">&#9670;&#160;</a></span>operator&lt;()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">bool operator&lt; </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp;</td> <td class="paramname"><span class="paramname"><em>f</em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel inline">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a50949c38f9edc20949dda2b2e9be0c20" name="a50949c38f9edc20949dda2b2e9be0c20"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a50949c38f9edc20949dda2b2e9be0c20">&#9670;&#160;</a></span>operator!=()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">bool operator!= </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classSteinberg_1_1FUID.html">FUID</a> &amp;</td> <td class="paramname"><span class="paramname"><em>f</em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel inline">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a69634d019cd59e996d3e58b7c73d77b3" name="a69634d019cd59e996d3e58b7c73d77b3"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a69634d019cd59e996d3e58b7c73d77b3">&#9670;&#160;</a></span>getLong1()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> getLong1 </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a2c9ff52f208fe256a9798bbcc00e1eac" name="a2c9ff52f208fe256a9798bbcc00e1eac"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a2c9ff52f208fe256a9798bbcc00e1eac">&#9670;&#160;</a></span>getLong2()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> getLong2 </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="acf6839f0503110cef6b68d8ea88fc80b" name="acf6839f0503110cef6b68d8ea88fc80b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#acf6839f0503110cef6b68d8ea88fc80b">&#9670;&#160;</a></span>getLong3()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> getLong3 </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="ae8f158cac1ea26a24ddc1a8ad22cb4b6" name="ae8f158cac1ea26a24ddc1a8ad22cb4b6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae8f158cac1ea26a24ddc1a8ad22cb4b6">&#9670;&#160;</a></span>getLong4()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> getLong4 </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="ad4ecb2d9af5f8cf17d6ec497f871f13a" name="ad4ecb2d9af5f8cf17d6ec497f871f13a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad4ecb2d9af5f8cf17d6ec497f871f13a">&#9670;&#160;</a></span>from4Int()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void from4Int </td>
<td>(</td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a></td> <td class="paramname"><span class="paramname"><em>d1</em></span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a></td> <td class="paramname"><span class="paramname"><em>d2</em></span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a></td> <td class="paramname"><span class="paramname"><em>d3</em></span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a></td> <td class="paramname"><span class="paramname"><em>d4</em></span>&#160;)</td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="af7f9ecc7a078e7ae6461165c94b2525f" name="af7f9ecc7a078e7ae6461165c94b2525f"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af7f9ecc7a078e7ae6461165c94b2525f">&#9670;&#160;</a></span>to4Int()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void to4Int </td>
<td>(</td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> &amp;</td> <td class="paramname"><span class="paramname"><em>d1</em></span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> &amp;</td> <td class="paramname"><span class="paramname"><em>d2</em></span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> &amp;</td> <td class="paramname"><span class="paramname"><em>d3</em></span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> &amp;</td> <td class="paramname"><span class="paramname"><em>d4</em></span>&#160;) const</td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a9ee7f374796ccad9af741f533e79dbea" name="a9ee7f374796ccad9af741f533e79dbea"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9ee7f374796ccad9af741f533e79dbea">&#9670;&#160;</a></span>toString()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void toString </td>
<td>(</td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *</td> <td class="paramname"><span class="paramname"><em>string</em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Converts UID to a string. </p>
<p>The string will be 32 characters long, representing the hexadecimal values of each data byte (e.g. "9127BE30160E4BB69966670AA6087880").</p>
<p>Typical use-case is: </p><div class="fragment"><div class="line"><a class="code hl_typedef" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a>[33] strUID = {0};</div>
<div class="line"><a class="code hl_class" href="classSteinberg_1_1FUID.html">FUID</a> uid;</div>
<div class="line"><span class="keywordflow">if</span> (uid.<a class="code hl_function" href="#aa854636edbaec64049039c593403bc70">generate</a> ())</div>
<div class="line"> uid.<a class="code hl_function" href="#a9ee7f374796ccad9af741f533e79dbea">toString</a> (strUID);</div>
<div class="ttc" id="aclassSteinberg_1_1FUID_html"><div class="ttname"><a href="classSteinberg_1_1FUID.html">Steinberg::FUID</a></div><div class="ttdoc">Handling 16 Byte Globally Unique Identifiers.</div><div class="ttdef"><b>Definition</b> funknown.h:246</div></div>
<div class="ttc" id="aclassSteinberg_1_1FUID_html_a9ee7f374796ccad9af741f533e79dbea"><div class="ttname"><a href="#a9ee7f374796ccad9af741f533e79dbea">Steinberg::FUID::toString</a></div><div class="ttdeci">void toString(char8 *string) const</div><div class="ttdoc">Converts UID to a string.</div><div class="ttdef"><b>Definition</b> funknown.cpp:290</div></div>
<div class="ttc" id="aclassSteinberg_1_1FUID_html_aa854636edbaec64049039c593403bc70"><div class="ttname"><a href="#aa854636edbaec64049039c593403bc70">Steinberg::FUID::generate</a></div><div class="ttdeci">bool generate()</div><div class="ttdoc">Generates a new Unique Identifier (UID).</div><div class="ttdef"><b>Definition</b> funknown.cpp:150</div></div>
<div class="ttc" id="agroup__smtgtypedef_html_gac9e1c0f508ae0f5f8a2b704a91e1ae86"><div class="ttname"><a href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">Steinberg::char8</a></div><div class="ttdeci">char char8</div><div class="ttdef"><b>Definition</b> ftypes.h:87</div></div>
</div><!-- fragment -->
</div>
</div>
<a id="a1e809eb52c1b13101a137f4f722d93ab" name="a1e809eb52c1b13101a137f4f722d93ab"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1e809eb52c1b13101a137f4f722d93ab">&#9670;&#160;</a></span>fromString()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">bool fromString </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *</td> <td class="paramname"><span class="paramname"><em>string</em></span></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Sets the UID data from a string. </p>
<p>The string has to be 32 characters long, where each character-pair is the ASCII-encoded hexadecimal value of the corresponding data byte. </p>
</div>
</div>
<a id="ab89459cc6a432d8ed103b5113a74cfc9" name="ab89459cc6a432d8ed103b5113a74cfc9"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ab89459cc6a432d8ed103b5113a74cfc9">&#9670;&#160;</a></span>toRegistryString()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void toRegistryString </td>
<td>(</td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *</td> <td class="paramname"><span class="paramname"><em>string</em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Converts UID to a string in Microsoft(R) OLE format. </p>
<p>(e.g. "{c200e360-38c5-11ce-ae62-08002b2b79ef}") </p>
</div>
</div>
<a id="a8124e38def2946aa169b72c0fdb115bb" name="a8124e38def2946aa169b72c0fdb115bb"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8124e38def2946aa169b72c0fdb115bb">&#9670;&#160;</a></span>fromRegistryString()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">bool fromRegistryString </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *</td> <td class="paramname"><span class="paramname"><em>string</em></span></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Sets the UID data from a string in Microsoft(R) OLE format. </p>
</div>
</div>
<a id="a455f8339a8295a98549aa87d3ee0c63a" name="a455f8339a8295a98549aa87d3ee0c63a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a455f8339a8295a98549aa87d3ee0c63a">&#9670;&#160;</a></span>print()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void print </td>
<td>(</td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gab7903878916593daecbeb95b98115ab0">int32</a></td> <td class="paramname"><span class="paramname"><em>style</em></span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="group__smtgtypedef.html#gac9e1c0f508ae0f5f8a2b704a91e1ae86">char8</a> *</td> <td class="paramname"><span class="paramname"><em>string</em></span><span class="paramdefsep"> = </span><span class="paramdefval">nullptr</span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t</td> <td class="paramname"><span class="paramname"><em>stringBufferSize</em></span><span class="paramdefsep"> = </span><span class="paramdefval">0</span>&#160;) const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Prints the UID to a string (or debug output if string is NULL). </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">style</td><td>can be chosen from the <a class="el" href="#a4c6d5af58eee71460b173f2a3fc16e83">FUID::UIDPrintStyle</a> enumeration. </td></tr>
<tr><td class="paramname">string</td><td>is the output string if not NULL. </td></tr>
<tr><td class="paramname">stringBufferSize</td><td>is the size of the output string </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a id="af2e718c3b14a4a50caf23cadeebe862c" name="af2e718c3b14a4a50caf23cadeebe862c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af2e718c3b14a4a50caf23cadeebe862c">&#9670;&#160;</a></span>toTUID() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void toTUID </td>
<td>(</td>
<td class="paramtype"><a class="el" href="group__pluginBase.html#ga6935af93744bfe4ecc455f274ef1ec36">TUID</a></td> <td class="paramname"><span class="paramname"><em>result</em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel inline">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="afae4e80e8075a18550e4fc7133be806e" name="afae4e80e8075a18550e4fc7133be806e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#afae4e80e8075a18550e4fc7133be806e">&#9670;&#160;</a></span>operator const TUID &amp;()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">operator const <a class="el" href="group__pluginBase.html#ga6935af93744bfe4ecc455f274ef1ec36">TUID</a> &amp; </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel inline">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="ada4c8b233567ae46549da9769a739f02" name="ada4c8b233567ae46549da9769a739f02"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ada4c8b233567ae46549da9769a739f02">&#9670;&#160;</a></span>toTUID() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">const <a class="el" href="group__pluginBase.html#ga6935af93744bfe4ecc455f274ef1ec36">TUID</a> &amp; toTUID </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel inline">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a23ebc24784d7e1065dd4685c348921d6" name="a23ebc24784d7e1065dd4685c348921d6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a23ebc24784d7e1065dd4685c348921d6">&#9670;&#160;</a></span>fromTUID()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">static <a class="el" href="classSteinberg_1_1FUID.html">FUID</a> fromTUID </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="group__pluginBase.html#ga6935af93744bfe4ecc455f274ef1ec36">TUID</a></td> <td class="paramname"><span class="paramname"><em>uid</em></span></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel inline">inline</span><span class="mlabel static">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<h2 class="groupheader">Member Data Documentation</h2>
<a id="a5831f7a540668b040269fcc4a4634a6c" name="a5831f7a540668b040269fcc4a4634a6c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a5831f7a540668b040269fcc4a4634a6c">&#9670;&#160;</a></span>data</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__pluginBase.html#ga6935af93744bfe4ecc455f274ef1ec36">TUID</a> data</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel protected">protected</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
</div><!-- contents -->
</div><!-- doc-content -->
<html>
<head>
<title>Empty</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Steinberg">
</head>
<body>
<br/>
<hr width="100%" size="2" align="left" />
<div align=right>
Copyright &copy;<span id="year"></span> <a href="http://www.steinberg.net" target="_blank"><u>Steinberg Media Technologies GmbH</u></a>.
All Rights Reserved. This documentation is under this <a href="http://www.steinberg.net/sdklicenses" target="_blank"><u>license</u></a>.
</div>
<script>
document.querySelector("#year").textContent = new Date().getFullYear();
</script>
</body>
</html>
@@ -0,0 +1,36 @@
var classSteinberg_1_1FUID =
[
[ "String", "classSteinberg_1_1FUID.html#a2e69817c730e10bae2a6d442eb32b9a7", null ],
[ "UIDPrintStyle", "classSteinberg_1_1FUID.html#a4c6d5af58eee71460b173f2a3fc16e83", [
[ "kINLINE_UID", "classSteinberg_1_1FUID.html#a4c6d5af58eee71460b173f2a3fc16e83a9f131fba80cf6b9f835dbcd1893a8e2a", null ],
[ "kDECLARE_UID", "classSteinberg_1_1FUID.html#a4c6d5af58eee71460b173f2a3fc16e83a0645d915ab71dfc6a46b46b2e0437b01", null ],
[ "kFUID", "classSteinberg_1_1FUID.html#a4c6d5af58eee71460b173f2a3fc16e83a786d38db04f85fa7d41ffb4bfdb38283", null ],
[ "kCLASS_UID", "classSteinberg_1_1FUID.html#a4c6d5af58eee71460b173f2a3fc16e83af0e94a5c0c5e442c941dedb3488540dd", null ]
] ],
[ "FUID", "classSteinberg_1_1FUID.html#aef4d827e945c171d056b9ed79a8964f8", null ],
[ "FUID", "classSteinberg_1_1FUID.html#a29217891f71b9c22549ae79a894f480f", null ],
[ "FUID", "classSteinberg_1_1FUID.html#a0404d1a9d834c21a3c91a2d9b8c1a361", null ],
[ "~FUID", "classSteinberg_1_1FUID.html#a55b6f76b0487f0ceb85525b05fa4009f", null ],
[ "FUID", "classSteinberg_1_1FUID.html#a520fecef8e1598c4068262db433bef10", null ],
[ "generate", "classSteinberg_1_1FUID.html#aa854636edbaec64049039c593403bc70", null ],
[ "isValid", "classSteinberg_1_1FUID.html#a5bc2a781be2586924afce4e4a4ea6697", null ],
[ "operator=", "classSteinberg_1_1FUID.html#ac8fc81bf202c6eb2f5832bc9605bf0bc", null ],
[ "operator==", "classSteinberg_1_1FUID.html#a5ad5c12f86e9e7ba00d880779d52d41c", null ],
[ "operator<", "classSteinberg_1_1FUID.html#a47e1a323874d7aeb090bb8b82ef1b9ce", null ],
[ "operator!=", "classSteinberg_1_1FUID.html#a50949c38f9edc20949dda2b2e9be0c20", null ],
[ "getLong1", "classSteinberg_1_1FUID.html#a69634d019cd59e996d3e58b7c73d77b3", null ],
[ "getLong2", "classSteinberg_1_1FUID.html#a2c9ff52f208fe256a9798bbcc00e1eac", null ],
[ "getLong3", "classSteinberg_1_1FUID.html#acf6839f0503110cef6b68d8ea88fc80b", null ],
[ "getLong4", "classSteinberg_1_1FUID.html#ae8f158cac1ea26a24ddc1a8ad22cb4b6", null ],
[ "from4Int", "classSteinberg_1_1FUID.html#ad4ecb2d9af5f8cf17d6ec497f871f13a", null ],
[ "to4Int", "classSteinberg_1_1FUID.html#af7f9ecc7a078e7ae6461165c94b2525f", null ],
[ "toString", "classSteinberg_1_1FUID.html#a9ee7f374796ccad9af741f533e79dbea", null ],
[ "fromString", "classSteinberg_1_1FUID.html#a1e809eb52c1b13101a137f4f722d93ab", null ],
[ "toRegistryString", "classSteinberg_1_1FUID.html#ab89459cc6a432d8ed103b5113a74cfc9", null ],
[ "fromRegistryString", "classSteinberg_1_1FUID.html#a8124e38def2946aa169b72c0fdb115bb", null ],
[ "print", "classSteinberg_1_1FUID.html#a455f8339a8295a98549aa87d3ee0c63a", null ],
[ "toTUID", "classSteinberg_1_1FUID.html#af2e718c3b14a4a50caf23cadeebe862c", null ],
[ "operator const TUID &", "classSteinberg_1_1FUID.html#afae4e80e8075a18550e4fc7133be806e", null ],
[ "toTUID", "classSteinberg_1_1FUID.html#ada4c8b233567ae46549da9769a739f02", null ],
[ "data", "classSteinberg_1_1FUID.html#a5831f7a540668b040269fcc4a4634a6c", null ]
];
@@ -0,0 +1,130 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Interface Technology Basics: Member List</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="smtg_extra.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Interface Technology Basics<span id="projectnumber">&#160;VST 3.8</span>
</div>
<div id="projectbrief">SDK for developing VST plug-in</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search',true);
$(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){initNavTree('classSteinberg_1_1FUnknown.html',''); initResizable(true); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="headertitle"><div class="title">FUnknown Member List</div></div>
</div><!--header-->
<div class="contents">
<p>This is the complete list of members for <a class="el" href="classSteinberg_1_1FUnknown.html">FUnknown</a>, including all inherited members.</p>
<table class="directory">
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUnknown.html#aaa3c5a2a5410d41153d7f5e3f4e0a635">addRef</a>()=0</td><td class="entry"><a class="el" href="classSteinberg_1_1FUnknown.html">FUnknown</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUnknown.html#a07978c93295b03d09c4bc97aa12e9c60">iid</a></td><td class="entry"><a class="el" href="classSteinberg_1_1FUnknown.html">FUnknown</a></td><td class="entry"><span class="mlabel">static</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classSteinberg_1_1FUnknown.html#a4199134d0669bfa92b7419dac14c01a7">queryInterface</a>(const TUID _iid, void **obj)=0</td><td class="entry"><a class="el" href="classSteinberg_1_1FUnknown.html">FUnknown</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classSteinberg_1_1FUnknown.html#a58847c78bf6142f01ce214c2802cb146">release</a>()=0</td><td class="entry"><a class="el" href="classSteinberg_1_1FUnknown.html">FUnknown</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
</table></div><!-- contents -->
</div><!-- doc-content -->
<html>
<head>
<title>Empty</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Steinberg">
</head>
<body>
<br/>
<hr width="100%" size="2" align="left" />
<div align=right>
Copyright &copy;<span id="year"></span> <a href="http://www.steinberg.net" target="_blank"><u>Steinberg Media Technologies GmbH</u></a>.
All Rights Reserved. This documentation is under this <a href="http://www.steinberg.net/sdklicenses" target="_blank"><u>license</u></a>.
</div>
<script>
document.querySelector("#year").textContent = new Date().getFullYear();
</script>
</body>
</html>
@@ -0,0 +1,332 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Interface Technology Basics: FUnknown Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="smtg_extra.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Interface Technology Basics<span id="projectnumber">&#160;VST 3.8</span>
</div>
<div id="projectbrief">SDK for developing VST plug-in</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search',true);
$(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){initNavTree('classSteinberg_1_1FUnknown.html',''); initResizable(true); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="summary">
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pub-static-attribs">Static Public Attributes</a> &#124;
<a href="classSteinberg_1_1FUnknown-members.html">List of all members</a> </div>
<div class="headertitle"><div class="title">FUnknown Class Reference<span class="mlabels"><span class="mlabel abstract">abstract</span></span><div class="ingroups"><a class="el" href="group__pluginBase.html">Basic Interfaces</a></div></div></div>
</div><!--header-->
<div class="contents">
<p>The basic interface of all interfaces.
<a href="#details">More...</a></p>
<p><code>#include &lt;funknown.h&gt;</code></p>
<div id="dynsection-0" onclick="return dynsection.toggleVisibility(this)" class="dynheader closed" style="cursor:pointer;">
<img id="dynsection-0-trigger" src="closed.png" alt="+"/> Inheritance diagram for FUnknown:</div>
<div id="dynsection-0-summary" class="dynsummary" style="display:block;">
</div>
<div id="dynsection-0-content" class="dyncontent" style="display:none;">
<div class="center"><img src="classSteinberg_1_1FUnknown__inherit__graph.png" border="0" usemap="#aFUnknown_inherit__map" alt="Inheritance graph"/></div>
<map name="aFUnknown_inherit__map" id="aFUnknown_inherit__map">
<area shape="rect" title="The basic interface of all interfaces." alt="" coords="1277,5,1386,107"/>
<area shape="rect" href="structSteinberg_1_1FUnknownImpl_1_1HideIIDBase.html" title="A base class which hides the FUnknown::iid static var." alt="" coords="5,281,85,344"/>
<area shape="poly" title=" " alt="" coords="1263,61,989,68,622,84,442,97,284,113,164,133,124,145,99,157,76,184,61,217,52,251,48,281,43,281,47,250,56,215,71,181,96,153,122,140,163,128,283,108,441,92,622,79,989,63,1263,56"/>
<area shape="rect" href="classSteinberg_1_1IAttributes.html" title="Object Data Archive Interface." alt="" coords="109,155,250,470"/>
<area shape="poly" title=" " alt="" coords="1262,63,1024,74,710,93,557,106,423,121,321,138,286,148,264,158,252,167,248,163,261,153,284,143,320,133,422,116,556,101,709,88,1023,68,1262,58"/>
<area shape="rect" href="classSteinberg_1_1IBStream.html" title="Base class for streams." alt="" coords="275,252,336,373"/>
<area shape="poly" title=" " alt="" coords="1262,63,1039,73,751,91,611,104,489,119,398,137,367,147,348,157,331,177,319,201,308,253,303,252,314,199,327,174,345,153,365,142,396,132,489,114,610,99,750,86,1039,67,1262,57"/>
<area shape="rect" href="classSteinberg_1_1ICloneable.html" title="Interface allowing an object to be copied." alt="" coords="359,281,430,344"/>
<area shape="poly" title=" " alt="" coords="1262,64,1059,75,802,95,678,108,570,123,488,139,461,148,444,157,422,184,408,217,400,251,397,282,392,281,395,250,403,216,417,182,441,153,459,143,487,134,569,117,677,103,801,90,1059,70,1262,58"/>
<area shape="rect" href="classSteinberg_1_1IDependent.html" title="A dependent will get notified about changes of a model." alt="" coords="454,281,529,344"/>
<area shape="poly" title=" " alt="" coords="1262,60,1092,62,878,75,772,87,676,104,597,128,567,142,543,157,520,184,506,217,498,251,495,282,490,281,493,251,501,216,516,182,539,153,564,137,595,123,675,99,771,82,878,69,1092,57,1262,54"/>
<area shape="rect" href="classSteinberg_1_1IErrorContext.html" title="Interface for error handling." alt="" coords="553,262,698,364"/>
<area shape="poly" title=" " alt="" coords="1263,64,1128,73,966,90,886,103,813,118,753,136,711,158,687,179,668,206,641,263,636,261,663,204,683,176,708,153,751,131,812,113,885,97,965,85,1128,68,1262,58"/>
<area shape="rect" href="classSteinberg_1_1IPersistent.html" title="Persistent Object Interface." alt="" coords="722,262,830,364"/>
<area shape="poly" title=" " alt="" coords="1263,66,1156,78,1032,97,919,123,875,139,844,157,823,180,807,206,787,263,782,261,802,204,819,177,841,153,873,135,918,118,1031,92,1155,73,1262,61"/>
<area shape="rect" href="classSteinberg_1_1IPlugFrame.html" title="Callback interface passed to IPlugView." alt="" coords="854,281,945,344"/>
<area shape="poly" title=" " alt="" coords="1263,60,1192,66,1112,82,1071,94,1031,111,994,132,960,157,937,185,921,219,911,252,905,282,900,281,906,251,916,217,933,183,957,153,991,127,1029,106,1069,89,1111,77,1192,61,1262,55"/>
<area shape="rect" href="classSteinberg_1_1IPlugView.html" title="Plug&#45;in definition of a view." alt="" coords="970,175,1139,451"/>
<area shape="poly" title=" " alt="" coords="1265,86,1207,117,1152,157,1134,177,1130,173,1149,153,1204,112,1263,82"/>
<area shape="rect" href="classSteinberg_1_1IPlugViewContentScaleSupport.html" title="Plug&#45;in view content scale support." alt="" coords="1163,281,1346,344"/>
<area shape="poly" title=" " alt="" coords="1315,122,1266,282,1261,280,1310,121"/>
<area shape="rect" href="classSteinberg_1_1IPluginBase.html" title="Basic interface to a plug&#45;in component: IPluginBase." alt="" coords="1370,271,1452,354"/>
<area shape="poly" title=" " alt="" coords="1354,120,1401,271,1396,272,1349,122"/>
<area shape="rect" href="classSteinberg_1_1IPluginCompatibility.html" title="optional interface to query the compatibility of the plug&#45;ins classes" alt="" coords="1475,281,1626,344"/>
<area shape="poly" title=" " alt="" coords="1400,96,1434,123,1466,154,1490,185,1511,219,1541,280,1536,283,1506,222,1486,188,1462,157,1431,127,1397,101"/>
<area shape="rect" href="classSteinberg_1_1IPluginFactory.html" title="Class factory that any plug&#45;in defines for creating class instances: IPluginFactory." alt="" coords="1650,252,1761,373"/>
<area shape="poly" title=" " alt="" coords="1402,61,1458,70,1521,88,1584,114,1614,132,1640,153,1660,175,1675,200,1695,251,1690,253,1670,202,1655,178,1637,157,1611,137,1582,119,1520,93,1457,76,1401,66"/>
<area shape="rect" href="classSteinberg_1_1ISizeableStream.html" title="Stream with a size." alt="" coords="1784,271,1895,354"/>
<area shape="poly" title=" " alt="" coords="1402,63,1498,76,1608,95,1708,121,1747,136,1775,153,1798,179,1816,210,1836,271,1831,272,1811,212,1794,182,1771,157,1744,141,1706,126,1607,100,1497,81,1401,68"/>
<area shape="rect" href="classSteinberg_1_1IString.html" title="Interface to a string of variable size and encoding." alt="" coords="1919,233,2019,393"/>
<area shape="poly" title=" " alt="" coords="1401,58,1527,68,1677,85,1750,98,1816,113,1871,131,1909,153,1926,170,1939,189,1958,232,1953,234,1935,192,1922,173,1906,157,1868,136,1815,118,1749,103,1676,90,1526,73,1401,64"/>
<area shape="rect" href="classSteinberg_1_1IStringResult.html" title="Interface to return an ascii string of variable size." alt="" coords="2044,281,2124,344"/>
<area shape="poly" title=" " alt="" coords="1401,56,1553,61,1740,76,1832,88,1916,105,1985,126,2012,139,2034,153,2057,182,2073,216,2082,251,2085,281,2080,282,2076,252,2068,218,2053,185,2030,157,2010,144,1983,131,1915,110,1832,93,1740,81,1553,66,1401,61"/>
<area shape="rect" href="classSteinberg_1_1IUpdateHandler.html" title="Host implements dependency handling for plugins." alt="" coords="2148,252,2281,373"/>
<area shape="poly" title=" " alt="" coords="1401,55,1572,60,1789,74,1897,86,1996,103,2078,125,2111,138,2137,153,2160,173,2178,198,2202,251,2197,253,2173,201,2156,177,2134,157,2109,143,2077,130,1995,108,1896,91,1788,79,1572,65,1401,61"/>
<area shape="rect" href="classSteinberg_1_1Linux_1_1IEventHandler.html" title="Linux event handler interface." alt="" coords="2305,281,2394,344"/>
<area shape="poly" title=" " alt="" coords="1401,58,1619,69,1899,88,2036,101,2154,116,2244,133,2275,143,2295,153,2320,181,2336,215,2346,250,2350,281,2345,282,2340,251,2331,217,2315,184,2292,157,2273,148,2243,138,2153,121,2035,106,1899,93,1619,74,1401,63"/>
<area shape="rect" href="classSteinberg_1_1Linux_1_1IRunLoop.html" title="Linux host run loop interface." alt="" coords="2418,252,2579,373"/>
<area shape="poly" title=" " alt="" coords="1402,58,1641,69,1956,89,2110,102,2244,117,2347,134,2383,143,2407,153,2431,173,2452,198,2481,251,2476,253,2447,201,2428,177,2404,158,2382,148,2346,139,2244,122,2109,107,1955,94,1641,74,1401,63"/>
<area shape="rect" href="classSteinberg_1_1Linux_1_1ITimerHandler.html" title="Linux timer handler interface." alt="" coords="2604,281,2692,344"/>
<area shape="poly" title=" " alt="" coords="1402,56,1680,63,2054,79,2239,92,2400,108,2523,128,2565,140,2592,153,2617,181,2634,215,2644,250,2649,281,2643,281,2639,251,2629,217,2613,184,2589,157,2563,145,2522,133,2399,113,2238,97,2054,84,1679,68,1401,61"/>
<area shape="rect" href="classSteinberg_1_1IAttributes2.html" title="Extended access to Attributes; supports Attribute retrieval via iteration." alt="" coords="124,518,236,601"/>
<area shape="poly" title=" " alt="" coords="182,485,182,518,177,518,177,485"/>
<area shape="rect" href="classSteinberg_1_1IPluginFactory2.html" title="Version 2 of class factory supporting PClassInfo2: IPluginFactory2." alt="" coords="1652,528,1758,591"/>
<area shape="poly" title=" " alt="" coords="1708,388,1708,528,1702,528,1702,388"/>
<area shape="rect" href="classSteinberg_1_1IPluginFactory3.html" title="Version 3 of class factory supporting PClassInfoW: IPluginFactory3." alt="" coords="1633,649,1778,731"/>
<area shape="poly" title=" " alt="" coords="1708,606,1708,649,1702,649,1702,606"/>
</map>
</div>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:a4199134d0669bfa92b7419dac14c01a7" id="r_a4199134d0669bfa92b7419dac14c01a7"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="group__smtgtypedef.html#ga902761e005a6252e538c766de48fc957">tresult</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a4199134d0669bfa92b7419dac14c01a7">queryInterface</a> (const <a class="el" href="group__pluginBase.html#ga6935af93744bfe4ecc455f274ef1ec36">TUID</a> _iid, void **obj)=0</td></tr>
<tr class="memdesc:a4199134d0669bfa92b7419dac14c01a7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Query for a pointer to the specified interface. <br /></td></tr>
<tr class="separator:a4199134d0669bfa92b7419dac14c01a7"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aaa3c5a2a5410d41153d7f5e3f4e0a635" id="r_aaa3c5a2a5410d41153d7f5e3f4e0a635"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#aaa3c5a2a5410d41153d7f5e3f4e0a635">addRef</a> ()=0</td></tr>
<tr class="memdesc:aaa3c5a2a5410d41153d7f5e3f4e0a635"><td class="mdescLeft">&#160;</td><td class="mdescRight">Adds a reference and returns the new reference count. <br /></td></tr>
<tr class="separator:aaa3c5a2a5410d41153d7f5e3f4e0a635"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a58847c78bf6142f01ce214c2802cb146" id="r_a58847c78bf6142f01ce214c2802cb146"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a58847c78bf6142f01ce214c2802cb146">release</a> ()=0</td></tr>
<tr class="memdesc:a58847c78bf6142f01ce214c2802cb146"><td class="mdescLeft">&#160;</td><td class="mdescRight">Releases a reference and returns the new reference count. <br /></td></tr>
<tr class="separator:a58847c78bf6142f01ce214c2802cb146"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-static-attribs" name="pub-static-attribs"></a>
Static Public Attributes</h2></td></tr>
<tr class="memitem:a07978c93295b03d09c4bc97aa12e9c60" id="r_a07978c93295b03d09c4bc97aa12e9c60"><td class="memItemLeft" align="right" valign="top">static const <a class="el" href="classSteinberg_1_1FUID.html">FUID</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="#a07978c93295b03d09c4bc97aa12e9c60">iid</a></td></tr>
<tr class="separator:a07978c93295b03d09c4bc97aa12e9c60"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>The basic interface of all interfaces. </p>
<ul>
<li>The <a class="el" href="#a4199134d0669bfa92b7419dac14c01a7" title="Query for a pointer to the specified interface.">FUnknown::queryInterface</a> method is used to retrieve pointers to other interfaces of the object.</li>
<li><a class="el" href="#aaa3c5a2a5410d41153d7f5e3f4e0a635" title="Adds a reference and returns the new reference count.">FUnknown::addRef</a> and <a class="el" href="#a58847c78bf6142f01ce214c2802cb146" title="Releases a reference and returns the new reference count.">FUnknown::release</a> manage the lifetime of the object. If no more references exist, the object is destroyed in memory.</li>
</ul>
<p>Interfaces are identified by 16 byte Globally Unique Identifiers. The SDK provides a class called <a class="el" href="classSteinberg_1_1FUID.html" title="Handling 16 Byte Globally Unique Identifiers.">FUID</a> for this purpose.</p>
<p>howtoClass </p>
</div><h2 class="groupheader">Member Function Documentation</h2>
<a id="a4199134d0669bfa92b7419dac14c01a7" name="a4199134d0669bfa92b7419dac14c01a7"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a4199134d0669bfa92b7419dac14c01a7">&#9670;&#160;</a></span>queryInterface()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">virtual <a class="el" href="group__smtgtypedef.html#ga902761e005a6252e538c766de48fc957">tresult</a> queryInterface </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="group__pluginBase.html#ga6935af93744bfe4ecc455f274ef1ec36">TUID</a></td> <td class="paramname"><span class="paramname"><em>_iid</em></span>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">void **</td> <td class="paramname"><span class="paramname"><em>obj</em></span>&#160;)</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel pure-virtual">pure virtual</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Query for a pointer to the specified interface. </p>
<p>Returns kResultOk on success or kNoInterface if the object does not implement the interface. The object has to call addRef when returning an interface. </p><dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">_iid</td><td>: (in) 16 Byte interface identifier (-&gt; <a class="el" href="classSteinberg_1_1FUID.html" title="Handling 16 Byte Globally Unique Identifiers.">FUID</a>) </td></tr>
<tr><td class="paramname">obj</td><td>: (out) On return, *obj points to the requested interface </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a id="aaa3c5a2a5410d41153d7f5e3f4e0a635" name="aaa3c5a2a5410d41153d7f5e3f4e0a635"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aaa3c5a2a5410d41153d7f5e3f4e0a635">&#9670;&#160;</a></span>addRef()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">virtual <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> addRef </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel pure-virtual">pure virtual</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Adds a reference and returns the new reference count. </p>
<dl class="section user"><dt>Remarks:</dt><dd>The initial reference count after creating an object is 1. </dd></dl>
</div>
</div>
<a id="a58847c78bf6142f01ce214c2802cb146" name="a58847c78bf6142f01ce214c2802cb146"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a58847c78bf6142f01ce214c2802cb146">&#9670;&#160;</a></span>release()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">virtual <a class="el" href="group__smtgtypedef.html#gacbd4acd0d29e2d6c43104827f77d9cd2">uint32</a> release </td>
<td>(</td>
<td class="paramname"><span class="paramname"><em></em></span></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel pure-virtual">pure virtual</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Releases a reference and returns the new reference count. </p>
<p>If the reference count reaches zero, the object will be destroyed in memory. </p>
</div>
</div>
<h2 class="groupheader">Member Data Documentation</h2>
<a id="a07978c93295b03d09c4bc97aa12e9c60" name="a07978c93295b03d09c4bc97aa12e9c60"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a07978c93295b03d09c4bc97aa12e9c60">&#9670;&#160;</a></span>iid</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">const::Steinberg::FUID iid</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel static">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
</div><!-- contents -->
</div><!-- doc-content -->
<html>
<head>
<title>Empty</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Steinberg">
</head>
<body>
<br/>
<hr width="100%" size="2" align="left" />
<div align=right>
Copyright &copy;<span id="year"></span> <a href="http://www.steinberg.net" target="_blank"><u>Steinberg Media Technologies GmbH</u></a>.
All Rights Reserved. This documentation is under this <a href="http://www.steinberg.net/sdklicenses" target="_blank"><u>license</u></a>.
</div>
<script>
document.querySelector("#year").textContent = new Date().getFullYear();
</script>
</body>
</html>
@@ -0,0 +1,6 @@
var classSteinberg_1_1FUnknown =
[
[ "queryInterface", "classSteinberg_1_1FUnknown.html#a4199134d0669bfa92b7419dac14c01a7", null ],
[ "addRef", "classSteinberg_1_1FUnknown.html#aaa3c5a2a5410d41153d7f5e3f4e0a635", null ],
[ "release", "classSteinberg_1_1FUnknown.html#a58847c78bf6142f01ce214c2802cb146", null ]
];
@@ -0,0 +1,125 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Interface Technology Basics: ImplementsImpl&lt; Base, D, I &gt; Class Template Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="smtg_extra.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Interface Technology Basics<span id="projectnumber">&#160;VST 3.8</span>
</div>
<div id="projectbrief">SDK for developing VST plug-in</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search',true);
$(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){initNavTree('classSteinberg_1_1FUnknownImpl_1_1ImplementsImpl.html',''); initResizable(true); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="headertitle"><div class="title">ImplementsImpl&lt; Base, D, I &gt; Class Template Reference</div></div>
</div><!--header-->
<div class="contents">
<p><code>#include &lt;funknownimpl.h&gt;</code></p>
</div><!-- contents -->
</div><!-- doc-content -->
<html>
<head>
<title>Empty</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Steinberg">
</head>
<body>
<br/>
<hr width="100%" size="2" align="left" />
<div align=right>
Copyright &copy;<span id="year"></span> <a href="http://www.steinberg.net" target="_blank"><u>Steinberg Media Technologies GmbH</u></a>.
All Rights Reserved. This documentation is under this <a href="http://www.steinberg.net/sdklicenses" target="_blank"><u>license</u></a>.
</div>
<script>
document.querySelector("#year").textContent = new Date().getFullYear();
</script>
</body>
</html>
@@ -0,0 +1,125 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Interface Technology Basics: ImplementsImpl&lt; Base, Indirectly&lt; IndirectInterfaces... &gt;, Directly&lt; DirectInterfaces... &gt; &gt; Class Template Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="smtg_extra.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Interface Technology Basics<span id="projectnumber">&#160;VST 3.8</span>
</div>
<div id="projectbrief">SDK for developing VST plug-in</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search',true);
$(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){initNavTree('classSteinberg_1_1FUnknownImpl_1_1ImplementsImpl_3_01Base_00_01Indirectly_3_01IndirectInterfaces9a4a5325b3bc049eba78ef3421c75dc0.html',''); initResizable(true); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div class="header">
<div class="headertitle"><div class="title">ImplementsImpl&lt; Base, Indirectly&lt; IndirectInterfaces... &gt;, Directly&lt; DirectInterfaces... &gt; &gt; Class Template Reference</div></div>
</div><!--header-->
<div class="contents">
<p><code>#include &lt;funknownimpl.h&gt;</code></p>
</div><!-- contents -->
</div><!-- doc-content -->
<html>
<head>
<title>Empty</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Steinberg">
</head>
<body>
<br/>
<hr width="100%" size="2" align="left" />
<div align=right>
Copyright &copy;<span id="year"></span> <a href="http://www.steinberg.net" target="_blank"><u>Steinberg Media Technologies GmbH</u></a>.
All Rights Reserved. This documentation is under this <a href="http://www.steinberg.net/sdklicenses" target="_blank"><u>license</u></a>.
</div>
<script>
document.querySelector("#year").textContent = new Date().getFullYear();
</script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More