Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

599 lines
14KB

  1. /*
  2. * Carla common utils
  3. * Copyright (C) 2011-2016 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_UTILS_HPP_INCLUDED
  18. #define CARLA_UTILS_HPP_INCLUDED
  19. #include "CarlaDefines.h"
  20. #include <cassert>
  21. #include <cstdarg>
  22. #include <cstdio>
  23. #include <cstdlib>
  24. #include <cstring>
  25. #ifdef CARLA_PROPER_CPP11_SUPPORT
  26. # include <cxxabi.h>
  27. # include <cstdint>
  28. #else
  29. # include <stdint.h>
  30. #endif
  31. #ifdef CARLA_OS_WIN
  32. # define WIN32_LEAN_AND_MEAN 1
  33. # include <winsock2.h>
  34. # include <windows.h>
  35. #else
  36. # include <unistd.h>
  37. #endif
  38. // --------------------------------------------------------------------------------------------------------------------
  39. // misc functions
  40. /*
  41. * Return "true" or "false" according to yesNo.
  42. */
  43. static inline
  44. const char* bool2str(const bool yesNo) noexcept
  45. {
  46. return yesNo ? "true" : "false";
  47. }
  48. /*
  49. * Set a string as empty/null.
  50. */
  51. static inline
  52. void nullStrBuf(char* const strBuf) noexcept
  53. {
  54. strBuf[0] = '\0';
  55. }
  56. /*
  57. * Dummy function.
  58. */
  59. static inline
  60. void pass() noexcept {}
  61. // --------------------------------------------------------------------------------------------------------------------
  62. // string print functions
  63. /*
  64. * Internal noexcept-safe fopen function.
  65. */
  66. static inline
  67. FILE* __carla_fopen(const char* const filename, FILE* const fallback) noexcept
  68. {
  69. #ifdef CARLA_OS_LINUX
  70. if (std::getenv("CARLA_CAPTURE_CONSOLE_OUTPUT") == nullptr)
  71. return fallback;
  72. FILE* ret = nullptr;
  73. try {
  74. ret = std::fopen(filename, "a+");
  75. } catch (...) {}
  76. if (ret == nullptr)
  77. ret = fallback;
  78. return ret;
  79. #else
  80. return fallback;
  81. // unused
  82. (void)filename;
  83. #endif
  84. }
  85. /*
  86. * Print a string to stdout with newline (gray color).
  87. * Does nothing if DEBUG is not defined.
  88. */
  89. #ifndef DEBUG
  90. # define carla_debug(...)
  91. #else
  92. static inline
  93. void carla_debug(const char* const fmt, ...) noexcept
  94. {
  95. static FILE* const output = __carla_fopen("/tmp/carla.debug.log", stdout);
  96. try {
  97. ::va_list args;
  98. ::va_start(args, fmt);
  99. if (output == stdout)
  100. {
  101. std::fprintf(output, "\x1b[30;1m");
  102. std::vfprintf(output, fmt, args);
  103. std::fprintf(output, "\x1b[0m\n");
  104. }
  105. else
  106. {
  107. std::vfprintf(output, fmt, args);
  108. std::fprintf(output, "\n");
  109. std::fflush(output);
  110. }
  111. ::va_end(args);
  112. } catch (...) {}
  113. }
  114. #endif
  115. /*
  116. * Print a string to stdout with newline.
  117. */
  118. static inline
  119. void carla_stdout(const char* const fmt, ...) noexcept
  120. {
  121. static FILE* const output = __carla_fopen("/tmp/carla.stdout.log", stdout);
  122. try {
  123. ::va_list args;
  124. ::va_start(args, fmt);
  125. std::vfprintf(output, fmt, args);
  126. std::fprintf(output, "\n");
  127. if (output != stdout)
  128. std::fflush(output);
  129. ::va_end(args);
  130. } catch (...) {}
  131. }
  132. /*
  133. * Print a string to stderr with newline.
  134. */
  135. static inline
  136. void carla_stderr(const char* const fmt, ...) noexcept
  137. {
  138. static FILE* const output = __carla_fopen("/tmp/carla.stderr.log", stderr);
  139. try {
  140. ::va_list args;
  141. ::va_start(args, fmt);
  142. std::vfprintf(output, fmt, args);
  143. std::fprintf(output, "\n");
  144. if (output != stderr)
  145. std::fflush(output);
  146. ::va_end(args);
  147. } catch (...) {}
  148. }
  149. /*
  150. * Print a string to stderr with newline (red color).
  151. */
  152. static inline
  153. void carla_stderr2(const char* const fmt, ...) noexcept
  154. {
  155. static FILE* const output = __carla_fopen("/tmp/carla.stderr2.log", stderr);
  156. try {
  157. ::va_list args;
  158. ::va_start(args, fmt);
  159. if (output == stderr)
  160. {
  161. std::fprintf(output, "\x1b[31m");
  162. std::vfprintf(output, fmt, args);
  163. std::fprintf(output, "\x1b[0m\n");
  164. }
  165. else
  166. {
  167. std::vfprintf(output, fmt, args);
  168. std::fprintf(output, "\n");
  169. std::fflush(output);
  170. }
  171. ::va_end(args);
  172. } catch (...) {}
  173. }
  174. // --------------------------------------------------------------------------------------------------------------------
  175. // carla_safe_assert*
  176. /*
  177. * Print a safe assertion error message.
  178. */
  179. static inline
  180. void carla_safe_assert(const char* const assertion, const char* const file, const int line) noexcept
  181. {
  182. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
  183. }
  184. /*
  185. * Print a safe assertion error message, with 1 extra signed integer value.
  186. */
  187. static inline
  188. void carla_safe_assert_int(const char* const assertion, const char* const file,
  189. const int line, const int value) noexcept
  190. {
  191. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
  192. }
  193. /*
  194. * Print a safe assertion error message, with 1 extra unsigned integer value.
  195. */
  196. static inline
  197. void carla_safe_assert_uint(const char* const assertion, const char* const file,
  198. const int line, const uint value) noexcept
  199. {
  200. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %u", assertion, file, line, value);
  201. }
  202. /*
  203. * Print a safe assertion error message, with 2 extra signed integer values.
  204. */
  205. static inline
  206. void carla_safe_assert_int2(const char* const assertion, const char* const file,
  207. const int line, const int v1, const int v2) noexcept
  208. {
  209. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2);
  210. }
  211. /*
  212. * Print a safe assertion error message, with 2 extra unsigned integer values.
  213. */
  214. static inline
  215. void carla_safe_assert_uint2(const char* const assertion, const char* const file,
  216. const int line, const uint v1, const uint v2) noexcept
  217. {
  218. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %u, v2 %u", assertion, file, line, v1, v2);
  219. }
  220. // --------------------------------------------------------------------------------------------------------------------
  221. // carla_safe_exception*
  222. /*
  223. * Print a safe exception error message.
  224. */
  225. static inline
  226. void carla_safe_exception(const char* const exception, const char* const file, const int line) noexcept
  227. {
  228. carla_stderr2("Carla exception caught: \"%s\" in file %s, line %i", exception, file, line);
  229. }
  230. // --------------------------------------------------------------------------------------------------------------------
  231. // carla_*sleep
  232. /*
  233. * Sleep for 'secs' seconds.
  234. */
  235. static inline
  236. void carla_sleep(const uint secs) noexcept
  237. {
  238. CARLA_SAFE_ASSERT_RETURN(secs > 0,);
  239. try {
  240. #ifdef CARLA_OS_WIN
  241. ::Sleep(secs * 1000);
  242. #else
  243. ::sleep(secs);
  244. #endif
  245. } CARLA_SAFE_EXCEPTION("carla_sleep");
  246. }
  247. /*
  248. * Sleep for 'msecs' milliseconds.
  249. */
  250. static inline
  251. void carla_msleep(const uint msecs) noexcept
  252. {
  253. CARLA_SAFE_ASSERT_RETURN(msecs > 0,);
  254. try {
  255. #ifdef CARLA_OS_WIN
  256. ::Sleep(msecs);
  257. #else
  258. ::usleep(msecs * 1000);
  259. #endif
  260. } CARLA_SAFE_EXCEPTION("carla_msleep");
  261. }
  262. // --------------------------------------------------------------------------------------------------------------------
  263. // carla_setenv
  264. /*
  265. * Set environment variable 'key' to 'value'.
  266. */
  267. static inline
  268. void carla_setenv(const char* const key, const char* const value) noexcept
  269. {
  270. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  271. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  272. #ifdef CARLA_OS_WIN
  273. try {
  274. ::SetEnvironmentVariableA(key, value);
  275. } CARLA_SAFE_EXCEPTION("carla_setenv");
  276. #else
  277. ::setenv(key, value, 1);
  278. #endif
  279. }
  280. /*
  281. * Unset environment variable 'key'.
  282. */
  283. static inline
  284. void carla_unsetenv(const char* const key) noexcept
  285. {
  286. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  287. #ifdef CARLA_OS_WIN
  288. try {
  289. ::SetEnvironmentVariableA(key, nullptr);
  290. } CARLA_SAFE_EXCEPTION("carla_unsetenv");
  291. #else
  292. ::unsetenv(key);
  293. #endif
  294. }
  295. // --------------------------------------------------------------------------------------------------------------------
  296. // carla_strdup
  297. /*
  298. * Custom 'strdup' function.
  299. * Returned value is always valid, and must be freed with "delete[] var".
  300. * May throw.
  301. */
  302. static inline
  303. const char* carla_strdup(const char* const strBuf)
  304. {
  305. CARLA_SAFE_ASSERT(strBuf != nullptr);
  306. const std::size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0;
  307. char* const buffer = new char[bufferLen+1];
  308. if (bufferLen > 0)
  309. std::memcpy(buffer, strBuf, bufferLen);
  310. buffer[bufferLen] = '\0';
  311. return buffer;
  312. }
  313. /*
  314. * Custom 'strdup' function.
  315. * Calls "std::free(strBuf)".
  316. * Returned value is always valid, and must be freed with "delete[] var".
  317. * May throw.
  318. */
  319. static inline
  320. const char* carla_strdup_free(char* const strBuf)
  321. {
  322. const char* const buffer(carla_strdup(strBuf));
  323. std::free(strBuf);
  324. return buffer;
  325. }
  326. /*
  327. * Custom 'strdup' function, safe version.
  328. * Returned value may be null. It must be freed with "delete[] var".
  329. */
  330. static inline
  331. const char* carla_strdup_safe(const char* const strBuf) noexcept
  332. {
  333. CARLA_SAFE_ASSERT_RETURN(strBuf != nullptr, nullptr);
  334. const std::size_t bufferLen = std::strlen(strBuf);
  335. char* buffer;
  336. try {
  337. buffer = new char[bufferLen+1];
  338. } CARLA_SAFE_EXCEPTION_RETURN("carla_strdup_safe", nullptr);
  339. if (bufferLen > 0)
  340. std::memcpy(buffer, strBuf, bufferLen);
  341. buffer[bufferLen] = '\0';
  342. return buffer;
  343. }
  344. // --------------------------------------------------------------------------------------------------------------------
  345. // memory functions
  346. /*
  347. * Add array values to another array.
  348. */
  349. template<typename T>
  350. static inline
  351. void carla_add(T dest[], const T src[], const std::size_t count) noexcept
  352. {
  353. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  354. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  355. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  356. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  357. for (std::size_t i=0; i<count; ++i)
  358. *dest++ += *src++;
  359. }
  360. /*
  361. * Add array values to another array, with a multiplication factor.
  362. */
  363. template<typename T>
  364. static inline
  365. void carla_addWithMultiply(T dest[], const T src[], const T& multiplier, const std::size_t count) noexcept
  366. {
  367. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  368. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  369. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  370. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  371. for (std::size_t i=0; i<count; ++i)
  372. *dest++ += *src++ * multiplier;
  373. }
  374. /*
  375. * Copy array values to another array.
  376. */
  377. template<typename T>
  378. static inline
  379. void carla_copy(T dest[], const T src[], const std::size_t count) noexcept
  380. {
  381. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  382. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  383. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  384. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  385. std::memcpy(dest, src, count*sizeof(T));
  386. }
  387. /*
  388. * Copy array values to another array, with a multiplication factor.
  389. */
  390. template<typename T>
  391. static inline
  392. void carla_copyWithMultiply(T dest[], const T src[], const T& multiplier, const std::size_t count) noexcept
  393. {
  394. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  395. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  396. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  397. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  398. for (std::size_t i=0; i<count; ++i)
  399. *dest++ = *src++ * multiplier;
  400. }
  401. /*
  402. * Fill an array with a fixed value.
  403. */
  404. template<typename T>
  405. static inline
  406. void carla_fill(T data[], const T& value, const std::size_t count) noexcept
  407. {
  408. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  409. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  410. if (value == 0)
  411. {
  412. std::memset(data, 0, count*sizeof(T));
  413. }
  414. else
  415. {
  416. for (std::size_t i=0; i<count; ++i)
  417. *data++ = value;
  418. }
  419. }
  420. /*
  421. * Multiply an array with a fixed value.
  422. */
  423. template<typename T>
  424. static inline
  425. void carla_multiply(T data[], const T& multiplier, const std::size_t count) noexcept
  426. {
  427. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  428. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  429. if (multiplier == 0)
  430. {
  431. std::memset(data, 0, count*sizeof(T));
  432. }
  433. else
  434. {
  435. for (std::size_t i=0; i<count; ++i)
  436. *data++ *= multiplier;
  437. }
  438. }
  439. /*
  440. * Clear a byte array.
  441. */
  442. static inline
  443. void carla_zeroBytes(uint8_t bytes[], const std::size_t count) noexcept
  444. {
  445. CARLA_SAFE_ASSERT_RETURN(bytes != nullptr,);
  446. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  447. std::memset(bytes, 0, count*sizeof(uint8_t));
  448. }
  449. /*
  450. * Clear a char array.
  451. */
  452. static inline
  453. void carla_zeroChars(char chars[], const std::size_t count) noexcept
  454. {
  455. CARLA_SAFE_ASSERT_RETURN(chars != nullptr,);
  456. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  457. std::memset(chars, 0, count*sizeof(char));
  458. }
  459. /*
  460. * Clear a pointer array.
  461. */
  462. template<typename T>
  463. static inline
  464. void carla_zeroPointers(T* ptrs[], const std::size_t count) noexcept
  465. {
  466. CARLA_SAFE_ASSERT_RETURN(ptrs != nullptr,);
  467. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  468. std::memset(ptrs, 0, count*sizeof(T*));
  469. }
  470. /*
  471. * Clear a single struct.
  472. */
  473. template <typename T>
  474. static inline
  475. void carla_zeroStruct(T& s) noexcept
  476. {
  477. std::memset(&s, 0, sizeof(T));
  478. }
  479. /*
  480. * Clear a struct array.
  481. */
  482. template <typename T>
  483. static inline
  484. void carla_zeroStructs(T structs[], const std::size_t count) noexcept
  485. {
  486. CARLA_SAFE_ASSERT_RETURN(structs != nullptr,);
  487. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  488. std::memset(structs, 0, count*sizeof(T));
  489. }
  490. /*
  491. * Copy a single struct.
  492. */
  493. template <typename T>
  494. static inline
  495. void carla_copyStruct(T& dest, const T& src) noexcept
  496. {
  497. std::memcpy(&dest, &src, sizeof(T));
  498. }
  499. /*
  500. * Copy a struct array.
  501. */
  502. template <typename T>
  503. static inline
  504. void carla_copyStructs(T dest[], const T src[], const std::size_t count) noexcept
  505. {
  506. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  507. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  508. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  509. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  510. std::memcpy(dest, src, count*sizeof(T));
  511. }
  512. // --------------------------------------------------------------------------------------------------------------------
  513. #endif // CARLA_UTILS_HPP_INCLUDED