summaryrefslogtreecommitdiff
path: root/binparse
diff options
context:
space:
mode:
Diffstat (limited to 'binparse')
-rw-r--r--binparse/CMakeLists.txt7
-rw-r--r--binparse/output.cpp61
-rw-r--r--binparse/output.hpp57
-rw-r--r--binparse/parse.cpp (renamed from binparse/binparse.cpp)42
-rw-r--r--binparse/parse.hpp (renamed from binparse/binparse.hpp)43
5 files changed, 151 insertions, 59 deletions
diff --git a/binparse/CMakeLists.txt b/binparse/CMakeLists.txt
index 00fc246..cbc83b5 100644
--- a/binparse/CMakeLists.txt
+++ b/binparse/CMakeLists.txt
@@ -1,7 +1,8 @@
add_library(binparse STATIC
types.hpp
- binparse.hpp binparse.cpp
+ parse.hpp parse.cpp
+ output.hpp output.cpp
)
target_include_directories(binparse
@@ -10,4 +11,8 @@ target_include_directories(binparse
target_compile_options(binparse
PUBLIC "-std=c++14"
+)
+
+target_link_libraries(binparse
+ PRIVATE fusion-utils
) \ No newline at end of file
diff --git a/binparse/output.cpp b/binparse/output.cpp
new file mode 100644
index 0000000..78babd8
--- /dev/null
+++ b/binparse/output.cpp
@@ -0,0 +1,61 @@
+#include "output.hpp"
+
+#include <iomanip>
+
+namespace binparse {
+
+std::string to_string(Magic16 magic) {
+ char* c = reinterpret_cast<char*>(&magic);
+ return std::string(c, sizeof(Magic16));
+}
+
+std::ostream& operator<<(std::ostream& os, uint8_t i) {
+ return os << (unsigned int) i;
+}
+
+std::ostream& operator<<(std::ostream& os, Value8 v)
+{
+ return os << std::dec << static_cast<uint8_t>(v);
+}
+
+std::ostream& operator<<(std::ostream& os, Offset8 o)
+{
+ return os << std::hex << std::setw(2) << std::setfill('0') << static_cast<uint8_t>(o);
+}
+
+std::ostream& operator<<(std::ostream& os, Magic16 m) {
+ return os << std::hex << std::setw(4) << std::setfill('0') << static_cast<uint16_t>(m) << " (" << to_string(m) << ")";
+}
+
+std::ostream& operator<<(std::ostream& os, Value16 v) {
+ return os << std::dec << static_cast<uint16_t>(v);
+}
+
+std::ostream& operator<<(std::ostream& os, Offset16 o) {
+ return os << std::hex << std::setw(sizeof(o) * 2) << std::setfill('0') << static_cast<uint16_t>(o);
+}
+
+std::ostream& operator<<(std::ostream& os, Value32 v) {
+ return os << std::dec << static_cast<uint32_t>(v);
+}
+
+std::ostream& operator<<(std::ostream& os, Offset32 o) {
+ return os << std::hex << std::setw(sizeof(o) * 2) << std::setfill('0') << static_cast<uint32_t>(o);
+}
+
+std::ostream&operator<<(std::ostream& os, std::array<uint8_t, 8> a)
+{
+ return os;
+}
+
+std::ostream&operator<<(std::ostream& os, std::array<uint8_t, 22> a)
+{
+ return os;
+}
+
+std::ostream&operator<<(std::ostream& os, std::vector<uint8_t> vec)
+{
+ return os;
+}
+
+}
diff --git a/binparse/output.hpp b/binparse/output.hpp
new file mode 100644
index 0000000..b16dd89
--- /dev/null
+++ b/binparse/output.hpp
@@ -0,0 +1,57 @@
+#pragma once
+
+#include "types.hpp"
+
+#include "index_list.hpp"
+
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/fusion/sequence/intrinsic/at_c.hpp>
+#include <boost/fusion/adapted/struct/detail/extension.hpp>
+
+#include <array>
+#include <vector>
+
+namespace binparse {
+
+std::string to_string(Magic16 magic);
+
+//overload inside this namespace to output unsigned char as value not as characters.
+std::ostream& operator<<(std::ostream& os, uint8_t);
+
+std::ostream& operator<<(std::ostream& os, Value8 v);
+std::ostream& operator<<(std::ostream& os, Offset8 o);
+
+std::ostream& operator<<(std::ostream& os, Magic16 m);
+std::ostream& operator<<(std::ostream& os, Value16 v);
+std::ostream& operator<<(std::ostream& os, Offset16 o);
+
+std::ostream& operator<<(std::ostream& os, Value32 v);
+std::ostream& operator<<(std::ostream& os, Offset32 o);
+
+std::ostream& operator<<(std::ostream& os, std::array<uint8_t, 8> a);
+std::ostream& operator<<(std::ostream& os, std::array<uint8_t, 22> a);
+
+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 T>
+std::ostream& output_impl(std::ostream& os, T const&, indices<>) {
+ return os;
+}
+
+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{});
+}
+
+} \ No newline at end of file
diff --git a/binparse/binparse.cpp b/binparse/parse.cpp
index eae6143..cf7c0be 100644
--- a/binparse/binparse.cpp
+++ b/binparse/parse.cpp
@@ -1,5 +1,4 @@
-
-#include "binparse.hpp"
+#include "parse.hpp"
namespace binparse {
@@ -135,43 +134,4 @@ void dump_bytes(std::istream& is, std::vector<uint8_t>& buffer, std::string name
}
}
-std::string to_string(Magic16 magic) {
- char* c = reinterpret_cast<char*>(&magic);
- return std::string(c, sizeof(Magic16));
-}
-
-std::ostream& operator<<(std::ostream& os, uint8_t i) {
- return os << (unsigned int) i;
-}
-
-std::ostream& operator<<(std::ostream& os, Value8 v)
-{
- return os << std::dec << static_cast<uint8_t>(v);
-}
-
-std::ostream& operator<<(std::ostream& os, Offset8 o)
-{
- return os << std::hex << std::setw(2) << std::setfill('0') << static_cast<uint8_t>(o);
-}
-
-std::ostream& operator<<(std::ostream& os, Magic16 m) {
- return os << std::hex << std::setw(4) << std::setfill('0') << static_cast<uint16_t>(m) << " (" << to_string(m) << ")";
-}
-
-std::ostream& operator<<(std::ostream& os, Value16 v) {
- return os << std::dec << static_cast<uint16_t>(v);
-}
-
-std::ostream& operator<<(std::ostream& os, Offset16 o) {
- return os << std::hex << std::setw(sizeof(o) * 2) << std::setfill('0') << static_cast<uint16_t>(o);
-}
-
-std::ostream& operator<<(std::ostream& os, Value32 v) {
- return os << std::dec << static_cast<uint32_t>(v);
-}
-
-std::ostream& operator<<(std::ostream& os, Offset32 o) {
- return os << std::hex << std::setw(sizeof(o) * 2) << std::setfill('0') << static_cast<uint32_t>(o);
-}
-
} \ No newline at end of file
diff --git a/binparse/binparse.hpp b/binparse/parse.hpp
index e649ce7..8015ba3 100644
--- a/binparse/binparse.hpp
+++ b/binparse/parse.hpp
@@ -1,8 +1,15 @@
+#pragma once
+
#include "types.hpp"
-#include <string>
-#include <ostream>
-#include <iomanip>
+#include "index_list.hpp"
+
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/fusion/sequence/intrinsic/at_c.hpp>
+#include <boost/fusion/adapted/struct/detail/extension.hpp>
+
+#include <stdexcept>
+#include <array>
#include <vector>
namespace binparse {
@@ -13,7 +20,7 @@ struct UnexpectedEOS : public std::runtime_error {
UnexpectedEOS(std::string location);
};
-template<typename T>
+template<typename T, typename std::enable_if<!boost::fusion::traits::is_sequence<T>::value>::type* = nullptr>
T parse(std::istream& is, std::string name);
template<>
@@ -46,21 +53,23 @@ std::array<uint8_t, 8> parse<std::array<uint8_t, 8>>(std::istream& is, std::stri
template<>
std::array<uint8_t, 22> parse<std::array<uint8_t, 22>>(std::istream& is, std::string name);
-void dump_bytes(std::istream& is, std::vector<uint8_t>& buffer, std::string name);
-
-std::string to_string(Magic16 magic);
+template <typename T, typename std::enable_if<boost::fusion::traits::is_sequence<T>::value>::type* = nullptr>
+T parse(std::istream& is);
-//overload inside this namespace to output unsigned char as value not as characters.
-std::ostream& operator<<(std::ostream& os, uint8_t);
-
-std::ostream& operator<<(std::ostream& os, Value8 v);
-std::ostream& operator<<(std::ostream& os, Offset8 o);
+template <typename T, int... Indices>
+T parse_impl(std::istream& is, indices<Indices...>) {
+
+ return {parse<typename std::decay<typename boost::fusion::result_of::at_c<T, Indices>::type>::type>(is, boost::fusion::extension::struct_member_name<T, Indices>::call())...};
+
+}
-std::ostream& operator<<(std::ostream& os, Magic16 m);
-std::ostream& operator<<(std::ostream& os, Value16 v);
-std::ostream& operator<<(std::ostream& os, Offset16 o);
+template <typename T, typename std::enable_if<boost::fusion::traits::is_sequence<T>::value>::type*>
+T parse(std::istream& is) {
+ typedef typename build_indices<boost::fusion::result_of::size<T>::value>::type indices;
+
+ return parse_impl<T>(is, indices{});
+}
-std::ostream& operator<<(std::ostream& os, Value32 v);
-std::ostream& operator<<(std::ostream& os, Offset32 o);
+void dump_bytes(std::istream& is, std::vector<uint8_t>& buffer, std::string name);
} \ No newline at end of file