|  | /*
 * Carla common utils
 * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
 */
#ifndef CARLA_UTILS_HPP_INCLUDED
#define CARLA_UTILS_HPP_INCLUDED
#include "CarlaDefines.hpp"
#include <cassert>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#ifdef CARLA_PROPER_CPP11_SUPPORT
# include <cstdint>
#else
# include <stdint.h>
#endif
// -----------------------------------------------------------------------
// misc functions
static inline
const char* bool2str(const bool yesNo) noexcept
{
    return yesNo ? "true" : "false";
}
static inline
void pass() noexcept {}
// -----------------------------------------------------------------------
// string print functions
#ifndef DEBUG
# define carla_debug(...)
#else
static inline
void carla_debug(const char* const fmt, ...)
{
    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);
}
#endif
static inline
void carla_stdout(const char* const fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    std::vfprintf(stdout, fmt, args);
    std::fprintf(stdout, "\n");
    va_end(args);
}
static inline
void carla_stderr(const char* const fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    std::vfprintf(stderr, fmt, args);
    std::fprintf(stderr, "\n");
    va_end(args);
}
static inline
void carla_stderr2(const char* const fmt, ...)
{
    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);
}
// -----------------------------------------------------------------------
// carla_assert*
static inline
void carla_assert(const char* const assertion, const char* const file, const int line)
{
    carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
}
static inline
void carla_assert_int(const char* const assertion, const char* const file, const int line, const int value)
{
    carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
}
static inline
void carla_assert_int2(const char* const assertion, const char* const file, const int line, const int v1, const int v2)
{
    carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2);
}
// -----------------------------------------------------------------------
// carla_*sleep
static inline
void carla_sleep(const unsigned int secs)
{
    CARLA_SAFE_ASSERT_RETURN(secs > 0,);
#ifdef CARLA_OS_WIN
    Sleep(secs * 1000);
#else
    sleep(secs);
#endif
}
static inline
void carla_msleep(const unsigned int msecs)
{
    CARLA_SAFE_ASSERT_RETURN(msecs > 0,);
#ifdef CARLA_OS_WIN
    Sleep(msecs);
#else
    usleep(msecs * 1000);
#endif
}
// -----------------------------------------------------------------------
// carla_setenv
static inline
void carla_setenv(const char* const key, const char* const value)
{
    CARLA_SAFE_ASSERT_RETURN(key != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
#ifdef CARLA_OS_WIN
    SetEnvironmentVariableA(key, value);
#else
    setenv(key, value, 1);
#endif
}
// -----------------------------------------------------------------------
// carla_strdup
static inline
const char* carla_strdup(const char* const strBuf)
{
    CARLA_SAFE_ASSERT(strBuf != nullptr);
    const size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0;
    char* const  buffer    = new char[bufferLen+1];
    if (strBuf != nullptr && bufferLen > 0)
        std::strncpy(buffer, strBuf, bufferLen);
    buffer[bufferLen] = '\0';
    return buffer;
}
static inline
const char* carla_strdup_free(char* const strBuf)
{
    const char* const buffer(carla_strdup(strBuf));
    std::free(strBuf);
    return buffer;
}
// -----------------------------------------------------------------------
// math functions
template<typename T>
static inline
const T& carla_min(const T& v1, const T& v2, const T& min) noexcept
{
    return ((v1 < min || v2 < min) ? min : (v1 < v2 ? v1 : v2));
}
template<typename T>
static inline
const T& carla_max(const T& v1, const T& v2, const T& max) noexcept
{
    return ((v1 > max || v2 > max) ? max : (v1 > v2 ? v1 : v2));
}
template<typename T>
static inline
const T& carla_fixValue(const T& min, const T& max, const T& value)
{
    CARLA_SAFE_ASSERT_RETURN(max > min, max);
    if (value <= min)
        return min;
    if (value >= max)
        return max;
    return value;
}
template<typename T>
static inline
void carla_add(T* dataDst, T* dataSrc, const size_t size)
{
    CARLA_SAFE_ASSERT_RETURN(dataDst != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(dataSrc != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(size > 0,);
    for (size_t i=0; i < size; ++i)
        *dataDst++ += *dataSrc++;
}
template<typename T>
static inline
void carla_add(T* dataDst, const T* dataSrc, const size_t size)
{
    CARLA_SAFE_ASSERT_RETURN(dataDst != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(dataSrc != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(size > 0,);
    for (size_t i=0; i < size; ++i)
        *dataDst++ += *dataSrc++;
}
template<typename T>
static inline
void carla_copy(T* dataDst, T* dataSrc, const size_t size)
{
    CARLA_SAFE_ASSERT_RETURN(dataDst != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(dataSrc != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(size > 0,);
    for (size_t i=0; i < size; ++i)
        *dataDst++ = *dataSrc++;
}
template<typename T>
static inline
void carla_copy(T* dataDst, const T* dataSrc, const size_t size)
{
    CARLA_SAFE_ASSERT_RETURN(dataDst != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(dataSrc != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(size > 0,);
    for (size_t i=0; i < size; ++i)
        *dataDst++ = *dataSrc++;
}
template<typename T>
static inline
void carla_fill(T* data, const size_t size, const T v)
{
    CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(size > 0,);
    for (size_t i=0; i < size; ++i)
        *data++ = v;
}
static inline
void carla_addDouble(double* const dataDst, double* const dataSrc, const size_t size)
{
    carla_add<double>(dataDst, dataSrc, size);
}
static inline
void carla_addFloat(float* const dataDst, float* const dataSrc, const size_t size)
{
    carla_add<float>(dataDst, dataSrc, size);
}
static inline
void carla_copyDouble(double* const dataDst, double* const dataSrc, const size_t size)
{
    CARLA_SAFE_ASSERT_RETURN(dataDst != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(dataSrc != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(size > 0,);
    std::memcpy(dataDst, dataSrc, size*sizeof(double));
}
static inline
void carla_copyFloat(float* const dataDst, float* const dataSrc, const size_t size)
{
    CARLA_SAFE_ASSERT_RETURN(dataDst != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(dataSrc != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(size > 0,);
    std::memcpy(dataDst, dataSrc, size*sizeof(float));
}
static inline
void carla_zeroChar(char* const data, const size_t size)
{
    CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(size > 0,);
    std::memset(data, 0, size*sizeof(char));
}
static inline
void carla_zeroDouble(double* const data, const size_t size)
{
    CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(size > 0,);
    std::memset(data, 0, size*sizeof(double));
}
static inline
void carla_zeroFloat(float* const data, const size_t size)
{
    CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(size > 0,);
    std::memset(data, 0, size*sizeof(float));
}
#if defined(CARLA_OS_MAC) && ! defined(DISTRHO_OS_MAC)
namespace std {
inline float
  fmin(float __x, float __y)
  { return __builtin_fminf(__x, __y); }
inline float
  fmax(float __x, float __y)
  { return __builtin_fmaxf(__x, __y); }
inline float
  rint(float __x)
  { return __builtin_rintf(__x); }
}
#endif
// -----------------------------------------------------------------------
// memory functions
template <typename T>
static inline
void carla_copyStruct(T& struct1, T& struct2)
{
    std::memcpy(&struct1, &struct2, sizeof(T));
}
template <typename T>
static inline
void carla_copyStruct(T* const struct1, T* const struct2, const size_t count)
{
    CARLA_SAFE_ASSERT_RETURN(struct1 != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(struct2 != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(count > 0,);
    std::memcpy(struct1, struct2, count*sizeof(T));
}
static inline
void carla_zeroMem(void* const memory, const size_t numBytes)
{
    CARLA_SAFE_ASSERT_RETURN(memory != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(numBytes > 0,);
    std::memset(memory, 0, numBytes);
}
template <typename T>
static inline
void carla_zeroStruct(T& structure)
{
    std::memset(&structure, 0, sizeof(T));
}
template <typename T>
static inline
void carla_zeroStruct(T* const structure, const size_t count)
{
    CARLA_SAFE_ASSERT_RETURN(structure != nullptr,);
    CARLA_SAFE_ASSERT_RETURN(count > 0,);
    std::memset(structure, 0, count*sizeof(T));
}
// -----------------------------------------------------------------------
#endif // CARLA_UTILS_HPP_INCLUDED
 |