From 11df846b1ec951dd35feb9b0bad42486c7b94dca Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 4 Jun 2026 19:42:02 +0200 Subject: magic: refactor construction --- cabinet/magic.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++--- cabinet/magic.hpp | 17 +++++++++++++++-- cabinet/main.cpp | 14 +++++++++++++- 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 +#include +#include +#include +#include #include 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 + { + 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 +#include +#include +#include #include 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(); + 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(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 +#include +#include +#include + 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; + } } -- cgit v1.2.3