summaryrefslogtreecommitdiff
path: root/binparse
diff options
context:
space:
mode:
Diffstat (limited to 'binparse')
-rw-r--r--binparse/CMakeLists.txt13
-rw-r--r--binparse/binparse.cpp132
-rw-r--r--binparse/binparse.hpp57
-rw-r--r--binparse/types.hpp20
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