/* Userspace Virtual Filesystem Copyright (C) 2024. All rights reserved. This file is part of usvfs. usvfs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. usvfs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with usvfs. If not, see . */ #pragma once #include #include #include "ntdll_declarations.h" // formatters for standard types namespace usvfs::log { std::string to_string(LPCWSTR value); std::string to_string(PCUNICODE_STRING value); } // namespace usvfs::log template requires std::is_enum_v struct std::formatter : std::formatter, CharT> { template FmtContext::iterator format(Enum v, FmtContext& ctx) const { return std::formatter, CharT>::format( static_cast>(v), ctx); } }; template <> struct std::formatter : std::formatter { template FmtContext::iterator format(LPCWSTR v, FmtContext& ctx) const { return std::formatter::format(usvfs::log::to_string(v), ctx); } }; template <> struct std::formatter : std::formatter { template FmtContext::iterator format(const std::wstring& v, FmtContext& ctx) const { return std::formatter::format(v.c_str(), ctx); } }; template <> struct std::formatter : std::formatter { template FmtContext::iterator format(PCUNICODE_STRING v, FmtContext& ctx) const { return std::formatter::format(usvfs::log::to_string(v), ctx); } }; template <> struct std::formatter : std::formatter { template FmtContext::iterator format(UNICODE_STRING v, FmtContext& ctx) const { return std::formatter::format(usvfs::log::to_string(&v), ctx); } }; template requires(std::is_pointer_v && !std::is_same_v && !std::is_same_v && !std::is_same_v && !std::is_same_v) struct std::formatter : std::formatter { template FmtContext::iterator format(Pointer v, FmtContext& ctx) const { return std::formatter::format(v, ctx); } }; namespace usvfs::log { /** * a small helper class to wrap any object. The whole point is to give us a way * to ensure our own operator<< is used in addParam calls */ template class Wrap { public: explicit Wrap(const T& data) : m_Data(data) {} Wrap(Wrap&& reference) : m_Data(std::move(reference.m_Data)) {} Wrap(const Wrap& reference) = delete; Wrap& operator=(const Wrap& reference) = delete; private: friend struct ::std::formatter, char>; const T& m_Data; }; template Wrap wrap(const T& data) { return Wrap(data); } } // namespace usvfs::log template <> struct std::formatter, char> : std::formatter { template FmtContext::iterator format(const usvfs::log::Wrap& v, FmtContext& ctx) const { return std::format_to(ctx.out(), "{:x}", v.m_Data); } }; template <> struct std::formatter, char> : std::formatter { template FmtContext::iterator format(const usvfs::log::Wrap& v, FmtContext& ctx) const { switch (v.m_Data) { case 0x00000000: return std::format_to(ctx.out(), "ok"); case 0xC0000022: return std::format_to(ctx.out(), "access denied"); case 0xC0000035: return std::format_to(ctx.out(), "exists already"); } return std::format_to(ctx.out(), "err {:x}", v.m_Data); } };