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.

472 lines
12KB

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