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.

424 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. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  222. buffer[i] = 0;
  223. }
  224. void replace(char before, char after)
  225. {
  226. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  227. {
  228. if (buffer[i] == before)
  229. buffer[i] = after;
  230. }
  231. }
  232. void truncate(unsigned int n)
  233. {
  234. for (size_t i=n, len = ::strlen(buffer); i < len; i++)
  235. buffer[i] = 0;
  236. }
  237. void toBasic()
  238. {
  239. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  240. {
  241. if ((buffer[i] >= '0' && buffer[i] <= '9') || (buffer[i] >= 'A' && buffer[i] <= 'Z') || (buffer[i] >= 'a' && buffer[i] <= 'z'))
  242. continue;
  243. buffer[i] = '_';
  244. }
  245. }
  246. void toLower()
  247. {
  248. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  249. {
  250. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  251. buffer[i] += 32;
  252. }
  253. }
  254. void toUpper()
  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. // ---------------------------------------------
  263. // public operators
  264. operator const char*() const
  265. {
  266. return buffer;
  267. }
  268. char& operator[](int pos)
  269. {
  270. return buffer[pos];
  271. }
  272. bool operator==(const char* const strBuf) const
  273. {
  274. return (strBuf && ::strcmp(buffer, strBuf) == 0);
  275. }
  276. bool operator==(const CarlaString& str) const
  277. {
  278. return operator==(str.buffer);
  279. }
  280. bool operator!=(const char* const strBuf) const
  281. {
  282. return !operator==(strBuf);
  283. }
  284. bool operator!=(const CarlaString& str) const
  285. {
  286. return !operator==(str.buffer);
  287. }
  288. CarlaString& operator=(const char* const strBuf)
  289. {
  290. ::free(buffer);
  291. buffer = ::strdup(strBuf ? strBuf : "");
  292. return *this;
  293. }
  294. CarlaString& operator=(const CarlaString& str)
  295. {
  296. return operator=(str.buffer);
  297. }
  298. CarlaString& operator+=(const char* const strBuf)
  299. {
  300. const size_t newBufSize = ::strlen(buffer) + (strBuf ? ::strlen(strBuf) : 0) + 1;
  301. char newBuf[newBufSize];
  302. ::strcpy(newBuf, buffer);
  303. ::strcat(newBuf, strBuf);
  304. ::free(buffer);
  305. buffer = ::strdup(newBuf);
  306. return *this;
  307. }
  308. CarlaString& operator+=(const CarlaString& str)
  309. {
  310. return operator+=(str.buffer);
  311. }
  312. CarlaString operator+(const char* const strBuf)
  313. {
  314. const size_t newBufSize = ::strlen(buffer) + (strBuf ? ::strlen(strBuf) : 0) + 1;
  315. char newBuf[newBufSize];
  316. ::strcpy(newBuf, buffer);
  317. ::strcat(newBuf, strBuf);
  318. return CarlaString(newBuf);
  319. }
  320. CarlaString operator+(const CarlaString& str)
  321. {
  322. return operator+(str.buffer);
  323. }
  324. // ---------------------------------------------
  325. private:
  326. char* buffer;
  327. };
  328. static inline
  329. CarlaString operator+(const char* const strBufBefore, const CarlaString& strAfter)
  330. {
  331. const char* const strBufAfter = (const char*)strAfter;
  332. const size_t newBufSize = (strBufBefore ? ::strlen(strBufBefore) : 0) + ::strlen(strBufAfter) + 1;
  333. char newBuf[newBufSize];
  334. ::strcpy(newBuf, strBufBefore);
  335. ::strcat(newBuf, strBufAfter);
  336. return CarlaString(newBuf);
  337. }
  338. // -------------------------------------------------
  339. #endif // CARLA_UTILS_HPP