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.

536 lines
13KB

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