Collection of tools useful for audio production
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.

434 lines
9.8KB

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