summaryrefslogtreecommitdiff
path: root/mz
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-06-19 20:23:07 +0200
committerDennis Brentjes <d.brentjes@gmail.com>2016-06-19 20:23:07 +0200
commitcea325b7451c1fb8dd22462ec2e7b5b88ea9b547 (patch)
treeffa2811b2ca24b3aa7e08bb28b45e7e9adbd154c /mz
parentc66d1f5c0af70161f4ad4c4175f4280e95b55dfd (diff)
downloadopenwar-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.txt5
-rw-r--r--mz/mz_header.cpp103
-rw-r--r--mz/mz_header.hpp41
-rw-r--r--mz/mz_header_parser.cpp2
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;