diff options
Diffstat (limited to 'binparse')
| -rw-r--r-- | binparse/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | binparse/otreestream.cpp | 47 | ||||
| -rw-r--r-- | binparse/otreestream.hpp | 42 | ||||
| -rw-r--r-- | binparse/output.hpp | 33 | ||||
| -rw-r--r-- | binparse/types.hpp | 5 |
5 files changed, 127 insertions, 1 deletions
diff --git a/binparse/CMakeLists.txt b/binparse/CMakeLists.txt index cbc83b5..c41a2b5 100644 --- a/binparse/CMakeLists.txt +++ b/binparse/CMakeLists.txt @@ -3,6 +3,7 @@ add_library(binparse STATIC types.hpp parse.hpp parse.cpp output.hpp output.cpp + otreestream.hpp otreestream.cpp ) target_include_directories(binparse diff --git a/binparse/otreestream.cpp b/binparse/otreestream.cpp new file mode 100644 index 0000000..a93c0e9 --- /dev/null +++ b/binparse/otreestream.cpp @@ -0,0 +1,47 @@ +#include "otreestream.hpp" + +namespace binparse { + +int treebuf::sync() { + return this->sbuf->pubsync(); +} + +int treebuf::overflow(int c) { + if (c != std::char_traits<char>::eof()) { + if (this->need_prefix && !this->prefix.empty() && this->prefix.size() != this->sbuf->sputn(&this->prefix[0], this->prefix.size())) { + return std::char_traits<char>::eof(); + } + this->need_prefix = c == '\n'; + } + return this->sbuf->sputc(c); +} + +treebuf::treebuf(std::streambuf* sbuf) +: sbuf(sbuf) +, need_prefix(true) +{} + +void treebuf::indent() { + prefix += "\t"; +} + +void treebuf::unindent() { + prefix = std::string(prefix.begin(), prefix.end()-1); +} + +otreestream::otreestream(std::ostream& out) +: treebuf(out.rdbuf()) +, std::ios(static_cast<std::streambuf*>(this)) +, std::ostream(static_cast<std::streambuf*>(this)) { +} + +indent::indent(std::ostream& os) +: tb(dynamic_cast<treebuf&>(os)) { + tb.indent(); +} + +indent::~indent() { + tb.unindent(); +} + +} diff --git a/binparse/otreestream.hpp b/binparse/otreestream.hpp new file mode 100644 index 0000000..3f57d4e --- /dev/null +++ b/binparse/otreestream.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include <streambuf> +#include <string> +#include <ostream> + +namespace binparse { + +class treebuf : public std::streambuf +{ + std::string prefix; + std::streambuf* sbuf; + bool need_prefix; + + int sync(); + int overflow(int c); + +public: + treebuf(std::streambuf* sbuf); + + void indent(); + + void unindent(); +}; + +class otreestream : public virtual treebuf, public std::ostream +{ +public: + otreestream(std::ostream& out); +}; + +class indent { + + treebuf& tb; + +public: + indent(std::ostream& os); + + ~indent(); +}; + +}
\ No newline at end of file diff --git a/binparse/output.hpp b/binparse/output.hpp index b16dd89..705a380 100644 --- a/binparse/output.hpp +++ b/binparse/output.hpp @@ -1,6 +1,7 @@ #pragma once #include "types.hpp" +#include "otreestream.hpp" #include "index_list.hpp" @@ -10,6 +11,8 @@ #include <array> #include <vector> +#include <map> +#include <streambuf> namespace binparse { @@ -36,6 +39,24 @@ std::ostream& operator<<(std::ostream& os, std::vector<uint8_t> vec); template <typename T, typename std::enable_if<boost::fusion::traits::is_sequence<T>::value>::type* = nullptr> std::ostream& operator<<(std::ostream&, T const&); +template <typename Key, typename Value> +std::ostream& operator<<(std::ostream& os, std::map<Key, Value> const& map) { + try { + indent scoped(os); + os << std::endl; + for(auto&& entry : map) { + os << entry.first << ": " << entry.second << std::endl; + } + } catch(std::exception&) { + os << std::endl; + for(auto&& entry : map) { + os << entry.first << ": " << entry.second << std::endl; + } + } + + return os; +} + template<typename T> std::ostream& output_impl(std::ostream& os, T const&, indices<>) { return os; @@ -43,15 +64,25 @@ std::ostream& output_impl(std::ostream& os, T const&, indices<>) { template <typename T, int I, int... Indices> std::ostream& output_impl(std::ostream& os, T const& t, indices<I, Indices...>) { + os << boost::fusion::extension::struct_member_name<T, I>::call() << ": " << boost::fusion::at_c<I>(t) << std::endl; return output_impl(os, t, indices<Indices...>{}); + } template <typename T, typename std::enable_if<boost::fusion::traits::is_sequence<T>::value>::type*> std::ostream& operator<<(std::ostream& os, T const& t) { typedef typename build_indices<boost::fusion::result_of::size<T>::value>::type indices; - return output_impl<T>(os, t, indices{}); + try { + indent scoped(os); + os << std::endl; + output_impl<T>(os, t, indices{}); + } catch(std::exception&) { + os << std::endl; + output_impl<T>(os, t, indices{}); + } + return os; } }
\ No newline at end of file diff --git a/binparse/types.hpp b/binparse/types.hpp index e92a7a6..9b6c4a6 100644 --- a/binparse/types.hpp +++ b/binparse/types.hpp @@ -17,4 +17,9 @@ BOOST_STRONG_TYPEDEF(uint16_t, Value16) BOOST_STRONG_TYPEDEF(uint32_t, Offset32) BOOST_STRONG_TYPEDEF(uint32_t, Value32) +template <typename T> +T operator+(T const lh, T const rh) { + return T(0 + lh + rh); +} + }
\ No newline at end of file |
