From 59f46ad530e95751860e530e1b40048b7556ae99 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Feb 2025 14:58:41 +0300 Subject: [PATCH] add io::path.normalized() --- src/io/devices/StdfsDevice.cpp | 4 ++-- src/io/engine_paths.cpp | 26 -------------------------- src/io/engine_paths.hpp | 6 ------ src/io/path.cpp | 29 ++++++++++++++++++++++++++++- src/io/path.hpp | 9 +++++++++ 5 files changed, 39 insertions(+), 35 deletions(-) diff --git a/src/io/devices/StdfsDevice.cpp b/src/io/devices/StdfsDevice.cpp index f9598e6f..ad33547d 100644 --- a/src/io/devices/StdfsDevice.cpp +++ b/src/io/devices/StdfsDevice.cpp @@ -23,7 +23,7 @@ StdfsDevice::StdfsDevice(fs::path root, bool createDirectory) } fs::path StdfsDevice::resolve(std::string_view path) { - return root / fs::u8path(path); + return root / fs::u8path(io::path(std::string(path)).normalized().string()); } void StdfsDevice::write(std::string_view path, const void* data, size_t size) { @@ -123,5 +123,5 @@ private: }; std::unique_ptr StdfsDevice::list(std::string_view path) { - return std::make_unique(root / fs::u8path(path)); + return std::make_unique(resolve(path)); } diff --git a/src/io/engine_paths.cpp b/src/io/engine_paths.cpp index 5a0f0cb6..76485031 100644 --- a/src/io/engine_paths.cpp +++ b/src/io/engine_paths.cpp @@ -25,32 +25,6 @@ static inline io::path EXPORT_FOLDER = "export"; static inline io::path CONTROLS_FILE = "controls.toml"; static inline io::path SETTINGS_FILE = "settings.toml"; -static io::path toCanonic(io::path path) { - std::stack parts; - - path = std::filesystem::u8path(path.string()).lexically_normal().string(); - do { - parts.push(path.name()); - path = path.parent(); - } while (!path.empty()); - - path = ""; - - while (!parts.empty()) { - const std::string part = parts.top(); - parts.pop(); - if (part == ".") { - continue; - } - if (part == "..") { - throw files_access_error("entry point reached"); - } - - path = path / part; - } - return path; -} - void EnginePaths::prepare() { io::set_device("res", std::make_shared(resourcesFolder, false)); io::set_device("user", std::make_shared(userFilesFolder)); diff --git a/src/io/engine_paths.hpp b/src/io/engine_paths.hpp index 4858a215..65e5e067 100644 --- a/src/io/engine_paths.hpp +++ b/src/io/engine_paths.hpp @@ -10,12 +10,6 @@ #include "data/dv.hpp" #include "content/ContentPack.hpp" -class files_access_error : public std::runtime_error { -public: - files_access_error(const std::string& msg) : std::runtime_error(msg) { - } -}; - class EnginePaths { public: void prepare(); diff --git a/src/io/path.cpp b/src/io/path.cpp index e1dd5a98..08333c34 100644 --- a/src/io/path.cpp +++ b/src/io/path.cpp @@ -1,6 +1,6 @@ #include "path.hpp" -#include +#include using namespace io; @@ -9,3 +9,30 @@ void path::checkValid() const { throw std::runtime_error("path entry point is not specified: " + str); } } + +path path::normalized() const { + io::path path = pathPart(); + + std::stack parts; + do { + parts.push(path.name()); + path.str = path.parent().string(); + } while (!path.empty()); + + while (!parts.empty()) { + const std::string part = parts.top(); + parts.pop(); + if (part == ".") { + continue; + } + if (part == "..") { + throw access_error("entry point reached"); + } + + path = path / part; + } + if (path.colonPos != std::string::npos) { + path = path.entryPoint() + ":" + path.string(); + } + return path; +} diff --git a/src/io/path.hpp b/src/io/path.hpp index 6c6dea14..3911b1ef 100644 --- a/src/io/path.hpp +++ b/src/io/path.hpp @@ -1,9 +1,16 @@ #pragma once #include +#include #include namespace io { + class access_error : public std::runtime_error { + public: + access_error(const std::string& msg) : std::runtime_error(msg) { + } + }; + /// @brief std::filesystem::path project-specific alternative having /// `entry_point:path` scheme and solving std::filesystem::path problems: /// - implicit std::string conversions depending on compiler @@ -115,6 +122,8 @@ namespace io { return str.substr(0, slashpos); } + path normalized() const; + std::string string() const { return str; }