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.

707 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. // carla_strdup
  113. static inline
  114. const char* carla_strdup(const char* const strBuf)
  115. {
  116. const size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0;
  117. char* const buffer = new char [bufferLen+1];
  118. std::strcpy(buffer, strBuf);
  119. buffer[bufferLen] = '\0';
  120. return buffer;
  121. }
  122. static inline
  123. const char* carla_strdup_free(const char* const strBuf)
  124. {
  125. const char* const buffer = carla_strdup(strBuf);
  126. std::free((void*)strBuf);
  127. return buffer;
  128. }
  129. // -------------------------------------------------
  130. // math functions
  131. template<typename T>
  132. static inline
  133. const T& carla_min(const T& v1, const T& v2, const T& min)
  134. {
  135. return ((v1 < min || v2 < min) ? min : (v1 < v2 ? v1 : v2));
  136. }
  137. template<typename T>
  138. static inline
  139. const T& carla_fixValue(const T& min, const T& max, const T& value)
  140. {
  141. if (value < min)
  142. return min;
  143. if (value > max)
  144. return max;
  145. return value;
  146. }
  147. template<typename T>
  148. static inline
  149. void carla_fill(T* data, const unsigned int size, const T v)
  150. {
  151. CARLA_ASSERT(data != nullptr);
  152. CARLA_ASSERT(size > 0);
  153. if (data == nullptr)
  154. return;
  155. for (unsigned int i=0; i < size; i++)
  156. *data++ = v;
  157. }
  158. static inline
  159. void carla_zeroDouble(double* data, const unsigned size)
  160. {
  161. carla_fill<double>(data, size, 0.0);
  162. }
  163. static inline
  164. void carla_zeroFloat(float* data, const unsigned size)
  165. {
  166. carla_fill<float>(data, size, 0.0f);
  167. }
  168. // -------------------------------------------------
  169. // memory functions
  170. static inline
  171. void carla_zeroMem(void* const memory, const size_t numBytes)
  172. {
  173. CARLA_ASSERT(memory != nullptr);
  174. if (memory == nullptr)
  175. return;
  176. std::memset(memory, 0, numBytes);
  177. }
  178. template <typename T>
  179. static inline
  180. void carla_zeroStruct(T& structure)
  181. {
  182. std::memset(&structure, 0, sizeof(T));
  183. }
  184. // -------------------------------------------------
  185. // other misc functions
  186. static inline
  187. const char* bool2str(const bool yesNo)
  188. {
  189. return yesNo ? "true" : "false";
  190. }
  191. static inline
  192. void pass() {}
  193. // -------------------------------------------------
  194. // CarlaMutex class
  195. class CarlaMutex
  196. {
  197. public:
  198. CarlaMutex()
  199. {
  200. #ifndef CPP11_MUTEX
  201. pthread_mutex_init(&pmutex, nullptr);
  202. #endif
  203. }
  204. ~CarlaMutex()
  205. {
  206. #ifndef CPP11_MUTEX
  207. pthread_mutex_destroy(&pmutex);
  208. #endif
  209. }
  210. void lock()
  211. {
  212. #ifdef CPP11_MUTEX
  213. cmutex.lock();
  214. #else
  215. pthread_mutex_lock(&pmutex);
  216. #endif
  217. }
  218. bool tryLock()
  219. {
  220. #ifdef CPP11_MUTEX
  221. return cmutex.try_lock();
  222. #else
  223. return (pthread_mutex_trylock(&pmutex) == 0);
  224. #endif
  225. }
  226. void unlock()
  227. {
  228. #ifdef CPP11_MUTEX
  229. cmutex.unlock();
  230. #else
  231. pthread_mutex_unlock(&pmutex);
  232. #endif
  233. }
  234. class ScopedLocker
  235. {
  236. public:
  237. ScopedLocker(CarlaMutex* const mutex)
  238. : fMutex(mutex)
  239. {
  240. fMutex->lock();
  241. }
  242. ~ScopedLocker()
  243. {
  244. fMutex->unlock();
  245. }
  246. private:
  247. CarlaMutex* const fMutex;
  248. CARLA_PREVENT_HEAP_ALLOCATION
  249. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ScopedLocker)
  250. };
  251. private:
  252. #ifdef CPP11_MUTEX
  253. std::mutex cmutex;
  254. #else
  255. pthread_mutex_t pmutex;
  256. #endif
  257. CARLA_PREVENT_HEAP_ALLOCATION
  258. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaMutex)
  259. };
  260. // -------------------------------------------------
  261. // CarlaString class
  262. class CarlaString
  263. {
  264. public:
  265. // ---------------------------------------------
  266. // constructors (no explicit conversions allowed)
  267. explicit CarlaString()
  268. {
  269. _init();
  270. _dup(nullptr);
  271. }
  272. explicit CarlaString(char* const strBuf)
  273. {
  274. _init();
  275. _dup(strBuf);
  276. }
  277. explicit CarlaString(const char* const strBuf)
  278. {
  279. _init();
  280. _dup(strBuf);
  281. }
  282. explicit CarlaString(const int value)
  283. {
  284. const size_t strBufSize = std::abs(value/10) + 3;
  285. char strBuf[strBufSize];
  286. std::snprintf(strBuf, strBufSize, "%d", value);
  287. _init();
  288. _dup(strBuf, strBufSize);
  289. }
  290. explicit CarlaString(const unsigned int value, const bool hexadecimal = false)
  291. {
  292. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  293. char strBuf[strBufSize];
  294. std::snprintf(strBuf, strBufSize, hexadecimal ? "0x%x" : "%u", value);
  295. _init();
  296. _dup(strBuf, strBufSize);
  297. }
  298. explicit CarlaString(const long int value)
  299. {
  300. const size_t strBufSize = std::abs(value/10) + 3;
  301. char strBuf[strBufSize];
  302. std::snprintf(strBuf, strBufSize, "%ld", value);
  303. _init();
  304. _dup(strBuf, strBufSize);
  305. }
  306. explicit CarlaString(const unsigned long int value, const bool hexadecimal = false)
  307. {
  308. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  309. char strBuf[strBufSize];
  310. std::snprintf(strBuf, strBufSize, hexadecimal ? "0x%lx" : "%lu", value);
  311. _init();
  312. _dup(strBuf, strBufSize);
  313. }
  314. explicit CarlaString(const float value)
  315. {
  316. char strBuf[0xff];
  317. std::snprintf(strBuf, 0xff, "%f", value);
  318. _init();
  319. _dup(strBuf);
  320. }
  321. explicit CarlaString(const double value)
  322. {
  323. char strBuf[0xff];
  324. std::snprintf(strBuf, 0xff, "%g", value);
  325. _init();
  326. _dup(strBuf);
  327. }
  328. // ---------------------------------------------
  329. // non-explicit constructor
  330. CarlaString(const CarlaString& str)
  331. {
  332. _init();
  333. _dup(str.buffer);
  334. }
  335. // ---------------------------------------------
  336. // deconstructor
  337. ~CarlaString()
  338. {
  339. CARLA_ASSERT(buffer);
  340. delete[] buffer;
  341. }
  342. // ---------------------------------------------
  343. // public methods
  344. size_t length() const
  345. {
  346. return bufferLen;
  347. }
  348. bool isEmpty() const
  349. {
  350. return (bufferLen == 0);
  351. }
  352. bool isNotEmpty() const
  353. {
  354. return (bufferLen != 0);
  355. }
  356. #if __USE_GNU
  357. bool contains(const char* const strBuf, const bool ignoreCase = false) const
  358. {
  359. if (strBuf == nullptr)
  360. return false;
  361. if (ignoreCase)
  362. return (strcasestr(buffer, strBuf) != nullptr);
  363. else
  364. return (std::strstr(buffer, strBuf) != nullptr);
  365. }
  366. bool contains(const CarlaString& str, const bool ignoreCase = false) const
  367. {
  368. return contains(str.buffer, ignoreCase);
  369. }
  370. #else
  371. bool contains(const char* const strBuf) const
  372. {
  373. if (strBuf == nullptr)
  374. return false;
  375. return (std::strstr(buffer, strBuf) != nullptr);
  376. }
  377. bool contains(const CarlaString& str) const
  378. {
  379. return contains(str.buffer);
  380. }
  381. #endif
  382. bool isDigit(const size_t pos) const
  383. {
  384. if (pos >= bufferLen)
  385. return false;
  386. return (buffer[pos] >= '0' && buffer[pos] <= '9');
  387. }
  388. void clear()
  389. {
  390. truncate(0);
  391. }
  392. void replace(const char before, const char after)
  393. {
  394. if (after == '\0')
  395. return;
  396. for (size_t i=0; i < bufferLen; i++)
  397. {
  398. if (buffer[i] == before)
  399. buffer[i] = after;
  400. else if (buffer[i] == '\0')
  401. break;
  402. }
  403. }
  404. void truncate(const size_t n)
  405. {
  406. if (n >= bufferLen)
  407. return;
  408. for (size_t i=n; i < bufferLen; i++)
  409. buffer[i] = '\0';
  410. bufferLen = n;
  411. }
  412. void toBasic()
  413. {
  414. for (size_t i=0; i < bufferLen; i++)
  415. {
  416. if (buffer[i] >= '0' && buffer[i] <= '9')
  417. continue;
  418. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  419. continue;
  420. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  421. continue;
  422. if (buffer[i] == '_')
  423. continue;
  424. buffer[i] = '_';
  425. }
  426. }
  427. void toLower()
  428. {
  429. static const char charDiff = 'a' - 'A';
  430. for (size_t i=0; i < bufferLen; i++)
  431. {
  432. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  433. buffer[i] += charDiff;
  434. }
  435. }
  436. void toUpper()
  437. {
  438. static const char charDiff = 'a' - 'A';
  439. for (size_t i=0; i < bufferLen; i++)
  440. {
  441. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  442. buffer[i] -= charDiff;
  443. }
  444. }
  445. // ---------------------------------------------
  446. // public operators
  447. operator const char*() const
  448. {
  449. return buffer;
  450. }
  451. char& operator[](const size_t pos)
  452. {
  453. return buffer[pos];
  454. }
  455. bool operator==(const char* const strBuf) const
  456. {
  457. return (strBuf != nullptr && std::strcmp(buffer, strBuf) == 0);
  458. }
  459. bool operator==(const CarlaString& str) const
  460. {
  461. return operator==(str.buffer);
  462. }
  463. bool operator!=(const char* const strBuf) const
  464. {
  465. return !operator==(strBuf);
  466. }
  467. bool operator!=(const CarlaString& str) const
  468. {
  469. return !operator==(str.buffer);
  470. }
  471. CarlaString& operator=(const char* const strBuf)
  472. {
  473. _dup(strBuf);
  474. return *this;
  475. }
  476. CarlaString& operator=(const CarlaString& str)
  477. {
  478. return operator=(str.buffer);
  479. }
  480. CarlaString& operator+=(const char* const strBuf)
  481. {
  482. const size_t newBufSize = bufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1;
  483. char newBuf[newBufSize];
  484. std::strcpy(newBuf, buffer);
  485. std::strcat(newBuf, strBuf);
  486. _dup(newBuf, newBufSize-1);
  487. return *this;
  488. }
  489. CarlaString& operator+=(const CarlaString& str)
  490. {
  491. return operator+=(str.buffer);
  492. }
  493. CarlaString operator+(const char* const strBuf)
  494. {
  495. const size_t newBufSize = bufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1;
  496. char newBuf[newBufSize];
  497. std::strcpy(newBuf, buffer);
  498. std::strcat(newBuf, strBuf);
  499. return CarlaString(newBuf);
  500. }
  501. CarlaString operator+(const CarlaString& str)
  502. {
  503. return operator+(str.buffer);
  504. }
  505. // ---------------------------------------------
  506. private:
  507. char* buffer;
  508. size_t bufferLen;
  509. bool firstInit;
  510. void _init()
  511. {
  512. buffer = nullptr;
  513. bufferLen = 0;
  514. firstInit = true;
  515. }
  516. // allocate string strBuf if not null
  517. // size > 0 only if strBuf is valid
  518. void _dup(const char* const strBuf, const size_t size = 0)
  519. {
  520. if (strBuf != nullptr)
  521. {
  522. // don't recreate string if contents match
  523. if (firstInit || std::strcmp(buffer, strBuf) != 0)
  524. {
  525. if (! firstInit)
  526. {
  527. CARLA_ASSERT(buffer);
  528. delete[] buffer;
  529. }
  530. bufferLen = (size > 0) ? size : std::strlen(strBuf);
  531. buffer = new char[bufferLen+1];
  532. std::strcpy(buffer, strBuf);
  533. buffer[bufferLen] = '\0';
  534. firstInit = false;
  535. }
  536. }
  537. else
  538. {
  539. CARLA_ASSERT(size == 0);
  540. // don't recreate null string
  541. if (firstInit || bufferLen != 0)
  542. {
  543. if (! firstInit)
  544. {
  545. CARLA_ASSERT(buffer);
  546. delete[] buffer;
  547. }
  548. bufferLen = 0;
  549. buffer = new char[1];
  550. buffer[0] = '\0';
  551. firstInit = false;
  552. }
  553. }
  554. }
  555. CARLA_LEAK_DETECTOR(CarlaString)
  556. CARLA_PREVENT_HEAP_ALLOCATION
  557. };
  558. static inline
  559. CarlaString operator+(const char* const strBufBefore, const CarlaString& strAfter)
  560. {
  561. const char* const strBufAfter = (const char*)strAfter;
  562. const size_t newBufSize = ((strBufBefore != nullptr) ? std::strlen(strBufBefore) : 0) + std::strlen(strBufAfter) + 1;
  563. char newBuf[newBufSize];
  564. std::strcpy(newBuf, strBufBefore);
  565. std::strcat(newBuf, strBufAfter);
  566. return CarlaString(newBuf);
  567. }
  568. // -------------------------------------------------
  569. #endif // __CARLA_UTILS_HPP__