From a013fb35f1b1739f82468bb27cbd0a8aa2f5bdb6 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Mon, 2 Dec 2013 21:58:42 +0100 Subject: [PATCH] common: implemented improved EBML dumper class --- src/common/output.cpp | 137 +++++++++++++++++++++++------- src/common/output.h | 33 ++++++- src/common/xml/ebml_converter.cpp | 2 +- 3 files changed, 137 insertions(+), 35 deletions(-) diff --git a/src/common/output.cpp b/src/common/output.cpp index a7e345416..27466351e 100644 --- a/src/common/output.cpp +++ b/src/common/output.cpp @@ -13,9 +13,13 @@ #include "common/common_pch.h" +#include + #include "common/ebml.h" #include "common/endian.h" #include "common/locale.h" +#include "common/logger.h" +#include "common/mm_io.h" #include "common/strings/formatting.h" #include "common/strings/utf8.h" @@ -276,54 +280,121 @@ mxhexdump(unsigned int level, mxinfo(boost::format("%1%\n") % output); } -void -dump_ebml_elements(EbmlElement *element, - bool with_values, - unsigned int level) { - std::string indent_str, value_str; - size_t i; +ebml_dumper_c::ebml_dumper_c() + : m_values{} + , m_addresses{} + , m_indexes{} + , m_max_level{std::numeric_limits::max()} + , m_target_type{STDOUT} + , m_io_target{} +{ +} - for (i = 1; i <= level; ++i) - indent_str += " "; +std::string +ebml_dumper_c::to_string(EbmlElement const *element) + const { + return dynamic_cast(element) ? ::to_string(static_cast(element)->GetValue()) + : dynamic_cast(element) ? ::to_string(static_cast(element)->GetValue()) + : dynamic_cast(element) ? ::to_string(static_cast(element)->GetValue(), 9) + : dynamic_cast(element) ? static_cast(element)->GetValueUTF8() + : dynamic_cast(element) ? static_cast(element)->GetValue() + : dynamic_cast(element) ? ::to_string(static_cast(element)->GetEpochDate()) + : (boost::format("(type: %1% size: %2%)") % + ( dynamic_cast(element) ? "binary" + : dynamic_cast(element) ? "master" + : dynamic_cast(element) ? "void" + : "unknown") + % element->GetSize()).str(); +} - if (with_values) { - if (dynamic_cast(element)) - value_str = to_string(static_cast(element)->GetValue()); - else if (dynamic_cast(element)) - value_str = to_string(static_cast(element)->GetValue()); +ebml_dumper_c & +ebml_dumper_c::values(bool p_values) { + m_values = p_values; + return *this; +} - else if (dynamic_cast(element)) - value_str = to_string(static_cast(element)->GetValue(), 9); +ebml_dumper_c & +ebml_dumper_c::addresses(bool p_addresses) { + m_addresses = p_addresses; + return *this; +} - else if (dynamic_cast(element)) - value_str = static_cast(element)->GetValueUTF8(); +ebml_dumper_c & +ebml_dumper_c::indexes(bool p_indexes) { + m_indexes = p_indexes; + return *this; +} - else if (dynamic_cast(element)) - value_str = static_cast(element)->GetValue(); +ebml_dumper_c & +ebml_dumper_c::max_level(int p_max_level) { + m_max_level = p_max_level; + return *this; +} - else if (dynamic_cast(element)) - value_str = to_string(static_cast(element)->GetEpochDate()); +ebml_dumper_c & +ebml_dumper_c::target(target_type_e p_target_type, + mm_io_c *p_io_target) { + m_target_type = p_target_type; + m_io_target = p_io_target; + return *this; +} - else - value_str = (boost::format("(type: %1% size: %2%)") % - ( dynamic_cast(element) ? "binary" - : dynamic_cast(element) ? "master" - : dynamic_cast(element) ? "void" - : "unknown") - % element->GetSize()).str(); +ebml_dumper_c & +ebml_dumper_c::dump(EbmlElement const *element) { + dump_impl(element, 0, 0); - value_str = " " + value_str; + switch (m_target_type) { + case STDOUT: mxinfo(m_buffer.str()); break; + case LOGGER: log_it(m_buffer.str()); break; + case MM_IO: assert(!!m_io_target); m_io_target->puts(m_buffer.str()); break; + default: assert(false); } - mxinfo(boost::format("%1%%2%%3%\n") % indent_str % EBML_NAME(element) % value_str); + m_buffer.str(""); - EbmlMaster *master = dynamic_cast(element); + return *this; +} + +void +ebml_dumper_c::dump_impl(EbmlElement const *element, + size_t level, + size_t index) { + if (level > m_max_level) + return; + + m_buffer << std::string(level, ' '); + + if (m_indexes) + m_buffer << index << " "; + + if (!element) { + m_buffer << "nullptr" << std::endl; + return; + } + + m_buffer << EBML_NAME(element); + + if (m_addresses) + m_buffer << (boost::format(" @%1%") % element); + + if (m_values) + m_buffer << " " << to_string(element); + + m_buffer << std::endl; + + auto master = dynamic_cast(element); if (!master) return; - for (i = 0; master->ListSize() > i; ++i) - dump_ebml_elements((*master)[i], with_values, level + 1); + for (auto idx = 0u; master->ListSize() > idx; ++idx) + dump_impl((*master)[idx], level + 1, idx); +} + +void +dump_ebml_elements(EbmlElement *element, + bool with_values) { + ebml_dumper_c{}.values(with_values).dump(element); } std::string diff --git a/src/common/output.h b/src/common/output.h index e1ca4044e..395157dea 100644 --- a/src/common/output.h +++ b/src/common/output.h @@ -148,7 +148,38 @@ mxverb_tid(unsigned int level, extern const std::string empty_string; void mxhexdump(unsigned int level, const void *buffer_to_dump, size_t lenth, const std::string &prefix = empty_string); -void dump_ebml_elements(EbmlElement *element, bool with_values = false, unsigned int level = 0); +class ebml_dumper_c { +public: + enum target_type_e { + STDOUT, + MM_IO, + LOGGER, + }; + +private: + bool m_values, m_addresses, m_indexes; + size_t m_max_level; + target_type_e m_target_type; + mm_io_c *m_io_target; + std::stringstream m_buffer; + +public: + ebml_dumper_c(); + + ebml_dumper_c &values(bool p_values); + ebml_dumper_c &addresses(bool p_addresses); + ebml_dumper_c &indexes(bool p_indexes); + ebml_dumper_c &max_level(int p_max_level); + ebml_dumper_c &target(target_type_e p_target_type, mm_io_c *p_io_target = nullptr); + + ebml_dumper_c &dump(EbmlElement const *element); + +private: + void dump_impl(EbmlElement const *element, size_t level, size_t index); + std::string to_string(EbmlElement const *element) const; +}; + +void dump_ebml_elements(EbmlElement *element, bool with_values = false); std::string fourcc_to_string(uint32_t fourcc); diff --git a/src/common/xml/ebml_converter.cpp b/src/common/xml/ebml_converter.cpp index 7e252d15e..31bd3af44 100644 --- a/src/common/xml/ebml_converter.cpp +++ b/src/common/xml/ebml_converter.cpp @@ -353,7 +353,7 @@ ebml_converter_c::to_ebml(std::string const &file_name, ebml_root->Remove(0); if (debugging_requested("ebml_converter")) - dump_ebml_elements(master, true, 0); + dump_ebml_elements(master, true); return ebml_master_cptr{master}; }