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.

426 lines
9.6KB

  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_minU(const unsigned int& x, const unsigned int& y)
  94. {
  95. return (x < y ? x : y);
  96. }
  97. // other misc functions
  98. static inline
  99. const char* bool2str(const bool yesNo)
  100. {
  101. return yesNo ? "true" : "false";
  102. }
  103. static inline
  104. void pass() {}
  105. // -------------------------------------------------
  106. // CarlaString class
  107. class CarlaString
  108. {
  109. public:
  110. // ---------------------------------------------
  111. // constructors (no explicit conversions allowed)
  112. explicit CarlaString()
  113. {
  114. buffer = ::strdup("");
  115. }
  116. explicit CarlaString(char* const strBuf)
  117. {
  118. buffer = ::strdup(strBuf ? strBuf : "");
  119. }
  120. explicit CarlaString(const char* const strBuf)
  121. {
  122. buffer = ::strdup(strBuf ? strBuf : "");
  123. }
  124. explicit CarlaString(const int value)
  125. {
  126. const size_t strBufSize = ::abs(value/10) + 3;
  127. char strBuf[strBufSize];
  128. ::snprintf(strBuf, strBufSize, "%d", value);
  129. buffer = ::strdup(strBuf);
  130. }
  131. explicit CarlaString(const unsigned int value, const bool hexadecimal = false)
  132. {
  133. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  134. char strBuf[strBufSize];
  135. ::snprintf(strBuf, strBufSize, hexadecimal ? "%u" : "0x%x", value);
  136. buffer = ::strdup(strBuf);
  137. }
  138. explicit CarlaString(const long int value)
  139. {
  140. const size_t strBufSize = ::labs(value/10) + 3;
  141. char strBuf[strBufSize];
  142. ::snprintf(strBuf, strBufSize, "%ld", value);
  143. buffer = ::strdup(strBuf);
  144. }
  145. explicit CarlaString(const unsigned long int value, const bool hexadecimal = false)
  146. {
  147. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  148. char strBuf[strBufSize];
  149. ::snprintf(strBuf, strBufSize, hexadecimal ? "%lu" : "0x%lx", value);
  150. buffer = ::strdup(strBuf);
  151. }
  152. explicit CarlaString(const float value)
  153. {
  154. char strBuf[0xff];
  155. ::snprintf(strBuf, 0xff, "%f", value);
  156. buffer = ::strdup(strBuf);
  157. }
  158. explicit CarlaString(const double value)
  159. {
  160. char strBuf[0xff];
  161. ::snprintf(strBuf, 0xff, "%g", value);
  162. buffer = ::strdup(strBuf);
  163. }
  164. // ---------------------------------------------
  165. // non-explicit constructor
  166. CarlaString(const CarlaString& str)
  167. {
  168. buffer = ::strdup(str.buffer);
  169. }
  170. // ---------------------------------------------
  171. // deconstructor
  172. ~CarlaString()
  173. {
  174. ::free(buffer);
  175. }
  176. // ---------------------------------------------
  177. // public methods
  178. size_t length() const
  179. {
  180. return ::strlen(buffer);
  181. }
  182. bool isEmpty() const
  183. {
  184. return (*buffer == 0);
  185. }
  186. bool isNotEmpty() const
  187. {
  188. return !isEmpty();
  189. }
  190. bool contains(const char* const strBuf) const
  191. {
  192. if (! strBuf)
  193. return false;
  194. if (*strBuf == 0)
  195. return false;
  196. size_t thisLen = ::strlen(buffer);
  197. size_t thatLen = ::strlen(strBuf)-1;
  198. for (size_t i=0, j=0; i < thisLen; i++)
  199. {
  200. if (buffer[i] == strBuf[j])
  201. j++;
  202. else
  203. j = 0;
  204. if (j == thatLen)
  205. return true;
  206. }
  207. return false;
  208. }
  209. bool contains(const CarlaString& str) const
  210. {
  211. return contains(str.buffer);
  212. }
  213. bool isDigit(size_t pos) const
  214. {
  215. if (pos >= length())
  216. return false;
  217. return (buffer[pos] >= '0' && buffer[pos] <= '9');
  218. }
  219. void clear()
  220. {
  221. if (::strcmp(buffer, "") == 0)
  222. return;
  223. buffer = ::strdup("");
  224. }
  225. void replace(char before, char after)
  226. {
  227. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  228. {
  229. if (buffer[i] == before)
  230. buffer[i] = after;
  231. }
  232. }
  233. void truncate(unsigned int n)
  234. {
  235. for (size_t i=n, len = ::strlen(buffer); i < len; i++)
  236. buffer[i] = 0;
  237. }
  238. void toBasic()
  239. {
  240. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  241. {
  242. if ((buffer[i] >= '0' && buffer[i] <= '9') || (buffer[i] >= 'A' && buffer[i] <= 'Z') || (buffer[i] >= 'a' && buffer[i] <= 'z'))
  243. continue;
  244. buffer[i] = '_';
  245. }
  246. }
  247. void toLower()
  248. {
  249. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  250. {
  251. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  252. buffer[i] += 32;
  253. }
  254. }
  255. void toUpper()
  256. {
  257. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  258. {
  259. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  260. buffer[i] -= 32;
  261. }
  262. }
  263. // ---------------------------------------------
  264. // public operators
  265. operator const char*() const
  266. {
  267. return buffer;
  268. }
  269. char& operator[](int pos)
  270. {
  271. return buffer[pos];
  272. }
  273. bool operator==(const char* const strBuf) const
  274. {
  275. return (strBuf && ::strcmp(buffer, strBuf) == 0);
  276. }
  277. bool operator==(const CarlaString& str) const
  278. {
  279. return operator==(str.buffer);
  280. }
  281. bool operator!=(const char* const strBuf) const
  282. {
  283. return !operator==(strBuf);
  284. }
  285. bool operator!=(const CarlaString& str) const
  286. {
  287. return !operator==(str.buffer);
  288. }
  289. CarlaString& operator=(const char* const strBuf)
  290. {
  291. ::free(buffer);
  292. buffer = ::strdup(strBuf ? strBuf : "");
  293. return *this;
  294. }
  295. CarlaString& operator=(const CarlaString& str)
  296. {
  297. return operator=(str.buffer);
  298. }
  299. CarlaString& operator+=(const char* const strBuf)
  300. {
  301. const size_t newBufSize = ::strlen(buffer) + (strBuf ? ::strlen(strBuf) : 0) + 1;
  302. char newBuf[newBufSize];
  303. ::strcpy(newBuf, buffer);
  304. ::strcat(newBuf, strBuf);
  305. ::free(buffer);
  306. buffer = ::strdup(newBuf);
  307. return *this;
  308. }
  309. CarlaString& operator+=(const CarlaString& str)
  310. {
  311. return operator+=(str.buffer);
  312. }
  313. CarlaString operator+(const char* const strBuf)
  314. {
  315. const size_t newBufSize = ::strlen(buffer) + (strBuf ? ::strlen(strBuf) : 0) + 1;
  316. char newBuf[newBufSize];
  317. ::strcpy(newBuf, buffer);
  318. ::strcat(newBuf, strBuf);
  319. return CarlaString(newBuf);
  320. }
  321. CarlaString operator+(const CarlaString& str)
  322. {
  323. return operator+(str.buffer);
  324. }
  325. // ---------------------------------------------
  326. private:
  327. char* buffer;
  328. };
  329. static inline
  330. CarlaString operator+(const char* const strBufBefore, const CarlaString& strAfter)
  331. {
  332. const char* const strBufAfter = (const char*)strAfter;
  333. const size_t newBufSize = (strBufBefore ? ::strlen(strBufBefore) : 0) + ::strlen(strBufAfter) + 1;
  334. char newBuf[newBufSize];
  335. ::strcpy(newBuf, strBufBefore);
  336. ::strcat(newBuf, strBufAfter);
  337. return CarlaString(newBuf);
  338. }
  339. // -------------------------------------------------
  340. #endif // CARLA_UTILS_HPP