/*
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);
}
};