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.

683 lines
15KB

  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
  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 GPL.txt file
  16. */
  17. #ifndef __CARLA_UTILS_HPP__
  18. #define __CARLA_UTILS_HPP__
  19. #include "carla_juce_utils.hpp"
  20. #include <cstdio>
  21. #include <cstdlib>
  22. #include <cstring>
  23. #ifdef CPP11_MUTEX
  24. # include <mutex>
  25. #else
  26. # include <pthread.h>
  27. #endif
  28. #if defined(Q_OS_HAIKU)
  29. # include <kernel/OS.h>
  30. #elif defined(Q_OS_LINUX)
  31. # include <sys/prctl.h>
  32. # include <linux/prctl.h>
  33. #endif
  34. // -------------------------------------------------
  35. // carla_assert*
  36. static inline
  37. void carla_assert(const char* const assertion, const char* const file, const int line)
  38. {
  39. qCritical("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
  40. }
  41. static inline
  42. void carla_assert_int(const char* const assertion, const char* const file, const int line, const int value)
  43. {
  44. qCritical("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
  45. }
  46. static inline
  47. void carla_assert_int2(const char* const assertion, const char* const file, const int line, const int v1, const int v2)
  48. {
  49. qCritical("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2);
  50. }
  51. // -------------------------------------------------
  52. // carla_*sleep
  53. static inline
  54. void carla_sleep(const unsigned int secs)
  55. {
  56. CARLA_ASSERT(secs > 0);
  57. #ifdef Q_OS_WIN
  58. Sleep(secs * 1000);
  59. #else
  60. sleep(secs);
  61. #endif
  62. }
  63. static inline
  64. void carla_msleep(const unsigned int msecs)
  65. {
  66. CARLA_ASSERT(msecs > 0);
  67. #ifdef Q_OS_WIN
  68. Sleep(msecs);
  69. #else
  70. usleep(msecs * 1000);
  71. #endif
  72. }
  73. static inline
  74. void carla_usleep(const unsigned int usecs)
  75. {
  76. CARLA_ASSERT(usecs > 0);
  77. #ifdef Q_OS_WIN
  78. Sleep(usecs / 1000);
  79. #else
  80. usleep(usecs);
  81. #endif
  82. }
  83. // -------------------------------------------------
  84. // carla_setenv
  85. static inline
  86. void carla_setenv(const char* const key, const char* const value)
  87. {
  88. CARLA_ASSERT(key != nullptr);
  89. CARLA_ASSERT(value != nullptr);
  90. #ifdef Q_OS_WIN
  91. SetEnvironmentVariableA(key, value);
  92. #else
  93. setenv(key, value, 1);
  94. #endif
  95. }
  96. // -------------------------------------------------
  97. // carla_setprocname (not available on all platforms)
  98. static inline
  99. void carla_setprocname(const char* const name)
  100. {
  101. CARLA_ASSERT(name != nullptr);
  102. #if defined(Q_OS_HAIKU)
  103. if ((thread_id this_thread = find_thread(nullptr)) != B_NAME_NOT_FOUND)
  104. rename_thread(this_thread, name);
  105. #elif defined(Q_OS_LINUX)
  106. prctl(PR_SET_NAME, name);
  107. #else
  108. qWarning("carla_setprocname(\"%s\") - unsupported on this platform", name);
  109. #endif
  110. }
  111. // -------------------------------------------------
  112. // math functions
  113. template<typename T>
  114. static inline
  115. const T& carla_min(const T& v1, const T& v2, const T& min)
  116. {
  117. return ((v1 < min || v2 < min) ? min : (v1 < v2 ? v1 : v2));
  118. }
  119. template<typename T>
  120. static inline
  121. const T& carla_fixValue(const T& min, const T& max, const T& value)
  122. {
  123. if (value < min)
  124. return min;
  125. if (value > max)
  126. return max;
  127. return value;
  128. }
  129. template<typename T>
  130. static inline
  131. void carla_fill(T* data, const unsigned int size, const T v)
  132. {
  133. CARLA_ASSERT(data != nullptr);
  134. CARLA_ASSERT(size > 0);
  135. if (data == nullptr)
  136. return;
  137. for (unsigned int i=0; i < size; i++)
  138. *data++ = v;
  139. }
  140. static inline
  141. void carla_zeroDouble(double* data, const unsigned size)
  142. {
  143. carla_fill<double>(data, size, 0.0);
  144. }
  145. static inline
  146. void carla_zeroFloat(float* data, const unsigned size)
  147. {
  148. carla_fill<float>(data, size, 0.0f);
  149. }
  150. // -------------------------------------------------
  151. // memory functions
  152. static inline
  153. void carla_zeroMem(void* const memory, const size_t numBytes)
  154. {
  155. CARLA_ASSERT(memory != nullptr);
  156. if (memory == nullptr)
  157. return;
  158. std::memset(memory, 0, numBytes);
  159. }
  160. template <typename T>
  161. static inline
  162. void carla_zeroStruct(T& structure)
  163. {
  164. std::memset(&structure, 0, sizeof(T));
  165. }
  166. // -------------------------------------------------
  167. // other misc functions
  168. static inline
  169. const char* bool2str(const bool yesNo)
  170. {
  171. return yesNo ? "true" : "false";
  172. }
  173. static inline
  174. void pass() {}
  175. // -------------------------------------------------
  176. // CarlaMutex class
  177. class CarlaMutex
  178. {
  179. public:
  180. CarlaMutex()
  181. {
  182. #ifndef CPP11_MUTEX
  183. pthread_mutex_init(&pmutex, nullptr);
  184. #endif
  185. }
  186. ~CarlaMutex()
  187. {
  188. #ifndef CPP11_MUTEX
  189. pthread_mutex_destroy(&pmutex);
  190. #endif
  191. }
  192. void lock()
  193. {
  194. #ifdef CPP11_MUTEX
  195. cmutex.lock();
  196. #else
  197. pthread_mutex_lock(&pmutex);
  198. #endif
  199. }
  200. bool tryLock()
  201. {
  202. #ifdef CPP11_MUTEX
  203. return cmutex.try_lock();
  204. #else
  205. return (pthread_mutex_trylock(&pmutex) == 0);
  206. #endif
  207. }
  208. void unlock()
  209. {
  210. #ifdef CPP11_MUTEX
  211. cmutex.unlock();
  212. #else
  213. pthread_mutex_unlock(&pmutex);
  214. #endif
  215. }
  216. class ScopedLocker
  217. {
  218. public:
  219. ScopedLocker(CarlaMutex* const mutex)
  220. : fMutex(mutex)
  221. {
  222. fMutex->lock();
  223. }
  224. ~ScopedLocker()
  225. {
  226. fMutex->unlock();
  227. }
  228. private:
  229. CarlaMutex* const fMutex;
  230. CARLA_PREVENT_HEAP_ALLOCATION
  231. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ScopedLocker)
  232. };
  233. private:
  234. #ifdef CPP11_MUTEX
  235. std::mutex cmutex;
  236. #else
  237. pthread_mutex_t pmutex;
  238. #endif
  239. CARLA_PREVENT_HEAP_ALLOCATION
  240. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaMutex)
  241. };
  242. // -------------------------------------------------
  243. // CarlaString class
  244. class CarlaString
  245. {
  246. public:
  247. // ---------------------------------------------
  248. // constructors (no explicit conversions allowed)
  249. explicit CarlaString()
  250. {
  251. _init();
  252. _dup(nullptr);
  253. }
  254. explicit CarlaString(char* const strBuf)
  255. {
  256. _init();
  257. _dup(strBuf);
  258. }
  259. explicit CarlaString(const char* const strBuf)
  260. {
  261. _init();
  262. _dup(strBuf);
  263. }
  264. explicit CarlaString(const int value)
  265. {
  266. const size_t strBufSize = std::abs(value/10) + 3;
  267. char strBuf[strBufSize];
  268. std::snprintf(strBuf, strBufSize, "%d", value);
  269. _init();
  270. _dup(strBuf, strBufSize);
  271. }
  272. explicit CarlaString(const unsigned int value, const bool hexadecimal = false)
  273. {
  274. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  275. char strBuf[strBufSize];
  276. std::snprintf(strBuf, strBufSize, hexadecimal ? "0x%x" : "%u", value);
  277. _init();
  278. _dup(strBuf, strBufSize);
  279. }
  280. explicit CarlaString(const long int value)
  281. {
  282. const size_t strBufSize = std::abs(value/10) + 3;
  283. char strBuf[strBufSize];
  284. std::snprintf(strBuf, strBufSize, "%ld", value);
  285. _init();
  286. _dup(strBuf, strBufSize);
  287. }
  288. explicit CarlaString(const unsigned long int value, const bool hexadecimal = false)
  289. {
  290. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  291. char strBuf[strBufSize];
  292. std::snprintf(strBuf, strBufSize, hexadecimal ? "0x%lx" : "%lu", value);
  293. _init();
  294. _dup(strBuf, strBufSize);
  295. }
  296. explicit CarlaString(const float value)
  297. {
  298. char strBuf[0xff];
  299. std::snprintf(strBuf, 0xff, "%f", value);
  300. _init();
  301. _dup(strBuf);
  302. }
  303. explicit CarlaString(const double value)
  304. {
  305. char strBuf[0xff];
  306. std::snprintf(strBuf, 0xff, "%g", value);
  307. _init();
  308. _dup(strBuf);
  309. }
  310. // ---------------------------------------------
  311. // non-explicit constructor
  312. CarlaString(const CarlaString& str)
  313. {
  314. _init();
  315. _dup(str.buffer);
  316. }
  317. // ---------------------------------------------
  318. // deconstructor
  319. ~CarlaString()
  320. {
  321. CARLA_ASSERT(buffer);
  322. delete[] buffer;
  323. }
  324. // ---------------------------------------------
  325. // public methods
  326. size_t length() const
  327. {
  328. return bufferLen;
  329. }
  330. bool isEmpty() const
  331. {
  332. return (bufferLen == 0);
  333. }
  334. bool isNotEmpty() const
  335. {
  336. return (bufferLen != 0);
  337. }
  338. #if __USE_GNU
  339. bool contains(const char* const strBuf, const bool ignoreCase = false) const
  340. {
  341. if (strBuf == nullptr)
  342. return false;
  343. if (ignoreCase)
  344. return (strcasestr(buffer, strBuf) != nullptr);
  345. else
  346. return (std::strstr(buffer, strBuf) != nullptr);
  347. }
  348. bool contains(const CarlaString& str, const bool ignoreCase = false) const
  349. {
  350. return contains(str.buffer, ignoreCase);
  351. }
  352. #else
  353. bool contains(const char* const strBuf) const
  354. {
  355. if (strBuf == nullptr)
  356. return false;
  357. return (std::strstr(buffer, strBuf) != nullptr);
  358. }
  359. bool contains(const CarlaString& str) const
  360. {
  361. return contains(str.buffer);
  362. }
  363. #endif
  364. bool isDigit(const size_t pos) const
  365. {
  366. if (pos >= bufferLen)
  367. return false;
  368. return (buffer[pos] >= '0' && buffer[pos] <= '9');
  369. }
  370. void clear()
  371. {
  372. truncate(0);
  373. }
  374. void replace(const char before, const char after)
  375. {
  376. if (after == '\0')
  377. return;
  378. for (size_t i=0; i < bufferLen; i++)
  379. {
  380. if (buffer[i] == before)
  381. buffer[i] = after;
  382. else if (buffer[i] == '\0')
  383. break;
  384. }
  385. }
  386. void truncate(const size_t n)
  387. {
  388. if (n >= bufferLen)
  389. return;
  390. for (size_t i=n; i < bufferLen; i++)
  391. buffer[i] = '\0';
  392. bufferLen = n;
  393. }
  394. void toBasic()
  395. {
  396. for (size_t i=0; i < bufferLen; i++)
  397. {
  398. if (buffer[i] >= '0' && buffer[i] <= '9')
  399. continue;
  400. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  401. continue;
  402. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  403. continue;
  404. if (buffer[i] == '_')
  405. continue;
  406. buffer[i] = '_';
  407. }
  408. }
  409. void toLower()
  410. {
  411. static const char charDiff = 'a' - 'A';
  412. for (size_t i=0; i < bufferLen; i++)
  413. {
  414. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  415. buffer[i] += charDiff;
  416. }
  417. }
  418. void toUpper()
  419. {
  420. static const char charDiff = 'a' - 'A';
  421. for (size_t i=0; i < bufferLen; i++)
  422. {
  423. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  424. buffer[i] -= charDiff;
  425. }
  426. }
  427. // ---------------------------------------------
  428. // public operators
  429. operator const char*() const
  430. {
  431. return buffer;
  432. }
  433. char& operator[](const size_t pos)
  434. {
  435. return buffer[pos];
  436. }
  437. bool operator==(const char* const strBuf) const
  438. {
  439. return (strBuf != nullptr && std::strcmp(buffer, strBuf) == 0);
  440. }
  441. bool operator==(const CarlaString& str) const
  442. {
  443. return operator==(str.buffer);
  444. }
  445. bool operator!=(const char* const strBuf) const
  446. {
  447. return !operator==(strBuf);
  448. }
  449. bool operator!=(const CarlaString& str) const
  450. {
  451. return !operator==(str.buffer);
  452. }
  453. CarlaString& operator=(const char* const strBuf)
  454. {
  455. _dup(strBuf);
  456. return *this;
  457. }
  458. CarlaString& operator=(const CarlaString& str)
  459. {
  460. return operator=(str.buffer);
  461. }
  462. CarlaString& operator+=(const char* const strBuf)
  463. {
  464. const size_t newBufSize = bufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1;
  465. char newBuf[newBufSize];
  466. std::strcpy(newBuf, buffer);
  467. std::strcat(newBuf, strBuf);
  468. _dup(newBuf, newBufSize-1);
  469. return *this;
  470. }
  471. CarlaString& operator+=(const CarlaString& str)
  472. {
  473. return operator+=(str.buffer);
  474. }
  475. CarlaString operator+(const char* const strBuf)
  476. {
  477. const size_t newBufSize = bufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1;
  478. char newBuf[newBufSize];
  479. std::strcpy(newBuf, buffer);
  480. std::strcat(newBuf, strBuf);
  481. return CarlaString(newBuf);
  482. }
  483. CarlaString operator+(const CarlaString& str)
  484. {
  485. return operator+(str.buffer);
  486. }
  487. // ---------------------------------------------
  488. private:
  489. char* buffer;
  490. size_t bufferLen;
  491. bool firstInit;
  492. void _init()
  493. {
  494. buffer = nullptr;
  495. bufferLen = 0;
  496. firstInit = true;
  497. }
  498. // allocate string strBuf if not null
  499. // size > 0 only if strBuf is valid
  500. void _dup(const char* const strBuf, const size_t size = 0)
  501. {
  502. if (strBuf != nullptr)
  503. {
  504. // don't recreate string if contents match
  505. if (firstInit || std::strcmp(buffer, strBuf) != 0)
  506. {
  507. if (! firstInit)
  508. {
  509. CARLA_ASSERT(buffer);
  510. delete[] buffer;
  511. }
  512. bufferLen = (size > 0) ? size : std::strlen(strBuf);
  513. buffer = new char[bufferLen+1];
  514. std::strcpy(buffer, strBuf);
  515. buffer[bufferLen] = '\0';
  516. firstInit = false;
  517. }
  518. }
  519. else
  520. {
  521. CARLA_ASSERT(size == 0);
  522. // don't recreate null string
  523. if (firstInit || bufferLen != 0)
  524. {
  525. if (! firstInit)
  526. {
  527. CARLA_ASSERT(buffer);
  528. delete[] buffer;
  529. }
  530. bufferLen = 0;
  531. buffer = new char[1];
  532. buffer[0] = '\0';
  533. firstInit = false;
  534. }
  535. }
  536. }
  537. CARLA_LEAK_DETECTOR(CarlaString)
  538. CARLA_PREVENT_HEAP_ALLOCATION
  539. };
  540. static inline
  541. CarlaString operator+(const char* const strBufBefore, const CarlaString& strAfter)
  542. {
  543. const char* const strBufAfter = (const char*)strAfter;
  544. const size_t newBufSize = ((strBufBefore != nullptr) ? std::strlen(strBufBefore) : 0) + std::strlen(strBufAfter) + 1;
  545. char newBuf[newBufSize];
  546. std::strcpy(newBuf, strBufBefore);
  547. std::strcat(newBuf, strBufAfter);
  548. return CarlaString(newBuf);
  549. }
  550. // -------------------------------------------------
  551. #endif // __CARLA_UTILS_HPP__