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.

920 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 (pthreadId != 0)
  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(pthreadId == 0);
  312. if (pthreadId != 0)
  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 (pthreadId == 0)
  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 (pthreadId == 0)
  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. }
  425. void _zero()
  426. {
  427. carla_zeroStruct<pthread_t>(pthreadId);
  428. }
  429. #endif
  430. CARLA_PREVENT_HEAP_ALLOCATION
  431. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaThread)
  432. };
  433. // -------------------------------------------------
  434. // CarlaString class
  435. class CarlaString
  436. {
  437. public:
  438. // ---------------------------------------------
  439. // constructors (no explicit conversions allowed)
  440. explicit CarlaString()
  441. {
  442. _init();
  443. _dup(nullptr);
  444. }
  445. explicit CarlaString(char* const strBuf)
  446. {
  447. _init();
  448. _dup(strBuf);
  449. }
  450. explicit CarlaString(const char* const strBuf)
  451. {
  452. _init();
  453. _dup(strBuf);
  454. }
  455. explicit CarlaString(const int value)
  456. {
  457. const size_t strBufSize = std::abs(value/10) + 3;
  458. char strBuf[strBufSize];
  459. std::snprintf(strBuf, strBufSize, "%d", value);
  460. _init();
  461. _dup(strBuf, strBufSize);
  462. }
  463. explicit CarlaString(const unsigned int value, const bool hexadecimal = false)
  464. {
  465. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  466. char strBuf[strBufSize];
  467. std::snprintf(strBuf, strBufSize, hexadecimal ? "0x%x" : "%u", value);
  468. _init();
  469. _dup(strBuf, strBufSize);
  470. }
  471. explicit CarlaString(const long int value)
  472. {
  473. const size_t strBufSize = std::abs(value/10) + 3;
  474. char strBuf[strBufSize];
  475. std::snprintf(strBuf, strBufSize, "%ld", value);
  476. _init();
  477. _dup(strBuf, strBufSize);
  478. }
  479. explicit CarlaString(const unsigned long int value, const bool hexadecimal = false)
  480. {
  481. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  482. char strBuf[strBufSize];
  483. std::snprintf(strBuf, strBufSize, hexadecimal ? "0x%lx" : "%lu", value);
  484. _init();
  485. _dup(strBuf, strBufSize);
  486. }
  487. explicit CarlaString(const float value)
  488. {
  489. char strBuf[0xff];
  490. std::snprintf(strBuf, 0xff, "%f", value);
  491. _init();
  492. _dup(strBuf);
  493. }
  494. explicit CarlaString(const double value)
  495. {
  496. char strBuf[0xff];
  497. std::snprintf(strBuf, 0xff, "%g", value);
  498. _init();
  499. _dup(strBuf);
  500. }
  501. // ---------------------------------------------
  502. // non-explicit constructor
  503. CarlaString(const CarlaString& str)
  504. {
  505. _init();
  506. _dup(str.buffer);
  507. }
  508. // ---------------------------------------------
  509. // deconstructor
  510. ~CarlaString()
  511. {
  512. CARLA_ASSERT(buffer);
  513. delete[] buffer;
  514. }
  515. // ---------------------------------------------
  516. // public methods
  517. size_t length() const
  518. {
  519. return bufferLen;
  520. }
  521. bool isEmpty() const
  522. {
  523. return (bufferLen == 0);
  524. }
  525. bool isNotEmpty() const
  526. {
  527. return (bufferLen != 0);
  528. }
  529. #if __USE_GNU
  530. bool contains(const char* const strBuf, const bool ignoreCase = false) const
  531. {
  532. if (strBuf == nullptr)
  533. return false;
  534. if (ignoreCase)
  535. return (strcasestr(buffer, strBuf) != nullptr);
  536. else
  537. return (std::strstr(buffer, strBuf) != nullptr);
  538. }
  539. bool contains(const CarlaString& str, const bool ignoreCase = false) const
  540. {
  541. return contains(str.buffer, ignoreCase);
  542. }
  543. #else
  544. bool contains(const char* const strBuf) const
  545. {
  546. if (strBuf == nullptr)
  547. return false;
  548. return (std::strstr(buffer, strBuf) != nullptr);
  549. }
  550. bool contains(const CarlaString& str) const
  551. {
  552. return contains(str.buffer);
  553. }
  554. #endif
  555. bool isDigit(const size_t pos) const
  556. {
  557. if (pos >= bufferLen)
  558. return false;
  559. return (buffer[pos] >= '0' && buffer[pos] <= '9');
  560. }
  561. void clear()
  562. {
  563. truncate(0);
  564. }
  565. void replace(const char before, const char after)
  566. {
  567. if (after == '\0')
  568. return;
  569. for (size_t i=0; i < bufferLen; i++)
  570. {
  571. if (buffer[i] == before)
  572. buffer[i] = after;
  573. else if (buffer[i] == '\0')
  574. break;
  575. }
  576. }
  577. void truncate(const size_t n)
  578. {
  579. if (n >= bufferLen)
  580. return;
  581. for (size_t i=n; i < bufferLen; i++)
  582. buffer[i] = '\0';
  583. bufferLen = n;
  584. }
  585. void toBasic()
  586. {
  587. for (size_t i=0; i < bufferLen; i++)
  588. {
  589. if (buffer[i] >= '0' && buffer[i] <= '9')
  590. continue;
  591. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  592. continue;
  593. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  594. continue;
  595. if (buffer[i] == '_')
  596. continue;
  597. buffer[i] = '_';
  598. }
  599. }
  600. void toLower()
  601. {
  602. static const char charDiff = 'a' - 'A';
  603. for (size_t i=0; i < bufferLen; i++)
  604. {
  605. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  606. buffer[i] += charDiff;
  607. }
  608. }
  609. void toUpper()
  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. // ---------------------------------------------
  619. // public operators
  620. operator const char*() const
  621. {
  622. return buffer;
  623. }
  624. char& operator[](const size_t pos)
  625. {
  626. return buffer[pos];
  627. }
  628. bool operator==(const char* const strBuf) const
  629. {
  630. return (strBuf != nullptr && std::strcmp(buffer, strBuf) == 0);
  631. }
  632. bool operator==(const CarlaString& str) const
  633. {
  634. return operator==(str.buffer);
  635. }
  636. bool operator!=(const char* const strBuf) const
  637. {
  638. return !operator==(strBuf);
  639. }
  640. bool operator!=(const CarlaString& str) const
  641. {
  642. return !operator==(str.buffer);
  643. }
  644. CarlaString& operator=(const char* const strBuf)
  645. {
  646. _dup(strBuf);
  647. return *this;
  648. }
  649. CarlaString& operator=(const CarlaString& str)
  650. {
  651. return operator=(str.buffer);
  652. }
  653. CarlaString& operator+=(const char* const strBuf)
  654. {
  655. const size_t newBufSize = bufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1;
  656. char newBuf[newBufSize];
  657. std::strcpy(newBuf, buffer);
  658. std::strcat(newBuf, strBuf);
  659. _dup(newBuf, newBufSize-1);
  660. return *this;
  661. }
  662. CarlaString& operator+=(const CarlaString& str)
  663. {
  664. return operator+=(str.buffer);
  665. }
  666. CarlaString operator+(const char* const strBuf)
  667. {
  668. const size_t newBufSize = bufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1;
  669. char newBuf[newBufSize];
  670. std::strcpy(newBuf, buffer);
  671. std::strcat(newBuf, strBuf);
  672. return CarlaString(newBuf);
  673. }
  674. CarlaString operator+(const CarlaString& str)
  675. {
  676. return operator+(str.buffer);
  677. }
  678. // ---------------------------------------------
  679. private:
  680. char* buffer;
  681. size_t bufferLen;
  682. bool firstInit;
  683. void _init()
  684. {
  685. buffer = nullptr;
  686. bufferLen = 0;
  687. firstInit = true;
  688. }
  689. // allocate string strBuf if not null
  690. // size > 0 only if strBuf is valid
  691. void _dup(const char* const strBuf, const size_t size = 0)
  692. {
  693. if (strBuf != nullptr)
  694. {
  695. // don't recreate string if contents match
  696. if (firstInit || std::strcmp(buffer, strBuf) != 0)
  697. {
  698. if (! firstInit)
  699. {
  700. CARLA_ASSERT(buffer);
  701. delete[] buffer;
  702. }
  703. bufferLen = (size > 0) ? size : std::strlen(strBuf);
  704. buffer = new char[bufferLen+1];
  705. std::strcpy(buffer, strBuf);
  706. buffer[bufferLen] = '\0';
  707. firstInit = false;
  708. }
  709. }
  710. else
  711. {
  712. CARLA_ASSERT(size == 0);
  713. // don't recreate null string
  714. if (firstInit || bufferLen != 0)
  715. {
  716. if (! firstInit)
  717. {
  718. CARLA_ASSERT(buffer);
  719. delete[] buffer;
  720. }
  721. bufferLen = 0;
  722. buffer = new char[1];
  723. buffer[0] = '\0';
  724. firstInit = false;
  725. }
  726. }
  727. }
  728. CARLA_LEAK_DETECTOR(CarlaString)
  729. CARLA_PREVENT_HEAP_ALLOCATION
  730. };
  731. static inline
  732. CarlaString operator+(const char* const strBufBefore, const CarlaString& strAfter)
  733. {
  734. const char* const strBufAfter = (const char*)strAfter;
  735. const size_t newBufSize = ((strBufBefore != nullptr) ? std::strlen(strBufBefore) : 0) + std::strlen(strBufAfter) + 1;
  736. char newBuf[newBufSize];
  737. std::strcpy(newBuf, strBufBefore);
  738. std::strcat(newBuf, strBufAfter);
  739. return CarlaString(newBuf);
  740. }
  741. // -------------------------------------------------
  742. #endif // __CARLA_UTILS_HPP__