From 22231518b9c2c0b7f73c72a6ca834df659c63c7f Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Wed, 22 Jun 2016 00:15:08 +0200 Subject: Reduces the amount of boilerplate neccesary to parse the binary format. --- binparse/parse.cpp | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 binparse/parse.cpp (limited to 'binparse/parse.cpp') diff --git a/binparse/parse.cpp b/binparse/parse.cpp new file mode 100644 index 0000000..cf7c0be --- /dev/null +++ b/binparse/parse.cpp @@ -0,0 +1,137 @@ +#include "parse.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(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(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(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(std::istream& is, std::string name) { + return Value8(parse(is, name)); +} + +template<> +Value16 parse(std::istream& is, std::string name) { + return Value16(parse(is, name)); +} + +template<> +Magic16 parse(std::istream& is, std::string name) { + return Magic16(parse(is, name)); +} + +template<> +Offset16 parse(std::istream& is, std::string name) { + return Offset16(parse(is, name)); +} + +template<> +Value32 parse(std::istream& is, std::string name) { + return Value32(parse(is, name)); +} + +template<> +Offset32 parse(std::istream& is, std::string name) { + return Offset32(parse(is, name)); +} + +template<> +std::array parse>(std::istream& is, std::string name) { + if(!is) { + throw UnexpectedEOS(); + } + + std::array buffer; + is.read(reinterpret_cast(buffer.data()), buffer.size()); + + if(!is) { + throw UnexpectedEOS(name); + } + + return buffer; +} + +template<> +std::array parse>(std::istream& is, std::string name) { + if(!is) { + throw UnexpectedEOS(); + } + + std::array buffer; + is.read(reinterpret_cast(buffer.data()), buffer.size()); + + if(!is) { + throw UnexpectedEOS(name); + } + + return buffer; +} + +void dump_bytes(std::istream& is, std::vector& buffer, std::string name) +{ + if(!is) { + throw UnexpectedEOS(); + } + + is.read(reinterpret_cast(buffer.data()), buffer.size()); + + if(!is) { + throw UnexpectedEOS(name); + } +} + +} \ No newline at end of file -- cgit v1.2.3-70-g09d2