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
10KB

  1. /*
  2. * Carla common utils
  3. * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * 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 COPYING file
  16. */
  17. #ifndef __CARLA_UTILS_HPP__
  18. #define __CARLA_UTILS_HPP__
  19. #include "carla_defines.hpp"
  20. #include <cstdio>
  21. #include <cstdlib>
  22. #include <cstring>
  23. #if defined(Q_OS_HAIKU)
  24. # include <kernel/OS.h>
  25. #elif defined(Q_OS_LINUX)
  26. # include <sys/prctl.h>
  27. # include <linux/prctl.h>
  28. #endif
  29. // -------------------------------------------------
  30. // carla_assert*
  31. static inline
  32. void carla_assert(const char* const assertion, const char* const file, const int line)
  33. {
  34. qCritical("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
  35. }
  36. static inline
  37. void carla_assert_int(const char* const assertion, const char* const file, const int line, const int value)
  38. {
  39. qCritical("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
  40. }
  41. // -------------------------------------------------
  42. // carla_*sleep (carla_usleep not possible in Windows)
  43. static inline
  44. void carla_sleep(const int secs)
  45. {
  46. CARLA_ASSERT(secs > 0);
  47. #ifdef Q_OS_WIN
  48. Sleep(secs * 1000);
  49. #else
  50. sleep(secs);
  51. #endif
  52. }
  53. static inline
  54. void carla_msleep(const int msecs)
  55. {
  56. CARLA_ASSERT(msecs > 0);
  57. #ifdef Q_OS_WIN
  58. Sleep(msecs);
  59. #else
  60. usleep(msecs * 1000);
  61. #endif
  62. }
  63. static inline
  64. void carla_usleep(const int usecs)
  65. {
  66. CARLA_ASSERT(usecs > 0);
  67. #ifdef Q_OS_WIN
  68. Sleep(usecs / 1000);
  69. #else
  70. usleep(usecs);
  71. #endif
  72. }
  73. // -------------------------------------------------
  74. // carla_setenv
  75. static inline
  76. void carla_setenv(const char* const key, const char* const value)
  77. {
  78. CARLA_ASSERT(key);
  79. CARLA_ASSERT(value);
  80. #ifdef Q_OS_WIN
  81. SetEnvironmentVariableA(key, value);
  82. #else
  83. setenv(key, value, 1);
  84. #endif
  85. }
  86. // -------------------------------------------------
  87. // carla_setprocname (not available on all platforms)
  88. static inline
  89. void carla_setprocname(const char* const name)
  90. {
  91. CARLA_ASSERT(name);
  92. #if defined(Q_OS_HAIKU)
  93. if ((thread_id this_thread = find_thread(nullptr)) != B_NAME_NOT_FOUND)
  94. rename_thread(this_thread, name);
  95. #elif defined(Q_OS_LINUX)
  96. prctl(PR_SET_NAME, name);
  97. #else
  98. qWarning("carla_setprocname(\"%s\") - unsupported on this platform", name);
  99. #endif
  100. }
  101. // -------------------------------------------------
  102. // math functions
  103. template<typename T>
  104. static inline
  105. const T& carla_min(const T& v1, const T& v2, const T& min)
  106. {
  107. return ((v1 < min || v2 < min) ? min : (v1 < v2 ? v1 : v2));
  108. }
  109. template<typename T>
  110. static inline
  111. void carla_fill(T* data, const unsigned int size, const T v)
  112. {
  113. CARLA_ASSERT(data);
  114. CARLA_ASSERT(size > 0);
  115. for (unsigned int i=0; i < size; i++)
  116. *data++ = v;
  117. }
  118. void carla_zeroDouble(double* data, const unsigned size)
  119. {
  120. carla_fill<double>(data, size, 0.0);
  121. }
  122. void carla_zeroFloat(float* data, const unsigned size)
  123. {
  124. carla_fill<float>(data, size, 0.0f);
  125. }
  126. // -------------------------------------------------
  127. // other misc functions
  128. static inline
  129. const char* bool2str(const bool yesNo)
  130. {
  131. return yesNo ? "true" : "false";
  132. }
  133. static inline
  134. void pass() {}
  135. // -------------------------------------------------
  136. // CarlaString class
  137. class CarlaString
  138. {
  139. public:
  140. // ---------------------------------------------
  141. // constructors (no explicit conversions allowed)
  142. explicit CarlaString()
  143. {
  144. buffer = ::strdup("");
  145. }
  146. explicit CarlaString(char* const strBuf)
  147. {
  148. buffer = ::strdup(strBuf ? strBuf : "");
  149. }
  150. explicit CarlaString(const char* const strBuf)
  151. {
  152. buffer = ::strdup(strBuf ? strBuf : "");
  153. }
  154. explicit CarlaString(const int value)
  155. {
  156. const size_t strBufSize = ::abs(value/10) + 3;
  157. char strBuf[strBufSize];
  158. ::snprintf(strBuf, strBufSize, "%d", value);
  159. buffer = ::strdup(strBuf);
  160. }
  161. explicit CarlaString(const unsigned int value, const bool hexadecimal = false)
  162. {
  163. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  164. char strBuf[strBufSize];
  165. ::snprintf(strBuf, strBufSize, hexadecimal ? "%u" : "0x%x", value);
  166. buffer = ::strdup(strBuf);
  167. }
  168. explicit CarlaString(const long int value)
  169. {
  170. const size_t strBufSize = ::labs(value/10) + 3;
  171. char strBuf[strBufSize];
  172. ::snprintf(strBuf, strBufSize, "%ld", value);
  173. buffer = ::strdup(strBuf);
  174. }
  175. explicit CarlaString(const unsigned long int value, const bool hexadecimal = false)
  176. {
  177. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  178. char strBuf[strBufSize];
  179. ::snprintf(strBuf, strBufSize, hexadecimal ? "%lu" : "0x%lx", value);
  180. buffer = ::strdup(strBuf);
  181. }
  182. explicit CarlaString(const float value)
  183. {
  184. char strBuf[0xff];
  185. ::snprintf(strBuf, 0xff, "%f", value);
  186. buffer = ::strdup(strBuf);
  187. }
  188. explicit CarlaString(const double value)
  189. {
  190. char strBuf[0xff];
  191. ::snprintf(strBuf, 0xff, "%g", value);
  192. buffer = ::strdup(strBuf);
  193. }
  194. // ---------------------------------------------
  195. // non-explicit constructor
  196. CarlaString(const CarlaString& str)
  197. {
  198. buffer = ::strdup(str.buffer);
  199. }
  200. // ---------------------------------------------
  201. // deconstructor
  202. ~CarlaString()
  203. {
  204. CARLA_ASSERT(buffer);
  205. ::free(buffer);
  206. }
  207. // ---------------------------------------------
  208. // public methods
  209. size_t length() const
  210. {
  211. return ::strlen(buffer);
  212. }
  213. bool isEmpty() const
  214. {
  215. return (*buffer == 0);
  216. }
  217. bool isNotEmpty() const
  218. {
  219. return (*buffer != 0);
  220. }
  221. bool contains(const char* const strBuf) const
  222. {
  223. if (! strBuf)
  224. return false;
  225. if (*strBuf == 0)
  226. return false;
  227. size_t thisLen = ::strlen(buffer);
  228. size_t thatLen = ::strlen(strBuf)-1;
  229. for (size_t i=0, j=0; i < thisLen; i++)
  230. {
  231. if (buffer[i] == strBuf[j])
  232. j++;
  233. else
  234. j = 0;
  235. if (j == thatLen)
  236. return true;
  237. }
  238. return false;
  239. }
  240. bool contains(const CarlaString& str) const
  241. {
  242. return contains(str.buffer);
  243. }
  244. bool isDigit(const size_t pos) const
  245. {
  246. if (pos >= length())
  247. return false;
  248. return (buffer[pos] >= '0' && buffer[pos] <= '9');
  249. }
  250. void clear()
  251. {
  252. truncate(0);
  253. }
  254. void replace(const char before, const char after)
  255. {
  256. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  257. {
  258. if (buffer[i] == before)
  259. buffer[i] = after;
  260. }
  261. }
  262. void truncate(const unsigned int n)
  263. {
  264. for (size_t i=n, len = ::strlen(buffer); i < len; i++)
  265. buffer[i] = 0;
  266. }
  267. void toBasic()
  268. {
  269. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  270. {
  271. if (buffer[i] >= '0' && buffer[i] <= '9')
  272. continue;
  273. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  274. continue;
  275. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  276. continue;
  277. if (buffer[i] == '_')
  278. continue;
  279. buffer[i] = '_';
  280. }
  281. }
  282. void toLower()
  283. {
  284. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  285. {
  286. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  287. buffer[i] += 32;
  288. }
  289. }
  290. void toUpper()
  291. {
  292. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  293. {
  294. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  295. buffer[i] -= 32;
  296. }
  297. }
  298. // ---------------------------------------------
  299. // public operators
  300. operator const char*() const
  301. {
  302. return buffer;
  303. }
  304. char& operator[](const unsigned int pos)
  305. {
  306. return buffer[pos];
  307. }
  308. bool operator==(const char* const strBuf) const
  309. {
  310. return (strBuf && ::strcmp(buffer, strBuf) == 0);
  311. }
  312. bool operator==(const CarlaString& str) const
  313. {
  314. return operator==(str.buffer);
  315. }
  316. bool operator!=(const char* const strBuf) const
  317. {
  318. return !operator==(strBuf);
  319. }
  320. bool operator!=(const CarlaString& str) const
  321. {
  322. return !operator==(str.buffer);
  323. }
  324. CarlaString& operator=(const char* const strBuf)
  325. {
  326. ::free(buffer);
  327. buffer = ::strdup(strBuf ? strBuf : "");
  328. return *this;
  329. }
  330. CarlaString& operator=(const CarlaString& str)
  331. {
  332. return operator=(str.buffer);
  333. }
  334. CarlaString& operator+=(const char* const strBuf)
  335. {
  336. const size_t newBufSize = ::strlen(buffer) + (strBuf ? ::strlen(strBuf) : 0) + 1;
  337. char newBuf[newBufSize];
  338. ::strcpy(newBuf, buffer);
  339. ::strcat(newBuf, strBuf);
  340. ::free(buffer);
  341. buffer = ::strdup(newBuf);
  342. return *this;
  343. }
  344. CarlaString& operator+=(const CarlaString& str)
  345. {
  346. return operator+=(str.buffer);
  347. }
  348. CarlaString operator+(const char* const strBuf)
  349. {
  350. const size_t newBufSize = ::strlen(buffer) + (strBuf ? ::strlen(strBuf) : 0) + 1;
  351. char newBuf[newBufSize];
  352. ::strcpy(newBuf, buffer);
  353. ::strcat(newBuf, strBuf);
  354. return CarlaString(newBuf);
  355. }
  356. CarlaString operator+(const CarlaString& str)
  357. {
  358. return operator+(str.buffer);
  359. }
  360. // ---------------------------------------------
  361. private:
  362. char* buffer;
  363. };
  364. static inline
  365. CarlaString operator+(const char* const strBufBefore, const CarlaString& strAfter)
  366. {
  367. const char* const strBufAfter = (const char*)strAfter;
  368. const size_t newBufSize = (strBufBefore ? ::strlen(strBufBefore) : 0) + ::strlen(strBufAfter) + 1;
  369. char newBuf[newBufSize];
  370. ::strcpy(newBuf, strBufBefore);
  371. ::strcat(newBuf, strBufAfter);
  372. return CarlaString(newBuf);
  373. }
  374. // -------------------------------------------------
  375. #endif // __CARLA_UTILS_HPP__