summaryrefslogtreecommitdiff
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
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.
-rw-r--r--CMakeLists.txt2
-rw-r--r--binparse/CMakeLists.txt13
-rw-r--r--binparse/binparse.cpp132
-rw-r--r--binparse/binparse.hpp57
-rw-r--r--binparse/types.hpp20
-rw-r--r--le/CMakeLists.txt31
-rw-r--r--le/le_header.cpp92
-rw-r--r--le/le_header.hpp107
-rw-r--r--le/le_header_parser.cpp57
-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
13 files changed, 561 insertions, 101 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 24fb61f..c618557 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,5 +3,7 @@ cmake_minimum_required(VERSION 3.5.2)
project(openwar)
add_subdirectory(fusion-utils)
+add_subdirectory(binparse)
add_subdirectory(mz)
+add_subdirectory(le)
diff --git a/binparse/CMakeLists.txt b/binparse/CMakeLists.txt
new file mode 100644
index 0000000..00fc246
--- /dev/null
+++ b/binparse/CMakeLists.txt
@@ -0,0 +1,13 @@
+
+add_library(binparse STATIC
+ types.hpp
+ binparse.hpp binparse.cpp
+)
+
+target_include_directories(binparse
+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+target_compile_options(binparse
+ PUBLIC "-std=c++14"
+) \ No newline at end of file
diff --git a/binparse/binparse.cpp b/binparse/binparse.cpp
new file mode 100644
index 0000000..1dc4fc6
--- /dev/null
+++ b/binparse/binparse.cpp
@@ -0,0 +1,132 @@
+
+#include "binparse.hpp"
+
+namespace binparse {
+
+UnexpectedEOS::UnexpectedEOS()
+: std::runtime_error("Unexpected end of stream.")
+{}
+
+UnexpectedEOS::UnexpectedEOS(std::__cxx11::string location)
+: std::runtime_error("Unexpected end of stream after " + location)
+{}
+
+template<>
+uint8_t parse<uint8_t>(std::istream& is, std::string name) {
+ if(!is) {
+ throw UnexpectedEOS();
+ }
+ char data = 0;
+ is.read(&data, 1);
+ if(!is) {
+ throw UnexpectedEOS(name);
+ }
+
+ return (unsigned char) data;
+}
+
+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<>
+uint32_t parse<uint32_t>(std::istream& is, std::string name) {
+ if(!is) {
+ throw UnexpectedEOS();
+ }
+ char data[4] = {0, 0};
+ is.read(data, sizeof(data));
+ if(!is) {
+ throw UnexpectedEOS(name);
+ }
+
+ return (
+ ((unsigned char) data[3]) << 24
+ | ((unsigned char) data[2]) << 16
+ | ((unsigned char) data[1]) << 8
+ | ((unsigned char) data[0])
+ );
+}
+
+template<>
+Value8 parse<Value8>(std::istream& is, std::string name) {
+ return Value8(parse<uint8_t>(is, name));
+}
+
+template<>
+Value16 parse<Value16>(std::istream& is, std::string name) {
+ return Value16(parse<uint16_t>(is, name));
+}
+
+template<>
+Magic16 parse<Magic16>(std::istream& is, std::string name) {
+ return Magic16(parse<uint16_t>(is, name));
+}
+
+template<>
+Offset16 parse<Offset16>(std::istream& is, std::string name) {
+ return Offset16(parse<uint16_t>(is, name));
+}
+
+template<>
+Value32 parse<Value32>(std::istream& is, std::string name) {
+ return Value32(parse<uint32_t>(is, name));
+}
+
+template<>
+Offset32 parse<Offset32>(std::istream& is, std::string name) {
+ return Offset32(parse<uint32_t>(is, 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/binparse.hpp
new file mode 100644
index 0000000..1620ab5
--- /dev/null
+++ b/binparse/binparse.hpp
@@ -0,0 +1,57 @@
+#include "types.hpp"
+
+#include <string>
+#include <ostream>
+#include <iomanip>
+
+namespace binparse {
+
+struct UnexpectedEOS : public std::runtime_error {
+ UnexpectedEOS();
+
+ UnexpectedEOS(std::string location);
+};
+
+template<typename T>
+T parse(std::istream& is, std::string name);
+
+template<>
+uint8_t parse<uint8_t>(std::istream& is, std::string name);
+
+template<>
+uint16_t parse<uint16_t>(std::istream& is, std::string name);
+
+template<>
+uint32_t parse<uint32_t>(std::istream& is, std::string name);
+
+template<>
+Magic16 parse<Magic16>(std::istream& is, std::string name);
+
+template<>
+Value16 parse<Value16>(std::istream& is, std::string name);
+
+template<>
+Offset16 parse<Offset16>(std::istream& is, std::string name);
+
+template<>
+Value32 parse<Value32>(std::istream& is, std::string name);
+
+template<>
+Offset32 parse<Offset32>(std::istream& is, std::string name);
+
+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);
+
+} \ No newline at end of file
diff --git a/binparse/types.hpp b/binparse/types.hpp
new file mode 100644
index 0000000..e92a7a6
--- /dev/null
+++ b/binparse/types.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <boost/serialization/strong_typedef.hpp>
+
+#include <cstdint>
+
+namespace binparse {
+
+BOOST_STRONG_TYPEDEF(uint16_t, Magic16)
+
+BOOST_STRONG_TYPEDEF(uint8_t, Offset8)
+BOOST_STRONG_TYPEDEF(uint8_t, Value8)
+
+BOOST_STRONG_TYPEDEF(uint16_t, Offset16)
+BOOST_STRONG_TYPEDEF(uint16_t, Value16)
+
+BOOST_STRONG_TYPEDEF(uint32_t, Offset32)
+BOOST_STRONG_TYPEDEF(uint32_t, Value32)
+
+} \ No newline at end of file
diff --git a/le/CMakeLists.txt b/le/CMakeLists.txt
new file mode 100644
index 0000000..a4887c5
--- /dev/null
+++ b/le/CMakeLists.txt
@@ -0,0 +1,31 @@
+
+add_library(le STATIC
+ le_header.hpp le_header.cpp
+)
+
+target_include_directories(le
+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+target_link_libraries(le
+ PUBLIC fusion-utils
+ PUBLIC binparse
+)
+
+add_executable(le_header_parser
+ le_header_parser.cpp
+)
+
+find_package(Boost COMPONENTS filesystem program_options system REQUIRED)
+
+target_link_libraries(le_header_parser
+ PRIVATE le
+ PRIVATE ${Boost_LIBRARIES}
+)
+
+target_include_directories(le_header_parser
+ PRIVATE ${Boost_INCLUDE_DIRS}
+)
+
+
+
diff --git a/le/le_header.cpp b/le/le_header.cpp
new file mode 100644
index 0000000..a429add
--- /dev/null
+++ b/le/le_header.cpp
@@ -0,0 +1,92 @@
+
+#include "le_header.hpp"
+
+#include "index_list.hpp"
+#include "binparse.hpp"
+
+#include <boost/fusion/adapted/struct.hpp>
+
+BOOST_FUSION_ADAPT_STRUCT(
+ le::LEHeader,
+ (binparse::Magic16, magic)
+ (binparse::Value8, B_ord)
+ (binparse::Value8, W_ord)
+ (binparse::Value32, format_level)
+ (binparse::Value16, cpu_type)
+ (binparse::Value16, os_type)
+ (binparse::Value32, module_version)
+ (binparse::Value32, module_flags)
+ (binparse::Value32, module_nr_of_pages)
+ (binparse::Offset32, EIP_object)
+ (binparse::Offset32, EIP)
+ (binparse::Offset32, ESP_object)
+ (binparse::Offset32, ESP)
+ (binparse::Value32, page_size)
+ (binparse::Offset32, page_offset_shift)
+ (binparse::Value32, fixup_section_size)
+ (binparse::Value32, fixup_section_checksum)
+ (binparse::Value32, loader_section_size)
+ (binparse::Value32, loader_section_checksum)
+ (binparse::Offset32, object_table_offset)
+ (binparse::Value32, nr_objects_in_module)
+ (binparse::Offset32, object_page_table_offset)
+ (binparse::Offset32, objct_iter_pages_offset)
+ (binparse::Offset32, resource_table_offset)
+ (binparse::Value32, nr_resource_table_entries)
+ (binparse::Offset32, resident_name_table_offset)
+ (binparse::Offset32, entry_table_offset)
+ (binparse::Offset32, module_directives_offset)
+ (binparse::Value32, nr_module_directives)
+ (binparse::Offset32, fixup_page_table_offset)
+ (binparse::Offset32, fixup_record_table_offset)
+ (binparse::Offset32, import_module_table_offset)
+ (binparse::Value32, import_mod_entries)
+ (binparse::Offset32, import_proc_table_offset)
+ (binparse::Offset32, per_page_checksum_offset)
+ (binparse::Offset32, data_page_offset)
+ (binparse::Value32, nr_preload_pages)
+ (binparse::Offset32, non_res_name_table_offset)
+ (binparse::Value32, non_res_name_table_length)
+ (binparse::Value32, non_res_name_table_checksum)
+ (binparse::Value32, auto_ds_object_nr)
+ (binparse::Offset32, debug_info_offset)
+ (binparse::Value32, debug_info_length)
+ (binparse::Value32, nr_instance_preload)
+ (binparse::Value32, nr_instance_demand)
+ (binparse::Value32, heapsize)
+)
+
+namespace le {
+
+template <int... Indices>
+LEHeader parse_file_impl(std::istream& is, indices<Indices...>) {
+
+ return {parse<typename std::decay<typename boost::fusion::result_of::at_c<LEHeader, Indices>::type>::type>(is, boost::fusion::extension::struct_member_name<LEHeader, Indices>::call())...};
+
+}
+
+LEHeader parse_file(std::istream& is) {
+
+ typedef build_indices<boost::fusion::result_of::size<LEHeader>::value>::type indices;
+
+ return parse_file_impl(is, indices{});
+}
+
+std::ostream& output_impl(std::ostream& os, LEHeader const&, indices<>) {
+ return os;
+}
+
+template <int I, int... Indices>
+std::ostream& output_impl(std::ostream& os, const LEHeader& header, indices<I, Indices...>) {
+ os << boost::fusion::extension::struct_member_name<LEHeader, I>::call() << ": " << boost::fusion::at_c<I>(header) << std::endl;
+ return output_impl(os, header, indices<Indices...>{});
+}
+
+std::ostream& operator<<(std::ostream& os, LEHeader const& header)
+{
+ typedef build_indices<boost::fusion::result_of::size<LEHeader>::value>::type indices;
+
+ return output_impl(os, header, indices{});
+}
+
+} \ No newline at end of file
diff --git a/le/le_header.hpp b/le/le_header.hpp
new file mode 100644
index 0000000..9501127
--- /dev/null
+++ b/le/le_header.hpp
@@ -0,0 +1,107 @@
+
+#include "types.hpp"
+
+#include <cstdint>
+
+namespace le {
+
+using namespace binparse;
+
+struct NotALEFileException : public std::runtime_error {
+ NotALEFileException();
+};
+
+enum class Bord : uint8_t {
+ little_endian = 0,
+ big_endian = 1,
+};
+
+enum class Word : uint8_t {
+ little_endian = 0,
+ big_endian = 0,
+};
+
+enum class CpuType : uint16_t {
+ _80286 = 1,
+ _80386 = 2,
+ _80486 = 3,
+};
+
+enum class OsType : uint16_t {
+ Unknown = 0,
+ OS_2 = 1,
+ Windows = 2,
+ Dos_4x = 3,
+ Windows_386 = 4,
+};
+
+enum class module_flags {
+ per_process_library_initialization = 0x4,
+ internal_fixups = 0x10,
+ incompat_pm_windowing = 0x100,
+ compat_pm_windowing = 0x200,
+ uses_pm_windowing = 0x300,
+ module_not_loadable = 0x2000,
+ module_type_mask = 0x38000,
+ program_module = 0x0,
+ library_module = 0x8000,
+ protected_memory_library_module = 0x18000,
+ physical_device_driver_module = 0x20000,
+ virtual_device_driver_module = 0x28000,
+ per_process_library_temrination = 0x40000000,
+};
+
+struct LEHeader {
+ Magic16 magic;
+ Value8 B_ord;
+ Value8 W_ord;
+ Value32 format_level;
+ Value16 cpu_type;
+ Value16 os_type;
+ Value32 module_version;
+ Value32 module_flags;
+ Value32 module_nr_of_pages;
+ Offset32 EIP_object;
+ Offset32 EIP;
+ Offset32 ESP_object;
+ Offset32 ESP;
+ Value32 page_size;
+ Offset32 page_offset_shift;
+ Value32 fixup_section_size;
+ Value32 fixup_section_checksum;
+ Value32 loader_section_size;
+ Value32 loader_section_checksum;
+ Offset32 object_table_offset;
+ Value32 nr_objects_in_module;
+ Offset32 object_page_table_offset;
+ Offset32 objct_iter_pages_offset;
+ Offset32 resource_table_offset;
+ Value32 nr_resource_table_entries;
+ Offset32 resident_name_table_offset;
+ Offset32 entry_table_offset;
+ Offset32 module_directives_offset;
+ Value32 nr_module_directives;
+ Offset32 fixup_page_table_offset;
+ Offset32 fixup_record_table_offset;
+ Offset32 import_module_table_offset;
+ Value32 import_mod_entries;
+ Offset32 import_proc_table_offset;
+ Offset32 per_page_checksum_offset;
+ Offset32 data_page_offset;
+ Value32 nr_preload_pages;
+ Offset32 non_res_name_table_offset;
+ Value32 non_res_name_table_length;
+ Value32 non_res_name_table_checksum;
+ Value32 auto_ds_object_nr;
+ Offset32 debug_info_offset;
+ Value32 debug_info_length;
+ Value32 nr_instance_preload;
+ Value32 nr_instance_demand;
+ Value32 heapsize;
+};
+
+LEHeader parse_file(std::istream& is);
+
+std::ostream& operator<<(std::ostream& os, LEHeader const& header);
+
+} \ No newline at end of file
diff --git a/le/le_header_parser.cpp b/le/le_header_parser.cpp
new file mode 100644
index 0000000..524c60d
--- /dev/null
+++ b/le/le_header_parser.cpp
@@ -0,0 +1,57 @@
+
+#include "le_header.hpp"
+
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+
+#include <iostream>
+
+int main(int argc, char* argv[]) {
+ boost::program_options::options_description description;
+ description.add_options()
+ ("help,h", "produces this help message")
+ ("exe,e", boost::program_options::value<std::string>(), "The LE executable to parse the header for.")
+ ;
+
+ boost::program_options::variables_map vm;
+ boost::program_options::store(boost::program_options::parse_command_line(argc, argv, description), vm);
+ boost::program_options::notify(vm);
+
+ if(vm.count("help")) {
+ std::cout << description << std::endl;
+ return 0;
+ }
+
+ boost::filesystem::path file_path;
+ if(vm.count("exe")) {
+ std::string exe_file = vm["exe"].as<std::string>();
+
+ if(boost::filesystem::exists(exe_file)) {
+ if(!boost::filesystem::is_directory(exe_file)) {
+ file_path = exe_file;
+ } else {
+ std::cerr << exe_file << " is a folder" << std::endl;
+ std::cerr << std::endl;
+ std::cerr << description << std::endl;
+ return -1;
+ }
+ } else {
+ std::cerr << "file: " << exe_file << " does not exist" << std::endl;
+ std::cerr << std::endl;
+ std::cerr << description << std::endl;
+ return -1;
+ }
+ } else {
+ std::cerr << "Option \"exe_file\" is required";
+ std::cerr << std::endl;
+ std::cerr << description << std::endl;
+ return -1;
+ }
+
+ std::ifstream file(file_path.string());
+ file.seekg(0x2aa8);
+ auto x = le::parse_file(file);
+ std::cout << x << std::endl;
+
+ return 0;
+}
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;