diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2016-06-22 16:18:02 +0200 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2016-06-22 16:41:11 +0200 |
| commit | 0f2d7c9ed9dfa3716840fc112bd53e5ec6b6315b (patch) | |
| tree | a90760b1780d187028475bcb4080794f88ddc858 | |
| parent | 22231518b9c2c0b7f73c72a6ca834df659c63c7f (diff) | |
| download | openwar-0f2d7c9ed9dfa3716840fc112bd53e5ec6b6315b.tar.gz openwar-0f2d7c9ed9dfa3716840fc112bd53e5ec6b6315b.tar.bz2 openwar-0f2d7c9ed9dfa3716840fc112bd53e5ec6b6315b.zip | |
adds a tree format printer for "binparse" types.
| -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 | ||||
| -rw-r--r-- | le/le_file.cpp | 3 | ||||
| -rw-r--r-- | le/le_file_parser.cpp | 5 | ||||
| -rw-r--r-- | le/le_object_table.cpp | 7 | ||||
| -rw-r--r-- | le/le_object_table.hpp | 2 |
9 files changed, 141 insertions, 4 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 diff --git a/le/le_file.cpp b/le/le_file.cpp index b01f13e..4a9f57e 100644 --- a/le/le_file.cpp +++ b/le/le_file.cpp @@ -37,6 +37,8 @@ File parse_file(std::istream& is) { auto le_h = le::parse_header(is); + auto object_table = parse_object_table(is, le_offset + le_h.object_table_offset, le_h.nr_objects_in_module); + return { mz_h, unused, @@ -45,6 +47,7 @@ File parse_file(std::istream& is) { le_offset, dos_exe, le_h, + object_table, }; } diff --git a/le/le_file_parser.cpp b/le/le_file_parser.cpp index 2d5eed9..fe34857 100644 --- a/le/le_file_parser.cpp +++ b/le/le_file_parser.cpp @@ -1,6 +1,8 @@ #include "le_file.hpp" +#include "otreestream.hpp" + #include <boost/program_options.hpp> #include <boost/filesystem.hpp> @@ -50,7 +52,8 @@ int main(int argc, char* argv[]) { std::ifstream file(file_path.string()); auto x = le::parse_file(file); - std::cout << x << std::endl; + binparse::otreestream treestream (std::cout); + treestream << x << std::endl; return 0; } diff --git a/le/le_object_table.cpp b/le/le_object_table.cpp index 1155c35..3e87fb0 100644 --- a/le/le_object_table.cpp +++ b/le/le_object_table.cpp @@ -1,5 +1,9 @@ #include "le_object_table.hpp" +#include "output.hpp" + +#include <iostream> + namespace le { ObjectTable parse_object_table(std::istream& is, Offset32 offset, Value32 nr_objects) @@ -12,12 +16,13 @@ ObjectTable parse_object_table(std::istream& is, Offset32 offset, Value32 nr_obj for(Value32 i = Value32(0); i < nr_objects; i++) { table.entries.emplace(i+1, parse_object_table_entry(is)); } + return table; } std::ostream& operator<<(std::ostream& os, const ObjectTable& table) { - return os; + return binparse::operator<<(os, table.entries); } }
\ No newline at end of file diff --git a/le/le_object_table.hpp b/le/le_object_table.hpp index 8c57c60..c840734 100644 --- a/le/le_object_table.hpp +++ b/le/le_object_table.hpp @@ -13,5 +13,5 @@ struct ObjectTable { ObjectTable parse_object_table(std::istream& is, Offset32 offset, Value32 nr_objects); std::ostream& operator<<(std::ostream& os, ObjectTable const& table); - + }
\ No newline at end of file |
