add io::path.normalized()

This commit is contained in:
MihailRis 2025-02-04 14:58:41 +03:00
parent 1ec8f89599
commit 59f46ad530
5 changed files with 39 additions and 35 deletions

View File

@ -23,7 +23,7 @@ StdfsDevice::StdfsDevice(fs::path root, bool createDirectory)
} }
fs::path StdfsDevice::resolve(std::string_view path) { 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) { void StdfsDevice::write(std::string_view path, const void* data, size_t size) {
@ -123,5 +123,5 @@ private:
}; };
std::unique_ptr<PathsGenerator> StdfsDevice::list(std::string_view path) { std::unique_ptr<PathsGenerator> StdfsDevice::list(std::string_view path) {
return std::make_unique<StdfsPathsGenerator>(root / fs::u8path(path)); return std::make_unique<StdfsPathsGenerator>(resolve(path));
} }

View File

@ -25,32 +25,6 @@ static inline io::path EXPORT_FOLDER = "export";
static inline io::path CONTROLS_FILE = "controls.toml"; static inline io::path CONTROLS_FILE = "controls.toml";
static inline io::path SETTINGS_FILE = "settings.toml"; static inline io::path SETTINGS_FILE = "settings.toml";
static io::path toCanonic(io::path path) {
std::stack<std::string> 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() { void EnginePaths::prepare() {
io::set_device("res", std::make_shared<io::StdfsDevice>(resourcesFolder, false)); io::set_device("res", std::make_shared<io::StdfsDevice>(resourcesFolder, false));
io::set_device("user", std::make_shared<io::StdfsDevice>(userFilesFolder)); io::set_device("user", std::make_shared<io::StdfsDevice>(userFilesFolder));

View File

@ -10,12 +10,6 @@
#include "data/dv.hpp" #include "data/dv.hpp"
#include "content/ContentPack.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 { class EnginePaths {
public: public:
void prepare(); void prepare();

View File

@ -1,6 +1,6 @@
#include "path.hpp" #include "path.hpp"
#include <stdexcept> #include <stack>
using namespace io; using namespace io;
@ -9,3 +9,30 @@ void path::checkValid() const {
throw std::runtime_error("path entry point is not specified: " + str); throw std::runtime_error("path entry point is not specified: " + str);
} }
} }
path path::normalized() const {
io::path path = pathPart();
std::stack<std::string> 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;
}

View File

@ -1,9 +1,16 @@
#pragma once #pragma once
#include <string> #include <string>
#include <stdexcept>
#include <filesystem> #include <filesystem>
namespace io { 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 /// @brief std::filesystem::path project-specific alternative having
/// `entry_point:path` scheme and solving std::filesystem::path problems: /// `entry_point:path` scheme and solving std::filesystem::path problems:
/// - implicit std::string conversions depending on compiler /// - implicit std::string conversions depending on compiler
@ -115,6 +122,8 @@ namespace io {
return str.substr(0, slashpos); return str.substr(0, slashpos);
} }
path normalized() const;
std::string string() const { std::string string() const {
return str; return str;
} }