diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2016-06-19 20:23:07 +0200 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2016-06-19 20:23:07 +0200 |
| commit | cea325b7451c1fb8dd22462ec2e7b5b88ea9b547 (patch) | |
| tree | ffa2811b2ca24b3aa7e08bb28b45e7e9adbd154c /mz | |
| parent | c66d1f5c0af70161f4ad4c4175f4280e95b55dfd (diff) | |
| download | openwar-cea325b7451c1fb8dd22462ec2e7b5b88ea9b547.tar.gz openwar-cea325b7451c1fb8dd22462ec2e7b5b88ea9b547.tar.bz2 openwar-cea325b7451c1fb8dd22462ec2e7b5b88ea9b547.zip | |
Adds an LE executable parser.
Adds the binparse library that holds common components for the MZ and LE parsers.
Diffstat (limited to 'mz')
| -rw-r--r-- | mz/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | mz/mz_header.cpp | 103 | ||||
| -rw-r--r-- | mz/mz_header.hpp | 41 | ||||
| -rw-r--r-- | mz/mz_header_parser.cpp | 2 |
4 files changed, 50 insertions, 101 deletions
diff --git a/mz/CMakeLists.txt b/mz/CMakeLists.txt index aad239b..338872d 100644 --- a/mz/CMakeLists.txt +++ b/mz/CMakeLists.txt @@ -8,10 +8,7 @@ target_include_directories(mz target_link_libraries(mz PUBLIC fusion-utils -) - -target_compile_options(mz - PUBLIC "-std=c++14" + PUBLIC binparse ) find_package(Boost COMPONENTS filesystem program_options system REQUIRED) diff --git a/mz/mz_header.cpp b/mz/mz_header.cpp index e6d4461..323c9cd 100644 --- a/mz/mz_header.cpp +++ b/mz/mz_header.cpp @@ -1,110 +1,61 @@ + #include "mz_header.hpp" + #include "index_list.hpp" +#include "binparse.hpp" + #include <boost/fusion/adapted/struct.hpp> #include <boost/fusion/adapted/struct/detail/extension.hpp> #include <vector> #include <iomanip> -UnexpectedEOS::UnexpectedEOS() -: std::runtime_error("Unexpected end of stream.") -{} +BOOST_FUSION_ADAPT_STRUCT( + mz::MZHeader, + (binparse::Magic16, magic) + (binparse::Value16, bytes_in_last_block) + (binparse::Value16, blocks_in_file) + (binparse::Value16, num_relocs) + (binparse::Value16, header_paragraphs) + (binparse::Value16, min_extra_paragraphs) + (binparse::Value16, max_extra_paragraphs) + (binparse::Offset16, ss) + (binparse::Offset16, sp) + (binparse::Value16, checksum) + (binparse::Offset16, ip) + (binparse::Offset16, cs) + (binparse::Offset16, reloc_table_offset) + (binparse::Value16, overlay_number) +) -UnexpectedEOS::UnexpectedEOS(std::__cxx11::string location) -: std::runtime_error("Unexpected end of stream after " + location) -{} +namespace mz { NotAMZFileException::NotAMZFileException() : std::runtime_error("This stream does not contain a valid MZ executable") {} -BOOST_FUSION_ADAPT_STRUCT( - MZHeader, - (Magic, magic) - (uint16_t, bytes_in_last_block) - (uint16_t, blocks_in_file) - (uint16_t, num_relocs) - (uint16_t, header_paragraphs) - (uint16_t, min_extra_paragraphs) - (uint16_t, max_extra_paragraphs) - (uint16_t, ss) - (uint16_t, sp) - (uint16_t, checksum) - (uint16_t, ip) - (uint16_t, cs) - (uint16_t, reloc_table_offset) - (uint16_t, overlay_number) -) - -template<typename T> -T parse(std::istream& is, std::string name); - -template<> -uint16_t parse<uint16_t>(std::istream& is, std::string name) { - if(!is) { - throw UnexpectedEOS(); - } - char data[2] = {0, 0}; - is.read(data, 2); - if(!is) { - throw UnexpectedEOS(name); - } - - return (((unsigned char) data[1]) << 8) | (unsigned char) data[0]; -} - -template<> -Magic parse<Magic>(std::istream& is, std::string name) { - if(!is) { - throw UnexpectedEOS(); - } - char data[2]; - is.read(data, 2); - if(!is) { - throw UnexpectedEOS(name); - } - - return static_cast<Magic>((data[1] << 8) | data[0]); -} - template <int... Indices> -MZHeader parse_mz_file_impl(std::istream& is, indices<Indices...>) { +MZHeader parse_file_impl(std::istream& is, indices<Indices...>) { return {parse<typename std::decay<typename boost::fusion::result_of::at_c<MZHeader, Indices>::type>::type>(is, boost::fusion::extension::struct_member_name<MZHeader, Indices>::call())...}; } -MZHeader parse_mz_file(std::istream& is) { +MZHeader parse_file(std::istream& is) { typedef build_indices<boost::fusion::result_of::size<MZHeader>::value>::type indices; - return parse_mz_file_impl(is, indices{}); + return parse_file_impl(is, indices{}); } std::ostream& output_impl(std::ostream& os, MZHeader const&, indices<>) { return os; } -template<typename T> -std::ostream& output(std::ostream& os, T rh) { - return os << std::hex << std::setw(sizeof(T) * 2) << std::setfill('0') << rh << std::endl; -} - -std::string to_string(Magic magic) { - char* c = reinterpret_cast<char*>(&magic); - return std::string(c, sizeof(Magic)); -} - -template <> -std::ostream& output<Magic>(std::ostream& os, Magic m) { - return os << std::hex << std::setw(4) << std::setfill('0') << m << " (" << to_string(m) << ")" << std::endl; -} - template <int I, int... Indices> std::ostream& output_impl(std::ostream& os, const MZHeader& header, indices<I, Indices...>) { - os << boost::fusion::extension::struct_member_name<MZHeader, I>::call() << ": "; - output(os, boost::fusion::at_c<I>(header)); + os << boost::fusion::extension::struct_member_name<MZHeader, I>::call() << ": " << boost::fusion::at_c<I>(header) << std::endl; return output_impl(os, header, indices<Indices...>{}); } @@ -114,3 +65,5 @@ std::ostream& operator<<(std::ostream& os, MZHeader const& header) return output_impl(os, header, indices{}); } + +} diff --git a/mz/mz_header.hpp b/mz/mz_header.hpp index ad5f419..fd42b43 100644 --- a/mz/mz_header.hpp +++ b/mz/mz_header.hpp @@ -1,14 +1,16 @@ #pragma once +#include "types.hpp" + #include <cstdint> #include <cstddef> #include <stdexcept> #include <istream> #include <ostream> -#include <boost/serialization/strong_typedef.hpp> +namespace mz { -BOOST_STRONG_TYPEDEF(uint16_t, Magic); +using namespace binparse; struct NotAMZFileException : public std::runtime_error { NotAMZFileException(); @@ -21,27 +23,24 @@ struct UnexpectedEOS : public std::runtime_error { }; struct MZHeader { - Magic magic; - uint16_t bytes_in_last_block; - uint16_t blocks_in_file; - uint16_t num_relocs; - uint16_t header_paragraphs; - uint16_t min_extra_paragraphs; - uint16_t max_extra_paragraphs; - uint16_t ss; - uint16_t sp; - uint16_t checksum; - uint16_t ip; - uint16_t cs; - uint16_t reloc_table_offset; - uint16_t overlay_number; + Magic16 magic; + Value16 bytes_in_last_block; + Value16 blocks_in_file; + Value16 num_relocs; + Value16 header_paragraphs; + Value16 min_extra_paragraphs; + Value16 max_extra_paragraphs; + Offset16 ss; + Offset16 sp; + Value16 checksum; + Offset16 ip; + Offset16 cs; + Offset16 reloc_table_offset; + Value16 overlay_number; }; -uint16_t parse_uint16_t(std::istream& is, std::string name = ""); - -MZHeader parse_mz_file(std::istream& is); - -void print_mz_header(MZHeader const& header); +MZHeader parse_file(std::istream& is); std::ostream& operator<<(std::ostream& os, MZHeader const& header); +} diff --git a/mz/mz_header_parser.cpp b/mz/mz_header_parser.cpp index d18a72e..66718d1 100644 --- a/mz/mz_header_parser.cpp +++ b/mz/mz_header_parser.cpp @@ -49,7 +49,7 @@ int main(int argc, char* argv[]) { } std::ifstream file(file_path.string()); - auto x = parse_mz_file(file); + auto x = mz::parse_file(file); std::cout << x << std::endl; return 0; |
