| 
							- // Copyright 2021 Jean Pierre Cimalando
 - //
 - // Licensed under the Apache License, Version 2.0 (the "License");
 - // you may not use this file except in compliance with the License.
 - // You may obtain a copy of the License at
 - //
 - //     http://www.apache.org/licenses/LICENSE-2.0
 - //
 - // Unless required by applicable law or agreed to in writing, software
 - // distributed under the License is distributed on an "AS IS" BASIS,
 - // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 - // See the License for the specific language governing permissions and
 - // limitations under the License.
 - //
 - // SPDX-License-Identifier: Apache-2.0
 - //
 - 
 - #pragma once
 - #include "ysfx.h"
 - #include <string>
 - #include <vector>
 - #include <mutex>
 - #include <cstdio>
 - #include <cstdint>
 - #include <clocale>
 - #if defined(__APPLE__)
 - #   include <xlocale.h>
 - #endif
 - #if !defined(_WIN32) && !defined(__FreeBSD__)
 - #   include <alloca.h>
 - #else
 - #   include <malloc.h>
 - #endif
 - 
 - #if defined(YSFX_NO_STANDARD_MUTEX)
 - #   include "WDL/mutex.h"
 - #endif
 - 
 - namespace ysfx {
 - 
 - YSFX_DEFINE_AUTO_PTR(FILE_u, FILE, fclose);
 - 
 - FILE *fopen_utf8(const char *path, const char *mode);
 - int64_t fseek_lfs(FILE *stream, int64_t off, int whence);
 - int64_t ftell_lfs(FILE *stream);
 - 
 - //------------------------------------------------------------------------------
 - 
 - #if !defined(_WIN32)
 - using c_locale_t = locale_t;
 - #else
 - using c_locale_t = _locale_t;
 - #endif
 - 
 - c_locale_t c_numeric_locale();
 - 
 - //------------------------------------------------------------------------------
 - 
 - #if !defined(_WIN32)
 - #   define ysfx_alloca(n) alloca((n))
 - #else
 - #   define ysfx_alloca(n) _malloca((n))
 - #endif
 - 
 - //------------------------------------------------------------------------------
 - 
 - #if !defined(YSFX_NO_STANDARD_MUTEX)
 - using mutex = std::mutex;
 - #else
 - class mutex
 - {
 - public:
 -     void lock() { m_mutex.Enter(); }
 -     void unlock() { m_mutex.Leave(); }
 - 
 - private:
 -     WDL_Mutex m_mutex;
 - };
 - #endif
 - 
 - //------------------------------------------------------------------------------
 - 
 - using string_list = std::vector<std::string>;
 - 
 - double c_atof(const char *text, c_locale_t loc);
 - double c_strtod(const char *text, char **endp, c_locale_t loc);
 - double dot_atof(const char *text);
 - double dot_strtod(const char *text, char **endp);
 - bool ascii_isspace(char c);
 - bool ascii_isalpha(char c);
 - char ascii_tolower(char c);
 - char ascii_toupper(char c);
 - int ascii_casecmp(const char *a, const char *b);
 - uint32_t latin1_toupper(uint32_t c);
 - uint32_t latin1_tolower(uint32_t c);
 - char *strdup_using_new(const char *src);
 - string_list split_strings_noempty(const char *input, bool(*pred)(char));
 - std::string trim(const char *input, bool(*pred)(char));
 - 
 - //------------------------------------------------------------------------------
 - 
 - void pack_u32le(uint32_t value, uint8_t data[4]);
 - void pack_f32le(float value, uint8_t data[4]);
 - uint32_t unpack_u32le(const uint8_t data[4]);
 - float unpack_f32le(const uint8_t data[4]);
 - 
 - //------------------------------------------------------------------------------
 - 
 - std::vector<uint8_t> decode_base64(const char *text, size_t len = ~(size_t)0);
 - std::string encode_base64(const uint8_t *data, size_t len);
 - 
 - //------------------------------------------------------------------------------
 - 
 - using file_uid = std::pair<uint64_t, uint64_t>;
 - bool get_file_uid(const char *path, file_uid &uid);
 - bool get_stream_file_uid(FILE *stream, file_uid &uid);
 - bool get_descriptor_file_uid(int fd, file_uid &uid);
 - #if defined(_WIN32)
 - bool get_handle_file_uid(void *handle, file_uid &uid);
 - #endif
 - 
 - //------------------------------------------------------------------------------
 - 
 - struct split_path_t {
 -     std::string drive;
 -     std::string dir;
 -     std::string file;
 - };
 - 
 - // check if the character is a path separator
 - bool is_path_separator(char ch);
 - // break down a path into individual components
 - split_path_t split_path(const char *path);
 - // get the file name part (all after the final '/' separator)
 - std::string path_file_name(const char *path);
 - // get the directory part (all up to the '/' separator, inclusive)
 - std::string path_directory(const char *path);
 - // add the final '/' separator if absent; if empty, does nothing
 - std::string path_ensure_final_separator(const char *path);
 - // compare the tail of the path with the suffix, case-insensitively
 - bool path_has_suffix(const char *path, const char *suffix);
 - // check whether the path is relative
 - bool path_is_relative(const char *path);
 - 
 - //------------------------------------------------------------------------------
 - 
 - // check whether a file exists on disk
 - bool exists(const char *path);
 - // list the elements of a directory; directories are distinguished with a final '/'
 - string_list list_directory(const char *path);
 - // visit the root and subdirectories in depth-first order
 - void visit_directories(const char *rootpath, bool (*visit)(const std::string &, void *), void *data);
 - // resolve a path which matches root/fragment, where fragment is case-insensitive (0=failed, 1=exact, 2=inexact)
 - int case_resolve(const char *root, const char *fragment, std::string &result);
 - 
 - //------------------------------------------------------------------------------
 - 
 - #if defined(_WIN32)
 - std::wstring widen(const std::string &u8str);
 - std::wstring widen(const char *u8data, size_t u8len = ~(size_t)0);
 - std::string narrow(const std::wstring &wstr);
 - std::string narrow(const wchar_t *wdata, size_t wlen = ~(size_t)0);
 - #endif
 - 
 - //------------------------------------------------------------------------------
 - 
 - template <class F>
 - class scope_guard {
 - public:
 -     explicit scope_guard(F &&f) : f(std::forward<F>(f)), a(true) {}
 -     scope_guard(scope_guard &&o) : f(std::move(o.f)), a(o.a) { o.a = false; }
 -     ~scope_guard() { if (a) f(); }
 -     void disarm() { a = false; }
 - private:
 -     F f;
 -     bool a;
 -     scope_guard(const scope_guard &) = delete;
 -     scope_guard &operator=(const scope_guard &) = delete;
 - };
 - 
 - template <class F> scope_guard<F> defer(F &&f)
 - {
 -     return scope_guard<F>(std::forward<F>(f));
 - }
 - 
 - } // namespace ysfx
 
 
  |