summaryrefslogtreecommitdiff
path: root/binparse/binparse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'binparse/binparse.cpp')
-rw-r--r--binparse/binparse.cpp132
1 files changed, 132 insertions, 0 deletions
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