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.

ysfx_utils.hpp 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. // Copyright 2021 Jean Pierre Cimalando
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. // SPDX-License-Identifier: Apache-2.0
  16. //
  17. #pragma once
  18. #include "ysfx.h"
  19. #include <string>
  20. #include <vector>
  21. #include <mutex>
  22. #include <cstdio>
  23. #include <cstdint>
  24. #include <clocale>
  25. #if defined(__APPLE__)
  26. # include <xlocale.h>
  27. #endif
  28. #if !defined(_WIN32) && !defined(__FreeBSD__)
  29. # include <alloca.h>
  30. #else
  31. # include <malloc.h>
  32. #endif
  33. #if defined(YSFX_NO_STANDARD_MUTEX)
  34. # include "WDL/mutex.h"
  35. #endif
  36. namespace ysfx {
  37. YSFX_DEFINE_AUTO_PTR(FILE_u, FILE, fclose);
  38. FILE *fopen_utf8(const char *path, const char *mode);
  39. int64_t fseek_lfs(FILE *stream, int64_t off, int whence);
  40. int64_t ftell_lfs(FILE *stream);
  41. //------------------------------------------------------------------------------
  42. #if !defined(_WIN32)
  43. using c_locale_t = locale_t;
  44. #else
  45. using c_locale_t = _locale_t;
  46. #endif
  47. c_locale_t c_numeric_locale();
  48. //------------------------------------------------------------------------------
  49. #if !defined(_WIN32)
  50. # define ysfx_alloca(n) alloca((n))
  51. #else
  52. # define ysfx_alloca(n) _malloca((n))
  53. #endif
  54. //------------------------------------------------------------------------------
  55. #if !defined(YSFX_NO_STANDARD_MUTEX)
  56. using mutex = std::mutex;
  57. #else
  58. class mutex
  59. {
  60. public:
  61. void lock() { m_mutex.Enter(); }
  62. void unlock() { m_mutex.Leave(); }
  63. private:
  64. WDL_Mutex m_mutex;
  65. };
  66. #endif
  67. //------------------------------------------------------------------------------
  68. using string_list = std::vector<std::string>;
  69. double c_atof(const char *text, c_locale_t loc);
  70. double c_strtod(const char *text, char **endp, c_locale_t loc);
  71. double dot_atof(const char *text);
  72. double dot_strtod(const char *text, char **endp);
  73. bool ascii_isspace(char c);
  74. bool ascii_isalpha(char c);
  75. char ascii_tolower(char c);
  76. char ascii_toupper(char c);
  77. int ascii_casecmp(const char *a, const char *b);
  78. uint32_t latin1_toupper(uint32_t c);
  79. uint32_t latin1_tolower(uint32_t c);
  80. char *strdup_using_new(const char *src);
  81. string_list split_strings_noempty(const char *input, bool(*pred)(char));
  82. std::string trim(const char *input, bool(*pred)(char));
  83. //------------------------------------------------------------------------------
  84. void pack_u32le(uint32_t value, uint8_t data[4]);
  85. void pack_f32le(float value, uint8_t data[4]);
  86. uint32_t unpack_u32le(const uint8_t data[4]);
  87. float unpack_f32le(const uint8_t data[4]);
  88. //------------------------------------------------------------------------------
  89. std::vector<uint8_t> decode_base64(const char *text, size_t len = ~(size_t)0);
  90. std::string encode_base64(const uint8_t *data, size_t len);
  91. //------------------------------------------------------------------------------
  92. using file_uid = std::pair<uint64_t, uint64_t>;
  93. bool get_file_uid(const char *path, file_uid &uid);
  94. bool get_stream_file_uid(FILE *stream, file_uid &uid);
  95. bool get_descriptor_file_uid(int fd, file_uid &uid);
  96. #if defined(_WIN32)
  97. bool get_handle_file_uid(void *handle, file_uid &uid);
  98. #endif
  99. //------------------------------------------------------------------------------
  100. struct split_path_t {
  101. std::string drive;
  102. std::string dir;
  103. std::string file;
  104. };
  105. // check if the character is a path separator
  106. bool is_path_separator(char ch);
  107. // break down a path into individual components
  108. split_path_t split_path(const char *path);
  109. // get the file name part (all after the final '/' separator)
  110. std::string path_file_name(const char *path);
  111. // get the directory part (all up to the '/' separator, inclusive)
  112. std::string path_directory(const char *path);
  113. // add the final '/' separator if absent; if empty, does nothing
  114. std::string path_ensure_final_separator(const char *path);
  115. // compare the tail of the path with the suffix, case-insensitively
  116. bool path_has_suffix(const char *path, const char *suffix);
  117. // check whether the path is relative
  118. bool path_is_relative(const char *path);
  119. //------------------------------------------------------------------------------
  120. // check whether a file exists on disk
  121. bool exists(const char *path);
  122. // list the elements of a directory; directories are distinguished with a final '/'
  123. string_list list_directory(const char *path);
  124. // visit the root and subdirectories in depth-first order
  125. void visit_directories(const char *rootpath, bool (*visit)(const std::string &, void *), void *data);
  126. // resolve a path which matches root/fragment, where fragment is case-insensitive (0=failed, 1=exact, 2=inexact)
  127. int case_resolve(const char *root, const char *fragment, std::string &result);
  128. //------------------------------------------------------------------------------
  129. #if defined(_WIN32)
  130. std::wstring widen(const std::string &u8str);
  131. std::wstring widen(const char *u8data, size_t u8len = ~(size_t)0);
  132. std::string narrow(const std::wstring &wstr);
  133. std::string narrow(const wchar_t *wdata, size_t wlen = ~(size_t)0);
  134. #endif
  135. //------------------------------------------------------------------------------
  136. template <class F>
  137. class scope_guard {
  138. public:
  139. explicit scope_guard(F &&f) : f(std::forward<F>(f)), a(true) {}
  140. scope_guard(scope_guard &&o) : f(std::move(o.f)), a(o.a) { o.a = false; }
  141. ~scope_guard() { if (a) f(); }
  142. void disarm() { a = false; }
  143. private:
  144. F f;
  145. bool a;
  146. scope_guard(const scope_guard &) = delete;
  147. scope_guard &operator=(const scope_guard &) = delete;
  148. };
  149. template <class F> scope_guard<F> defer(F &&f)
  150. {
  151. return scope_guard<F>(std::forward<F>(f));
  152. }
  153. } // namespace ysfx