Add initial bits for Qt6 support
[carla.git] / source / modules / ysfx / sources / ysfx_utils.hpp
blob86a4dc63645f777814a74eb428d47c6bc5aaa606
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.
15 // SPDX-License-Identifier: Apache-2.0
18 #pragma once
19 #include "ysfx.h"
20 #include <string>
21 #include <vector>
22 #include <mutex>
23 #include <cstdio>
24 #include <cstdint>
25 #include <clocale>
26 #if defined(__APPLE__)
27 # include <xlocale.h>
28 #endif
29 #if !defined(_WIN32) && !defined(__FreeBSD__)
30 # include <alloca.h>
31 #else
32 # include <malloc.h>
33 #endif
35 #if defined(YSFX_NO_STANDARD_MUTEX)
36 # include "WDL/mutex.h"
37 #endif
39 namespace ysfx {
41 YSFX_DEFINE_AUTO_PTR(FILE_u, FILE, fclose);
43 FILE *fopen_utf8(const char *path, const char *mode);
44 int64_t fseek_lfs(FILE *stream, int64_t off, int whence);
45 int64_t ftell_lfs(FILE *stream);
47 //------------------------------------------------------------------------------
49 #if !defined(_WIN32)
50 using c_locale_t = locale_t;
51 #else
52 using c_locale_t = _locale_t;
53 #endif
55 c_locale_t c_numeric_locale();
57 //------------------------------------------------------------------------------
59 #if !defined(_WIN32)
60 # define ysfx_alloca(n) alloca((n))
61 #else
62 # define ysfx_alloca(n) _malloca((n))
63 #endif
65 //------------------------------------------------------------------------------
67 #if !defined(YSFX_NO_STANDARD_MUTEX)
68 using mutex = std::mutex;
69 #else
70 class mutex
72 public:
73 void lock() { m_mutex.Enter(); }
74 void unlock() { m_mutex.Leave(); }
76 private:
77 WDL_Mutex m_mutex;
79 #endif
81 //------------------------------------------------------------------------------
83 using string_list = std::vector<std::string>;
85 double c_atof(const char *text, c_locale_t loc);
86 double c_strtod(const char *text, char **endp, c_locale_t loc);
87 double dot_atof(const char *text);
88 double dot_strtod(const char *text, char **endp);
89 bool ascii_isspace(char c);
90 bool ascii_isalpha(char c);
91 char ascii_tolower(char c);
92 char ascii_toupper(char c);
93 int ascii_casecmp(const char *a, const char *b);
94 uint32_t latin1_toupper(uint32_t c);
95 uint32_t latin1_tolower(uint32_t c);
96 char *strdup_using_new(const char *src);
97 string_list split_strings_noempty(const char *input, bool(*pred)(char));
98 std::string trim(const char *input, bool(*pred)(char));
100 //------------------------------------------------------------------------------
102 void pack_u32le(uint32_t value, uint8_t data[4]);
103 void pack_f32le(float value, uint8_t data[4]);
104 uint32_t unpack_u32le(const uint8_t data[4]);
105 float unpack_f32le(const uint8_t data[4]);
107 //------------------------------------------------------------------------------
109 std::vector<uint8_t> decode_base64(const char *text, size_t len = ~(size_t)0);
110 std::string encode_base64(const uint8_t *data, size_t len);
112 //------------------------------------------------------------------------------
114 using file_uid = std::pair<uint64_t, uint64_t>;
115 bool get_file_uid(const char *path, file_uid &uid);
116 bool get_stream_file_uid(FILE *stream, file_uid &uid);
117 bool get_descriptor_file_uid(int fd, file_uid &uid);
118 #if defined(_WIN32)
119 bool get_handle_file_uid(void *handle, file_uid &uid);
120 #endif
122 //------------------------------------------------------------------------------
124 struct split_path_t {
125 std::string drive;
126 std::string dir;
127 std::string file;
130 // check if the character is a path separator
131 bool is_path_separator(char ch);
132 // break down a path into individual components
133 split_path_t split_path(const char *path);
134 // get the file name part (all after the final '/' separator)
135 std::string path_file_name(const char *path);
136 // get the directory part (all up to the '/' separator, inclusive)
137 std::string path_directory(const char *path);
138 // add the final '/' separator if absent; if empty, does nothing
139 std::string path_ensure_final_separator(const char *path);
140 // compare the tail of the path with the suffix, case-insensitively
141 bool path_has_suffix(const char *path, const char *suffix);
142 // check whether the path is relative
143 bool path_is_relative(const char *path);
145 //------------------------------------------------------------------------------
147 // check whether a file exists on disk
148 bool exists(const char *path);
149 // list the elements of a directory; directories are distinguished with a final '/'
150 string_list list_directory(const char *path);
151 // visit the root and subdirectories in depth-first order
152 void visit_directories(const char *rootpath, bool (*visit)(const std::string &, void *), void *data);
153 // resolve a path which matches root/fragment, where fragment is case-insensitive (0=failed, 1=exact, 2=inexact)
154 int case_resolve(const char *root, const char *fragment, std::string &result);
156 //------------------------------------------------------------------------------
158 #if defined(_WIN32)
159 std::wstring widen(const std::string &u8str);
160 std::wstring widen(const char *u8data, size_t u8len = ~(size_t)0);
161 std::string narrow(const std::wstring &wstr);
162 std::string narrow(const wchar_t *wdata, size_t wlen = ~(size_t)0);
163 #endif
165 //------------------------------------------------------------------------------
167 template <class F>
168 class scope_guard {
169 public:
170 explicit scope_guard(F &&f) : f(std::forward<F>(f)), a(true) {}
171 scope_guard(scope_guard &&o) : f(std::move(o.f)), a(o.a) { o.a = false; }
172 ~scope_guard() { if (a) f(); }
173 void disarm() { a = false; }
174 private:
175 F f;
176 bool a;
177 scope_guard(const scope_guard &) = delete;
178 scope_guard &operator=(const scope_guard &) = delete;
181 template <class F> scope_guard<F> defer(F &&f)
183 return scope_guard<F>(std::forward<F>(f));
186 } // namespace ysfx