diff options
author | HampusM <hampus@hampusmat.com> | 2022-06-12 13:44:58 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2022-06-13 17:57:01 +0200 |
commit | 927e065f9829045247be7c0b3296408b6f577c1f (patch) | |
tree | 7da3d9cd5aa4070414a8708a582f6c3ab3e1e708 /src/util | |
parent | eb66598c326862fd9dfc1899be4eac93f81a8023 (diff) |
feat: add reading RLE files
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/algorithm.hpp | 7 | ||||
-rw-r--r-- | src/util/algorithm_impl.hpp | 10 | ||||
-rw-r--r-- | src/util/fs.cpp | 29 | ||||
-rw-r--r-- | src/util/fs.hpp | 22 | ||||
-rw-r--r-- | src/util/io.hpp | 14 | ||||
-rw-r--r-- | src/util/io_impl.hpp | 55 |
6 files changed, 137 insertions, 0 deletions
diff --git a/src/util/algorithm.hpp b/src/util/algorithm.hpp index e3d8b6f..60c68e2 100644 --- a/src/util/algorithm.hpp +++ b/src/util/algorithm.hpp @@ -9,6 +9,13 @@ requires Container<ContainerType> constexpr auto container_find(const ContainerType &container, const Value &value) noexcept -> typename ContainerType::const_iterator; +template <typename ContainerType, typename Predicate> +requires Container<ContainerType> && + std::predicate<Predicate, typename ContainerType::value_type> +constexpr auto +container_find(const ContainerType &container, Predicate predicate) noexcept -> + typename ContainerType::const_iterator; + template <typename ContainerType, typename Value> requires Container<ContainerType> constexpr auto container_has(const ContainerType &container, const Value &value) noexcept diff --git a/src/util/algorithm_impl.hpp b/src/util/algorithm_impl.hpp index 00269ed..d7c5e3b 100644 --- a/src/util/algorithm_impl.hpp +++ b/src/util/algorithm_impl.hpp @@ -12,6 +12,16 @@ constexpr auto container_find(const ContainerType &container, const Value &value return std::find(container.begin(), container.end(), value); } +template <typename ContainerType, typename Predicate> +requires Container<ContainerType> && + std::predicate<Predicate, typename ContainerType::value_type> +constexpr auto +container_find(const ContainerType &container, Predicate predicate) noexcept -> + typename ContainerType::const_iterator +{ + return std::find_if(container.begin(), container.end(), predicate); +} + template <typename ContainerType, typename Value> requires Container<ContainerType> constexpr auto container_has(const ContainerType &container, const Value &value) noexcept diff --git a/src/util/fs.cpp b/src/util/fs.cpp new file mode 100644 index 0000000..68c3dd9 --- /dev/null +++ b/src/util/fs.cpp @@ -0,0 +1,29 @@ +#include "fs.hpp" + +#include <cstdlib> +#include <pwd.h> +#include <unistd.h> + +auto get_current_user_home_path() noexcept -> std::filesystem::path +{ + const auto *home_path_env = std::getenv("HOME"); + + if (home_path_env == nullptr) + { + return getpwuid(getuid())->pw_dir; + } + + return home_path_env; +} + +auto expand_path_home(const std::filesystem::path &path) noexcept -> std::filesystem::path +{ + const auto path_str = path.string(); + + if (!path_str.starts_with("~/")) + { + return path; + } + + return get_current_user_home_path() / std::filesystem::path(path_str.substr(2)); +} diff --git a/src/util/fs.hpp b/src/util/fs.hpp new file mode 100644 index 0000000..860c055 --- /dev/null +++ b/src/util/fs.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include <filesystem> +#include <string_view> +#include <unordered_map> + +const std::unordered_map<std::filesystem::file_type, std::string_view> file_type_names = { + {std::filesystem::file_type::none, "none"}, + {std::filesystem::file_type::not_found, "not_found"}, + {std::filesystem::file_type::regular, "regular"}, + {std::filesystem::file_type::directory, "directory"}, + {std::filesystem::file_type::symlink, "symlink"}, + {std::filesystem::file_type::block, "block"}, + {std::filesystem::file_type::character, "character"}, + {std::filesystem::file_type::fifo, "fifo"}, + {std::filesystem::file_type::socket, "socket"}, + {std::filesystem::file_type::unknown, "unknown"}}; + +auto get_current_user_home_path() noexcept -> std::filesystem::path; + +auto expand_path_home(const std::filesystem::path &path) noexcept + -> std::filesystem::path; diff --git a/src/util/io.hpp b/src/util/io.hpp new file mode 100644 index 0000000..2c248f7 --- /dev/null +++ b/src/util/io.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "util/concepts.hpp" + +#include <concepts> +#include <filesystem> +#include <string> + +template <typename ContainerType> +requires Container<ContainerType> && HasPushBack<ContainerType> && + std::same_as<typename ContainerType::value_type, std::string> +auto read_file_lines(const std::filesystem::path &path) -> ContainerType; + +#include "io_impl.hpp" diff --git a/src/util/io_impl.hpp b/src/util/io_impl.hpp new file mode 100644 index 0000000..14f4ded --- /dev/null +++ b/src/util/io_impl.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include "io.hpp" + +#include "errors/io.hpp" + +#include <fstream> + +template <typename ContainerType> +requires Container<ContainerType> && HasPushBack<ContainerType> && + std::same_as<typename ContainerType::value_type, std::string> +auto read_file_lines(const std::filesystem::path &path) -> ContainerType +{ + if (!std::filesystem::exists(path)) + { + throw NoSuchFileOrDirectoryError(path); + } + + const auto file_status = std::filesystem::status(path); + + const auto file_type = file_status.type(); + + if (file_type != std::filesystem::file_type::regular) + { + throw WrongFileTypeError(path, std::filesystem::file_type::regular, file_type); + } + + auto file = std::ifstream(); + + file.open(path); + + if (!file.is_open()) + { + throw FileNotOpenError(path); + } + + auto content_lines = ContainerType(); + + while (file) + { + auto line = std::string(); + std::getline(file, line); + + std::erase(line, '\r'); + + content_lines.push_back(line); + } + + if (!content_lines.empty() && content_lines.back().empty()) + { + content_lines.pop_back(); + } + + return content_lines; +} |