@@ -21,6 +21,12 @@ | |||||
#include <cmath> | #include <cmath> | ||||
#ifdef PROPER_CPP11_SUPPORT | |||||
# include <cstdint> | |||||
#else | |||||
# include <stdint.h> | |||||
#endif | |||||
#ifndef M_PI | #ifndef M_PI | ||||
# define M_PI 3.14159265358979323846 | # define M_PI 3.14159265358979323846 | ||||
#endif | #endif | ||||
@@ -19,7 +19,6 @@ | |||||
#include "src/DistrhoDefines.h" | #include "src/DistrhoDefines.h" | ||||
#include <cassert> | |||||
#include <cstdarg> | #include <cstdarg> | ||||
#include <cstdio> | #include <cstdio> | ||||
#include <cstdlib> | #include <cstdlib> | ||||
@@ -59,7 +58,7 @@ inline float | |||||
// misc functions | // misc functions | ||||
static inline | static inline | ||||
long d_cconst(int a, int b, int c, int d) noexcept | |||||
long d_cconst(const int a, const int b, const int c, const int d) noexcept | |||||
{ | { | ||||
return (a << 24) | (b << 16) | (c << 8) | (d << 0); | return (a << 24) | (b << 16) | (c << 8) | (d << 0); | ||||
} | } | ||||
@@ -71,622 +70,97 @@ long d_cconst(int a, int b, int c, int d) noexcept | |||||
# define d_debug(...) | # define d_debug(...) | ||||
#else | #else | ||||
static inline | static inline | ||||
void d_debug(const char* const fmt, ...) | |||||
void d_debug(const char* const fmt, ...) noexcept | |||||
{ | { | ||||
::va_list args; | |||||
::va_start(args, fmt); | |||||
std::fprintf(stdout, "\x1b[30;1m"); | |||||
std::vfprintf(stdout, fmt, args); | |||||
std::fprintf(stdout, "\x1b[0m\n"); | |||||
::va_end(args); | |||||
try { | |||||
::va_list args; | |||||
::va_start(args, fmt); | |||||
std::fprintf(stdout, "\x1b[30;1m"); | |||||
std::vfprintf(stdout, fmt, args); | |||||
std::fprintf(stdout, "\x1b[0m\n"); | |||||
::va_end(args); | |||||
} catch (...) {} | |||||
} | } | ||||
#endif | #endif | ||||
static inline | static inline | ||||
void d_stdout(const char* const fmt, ...) | |||||
void d_stdout(const char* const fmt, ...) noexcept | |||||
{ | { | ||||
::va_list args; | |||||
::va_start(args, fmt); | |||||
std::vfprintf(stdout, fmt, args); | |||||
std::fprintf(stdout, "\n"); | |||||
::va_end(args); | |||||
try { | |||||
::va_list args; | |||||
::va_start(args, fmt); | |||||
std::vfprintf(stdout, fmt, args); | |||||
std::fprintf(stdout, "\n"); | |||||
::va_end(args); | |||||
} catch (...) {} | |||||
} | } | ||||
static inline | static inline | ||||
void d_stderr(const char* const fmt, ...) | |||||
void d_stderr(const char* const fmt, ...) noexcept | |||||
{ | { | ||||
::va_list args; | |||||
::va_start(args, fmt); | |||||
std::vfprintf(stderr, fmt, args); | |||||
std::fprintf(stderr, "\n"); | |||||
::va_end(args); | |||||
try { | |||||
::va_list args; | |||||
::va_start(args, fmt); | |||||
std::vfprintf(stderr, fmt, args); | |||||
std::fprintf(stderr, "\n"); | |||||
::va_end(args); | |||||
} catch (...) {} | |||||
} | } | ||||
static inline | static inline | ||||
void d_stderr2(const char* const fmt, ...) | |||||
void d_stderr2(const char* const fmt, ...) noexcept | |||||
{ | { | ||||
::va_list args; | |||||
::va_start(args, fmt); | |||||
std::fprintf(stderr, "\x1b[31m"); | |||||
std::vfprintf(stderr, fmt, args); | |||||
std::fprintf(stderr, "\x1b[0m\n"); | |||||
::va_end(args); | |||||
try { | |||||
::va_list args; | |||||
::va_start(args, fmt); | |||||
std::fprintf(stderr, "\x1b[31m"); | |||||
std::vfprintf(stderr, fmt, args); | |||||
std::fprintf(stderr, "\x1b[0m\n"); | |||||
::va_end(args); | |||||
} catch (...) {} | |||||
} | } | ||||
static inline | static inline | ||||
void d_safe_assert(const char* const assertion, const char* const file, const int line) | |||||
void d_safe_assert(const char* const assertion, const char* const file, const int line) noexcept | |||||
{ | { | ||||
d_stderr2("assertion failure: \"%s\" in file %s, line %i", assertion, file, line); | d_stderr2("assertion failure: \"%s\" in file %s, line %i", assertion, file, line); | ||||
} | } | ||||
// ----------------------------------------------------------------------- | |||||
// d_*sleep | |||||
static inline | |||||
void d_sleep(unsigned int secs) | |||||
{ | |||||
#ifdef DISTRHO_OS_WINDOWS | |||||
::Sleep(secs * 1000); | |||||
#else | |||||
::sleep(secs); | |||||
#endif | |||||
} | |||||
static inline | static inline | ||||
void d_msleep(unsigned int msecs) | |||||
void d_safe_exception(const char* const exception, const char* const file, const int line) noexcept | |||||
{ | { | ||||
#ifdef DISTRHO_OS_WINDOWS | |||||
::Sleep(msecs); | |||||
#else | |||||
::usleep(msecs * 1000); | |||||
#endif | |||||
d_stderr2("exception caught: \"%s\" in file %s, line %i", exception, file, line); | |||||
} | } | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// d_string class | |||||
// d_*sleep | |||||
class d_string | |||||
static inline | |||||
void d_sleep(const uint secs) | |||||
{ | { | ||||
public: | |||||
// ------------------------------------------------------------------- | |||||
// constructors (no explicit conversions allowed) | |||||
/* | |||||
* Empty string. | |||||
*/ | |||||
explicit d_string() | |||||
{ | |||||
_init(); | |||||
_dup(nullptr); | |||||
} | |||||
/* | |||||
* Simple character. | |||||
*/ | |||||
explicit d_string(const char c) | |||||
{ | |||||
char ch[2]; | |||||
ch[0] = c; | |||||
ch[1] = '\0'; | |||||
_init(); | |||||
_dup(ch); | |||||
} | |||||
/* | |||||
* Simple char string. | |||||
*/ | |||||
explicit d_string(char* const strBuf) | |||||
{ | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Simple const char string. | |||||
*/ | |||||
explicit d_string(const char* const strBuf) | |||||
{ | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Integer. | |||||
*/ | |||||
explicit d_string(const int value) | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::memset(strBuf, 0, (0xff+1)*sizeof(char)); | |||||
std::snprintf(strBuf, 0xff, "%d", value); | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Unsigned integer, possibly in hexadecimal. | |||||
*/ | |||||
explicit d_string(const unsigned int value, const bool hexadecimal = false) | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::memset(strBuf, 0, (0xff+1)*sizeof(char)); | |||||
std::snprintf(strBuf, 0xff, hexadecimal ? "0x%x" : "%u", value); | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Long integer. | |||||
*/ | |||||
explicit d_string(const long int value) | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::memset(strBuf, 0, (0xff+1)*sizeof(char)); | |||||
std::snprintf(strBuf, 0xff, "%ld", value); | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Long unsigned integer, possibly hexadecimal. | |||||
*/ | |||||
explicit d_string(const unsigned long int value, const bool hexadecimal = false) | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::memset(strBuf, 0, (0xff+1)*sizeof(char)); | |||||
std::snprintf(strBuf, 0xff, hexadecimal ? "0x%lx" : "%lu", value); | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
DISTRHO_SAFE_ASSERT_RETURN(secs > 0,); | |||||
/* | |||||
* Single-precision floating point number. | |||||
*/ | |||||
explicit d_string(const float value) | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::memset(strBuf, 0, (0xff+1)*sizeof(char)); | |||||
std::snprintf(strBuf, 0xff, "%f", value); | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Double-precision floating point number. | |||||
*/ | |||||
explicit d_string(const double value) | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::memset(strBuf, 0, (0xff+1)*sizeof(char)); | |||||
std::snprintf(strBuf, 0xff, "%g", value); | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// non-explicit constructor | |||||
/* | |||||
* Create string from another string. | |||||
*/ | |||||
d_string(const d_string& str) | |||||
{ | |||||
_init(); | |||||
_dup(str.fBuffer); | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// destructor | |||||
/* | |||||
* Destructor. | |||||
*/ | |||||
~d_string() | |||||
{ | |||||
assert(fBuffer != nullptr); | |||||
delete[] fBuffer; | |||||
fBuffer = nullptr; | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// public methods | |||||
/* | |||||
* Get length of the string. | |||||
*/ | |||||
size_t length() const noexcept | |||||
{ | |||||
return fBufferLen; | |||||
} | |||||
/* | |||||
* Check if the string is empty. | |||||
*/ | |||||
bool isEmpty() const noexcept | |||||
{ | |||||
return (fBufferLen == 0); | |||||
} | |||||
/* | |||||
* Check if the string is not empty. | |||||
*/ | |||||
bool isNotEmpty() const noexcept | |||||
{ | |||||
return (fBufferLen != 0); | |||||
} | |||||
/* | |||||
* Check if the string contains another string, optionally ignoring case. | |||||
*/ | |||||
bool contains(const char* const strBuf, const bool ignoreCase = false) const | |||||
{ | |||||
if (strBuf == nullptr) | |||||
return false; | |||||
if (ignoreCase) | |||||
{ | |||||
#ifdef __USE_GNU | |||||
return (strcasestr(fBuffer, strBuf) != nullptr); | |||||
try { | |||||
#ifdef DISTRHO_OS_WIN | |||||
::Sleep(secs * 1000); | |||||
#else | #else | ||||
d_string tmp1(fBuffer), tmp2(strBuf); | |||||
tmp1.toLower(); | |||||
tmp2.toLower(); | |||||
return (std::strstr((const char*)tmp1, (const char*)tmp2) != nullptr); | |||||
::sleep(secs); | |||||
#endif | #endif | ||||
} | |||||
return (std::strstr(fBuffer, strBuf) != nullptr); | |||||
} | |||||
/* | |||||
* Overloaded function. | |||||
*/ | |||||
bool contains(const d_string& str, const bool ignoreCase = false) const | |||||
{ | |||||
return contains(str.fBuffer, ignoreCase); | |||||
} | |||||
/* | |||||
* Check if character at 'pos' is a digit. | |||||
*/ | |||||
bool isDigit(const size_t pos) const noexcept | |||||
{ | |||||
if (pos >= fBufferLen) | |||||
return false; | |||||
return (fBuffer[pos] >= '0' && fBuffer[pos] <= '9'); | |||||
} | |||||
/* | |||||
* Check if the string starts with the character 'c'. | |||||
*/ | |||||
bool startsWith(const char c) const | |||||
{ | |||||
if (c == '\0') | |||||
return false; | |||||
return (fBufferLen > 0 && fBuffer[0] == c); | |||||
} | |||||
/* | |||||
* Check if the string starts with the string 'prefix'. | |||||
*/ | |||||
bool startsWith(const char* const prefix) const | |||||
{ | |||||
if (prefix == nullptr) | |||||
return false; | |||||
const size_t prefixLen(std::strlen(prefix)); | |||||
if (fBufferLen < prefixLen) | |||||
return false; | |||||
return (std::strncmp(fBuffer + (fBufferLen-prefixLen), prefix, prefixLen) == 0); | |||||
} | |||||
/* | |||||
* Check if the string ends with the character 'c'. | |||||
*/ | |||||
bool endsWith(const char c) const | |||||
{ | |||||
if (c == '\0') | |||||
return false; | |||||
return (fBufferLen > 0 && fBuffer[fBufferLen] == c); | |||||
} | |||||
/* | |||||
* Check if the string ends with the string 'suffix'. | |||||
*/ | |||||
bool endsWith(const char* const suffix) const | |||||
{ | |||||
if (suffix == nullptr) | |||||
return false; | |||||
const size_t suffixLen(std::strlen(suffix)); | |||||
if (fBufferLen < suffixLen) | |||||
return false; | |||||
return (std::strncmp(fBuffer + (fBufferLen-suffixLen), suffix, suffixLen) == 0); | |||||
} | |||||
/* | |||||
* Clear the string. | |||||
*/ | |||||
void clear() noexcept | |||||
{ | |||||
truncate(0); | |||||
} | |||||
/* | |||||
* Replace all occurrences of character 'before' with character 'after'. | |||||
*/ | |||||
void replace(const char before, const char after) noexcept | |||||
{ | |||||
if (before == '\0' || after == '\0') | |||||
return; | |||||
for (size_t i=0; i < fBufferLen; ++i) | |||||
{ | |||||
if (fBuffer[i] == before) | |||||
fBuffer[i] = after; | |||||
else if (fBuffer[i] == '\0') | |||||
break; | |||||
} | |||||
} | |||||
/* | |||||
* Truncate the string to size 'n'. | |||||
*/ | |||||
void truncate(const size_t n) noexcept | |||||
{ | |||||
if (n >= fBufferLen) | |||||
return; | |||||
for (size_t i=n; i < fBufferLen; ++i) | |||||
fBuffer[i] = '\0'; | |||||
fBufferLen = n; | |||||
} | |||||
/* | |||||
* Convert all non-basic characters to '_'. | |||||
*/ | |||||
void toBasic() noexcept | |||||
{ | |||||
for (size_t i=0; i < fBufferLen; ++i) | |||||
{ | |||||
if (fBuffer[i] >= '0' && fBuffer[i] <= '9') | |||||
continue; | |||||
if (fBuffer[i] >= 'A' && fBuffer[i] <= 'Z') | |||||
continue; | |||||
if (fBuffer[i] >= 'a' && fBuffer[i] <= 'z') | |||||
continue; | |||||
if (fBuffer[i] == '_') | |||||
continue; | |||||
fBuffer[i] = '_'; | |||||
} | |||||
} | |||||
/* | |||||
* Convert to all ascii characters to lowercase. | |||||
*/ | |||||
void toLower() noexcept | |||||
{ | |||||
static const char kCharDiff('a' - 'A'); | |||||
for (size_t i=0; i < fBufferLen; ++i) | |||||
{ | |||||
if (fBuffer[i] >= 'A' && fBuffer[i] <= 'Z') | |||||
fBuffer[i] += kCharDiff; | |||||
} | |||||
} | |||||
/* | |||||
* Convert to all ascii characters to uppercase. | |||||
*/ | |||||
void toUpper() noexcept | |||||
{ | |||||
static const char kCharDiff('a' - 'A'); | |||||
for (size_t i=0; i < fBufferLen; ++i) | |||||
{ | |||||
if (fBuffer[i] >= 'a' && fBuffer[i] <= 'z') | |||||
fBuffer[i] -= kCharDiff; | |||||
} | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// public operators | |||||
operator const char*() const noexcept | |||||
{ | |||||
return fBuffer; | |||||
} | |||||
char& operator[](const size_t pos) const noexcept | |||||
{ | |||||
return fBuffer[pos]; | |||||
} | |||||
bool operator==(const char* const strBuf) const | |||||
{ | |||||
return (strBuf != nullptr && std::strcmp(fBuffer, strBuf) == 0); | |||||
} | |||||
bool operator==(const d_string& str) const | |||||
{ | |||||
return operator==(str.fBuffer); | |||||
} | |||||
bool operator!=(const char* const strBuf) const | |||||
{ | |||||
return !operator==(strBuf); | |||||
} | |||||
bool operator!=(const d_string& str) const | |||||
{ | |||||
return !operator==(str.fBuffer); | |||||
} | |||||
d_string& operator=(const char* const strBuf) | |||||
{ | |||||
_dup(strBuf); | |||||
return *this; | |||||
} | |||||
d_string& operator=(const d_string& str) | |||||
{ | |||||
return operator=(str.fBuffer); | |||||
} | |||||
d_string& operator+=(const char* const strBuf) | |||||
{ | |||||
if (strBuf == nullptr) | |||||
return *this; | |||||
const size_t newBufSize = fBufferLen + std::strlen(strBuf) + 1; | |||||
char newBuf[newBufSize]; | |||||
std::strcpy(newBuf, fBuffer); | |||||
std::strcat(newBuf, strBuf); | |||||
_dup(newBuf, newBufSize-1); | |||||
return *this; | |||||
} | |||||
d_string& operator+=(const d_string& str) | |||||
{ | |||||
return operator+=(str.fBuffer); | |||||
} | |||||
d_string operator+(const char* const strBuf) | |||||
{ | |||||
const size_t newBufSize = fBufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1; | |||||
char newBuf[newBufSize]; | |||||
std::strcpy(newBuf, fBuffer); | |||||
if (strBuf != nullptr) | |||||
std::strcat(newBuf, strBuf); | |||||
return d_string(newBuf); | |||||
} | |||||
d_string operator+(const d_string& str) | |||||
{ | |||||
return operator+(str.fBuffer); | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
private: | |||||
char* fBuffer; // the actual string buffer | |||||
size_t fBufferLen; // string length | |||||
bool fFirstInit; // true when first initiated | |||||
/* | |||||
* Shared init function. | |||||
* Called on all constructors. | |||||
*/ | |||||
void _init() noexcept | |||||
{ | |||||
fBuffer = nullptr; | |||||
fBufferLen = 0; | |||||
fFirstInit = true; | |||||
} | |||||
/* | |||||
* Helper function. | |||||
* Called whenever the string needs to be allocated. | |||||
* | |||||
* Notes: | |||||
* - Allocates string only if first initiated, or if 'strBuf' is not null and new string contents are different | |||||
* - If 'strBuf' is null 'size' must be 0 | |||||
*/ | |||||
void _dup(const char* const strBuf, const size_t size = 0) | |||||
{ | |||||
if (strBuf != nullptr) | |||||
{ | |||||
// don't recreate string if contents match | |||||
if (fFirstInit || std::strcmp(fBuffer, strBuf) != 0) | |||||
{ | |||||
if (! fFirstInit) | |||||
{ | |||||
assert(fBuffer != nullptr); | |||||
delete[] fBuffer; | |||||
} | |||||
fBufferLen = (size > 0) ? size : std::strlen(strBuf); | |||||
fBuffer = new char[fBufferLen+1]; | |||||
std::strcpy(fBuffer, strBuf); | |||||
fBuffer[fBufferLen] = '\0'; | |||||
fFirstInit = false; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
assert(size == 0); | |||||
// don't recreate null string | |||||
if (fFirstInit || fBufferLen != 0) | |||||
{ | |||||
if (! fFirstInit) | |||||
{ | |||||
assert(fBuffer != nullptr); | |||||
delete[] fBuffer; | |||||
} | |||||
fBufferLen = 0; | |||||
fBuffer = new char[1]; | |||||
fBuffer[0] = '\0'; | |||||
fFirstInit = false; | |||||
} | |||||
} | |||||
} | |||||
}; | |||||
// ----------------------------------------------------------------------- | |||||
static inline | |||||
d_string operator+(const d_string& strBefore, const char* const strBufAfter) | |||||
{ | |||||
const char* const strBufBefore = (const char*)strBefore; | |||||
const size_t newBufSize = strBefore.length() + ((strBufAfter != nullptr) ? std::strlen(strBufAfter) : 0) + 1; | |||||
char newBuf[newBufSize]; | |||||
std::strcpy(newBuf, strBufBefore); | |||||
std::strcat(newBuf, strBufAfter); | |||||
return d_string(newBuf); | |||||
} DISTRHO_SAFE_EXCEPTION("carla_sleep"); | |||||
} | } | ||||
static inline | static inline | ||||
d_string operator+(const char* const strBufBefore, const d_string& strAfter) | |||||
void d_msleep(const uint msecs) | |||||
{ | { | ||||
const char* const strBufAfter = (const char*)strAfter; | |||||
const size_t newBufSize = ((strBufBefore != nullptr) ? std::strlen(strBufBefore) : 0) + strAfter.length() + 1; | |||||
char newBuf[newBufSize]; | |||||
DISTRHO_SAFE_ASSERT_RETURN(msecs > 0,); | |||||
std::strcpy(newBuf, strBufBefore); | |||||
std::strcat(newBuf, strBufAfter); | |||||
return d_string(newBuf); | |||||
try { | |||||
#ifdef DISTRHO_OS_WIN | |||||
::Sleep(msecs); | |||||
#else | |||||
::usleep(msecs * 1000); | |||||
#endif | |||||
} DISTRHO_SAFE_EXCEPTION("carla_msleep"); | |||||
} | } | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -0,0 +1,746 @@ | |||||
/* | |||||
* DISTRHO Plugin Framework (DPF) | |||||
* Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> | |||||
* | |||||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||||
* or without fee is hereby granted, provided that the above copyright notice and this | |||||
* permission notice appear in all copies. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
*/ | |||||
#ifndef DISTRHO_STRING_HPP_INCLUDED | |||||
#define DISTRHO_STRING_HPP_INCLUDED | |||||
#include "../DistrhoUtils.hpp" | |||||
// ----------------------------------------------------------------------- | |||||
// d_string class | |||||
class d_string | |||||
{ | |||||
public: | |||||
// ------------------------------------------------------------------- | |||||
// constructors (no explicit conversions allowed) | |||||
/* | |||||
* Empty string. | |||||
*/ | |||||
explicit d_string() noexcept | |||||
{ | |||||
_init(); | |||||
} | |||||
/* | |||||
* Simple character. | |||||
*/ | |||||
explicit d_string(const char c) noexcept | |||||
{ | |||||
char ch[2]; | |||||
ch[0] = c; | |||||
ch[1] = '\0'; | |||||
_init(); | |||||
_dup(ch); | |||||
} | |||||
/* | |||||
* Simple char string. | |||||
*/ | |||||
explicit d_string(char* const strBuf) noexcept | |||||
{ | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Simple const char string. | |||||
*/ | |||||
explicit d_string(const char* const strBuf) noexcept | |||||
{ | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Integer. | |||||
*/ | |||||
explicit d_string(const int value) noexcept | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::snprintf(strBuf, 0xff, "%d", value); | |||||
strBuf[0xff] = '\0'; | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Unsigned integer, possibly in hexadecimal. | |||||
*/ | |||||
explicit d_string(const unsigned int value, const bool hexadecimal = false) noexcept | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::snprintf(strBuf, 0xff, hexadecimal ? "0x%x" : "%u", value); | |||||
strBuf[0xff] = '\0'; | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Long integer. | |||||
*/ | |||||
explicit d_string(const long value) noexcept | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::snprintf(strBuf, 0xff, "%ld", value); | |||||
strBuf[0xff] = '\0'; | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Long unsigned integer, possibly hexadecimal. | |||||
*/ | |||||
explicit d_string(const unsigned long value, const bool hexadecimal = false) noexcept | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::snprintf(strBuf, 0xff, hexadecimal ? "0x%lx" : "%lu", value); | |||||
strBuf[0xff] = '\0'; | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Long long integer. | |||||
*/ | |||||
explicit d_string(const long long value) noexcept | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::snprintf(strBuf, 0xff, "%lld", value); | |||||
strBuf[0xff] = '\0'; | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Long long unsigned integer, possibly hexadecimal. | |||||
*/ | |||||
explicit d_string(const unsigned long long value, const bool hexadecimal = false) noexcept | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::snprintf(strBuf, 0xff, hexadecimal ? "0x%llx" : "%llu", value); | |||||
strBuf[0xff] = '\0'; | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Single-precision floating point number. | |||||
*/ | |||||
explicit d_string(const float value) noexcept | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::snprintf(strBuf, 0xff, "%f", value); | |||||
strBuf[0xff] = '\0'; | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
/* | |||||
* Double-precision floating point number. | |||||
*/ | |||||
explicit d_string(const double value) noexcept | |||||
{ | |||||
char strBuf[0xff+1]; | |||||
std::snprintf(strBuf, 0xff, "%g", value); | |||||
strBuf[0xff] = '\0'; | |||||
_init(); | |||||
_dup(strBuf); | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// non-explicit constructor | |||||
/* | |||||
* Create string from another string. | |||||
*/ | |||||
d_string(const d_string& str) noexcept | |||||
{ | |||||
_init(); | |||||
_dup(str.fBuffer); | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// destructor | |||||
/* | |||||
* Destructor. | |||||
*/ | |||||
~d_string() noexcept | |||||
{ | |||||
DISTRHO_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | |||||
if (fBuffer == _null()) | |||||
return; | |||||
std::free(fBuffer); | |||||
fBuffer = nullptr; | |||||
fBufferLen = 0; | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// public methods | |||||
/* | |||||
* Get length of the string. | |||||
*/ | |||||
size_t length() const noexcept | |||||
{ | |||||
return fBufferLen; | |||||
} | |||||
/* | |||||
* Check if the string is empty. | |||||
*/ | |||||
bool isEmpty() const noexcept | |||||
{ | |||||
return (fBufferLen == 0); | |||||
} | |||||
/* | |||||
* Check if the string is not empty. | |||||
*/ | |||||
bool isNotEmpty() const noexcept | |||||
{ | |||||
return (fBufferLen != 0); | |||||
} | |||||
/* | |||||
* Check if the string contains another string, optionally ignoring case. | |||||
*/ | |||||
bool contains(const char* const strBuf, const bool ignoreCase = false) const noexcept | |||||
{ | |||||
DISTRHO_SAFE_ASSERT_RETURN(strBuf != nullptr, false); | |||||
if (ignoreCase) | |||||
{ | |||||
#ifdef __USE_GNU | |||||
return (strcasestr(fBuffer, strBuf) != nullptr); | |||||
#else | |||||
d_string tmp1(fBuffer), tmp2(strBuf); | |||||
// memory allocation failed or empty string(s) | |||||
if (tmp1.fBuffer == _null() || tmp2.fBuffer == _null()) | |||||
return false; | |||||
tmp1.toLower(); | |||||
tmp2.toLower(); | |||||
return (std::strstr(tmp1, tmp2) != nullptr); | |||||
#endif | |||||
} | |||||
return (std::strstr(fBuffer, strBuf) != nullptr); | |||||
} | |||||
/* | |||||
* Check if character at 'pos' is a digit. | |||||
*/ | |||||
bool isDigit(const size_t pos) const noexcept | |||||
{ | |||||
DISTRHO_SAFE_ASSERT_RETURN(pos < fBufferLen, false); | |||||
return (fBuffer[pos] >= '0' && fBuffer[pos] <= '9'); | |||||
} | |||||
/* | |||||
* Check if the string starts with the character 'c'. | |||||
*/ | |||||
bool startsWith(const char c) const noexcept | |||||
{ | |||||
DISTRHO_SAFE_ASSERT_RETURN(c != '\0', false); | |||||
return (fBufferLen > 0 && fBuffer[0] == c); | |||||
} | |||||
/* | |||||
* Check if the string starts with the string 'prefix'. | |||||
*/ | |||||
bool startsWith(const char* const prefix) const noexcept | |||||
{ | |||||
DISTRHO_SAFE_ASSERT_RETURN(prefix != nullptr, false); | |||||
const size_t prefixLen(std::strlen(prefix)); | |||||
if (fBufferLen < prefixLen) | |||||
return false; | |||||
return (std::strncmp(fBuffer, prefix, prefixLen) == 0); | |||||
} | |||||
/* | |||||
* Check if the string ends with the character 'c'. | |||||
*/ | |||||
bool endsWith(const char c) const noexcept | |||||
{ | |||||
DISTRHO_SAFE_ASSERT_RETURN(c != '\0', false); | |||||
return (fBufferLen > 0 && fBuffer[fBufferLen-1] == c); | |||||
} | |||||
/* | |||||
* Check if the string ends with the string 'suffix'. | |||||
*/ | |||||
bool endsWith(const char* const suffix) const noexcept | |||||
{ | |||||
DISTRHO_SAFE_ASSERT_RETURN(suffix != nullptr, false); | |||||
const size_t suffixLen(std::strlen(suffix)); | |||||
if (fBufferLen < suffixLen) | |||||
return false; | |||||
return (std::strncmp(fBuffer + (fBufferLen-suffixLen), suffix, suffixLen) == 0); | |||||
} | |||||
/* | |||||
* Find the first occurrence of character 'c' in the string. | |||||
* Returns "length()" if the character is not found. | |||||
*/ | |||||
size_t find(const char c, bool* const found = nullptr) const noexcept | |||||
{ | |||||
if (fBufferLen == 0 || c == '\0') | |||||
{ | |||||
if (found != nullptr) | |||||
*found = false; | |||||
return fBufferLen; | |||||
} | |||||
for (size_t i=0; i < fBufferLen; ++i) | |||||
{ | |||||
if (fBuffer[i] == c) | |||||
{ | |||||
if (found != nullptr) | |||||
*found = true; | |||||
return i; | |||||
} | |||||
} | |||||
if (found != nullptr) | |||||
*found = false; | |||||
return fBufferLen; | |||||
} | |||||
/* | |||||
* Find the first occurrence of string 'strBuf' in the string. | |||||
* Returns "length()" if the string is not found. | |||||
*/ | |||||
size_t find(const char* const strBuf, bool* const found = nullptr) const noexcept | |||||
{ | |||||
if (fBufferLen == 0 || strBuf == nullptr || strBuf[0] == '\0') | |||||
{ | |||||
if (found != nullptr) | |||||
*found = false; | |||||
return fBufferLen; | |||||
} | |||||
if (char* const subStrBuf = std::strstr(fBuffer, strBuf)) | |||||
{ | |||||
const ssize_t ret(subStrBuf - fBuffer); | |||||
if (ret < 0) | |||||
{ | |||||
// should never happen! | |||||
d_safe_assert("ret >= 0", __FILE__, __LINE__); | |||||
if (found != nullptr) | |||||
*found = false; | |||||
return fBufferLen; | |||||
} | |||||
if (found != nullptr) | |||||
*found = true; | |||||
return static_cast<size_t>(ret); | |||||
} | |||||
if (found != nullptr) | |||||
*found = false; | |||||
return fBufferLen; | |||||
} | |||||
/* | |||||
* Find the last occurrence of character 'c' in the string. | |||||
* Returns "length()" if the character is not found. | |||||
*/ | |||||
size_t rfind(const char c, bool* const found = nullptr) const noexcept | |||||
{ | |||||
if (fBufferLen == 0 || c == '\0') | |||||
{ | |||||
if (found != nullptr) | |||||
*found = false; | |||||
return fBufferLen; | |||||
} | |||||
for (size_t i=fBufferLen; i > 0; --i) | |||||
{ | |||||
if (fBuffer[i-1] == c) | |||||
{ | |||||
if (found != nullptr) | |||||
*found = true; | |||||
return i-1; | |||||
} | |||||
} | |||||
if (found != nullptr) | |||||
*found = false; | |||||
return fBufferLen; | |||||
} | |||||
/* | |||||
* Find the last occurrence of string 'strBuf' in the string. | |||||
* Returns "length()" if the string is not found. | |||||
*/ | |||||
size_t rfind(const char* const strBuf, bool* const found = nullptr) const noexcept | |||||
{ | |||||
if (found != nullptr) | |||||
*found = false; | |||||
if (fBufferLen == 0 || strBuf == nullptr || strBuf[0] == '\0') | |||||
return fBufferLen; | |||||
const size_t strBufLen(std::strlen(strBuf)); | |||||
size_t ret = fBufferLen; | |||||
const char* tmpBuf = fBuffer; | |||||
for (size_t i=0; i < fBufferLen; ++i) | |||||
{ | |||||
if (std::strstr(tmpBuf+1, strBuf) == nullptr && std::strncmp(tmpBuf, strBuf, strBufLen) == 0) | |||||
{ | |||||
if (found != nullptr) | |||||
*found = true; | |||||
break; | |||||
} | |||||
--ret; | |||||
++tmpBuf; | |||||
} | |||||
return fBufferLen-ret; | |||||
} | |||||
/* | |||||
* Clear the string. | |||||
*/ | |||||
void clear() noexcept | |||||
{ | |||||
truncate(0); | |||||
} | |||||
/* | |||||
* Replace all occurrences of character 'before' with character 'after'. | |||||
*/ | |||||
void replace(const char before, const char after) noexcept | |||||
{ | |||||
DISTRHO_SAFE_ASSERT_RETURN(before != '\0' && after != '\0',); | |||||
for (size_t i=0; i < fBufferLen; ++i) | |||||
{ | |||||
if (fBuffer[i] == before) | |||||
fBuffer[i] = after; | |||||
} | |||||
} | |||||
/* | |||||
* Truncate the string to size 'n'. | |||||
*/ | |||||
void truncate(const size_t n) noexcept | |||||
{ | |||||
if (n >= fBufferLen) | |||||
return; | |||||
for (size_t i=n; i < fBufferLen; ++i) | |||||
fBuffer[i] = '\0'; | |||||
fBufferLen = n; | |||||
} | |||||
/* | |||||
* Convert all non-basic characters to '_'. | |||||
*/ | |||||
void toBasic() noexcept | |||||
{ | |||||
for (size_t i=0; i < fBufferLen; ++i) | |||||
{ | |||||
if (fBuffer[i] >= '0' && fBuffer[i] <= '9') | |||||
continue; | |||||
if (fBuffer[i] >= 'A' && fBuffer[i] <= 'Z') | |||||
continue; | |||||
if (fBuffer[i] >= 'a' && fBuffer[i] <= 'z') | |||||
continue; | |||||
if (fBuffer[i] == '_') | |||||
continue; | |||||
fBuffer[i] = '_'; | |||||
} | |||||
} | |||||
/* | |||||
* Convert to all ascii characters to lowercase. | |||||
*/ | |||||
void toLower() noexcept | |||||
{ | |||||
static const char kCharDiff('a' - 'A'); | |||||
for (size_t i=0; i < fBufferLen; ++i) | |||||
{ | |||||
if (fBuffer[i] >= 'A' && fBuffer[i] <= 'Z') | |||||
fBuffer[i] = static_cast<char>(fBuffer[i] + kCharDiff); | |||||
} | |||||
} | |||||
/* | |||||
* Convert to all ascii characters to uppercase. | |||||
*/ | |||||
void toUpper() noexcept | |||||
{ | |||||
static const char kCharDiff('a' - 'A'); | |||||
for (size_t i=0; i < fBufferLen; ++i) | |||||
{ | |||||
if (fBuffer[i] >= 'a' && fBuffer[i] <= 'z') | |||||
fBuffer[i] = static_cast<char>(fBuffer[i] - kCharDiff); | |||||
} | |||||
} | |||||
/* | |||||
* Direct access to the string buffer (read-only). | |||||
*/ | |||||
const char* buffer() const noexcept | |||||
{ | |||||
return fBuffer; | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// public operators | |||||
operator const char*() const noexcept | |||||
{ | |||||
return fBuffer; | |||||
} | |||||
char operator[](const size_t pos) const noexcept | |||||
{ | |||||
if (pos < fBufferLen) | |||||
return fBuffer[pos]; | |||||
d_safe_assert("pos < fBufferLen", __FILE__, __LINE__); | |||||
static char fallback; | |||||
fallback = '\0'; | |||||
return fallback; | |||||
} | |||||
char& operator[](const size_t pos) noexcept | |||||
{ | |||||
if (pos < fBufferLen) | |||||
return fBuffer[pos]; | |||||
d_safe_assert("pos < fBufferLen", __FILE__, __LINE__); | |||||
static char fallback; | |||||
fallback = '\0'; | |||||
return fallback; | |||||
} | |||||
bool operator==(const char* const strBuf) const noexcept | |||||
{ | |||||
return (strBuf != nullptr && std::strcmp(fBuffer, strBuf) == 0); | |||||
} | |||||
bool operator==(const d_string& str) const noexcept | |||||
{ | |||||
return operator==(str.fBuffer); | |||||
} | |||||
bool operator!=(const char* const strBuf) const noexcept | |||||
{ | |||||
return !operator==(strBuf); | |||||
} | |||||
bool operator!=(const d_string& str) const noexcept | |||||
{ | |||||
return !operator==(str.fBuffer); | |||||
} | |||||
d_string& operator=(const char* const strBuf) noexcept | |||||
{ | |||||
_dup(strBuf); | |||||
return *this; | |||||
} | |||||
d_string& operator=(const d_string& str) noexcept | |||||
{ | |||||
_dup(str.fBuffer); | |||||
return *this; | |||||
} | |||||
d_string& operator+=(const char* const strBuf) noexcept | |||||
{ | |||||
if (strBuf == nullptr) | |||||
return *this; | |||||
const size_t newBufSize = fBufferLen + std::strlen(strBuf) + 1; | |||||
char newBuf[newBufSize]; | |||||
std::strcpy(newBuf, fBuffer); | |||||
std::strcat(newBuf, strBuf); | |||||
_dup(newBuf, newBufSize-1); | |||||
return *this; | |||||
} | |||||
d_string& operator+=(const d_string& str) noexcept | |||||
{ | |||||
return operator+=(str.fBuffer); | |||||
} | |||||
d_string operator+(const char* const strBuf) noexcept | |||||
{ | |||||
const size_t newBufSize = fBufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1; | |||||
char newBuf[newBufSize]; | |||||
std::strcpy(newBuf, fBuffer); | |||||
if (strBuf != nullptr) | |||||
std::strcat(newBuf, strBuf); | |||||
return d_string(newBuf); | |||||
} | |||||
d_string operator+(const d_string& str) noexcept | |||||
{ | |||||
return operator+(str.fBuffer); | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
private: | |||||
char* fBuffer; // the actual string buffer | |||||
size_t fBufferLen; // string length | |||||
/* | |||||
* Static null string. | |||||
* Prevents allocation for new and/or empty strings. | |||||
*/ | |||||
static char* _null() noexcept | |||||
{ | |||||
static char sNull = '\0'; | |||||
return &sNull; | |||||
} | |||||
/* | |||||
* Shared init function. | |||||
* Called on all constructors. | |||||
*/ | |||||
void _init() noexcept | |||||
{ | |||||
fBuffer = _null(); | |||||
fBufferLen = 0; | |||||
} | |||||
/* | |||||
* Helper function. | |||||
* Called whenever the string needs to be allocated. | |||||
* | |||||
* Notes: | |||||
* - Allocates string only if 'strBuf' is not null and new string contents are different | |||||
* - If 'strBuf' is null, 'size' must be 0 | |||||
*/ | |||||
void _dup(const char* const strBuf, const size_t size = 0) noexcept | |||||
{ | |||||
if (strBuf != nullptr) | |||||
{ | |||||
// don't recreate string if contents match | |||||
if (std::strcmp(fBuffer, strBuf) == 0) | |||||
return; | |||||
if (fBuffer != _null()) | |||||
std::free(fBuffer); | |||||
fBufferLen = (size > 0) ? size : std::strlen(strBuf); | |||||
fBuffer = (char*)std::malloc(fBufferLen+1); | |||||
if (fBuffer == nullptr) | |||||
return _init(); | |||||
std::strcpy(fBuffer, strBuf); | |||||
fBuffer[fBufferLen] = '\0'; | |||||
} | |||||
else | |||||
{ | |||||
DISTRHO_SAFE_ASSERT(size == 0); | |||||
// don't recreate null string | |||||
if (fBuffer == _null()) | |||||
return; | |||||
DISTRHO_SAFE_ASSERT(fBuffer != nullptr); | |||||
std::free(fBuffer); | |||||
_init(); | |||||
} | |||||
} | |||||
//DISTRHO_LEAK_DETECTOR(d_string) | |||||
DISTRHO_PREVENT_HEAP_ALLOCATION | |||||
}; | |||||
// ----------------------------------------------------------------------- | |||||
static inline | |||||
d_string operator+(const d_string& strBefore, const char* const strBufAfter) noexcept | |||||
{ | |||||
const char* const strBufBefore = strBefore.buffer(); | |||||
const size_t newBufSize = strBefore.length() + ((strBufAfter != nullptr) ? std::strlen(strBufAfter) : 0) + 1; | |||||
char newBuf[newBufSize]; | |||||
std::strcpy(newBuf, strBufBefore); | |||||
std::strcat(newBuf, strBufAfter); | |||||
return d_string(newBuf); | |||||
} | |||||
static inline | |||||
d_string operator+(const char* const strBufBefore, const d_string& strAfter) noexcept | |||||
{ | |||||
const char* const strBufAfter = strAfter.buffer(); | |||||
const size_t newBufSize = ((strBufBefore != nullptr) ? std::strlen(strBufBefore) : 0) + strAfter.length() + 1; | |||||
char newBuf[newBufSize]; | |||||
std::strcpy(newBuf, strBufBefore); | |||||
std::strcat(newBuf, strBufAfter); | |||||
return d_string(newBuf); | |||||
} | |||||
// ----------------------------------------------------------------------- | |||||
#endif // DISTRHO_STRING_HPP_INCLUDED |
@@ -108,6 +108,59 @@ | |||||
# define nullptr (0) | # define nullptr (0) | ||||
#endif | #endif | ||||
/* Define DISTRHO_SAFE_ASSERT* */ | |||||
#define DISTRHO_SAFE_ASSERT(cond) if (cond) pass(); else d_safe_assert(#cond, __FILE__, __LINE__); | |||||
#define DISTRHO_SAFE_ASSERT_BREAK(cond) if (cond) pass(); else { d_safe_assert(#cond, __FILE__, __LINE__); break; } | |||||
#define DISTRHO_SAFE_ASSERT_CONTINUE(cond) if (cond) pass(); else { d_safe_assert(#cond, __FILE__, __LINE__); continue; } | |||||
#define DISTRHO_SAFE_ASSERT_RETURN(cond, ret) if (cond) pass(); else { d_safe_assert(#cond, __FILE__, __LINE__); return ret; } | |||||
/* Define DISTRHO_SAFE_EXCEPTION */ | |||||
#define DISTRHO_SAFE_EXCEPTION(msg) catch(...) { d_safe_exception(msg, __FILE__, __LINE__); } | |||||
#define DISTRHO_SAFE_EXCEPTION_BREAK(msg) catch(...) { d_safe_exception(msg, __FILE__, __LINE__); break; } | |||||
#define DISTRHO_SAFE_EXCEPTION_CONTINUE(msg) catch(...) { d_safe_exception(msg, __FILE__, __LINE__); continue; } | |||||
#define DISTRHO_SAFE_EXCEPTION_RETURN(msg, ret) catch(...) { d_safe_exception(msg, __FILE__, __LINE__); return ret; } | |||||
/* Define DISTRHO_DECLARE_NON_COPY_CLASS */ | |||||
#ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||||
# define DISTRHO_DECLARE_NON_COPY_CLASS(ClassName) \ | |||||
private: \ | |||||
ClassName(ClassName&) = delete; \ | |||||
ClassName(const ClassName&) = delete; \ | |||||
ClassName& operator=(ClassName&) = delete; \ | |||||
ClassName& operator=(const ClassName&) = delete; | |||||
#else | |||||
# define DISTRHO_DECLARE_NON_COPY_CLASS(ClassName) \ | |||||
private: \ | |||||
ClassName(ClassName&); \ | |||||
ClassName(const ClassName&); \ | |||||
ClassName& operator=(ClassName&); \ | |||||
ClassName& operator=(const ClassName&); | |||||
#endif | |||||
/* Define DISTRHO_DECLARE_NON_COPY_STRUCT */ | |||||
#ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||||
# define DISTRHO_DECLARE_NON_COPY_STRUCT(StructName) \ | |||||
StructName(StructName&) = delete; \ | |||||
StructName(const StructName&) = delete; \ | |||||
StructName& operator=(StructName&) = delete; \ | |||||
StructName& operator=(const StructName&) = delete; | |||||
#else | |||||
# define DISTRHO_DECLARE_NON_COPY_STRUCT(StructName) | |||||
#endif | |||||
/* Define DISTRHO_PREVENT_HEAP_ALLOCATION */ | |||||
#ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||||
# define DISTRHO_PREVENT_HEAP_ALLOCATION \ | |||||
private: \ | |||||
static void* operator new(size_t) = delete; \ | |||||
static void operator delete(void*) = delete; | |||||
#else | |||||
# define DISTRHO_PREVENT_HEAP_ALLOCATION \ | |||||
private: \ | |||||
static void* operator new(size_t); \ | |||||
static void operator delete(void*); | |||||
#endif | |||||
/* Define namespace */ | /* Define namespace */ | ||||
#ifndef DISTRHO_NO_NAMESPACE | #ifndef DISTRHO_NO_NAMESPACE | ||||
# ifndef DISTRHO_NAMESPACE | # ifndef DISTRHO_NAMESPACE | ||||
@@ -124,4 +177,10 @@ | |||||
#define DISTRHO_UI_URI DISTRHO_PLUGIN_URI "#UI" | #define DISTRHO_UI_URI DISTRHO_PLUGIN_URI "#UI" | ||||
/* Useful typedefs */ | |||||
typedef unsigned char uchar; | |||||
typedef unsigned long int ulong; | |||||
typedef unsigned short int ushort; | |||||
typedef unsigned int uint; | |||||
#endif // DISTRHO_DEFINES_H_INCLUDED | #endif // DISTRHO_DEFINES_H_INCLUDED |