aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2022-06-12 13:44:58 +0200
committerHampusM <hampus@hampusmat.com>2022-06-13 17:57:01 +0200
commit927e065f9829045247be7c0b3296408b6f577c1f (patch)
tree7da3d9cd5aa4070414a8708a582f6c3ab3e1e708 /src/util
parenteb66598c326862fd9dfc1899be4eac93f81a8023 (diff)
feat: add reading RLE files
Diffstat (limited to 'src/util')
-rw-r--r--src/util/algorithm.hpp7
-rw-r--r--src/util/algorithm_impl.hpp10
-rw-r--r--src/util/fs.cpp29
-rw-r--r--src/util/fs.hpp22
-rw-r--r--src/util/io.hpp14
-rw-r--r--src/util/io_impl.hpp55
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;
+}