summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2026-06-04 19:42:02 +0200
committerFelix Morgner <felix.morgner@gmail.com>2026-06-04 19:42:02 +0200
commit11df846b1ec951dd35feb9b0bad42486c7b94dca (patch)
tree3e94acde315473011793cad482f23f1adf02fc98
parent240e7804156c5c374d4cf1216161f4feefd3fcb1 (diff)
downloadcabinet-11df846b1ec951dd35feb9b0bad42486c7b94dca.tar.xz
cabinet-11df846b1ec951dd35feb9b0bad42486c7b94dca.zip
magic: refactor construction
-rw-r--r--cabinet/magic.cpp48
-rw-r--r--cabinet/magic.hpp17
-rw-r--r--cabinet/main.cpp14
3 files changed, 73 insertions, 6 deletions
diff --git a/cabinet/magic.cpp b/cabinet/magic.cpp
index f8d7337..96e212f 100644
--- a/cabinet/magic.cpp
+++ b/cabinet/magic.cpp
@@ -2,18 +2,60 @@
#include <magic.h>
+#include <cerrno>
+#include <expected>
+#include <string_view>
+#include <system_error>
#include <utility>
namespace cab
{
- magic::magic(magic::flags flags)
- : m_cookie{magic_open(std::to_underlying(flags))}
+ auto magic::open(magic::flags flags, std::string_view database) noexcept -> std::expected<magic, std::error_code>
+ {
+ auto cookie = magic_open(std::to_underlying(flags));
+ if (!cookie)
+ {
+ return std::unexpected{
+ std::error_code{errno, std::system_category()}
+ };
+ }
+
+ if (auto success = magic_load(cookie, database.data()); success < 0)
+ {
+ return std::unexpected{std::make_error_code(std::errc::invalid_argument)};
+ }
+
+ return magic{cookie};
+ }
+
+ magic::magic(::magic_t cookie) noexcept
+ : m_cookie{cookie}
+ {}
+
+ magic::magic(magic && other) noexcept
+ : m_cookie{std::exchange(other.m_cookie, nullptr)}
{}
magic::~magic()
{
- magic_close(m_cookie);
+ if (m_cookie)
+ {
+ magic_close(m_cookie);
+ }
+ }
+
+ auto magic::operator=(magic && other) noexcept -> magic &
+ {
+ std::swap(m_cookie, other.m_cookie);
+ return *this;
+ }
+
+ auto swap(magic & lhs, magic & rhs) noexcept -> void
+ {
+ auto temp = std::move(lhs);
+ lhs = std::move(rhs);
+ rhs = std::move(lhs);
}
} // namespace cab
diff --git a/cabinet/magic.hpp b/cabinet/magic.hpp
index 02af9c2..25cf60b 100644
--- a/cabinet/magic.hpp
+++ b/cabinet/magic.hpp
@@ -3,6 +3,9 @@
#include <magic.h>
+#include <expected>
+#include <string_view>
+#include <system_error>
#include <utility>
namespace cab
@@ -40,13 +43,23 @@ namespace cab
no_simh = MAGIC_NO_CHECK_SIMH,
};
- magic(flags flags);
+ auto static open(flags flags, std::string_view database = {}) noexcept -> std::expected<magic, std::error_code>;
+
~magic();
+ magic(magic const &) = delete;
+ magic(magic && other) noexcept;
+
+ auto operator=(magic const &) -> magic & = delete;
+ auto operator=(magic && other) noexcept -> magic &;
private:
- magic_t m_cookie{};
+ explicit magic(::magic_t cookie) noexcept;
+
+ ::magic_t m_cookie{};
};
+ auto swap(magic & lhs, magic & rhs) noexcept -> void;
+
constexpr auto operator|(magic::flags lhs, magic::flags rhs) noexcept -> magic::flags
{
return static_cast<magic::flags>(std::to_underlying(lhs) | std::to_underlying(rhs));
diff --git a/cabinet/main.cpp b/cabinet/main.cpp
index 26dd690..bec0a5c 100644
--- a/cabinet/main.cpp
+++ b/cabinet/main.cpp
@@ -1,6 +1,18 @@
#include <cabinet/magic.hpp>
+#include <cstdlib>
+#include <iostream>
+#include <print>
+
auto main() -> int
{
- [[maybe_unused]] auto magic = cab::magic{cab::magic::flags::print_debug | cab::magic::flags::follow_symlinks};
+ auto magic = cab::magic::open(cab::magic::flags::print_debug | //
+ cab::magic::flags::follow_symlinks | //
+ cab::magic::flags::mime);
+
+ if (!magic)
+ {
+ std::println(std::cerr, "Failed to initialize libmagic: {}", magic.error().message());
+ return EXIT_FAILURE;
+ }
}