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.

930 lines
19KB

  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. // #define CPP11_MUTEX
  24. #ifdef CPP11_MUTEX
  25. # include <mutex>
  26. # include <thread>
  27. #else
  28. # include <pthread.h>
  29. #endif
  30. #if defined(Q_OS_HAIKU)
  31. # include <kernel/OS.h>
  32. #elif defined(Q_OS_LINUX)
  33. # include <sys/prctl.h>
  34. # include <linux/prctl.h>
  35. #endif
  36. // -------------------------------------------------
  37. // carla_assert*
  38. static inline
  39. void carla_assert(const char* const assertion, const char* const file, const int line)
  40. {
  41. qCritical("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
  42. }
  43. static inline
  44. void carla_assert_int(const char* const assertion, const char* const file, const int line, const int value)
  45. {
  46. qCritical("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
  47. }
  48. static inline
  49. void carla_assert_int2(const char* const assertion, const char* const file, const int line, const int v1, const int v2)
  50. {
  51. qCritical("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2);
  52. }
  53. // -------------------------------------------------
  54. // carla_*sleep
  55. static inline
  56. void carla_sleep(const unsigned int secs)
  57. {
  58. CARLA_ASSERT(secs > 0);
  59. #ifdef Q_OS_WIN
  60. Sleep(secs * 1000);
  61. #else
  62. sleep(secs);
  63. #endif
  64. }
  65. static inline
  66. void carla_msleep(const unsigned int msecs)
  67. {
  68. CARLA_ASSERT(msecs > 0);
  69. #ifdef Q_OS_WIN
  70. Sleep(msecs);
  71. #else
  72. usleep(msecs * 1000);
  73. #endif
  74. }
  75. static inline
  76. void carla_usleep(const unsigned int usecs)
  77. {
  78. CARLA_ASSERT(usecs > 0);
  79. #ifdef Q_OS_WIN
  80. Sleep(usecs / 1000);
  81. #else
  82. usleep(usecs);
  83. #endif
  84. }
  85. // -------------------------------------------------
  86. // carla_setenv
  87. static inline
  88. void carla_setenv(const char* const key, const char* const value)
  89. {
  90. CARLA_ASSERT(key != nullptr);
  91. CARLA_ASSERT(value != nullptr);
  92. #ifdef Q_OS_WIN
  93. SetEnvironmentVariableA(key, value);
  94. #else
  95. setenv(key, value, 1);
  96. #endif
  97. }
  98. // -------------------------------------------------
  99. // carla_setprocname (not available on all platforms)
  100. static inline
  101. void carla_setprocname(const char* const name)
  102. {
  103. CARLA_ASSERT(name != nullptr);
  104. #if defined(Q_OS_HAIKU)
  105. if ((thread_id this_thread = find_thread(nullptr)) != B_NAME_NOT_FOUND)
  106. rename_thread(this_thread, name);
  107. #elif defined(Q_OS_LINUX)
  108. prctl(PR_SET_NAME, name);
  109. #else
  110. qWarning("carla_setprocname(\"%s\") - unsupported on this platform", name);
  111. #endif
  112. }
  113. // -------------------------------------------------
  114. // carla_strdup
  115. static inline
  116. const char* carla_strdup(const char* const strBuf)
  117. {
  118. const size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0;
  119. char* const buffer = new char [bufferLen+1];
  120. std::strcpy(buffer, strBuf);
  121. buffer[bufferLen] = '\0';
  122. return buffer;
  123. }
  124. static inline
  125. const char* carla_strdup_free(const char* const strBuf)
  126. {
  127. const char* const buffer = carla_strdup(strBuf);
  128. std::free((void*)strBuf);
  129. return buffer;
  130. }
  131. // -------------------------------------------------
  132. // math functions
  133. template<typename T>
  134. static inline
  135. const T& carla_min(const T& v1, const T& v2, const T& min)
  136. {
  137. return ((v1 < min || v2 < min) ? min : (v1 < v2 ? v1 : v2));
  138. }
  139. template<typename T>
  140. static inline
  141. const T& carla_fixValue(const T& min, const T& max, const T& value)
  142. {
  143. if (value < min)
  144. return min;
  145. if (value > max)
  146. return max;
  147. return value;
  148. }
  149. template<typename T>
  150. static inline
  151. void carla_fill(T* data, const unsigned int size, const T v)
  152. {
  153. CARLA_ASSERT(data != nullptr);
  154. CARLA_ASSERT(size > 0);
  155. if (data == nullptr)
  156. return;
  157. for (unsigned int i=0; i < size; i++)
  158. *data++ = v;
  159. }
  160. static inline
  161. void carla_zeroDouble(double* data, const unsigned size)
  162. {
  163. carla_fill<double>(data, size, 0.0);
  164. }
  165. static inline
  166. void carla_zeroFloat(float* data, const unsigned size)
  167. {
  168. carla_fill<float>(data, size, 0.0f);
  169. }
  170. // -------------------------------------------------
  171. // memory functions
  172. static inline
  173. void carla_zeroMem(void* const memory, const size_t numBytes)
  174. {
  175. CARLA_ASSERT(memory != nullptr);
  176. if (memory == nullptr)
  177. return;
  178. std::memset(memory, 0, numBytes);
  179. }
  180. template <typename T>
  181. static inline
  182. void carla_zeroStruct(T& structure)
  183. {
  184. std::memset(&structure, 0, sizeof(T));
  185. }
  186. // -------------------------------------------------
  187. // other misc functions
  188. static inline
  189. const char* bool2str(const bool yesNo)
  190. {
  191. return yesNo ? "true" : "false";
  192. }
  193. static inline
  194. void pass() {}
  195. // -------------------------------------------------
  196. // CarlaMutex class
  197. class CarlaMutex
  198. {
  199. public:
  200. CarlaMutex()
  201. {
  202. #ifndef CPP11_MUTEX
  203. pthread_mutex_init(&pmutex, nullptr);
  204. #endif
  205. }
  206. ~CarlaMutex()
  207. {
  208. #ifndef CPP11_MUTEX
  209. pthread_mutex_destroy(&pmutex);
  210. #endif
  211. }
  212. void lock()
  213. {
  214. #ifdef CPP11_MUTEX
  215. cmutex.lock();
  216. #else
  217. pthread_mutex_lock(&pmutex);
  218. #endif
  219. }
  220. bool tryLock()
  221. {
  222. #ifdef CPP11_MUTEX
  223. return cmutex.try_lock();
  224. #else
  225. return (pthread_mutex_trylock(&pmutex) == 0);
  226. #endif
  227. }
  228. void unlock()
  229. {
  230. #ifdef CPP11_MUTEX
  231. cmutex.unlock();
  232. #else
  233. pthread_mutex_unlock(&pmutex);
  234. #endif
  235. }
  236. class ScopedLocker
  237. {
  238. public:
  239. ScopedLocker(CarlaMutex* const mutex)
  240. : fMutex(mutex)
  241. {
  242. fMutex->lock();
  243. }
  244. ~ScopedLocker()
  245. {
  246. fMutex->unlock();
  247. }
  248. private:
  249. CarlaMutex* const fMutex;
  250. CARLA_PREVENT_HEAP_ALLOCATION
  251. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ScopedLocker)
  252. };
  253. private:
  254. #ifdef CPP11_MUTEX
  255. std::mutex cmutex;
  256. #else
  257. pthread_mutex_t pmutex;
  258. #endif
  259. CARLA_PREVENT_HEAP_ALLOCATION
  260. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaMutex)
  261. };
  262. // -------------------------------------------------
  263. // CarlaThread class
  264. class CarlaThread
  265. {
  266. public:
  267. CarlaThread()
  268. : fStarted(false),
  269. fFinished(false)
  270. {
  271. #ifdef CPP11_MUTEX
  272. cthread = nullptr;
  273. #else
  274. _zero();
  275. pthread_attr_init(&pthreadAttr);
  276. pthread_attr_setdetachstate(&pthreadAttr, PTHREAD_CREATE_JOINABLE);
  277. #endif
  278. }
  279. ~CarlaThread()
  280. {
  281. CARLA_ASSERT(! isRunning());
  282. if (isRunning())
  283. terminate();
  284. #ifdef CPP11_MUTEX
  285. if (cthread != nullptr)
  286. {
  287. cthread->join();
  288. delete cthread;
  289. }
  290. #else
  291. if (! _isNull())
  292. pthread_join(pthreadId, nullptr);
  293. pthread_attr_destroy(&pthreadAttr);
  294. #endif
  295. }
  296. bool start()
  297. {
  298. CARLA_ASSERT(! isRunning());
  299. if (isRunning())
  300. return false;
  301. fStarted = false;
  302. fFinished = false;
  303. #ifdef CPP11_MUTEX
  304. CARLA_ASSERT(cthread == nullptr);
  305. if (cthread != nullptr)
  306. return false;
  307. cthread = new std::thread(_cthreadRoutine, this);
  308. CARLA_ASSERT(cthread->joinable());
  309. return true;
  310. #else
  311. CARLA_ASSERT(_isNull());
  312. if (! _isNull())
  313. return false;
  314. return (pthread_create(&pthreadId, &pthreadAttr, _pthreadRoutine, this) == 0);
  315. #endif
  316. }
  317. bool stop(const unsigned int timeout = 0)
  318. {
  319. CARLA_ASSERT(isRunning());
  320. if (! isRunning())
  321. return true;
  322. #ifdef CPP11_MUTEX
  323. if (cthread == nullptr)
  324. return true;
  325. #else
  326. if (_isNull())
  327. return true;
  328. #endif
  329. if (timeout == 0)
  330. {
  331. #ifdef CPP11_MUTEX
  332. cthread->join();
  333. #else
  334. pthread_join(pthreadId, nullptr);
  335. #endif
  336. }
  337. else
  338. {
  339. for (unsigned int i=0; i < timeout && ! fFinished; i++)
  340. carla_msleep(1);
  341. }
  342. if (! fFinished)
  343. return false;
  344. #ifdef CPP11_MUTEX
  345. delete cthread;
  346. cthread = nullptr;
  347. #else
  348. _zero();
  349. #endif
  350. return true;
  351. }
  352. void terminate()
  353. {
  354. CARLA_ASSERT(isRunning());
  355. if (fFinished)
  356. return;
  357. #ifdef CPP11_MUTEX
  358. if (cthread == nullptr)
  359. return;
  360. #else
  361. if (_isNull())
  362. return;
  363. #endif
  364. #ifdef CPP11_MUTEX
  365. cthread->detach();
  366. //cthread->join();
  367. delete cthread;
  368. cthread = nullptr;
  369. #else
  370. pthread_detach(pthreadId);
  371. //pthread_join(pthreadId, nullptr);
  372. pthread_cancel(pthreadId);
  373. _zero();
  374. #endif
  375. fFinished = true;
  376. }
  377. bool isRunning()
  378. {
  379. return (fStarted && ! fFinished);
  380. }
  381. void waitForStarted(const unsigned int timeout = 0) // ms
  382. {
  383. if (fStarted)
  384. return;
  385. if (timeout == 0)
  386. {
  387. while (! fStarted) {}
  388. }
  389. else
  390. {
  391. for (unsigned int i=0; i < timeout && ! fStarted; i++)
  392. carla_msleep(1);
  393. }
  394. }
  395. void waitForFinished()
  396. {
  397. waitForStarted();
  398. stop(0);
  399. }
  400. protected:
  401. virtual void run() = 0;
  402. private:
  403. bool fStarted;
  404. bool fFinished;
  405. void handleRoutine()
  406. {
  407. fStarted = true;
  408. run();
  409. fFinished = true;
  410. }
  411. #ifdef CPP11_MUTEX
  412. std::thread* cthread;
  413. static void _cthreadRoutine(CarlaThread* const _this_)
  414. {
  415. _this_->handleRoutine();
  416. }
  417. #else
  418. pthread_t pthreadId;
  419. pthread_attr_t pthreadAttr;
  420. static void* _pthreadRoutine(void* const _this_)
  421. {
  422. ((CarlaThread*)_this_)->handleRoutine();
  423. pthread_exit(nullptr);
  424. return nullptr;
  425. }
  426. bool _isNull()
  427. {
  428. #ifdef Q_OS_WIN
  429. return pthreadId.p == nullptr;
  430. #else
  431. return pthreadId == 0;
  432. #endif
  433. }
  434. void _zero()
  435. {
  436. carla_zeroStruct<pthread_t>(pthreadId);
  437. }
  438. #endif
  439. CARLA_PREVENT_HEAP_ALLOCATION
  440. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaThread)
  441. };
  442. // -------------------------------------------------
  443. // CarlaString class
  444. class CarlaString
  445. {
  446. public:
  447. // ---------------------------------------------
  448. // constructors (no explicit conversions allowed)
  449. explicit CarlaString()
  450. {
  451. _init();
  452. _dup(nullptr);
  453. }
  454. explicit CarlaString(char* const strBuf)
  455. {
  456. _init();
  457. _dup(strBuf);
  458. }
  459. explicit CarlaString(const char* const strBuf)
  460. {
  461. _init();
  462. _dup(strBuf);
  463. }
  464. explicit CarlaString(const int value)
  465. {
  466. const size_t strBufSize = std::abs(value/10) + 3;
  467. char strBuf[strBufSize];
  468. std::snprintf(strBuf, strBufSize, "%d", value);
  469. _init();
  470. _dup(strBuf, strBufSize);
  471. }
  472. explicit CarlaString(const unsigned int value, const bool hexadecimal = false)
  473. {
  474. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  475. char strBuf[strBufSize];
  476. std::snprintf(strBuf, strBufSize, hexadecimal ? "0x%x" : "%u", value);
  477. _init();
  478. _dup(strBuf, strBufSize);
  479. }
  480. explicit CarlaString(const long int value)
  481. {
  482. const size_t strBufSize = std::abs(value/10) + 3;
  483. char strBuf[strBufSize];
  484. std::snprintf(strBuf, strBufSize, "%ld", value);
  485. _init();
  486. _dup(strBuf, strBufSize);
  487. }
  488. explicit CarlaString(const unsigned long int value, const bool hexadecimal = false)
  489. {
  490. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  491. char strBuf[strBufSize];
  492. std::snprintf(strBuf, strBufSize, hexadecimal ? "0x%lx" : "%lu", value);
  493. _init();
  494. _dup(strBuf, strBufSize);
  495. }
  496. explicit CarlaString(const float value)
  497. {
  498. char strBuf[0xff];
  499. std::snprintf(strBuf, 0xff, "%f", value);
  500. _init();
  501. _dup(strBuf);
  502. }
  503. explicit CarlaString(const double value)
  504. {
  505. char strBuf[0xff];
  506. std::snprintf(strBuf, 0xff, "%g", value);
  507. _init();
  508. _dup(strBuf);
  509. }
  510. // ---------------------------------------------
  511. // non-explicit constructor
  512. CarlaString(const CarlaString& str)
  513. {
  514. _init();
  515. _dup(str.buffer);
  516. }
  517. // ---------------------------------------------
  518. // deconstructor
  519. ~CarlaString()
  520. {
  521. CARLA_ASSERT(buffer);
  522. delete[] buffer;
  523. }
  524. // ---------------------------------------------
  525. // public methods
  526. size_t length() const
  527. {
  528. return bufferLen;
  529. }
  530. bool isEmpty() const
  531. {
  532. return (bufferLen == 0);
  533. }
  534. bool isNotEmpty() const
  535. {
  536. return (bufferLen != 0);
  537. }
  538. #if __USE_GNU
  539. bool contains(const char* const strBuf, const bool ignoreCase = false) const
  540. {
  541. if (strBuf == nullptr)
  542. return false;
  543. if (ignoreCase)
  544. return (strcasestr(buffer, strBuf) != nullptr);
  545. else
  546. return (std::strstr(buffer, strBuf) != nullptr);
  547. }
  548. bool contains(const CarlaString& str, const bool ignoreCase = false) const
  549. {
  550. return contains(str.buffer, ignoreCase);
  551. }
  552. #else
  553. bool contains(const char* const strBuf) const
  554. {
  555. if (strBuf == nullptr)
  556. return false;
  557. return (std::strstr(buffer, strBuf) != nullptr);
  558. }
  559. bool contains(const CarlaString& str) const
  560. {
  561. return contains(str.buffer);
  562. }
  563. #endif
  564. bool isDigit(const size_t pos) const
  565. {
  566. if (pos >= bufferLen)
  567. return false;
  568. return (buffer[pos] >= '0' && buffer[pos] <= '9');
  569. }
  570. void clear()
  571. {
  572. truncate(0);
  573. }
  574. void replace(const char before, const char after)
  575. {
  576. if (after == '\0')
  577. return;
  578. for (size_t i=0; i < bufferLen; i++)
  579. {
  580. if (buffer[i] == before)
  581. buffer[i] = after;
  582. else if (buffer[i] == '\0')
  583. break;
  584. }
  585. }
  586. void truncate(const size_t n)
  587. {
  588. if (n >= bufferLen)
  589. return;
  590. for (size_t i=n; i < bufferLen; i++)
  591. buffer[i] = '\0';
  592. bufferLen = n;
  593. }
  594. void toBasic()
  595. {
  596. for (size_t i=0; i < bufferLen; i++)
  597. {
  598. if (buffer[i] >= '0' && buffer[i] <= '9')
  599. continue;
  600. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  601. continue;
  602. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  603. continue;
  604. if (buffer[i] == '_')
  605. continue;
  606. buffer[i] = '_';
  607. }
  608. }
  609. void toLower()
  610. {
  611. static const char charDiff = 'a' - 'A';
  612. for (size_t i=0; i < bufferLen; i++)
  613. {
  614. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  615. buffer[i] += charDiff;
  616. }
  617. }
  618. void toUpper()
  619. {
  620. static const char charDiff = 'a' - 'A';
  621. for (size_t i=0; i < bufferLen; i++)
  622. {
  623. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  624. buffer[i] -= charDiff;
  625. }
  626. }
  627. // ---------------------------------------------
  628. // public operators
  629. operator const char*() const
  630. {
  631. return buffer;
  632. }
  633. char& operator[](const size_t pos)
  634. {
  635. return buffer[pos];
  636. }
  637. bool operator==(const char* const strBuf) const
  638. {
  639. return (strBuf != nullptr && std::strcmp(buffer, strBuf) == 0);
  640. }
  641. bool operator==(const CarlaString& str) const
  642. {
  643. return operator==(str.buffer);
  644. }
  645. bool operator!=(const char* const strBuf) const
  646. {
  647. return !operator==(strBuf);
  648. }
  649. bool operator!=(const CarlaString& str) const
  650. {
  651. return !operator==(str.buffer);
  652. }
  653. CarlaString& operator=(const char* const strBuf)
  654. {
  655. _dup(strBuf);
  656. return *this;
  657. }
  658. CarlaString& operator=(const CarlaString& str)
  659. {
  660. return operator=(str.buffer);
  661. }
  662. CarlaString& operator+=(const char* const strBuf)
  663. {
  664. const size_t newBufSize = bufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1;
  665. char newBuf[newBufSize];
  666. std::strcpy(newBuf, buffer);
  667. std::strcat(newBuf, strBuf);
  668. _dup(newBuf, newBufSize-1);
  669. return *this;
  670. }
  671. CarlaString& operator+=(const CarlaString& str)
  672. {
  673. return operator+=(str.buffer);
  674. }
  675. CarlaString operator+(const char* const strBuf)
  676. {
  677. const size_t newBufSize = bufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1;
  678. char newBuf[newBufSize];
  679. std::strcpy(newBuf, buffer);
  680. std::strcat(newBuf, strBuf);
  681. return CarlaString(newBuf);
  682. }
  683. CarlaString operator+(const CarlaString& str)
  684. {
  685. return operator+(str.buffer);
  686. }
  687. // ---------------------------------------------
  688. private:
  689. char* buffer;
  690. size_t bufferLen;
  691. bool firstInit;
  692. void _init()
  693. {
  694. buffer = nullptr;
  695. bufferLen = 0;
  696. firstInit = true;
  697. }
  698. // allocate string strBuf if not null
  699. // size > 0 only if strBuf is valid
  700. void _dup(const char* const strBuf, const size_t size = 0)
  701. {
  702. if (strBuf != nullptr)
  703. {
  704. // don't recreate string if contents match
  705. if (firstInit || std::strcmp(buffer, strBuf) != 0)
  706. {
  707. if (! firstInit)
  708. {
  709. CARLA_ASSERT(buffer);
  710. delete[] buffer;
  711. }
  712. bufferLen = (size > 0) ? size : std::strlen(strBuf);
  713. buffer = new char[bufferLen+1];
  714. std::strcpy(buffer, strBuf);
  715. buffer[bufferLen] = '\0';
  716. firstInit = false;
  717. }
  718. }
  719. else
  720. {
  721. CARLA_ASSERT(size == 0);
  722. // don't recreate null string
  723. if (firstInit || bufferLen != 0)
  724. {
  725. if (! firstInit)
  726. {
  727. CARLA_ASSERT(buffer);
  728. delete[] buffer;
  729. }
  730. bufferLen = 0;
  731. buffer = new char[1];
  732. buffer[0] = '\0';
  733. firstInit = false;
  734. }
  735. }
  736. }
  737. CARLA_LEAK_DETECTOR(CarlaString)
  738. CARLA_PREVENT_HEAP_ALLOCATION
  739. };
  740. static inline
  741. CarlaString operator+(const char* const strBufBefore, const CarlaString& strAfter)
  742. {
  743. const char* const strBufAfter = (const char*)strAfter;
  744. const size_t newBufSize = ((strBufBefore != nullptr) ? std::strlen(strBufBefore) : 0) + std::strlen(strBufAfter) + 1;
  745. char newBuf[newBufSize];
  746. std::strcpy(newBuf, strBufBefore);
  747. std::strcat(newBuf, strBufAfter);
  748. return CarlaString(newBuf);
  749. }
  750. // -------------------------------------------------
  751. #endif // __CARLA_UTILS_HPP__