summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-06-22 16:18:02 +0200
committerDennis Brentjes <d.brentjes@gmail.com>2016-06-22 16:41:11 +0200
commit0f2d7c9ed9dfa3716840fc112bd53e5ec6b6315b (patch)
treea90760b1780d187028475bcb4080794f88ddc858
parent22231518b9c2c0b7f73c72a6ca834df659c63c7f (diff)
downloadopenwar-0f2d7c9ed9dfa3716840fc112bd53e5ec6b6315b.tar.gz
openwar-0f2d7c9ed9dfa3716840fc112bd53e5ec6b6315b.tar.bz2
openwar-0f2d7c9ed9dfa3716840fc112bd53e5ec6b6315b.zip
adds a tree format printer for "binparse" types.
-rw-r--r--binparse/CMakeLists.txt1
-rw-r--r--binparse/otreestream.cpp47
-rw-r--r--binparse/otreestream.hpp42
-rw-r--r--binparse/output.hpp33
-rw-r--r--binparse/types.hpp5
-rw-r--r--le/le_file.cpp3
-rw-r--r--le/le_file_parser.cpp5
-rw-r--r--le/le_object_table.cpp7
-rw-r--r--le/le_object_table.hpp2
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