diff --git a/include/flatbuffers/base.h b/include/flatbuffers/base.h index a0c78fc2a..26adcc961 100644 --- a/include/flatbuffers/base.h +++ b/include/flatbuffers/base.h @@ -134,7 +134,7 @@ (defined(__cpp_constexpr) && __cpp_constexpr >= 200704) #define FLATBUFFERS_CONSTEXPR constexpr #else - #define FLATBUFFERS_CONSTEXPR + #define FLATBUFFERS_CONSTEXPR const #endif #if (defined(__cplusplus) && __cplusplus >= 201402L) || \ diff --git a/include/flatbuffers/util.h b/include/flatbuffers/util.h index 1ebb971e5..7509676c4 100644 --- a/include/flatbuffers/util.h +++ b/include/flatbuffers/util.h @@ -17,41 +17,19 @@ #ifndef FLATBUFFERS_UTIL_H_ #define FLATBUFFERS_UTIL_H_ -// clang-format off +#include "flatbuffers/base.h" + +#include #ifndef FLATBUFFERS_PREFER_PRINTF # include -#else // FLATBUFFERS_PREFER_PRINTF +#else // FLATBUFFERS_PREFER_PRINTF # include # include -#endif // FLATBUFFERS_PREFER_PRINTF - -#ifdef _WIN32 -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# ifndef NOMINMAX -# define NOMINMAX -# endif -# include // Must be included before -# include -# include -# undef interface // This is also important because of reasons -#else -# include -#endif -// clang-format on - -#include -#include -#include -#include -#include +#endif // FLATBUFFERS_PREFER_PRINTF #include -#include - -#include "flatbuffers/base.h" +#include namespace flatbuffers { @@ -435,13 +413,7 @@ bool LoadFile(const char *name, bool binary, std::string *buf); // If "binary" is false data is written using ifstream's // text mode, otherwise data is written with no // transcoding. -inline bool SaveFile(const char *name, const char *buf, size_t len, - bool binary) { - std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out); - if (!ofs.is_open()) return false; - ofs.write(buf, len); - return !ofs.bad(); -} +bool SaveFile(const char *name, const char *buf, size_t len, bool binary); // Save data "buf" into file "name" returning true if // successful, false otherwise. If "binary" is false @@ -457,102 +429,35 @@ inline bool SaveFile(const char *name, const std::string &buf, bool binary) { // Windows ('/' or '\\') separators are used. // Any new separators inserted are always posix. - -// We internally store paths in posix format ('/'). Paths supplied -// by the user should go through PosixPath to ensure correct behavior -// on Windows when paths are string-compared. - -static const char kPathSeparator = '/'; -static const char kPathSeparatorWindows = '\\'; -static const char *PathSeparatorSet = "\\/"; // Intentionally no ':' +FLATBUFFERS_CONSTEXPR char kPathSeparator = '/'; // Returns the path with the extension, if any, removed. -inline std::string StripExtension(const std::string &filepath) { - size_t i = filepath.find_last_of("."); - return i != std::string::npos ? filepath.substr(0, i) : filepath; -} +std::string StripExtension(const std::string &filepath); // Returns the extension, if any. -inline std::string GetExtension(const std::string &filepath) { - size_t i = filepath.find_last_of("."); - return i != std::string::npos ? filepath.substr(i + 1) : ""; -} +std::string GetExtension(const std::string &filepath); // Return the last component of the path, after the last separator. -inline std::string StripPath(const std::string &filepath) { - size_t i = filepath.find_last_of(PathSeparatorSet); - return i != std::string::npos ? filepath.substr(i + 1) : filepath; -} +std::string StripPath(const std::string &filepath); // Strip the last component of the path + separator. -inline std::string StripFileName(const std::string &filepath) { - size_t i = filepath.find_last_of(PathSeparatorSet); - return i != std::string::npos ? filepath.substr(0, i) : ""; -} +std::string StripFileName(const std::string &filepath); // Concatenates a path with a filename, regardless of wether the path // ends in a separator or not. -inline std::string ConCatPathFileName(const std::string &path, - const std::string &filename) { - std::string filepath = path; - if (filepath.length()) { - char &filepath_last_character = string_back(filepath); - if (filepath_last_character == kPathSeparatorWindows) { - filepath_last_character = kPathSeparator; - } else if (filepath_last_character != kPathSeparator) { - filepath += kPathSeparator; - } - } - filepath += filename; - // Ignore './' at the start of filepath. - if (filepath[0] == '.' && filepath[1] == kPathSeparator) { - filepath.erase(0, 2); - } - return filepath; -} +std::string ConCatPathFileName(const std::string &path, + const std::string &filename); // Replaces any '\\' separators with '/' -inline std::string PosixPath(const char *path) { - std::string p = path; - std::replace(p.begin(), p.end(), '\\', '/'); - return p; -} +std::string PosixPath(const char *path); // This function ensure a directory exists, by recursively // creating dirs for any parts of the path that don't exist yet. -inline void EnsureDirExists(const std::string &filepath) { - auto parent = StripFileName(filepath); - if (parent.length()) EnsureDirExists(parent); - // clang-format off - - #ifdef _WIN32 - (void)_mkdir(filepath.c_str()); - #else - mkdir(filepath.c_str(), S_IRWXU|S_IRGRP|S_IXGRP); - #endif - // clang-format on -} +void EnsureDirExists(const std::string &filepath); // Obtains the absolute path from any other path. // Returns the input path if the absolute path couldn't be resolved. -inline std::string AbsolutePath(const std::string &filepath) { - // clang-format off - - #ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION - return filepath; - #else - #ifdef _WIN32 - char abs_path[MAX_PATH]; - return GetFullPathNameA(filepath.c_str(), MAX_PATH, abs_path, nullptr) - #else - char abs_path[PATH_MAX]; - return realpath(filepath.c_str(), abs_path) - #endif - ? abs_path - : filepath; - #endif // FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION - // clang-format on -} +std::string AbsolutePath(const std::string &filepath); // To and from UTF-8 unicode conversion functions diff --git a/src/util.cpp b/src/util.cpp index f652f0f26..c1bb1975c 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -14,10 +14,31 @@ * limitations under the License. */ -#include +// clang-format off +// Dont't remove `format off`, it prevent reordering of win-includes. +#ifdef _WIN32 +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include // Must be included before +# include +# include +# undef interface // This is also important because of reasons +#else +# include +#endif +// clang-format on +#include "flatbuffers/base.h" #include "flatbuffers/util.h" +#include +#include +#include + namespace flatbuffers { bool FileExistsRaw(const char *name) { @@ -88,6 +109,97 @@ FileExistsFunction SetFileExistsFunction( return previous_function; } +bool SaveFile(const char *name, const char *buf, size_t len, bool binary) { + std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out); + if (!ofs.is_open()) return false; + ofs.write(buf, len); + return !ofs.bad(); +} + +// We internally store paths in posix format ('/'). Paths supplied +// by the user should go through PosixPath to ensure correct behavior +// on Windows when paths are string-compared. + +static const char kPathSeparatorWindows = '\\'; +static const char *PathSeparatorSet = "\\/"; // Intentionally no ':' + +std::string StripExtension(const std::string &filepath) { + size_t i = filepath.find_last_of("."); + return i != std::string::npos ? filepath.substr(0, i) : filepath; +} + +std::string GetExtension(const std::string &filepath) { + size_t i = filepath.find_last_of("."); + return i != std::string::npos ? filepath.substr(i + 1) : ""; +} + +std::string StripPath(const std::string &filepath) { + size_t i = filepath.find_last_of(PathSeparatorSet); + return i != std::string::npos ? filepath.substr(i + 1) : filepath; +} + +std::string StripFileName(const std::string &filepath) { + size_t i = filepath.find_last_of(PathSeparatorSet); + return i != std::string::npos ? filepath.substr(0, i) : ""; +} + +std::string ConCatPathFileName(const std::string &path, + const std::string &filename) { + std::string filepath = path; + if (filepath.length()) { + char &filepath_last_character = string_back(filepath); + if (filepath_last_character == kPathSeparatorWindows) { + filepath_last_character = kPathSeparator; + } else if (filepath_last_character != kPathSeparator) { + filepath += kPathSeparator; + } + } + filepath += filename; + // Ignore './' at the start of filepath. + if (filepath[0] == '.' && filepath[1] == kPathSeparator) { + filepath.erase(0, 2); + } + return filepath; +} + +std::string PosixPath(const char *path) { + std::string p = path; + std::replace(p.begin(), p.end(), '\\', '/'); + return p; +} + +void EnsureDirExists(const std::string &filepath) { + auto parent = StripFileName(filepath); + if (parent.length()) EnsureDirExists(parent); + // clang-format off + + #ifdef _WIN32 + (void)_mkdir(filepath.c_str()); + #else + mkdir(filepath.c_str(), S_IRWXU|S_IRGRP|S_IXGRP); + #endif + // clang-format on +} + +std::string AbsolutePath(const std::string &filepath) { + // clang-format off + + #ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION + return filepath; + #else + #ifdef _WIN32 + char abs_path[MAX_PATH]; + return GetFullPathNameA(filepath.c_str(), MAX_PATH, abs_path, nullptr) + #else + char abs_path[PATH_MAX]; + return realpath(filepath.c_str(), abs_path) + #endif + ? abs_path + : filepath; + #endif // FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION + // clang-format on +} + // Locale-independent code. #if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && \ (FLATBUFFERS_LOCALE_INDEPENDENT > 0) @@ -123,11 +235,10 @@ bool SetGlobalTestLocale(const char *locale_name, std::string *_value) { if (_value) *_value = std::string(the_locale); return true; } - -#ifdef _MSC_VER -# pragma warning(disable : 4996) // _CRT_SECURE_NO_WARNINGS -#endif bool ReadEnvironmentVariable(const char *var_name, std::string *_value) { + #ifdef _MSC_VER + __pragma(warning(disable : 4996)); // _CRT_SECURE_NO_WARNINGS + #endif auto env_str = std::getenv(var_name); if (!env_str) return false; if (_value) *_value = std::string(env_str);