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.

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