#include "filesystem_utils.hpp"
#include "platform_utils.hpp"
#include <cstring>
#include <string>
#if defined DISABLE_STD_FILESYSTEM
#define USE_EXPERIMENTAL_FS …
#define USE_FINAL_FS …
#else
#include "stdfs_conditions.h"
#endif
#if USE_FINAL_FS == 1
#include <filesystem>
#define FS_PREFIX …
#elif USE_EXPERIMENTAL_FS == 1
#include <experimental/filesystem>
#define FS_PREFIX …
#elif defined(XR_USE_PLATFORM_WIN32)
#include <stdint.h>
#include <direct.h>
#else
#include <sys/stat.h>
#include <unistd.h>
#include <limits.h>
#include <stdlib.h>
#include <dirent.h>
#endif
#if defined(XR_USE_PLATFORM_WIN32)
#define PATH_SEPARATOR …
#define DIRECTORY_SYMBOL …
#define ALTERNATE_DIRECTORY_SYMBOL …
#else
#define PATH_SEPARATOR …
#define DIRECTORY_SYMBOL …
#endif
#if (USE_FINAL_FS == 1) || (USE_EXPERIMENTAL_FS == 1)
bool FileSysUtilsIsRegularFile(const std::string& path) { return FS_PREFIX::is_regular_file(path); }
bool FileSysUtilsIsDirectory(const std::string& path) { return FS_PREFIX::is_directory(path); }
bool FileSysUtilsPathExists(const std::string& path) { return FS_PREFIX::exists(path); }
bool FileSysUtilsIsAbsolutePath(const std::string& path) {
FS_PREFIX::path file_path(path);
return file_path.is_absolute();
}
bool FileSysUtilsGetCurrentPath(std::string& path) {
FS_PREFIX::path cur_path = FS_PREFIX::current_path();
path = cur_path.string();
return true;
}
bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) {
FS_PREFIX::path path_var(file_path);
parent_path = path_var.parent_path().string();
return true;
}
bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) {
absolute = FS_PREFIX::absolute(path).string();
return true;
}
bool FileSysUtilsGetCanonicalPath(const std::string& path, std::string& canonical) {
#if defined(XR_USE_PLATFORM_WIN32)
canonical = path;
#else
canonical = FS_PREFIX::canonical(path).string();
#endif
return true;
}
bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) {
FS_PREFIX::path parent_path(parent);
FS_PREFIX::path child_path(child);
FS_PREFIX::path full_path = parent_path / child_path;
combined = full_path.string();
return true;
}
bool FileSysUtilsParsePathList(std::string& path_list, std::vector<std::string>& paths) {
std::string::size_type start = 0;
std::string::size_type location = path_list.find(PATH_SEPARATOR);
while (location != std::string::npos) {
paths.push_back(path_list.substr(start, location));
start = location + 1;
location = path_list.find(PATH_SEPARATOR, start);
}
paths.push_back(path_list.substr(start, location));
return true;
}
bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector<std::string>& files) {
for (auto& dir_iter : FS_PREFIX::directory_iterator(path)) {
files.push_back(dir_iter.path().filename().string());
}
return true;
}
#elif defined(XR_OS_WINDOWS)
bool FileSysUtilsIsRegularFile(const std::string& path) {
const DWORD attr = GetFileAttributesW(utf8_to_wide(path).c_str());
return attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY);
}
bool FileSysUtilsIsDirectory(const std::string& path) {
const DWORD attr = GetFileAttributesW(utf8_to_wide(path).c_str());
return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY);
}
bool FileSysUtilsPathExists(const std::string& path) {
return (GetFileAttributesW(utf8_to_wide(path).c_str()) != INVALID_FILE_ATTRIBUTES);
}
bool FileSysUtilsIsAbsolutePath(const std::string& path) {
bool pathStartsWithDir = (path.size() >= 1) && ((path[0] == DIRECTORY_SYMBOL) || (path[0] == ALTERNATE_DIRECTORY_SYMBOL));
bool pathStartsWithDrive =
(path.size() >= 3) && (path[1] == ':' && (path[2] == DIRECTORY_SYMBOL || path[2] == ALTERNATE_DIRECTORY_SYMBOL));
return pathStartsWithDir || pathStartsWithDrive;
}
bool FileSysUtilsGetCurrentPath(std::string& path) {
wchar_t tmp_path[MAX_PATH];
if (nullptr != _wgetcwd(tmp_path, MAX_PATH - 1)) {
path = wide_to_utf8(tmp_path);
return true;
}
return false;
}
bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) {
std::string full_path;
if (FileSysUtilsGetAbsolutePath(file_path, full_path)) {
std::string::size_type lastSeparator = full_path.find_last_of(DIRECTORY_SYMBOL);
parent_path = (lastSeparator == 0) ? full_path : full_path.substr(0, lastSeparator);
return true;
}
return false;
}
bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) {
wchar_t tmp_path[MAX_PATH];
if (0 != GetFullPathNameW(utf8_to_wide(path).c_str(), MAX_PATH, tmp_path, NULL)) {
absolute = wide_to_utf8(tmp_path);
return true;
}
return false;
}
bool FileSysUtilsGetCanonicalPath(const std::string& path, std::string& absolute) {
absolute = path;
return true;
}
bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) {
std::string::size_type parent_len = parent.length();
if (0 == parent_len || "." == parent || ".\\" == parent || "./" == parent) {
combined = child;
return true;
}
char last_char = parent[parent_len - 1];
if ((last_char == DIRECTORY_SYMBOL) || (last_char == ALTERNATE_DIRECTORY_SYMBOL)) {
parent_len--;
}
combined = parent.substr(0, parent_len) + DIRECTORY_SYMBOL + child;
return true;
}
bool FileSysUtilsParsePathList(std::string& path_list, std::vector<std::string>& paths) {
std::string::size_type start = 0;
std::string::size_type location = path_list.find(PATH_SEPARATOR);
while (location != std::string::npos) {
paths.push_back(path_list.substr(start, location));
start = location + 1;
location = path_list.find(PATH_SEPARATOR, start);
}
paths.push_back(path_list.substr(start, location));
return true;
}
bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector<std::string>& files) {
std::string searchPath;
FileSysUtilsCombinePaths(path, "*", searchPath);
WIN32_FIND_DATAW file_data;
HANDLE file_handle = FindFirstFileW(utf8_to_wide(searchPath).c_str(), &file_data);
if (file_handle != INVALID_HANDLE_VALUE) {
do {
if (!(file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
files.push_back(wide_to_utf8(file_data.cFileName));
}
} while (FindNextFileW(file_handle, &file_data));
return true;
}
return false;
}
#else
bool FileSysUtilsIsRegularFile(const std::string& path) { … }
bool FileSysUtilsIsDirectory(const std::string& path) { … }
bool FileSysUtilsPathExists(const std::string& path) { … }
bool FileSysUtilsIsAbsolutePath(const std::string& path) { … }
bool FileSysUtilsGetCurrentPath(std::string& path) { … }
bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) { … }
bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) { … }
bool FileSysUtilsGetCanonicalPath(const std::string& path, std::string& canonical) { … }
bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) { … }
bool FileSysUtilsParsePathList(std::string& path_list, std::vector<std::string>& paths) { … }
bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector<std::string>& files) { … }
#endif