diff options
Diffstat (limited to 'binparse')
| -rw-r--r-- | binparse/CMakeLists.txt | 13 | ||||
| -rw-r--r-- | binparse/binparse.cpp | 132 | ||||
| -rw-r--r-- | binparse/binparse.hpp | 57 | ||||
| -rw-r--r-- | binparse/types.hpp | 20 |
4 files changed, 222 insertions, 0 deletions
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 |
