#include namespace llarp { namespace { static void putSpaces(std::ostream& stream, size_t count) { // chunk n write static const char spaces[] = " "; static constexpr size_t size = sizeof(spaces) - 1; while(size < count) { stream.write(spaces, size); count -= size; } if(count > 0) { stream.write(spaces, count); } } } // namespace Printer::Printer(std::ostream& stream, int level, int spacesPerLevel) : m_stream(stream) , m_level(level < 0 ? -level : level) , m_levelPlusOne(m_level + 1) , m_suppressIndent(level < 0) , m_spaces(spacesPerLevel) { if(!m_suppressIndent) { const int absSpaces = m_spaces < 0 ? -m_spaces : m_spaces; putSpaces(m_stream, absSpaces * m_level); } m_stream << '['; if(m_spaces >= 0) { m_stream << '\n'; } } Printer::~Printer() { putSpaces(m_stream, m_spaces < 0 ? 1 : m_spaces * m_level); m_stream << ']'; } void Printer::printIndent() const { putSpaces(m_stream, m_spaces < 0 ? 1 : m_spaces * m_levelPlusOne); } void Printer::printHexAddr(string_view name, const void* address) const { printIndent(); m_stream << name << " = "; PrintHelper::print(m_stream, address, -m_levelPlusOne, m_spaces); } void Printer::printHexAddr(const void* address) const { printIndent(); PrintHelper::print(m_stream, address, -m_levelPlusOne, m_spaces); } void PrintHelper::printType(std::ostream& stream, char value, int, int spacesPerLevel, traits::select::Case< std::is_fundamental >) { if(std::isprint(static_cast< unsigned char >(value))) { stream << "'" << value << "'"; } else { #define PRINT_CONTROL_CHAR(x) \ case x: \ stream << #x; \ break; switch(value) { PRINT_CONTROL_CHAR('\n'); PRINT_CONTROL_CHAR('\t'); PRINT_CONTROL_CHAR('\0'); default: { // Print as hex FormatFlagsGuard guard(stream); stream << std::hex << std::showbase << static_cast< std::uintptr_t >( static_cast< unsigned char >(value)); } } } if(spacesPerLevel >= 0) { stream << '\n'; } } void PrintHelper::printType(std::ostream& stream, bool value, int, int spacesPerLevel, traits::select::Case< std::is_fundamental >) { { FormatFlagsGuard guard(stream); stream << std::boolalpha << value; } if(spacesPerLevel >= 0) { stream << '\n'; } } void PrintHelper::printType(std::ostream& stream, const char* value, int, int spacesPerLevel, traits::select::Case< std::is_pointer >) { if(value == nullptr) { stream << "null"; } else { stream << '"' << value << '"'; } if(spacesPerLevel >= 0) { stream << '\n'; } } void PrintHelper::printType(std::ostream& stream, const void* value, int, int spacesPerLevel, traits::select::Case< std::is_pointer >) { if(value == nullptr) { stream << "null"; } else { FormatFlagsGuard guard(stream); stream << std::hex << std::showbase << reinterpret_cast< std::uintptr_t >(value); } if(spacesPerLevel >= 0) { stream << '\n'; } } void PrintHelper::printType(std::ostream& stream, const string_view& value, int, int spacesPerLevel, traits::select::Case< traits::is_container >) { stream << '"' << value << '"'; if(spacesPerLevel >= 0) { stream << '\n'; } } } // namespace llarp