summaryrefslogtreecommitdiff
path: root/binparse/parse.cpp
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-06-22 00:15:08 +0200
committerDennis Brentjes <d.brentjes@gmail.com>2016-06-22 00:16:28 +0200
commit22231518b9c2c0b7f73c72a6ca834df659c63c7f (patch)
tree12b1d20efd3303583649966ddfe135a81ae8109b /binparse/parse.cpp
parent46145fe7d5b1d9f0921121a088a3d61f968cc473 (diff)
downloadopenwar-22231518b9c2c0b7f73c72a6ca834df659c63c7f.tar.gz
openwar-22231518b9c2c0b7f73c72a6ca834df659c63c7f.tar.bz2
openwar-22231518b9c2c0b7f73c72a6ca834df659c63c7f.zip
Reduces the amount of boilerplate neccesary to parse the binary format.
Diffstat (limited to 'binparse/parse.cpp')
-rw-r--r--binparse/parse.cpp137
1 files changed, 137 insertions, 0 deletions
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<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));
+}
+
+template<>
+std::array<uint8_t, 8> parse<std::array<uint8_t, 8>>(std::istream& is, std::string name) {
+ if(!is) {
+ throw UnexpectedEOS();
+ }
+
+ std::array<uint8_t, 8> buffer;
+ is.read(reinterpret_cast<char*>(buffer.data()), buffer.size());
+
+ if(!is) {
+ throw UnexpectedEOS(name);
+ }
+
+ return buffer;
+}
+
+template<>
+std::array<uint8_t, 22> parse<std::array<uint8_t, 22>>(std::istream& is, std::string name) {
+ if(!is) {
+ throw UnexpectedEOS();
+ }
+
+ std::array<uint8_t, 22> buffer;
+ is.read(reinterpret_cast<char*>(buffer.data()), buffer.size());
+
+ if(!is) {
+ throw UnexpectedEOS(name);
+ }
+
+ return buffer;
+}
+
+void dump_bytes(std::istream& is, std::vector<uint8_t>& buffer, std::string name)
+{
+ if(!is) {
+ throw UnexpectedEOS();
+ }
+
+ is.read(reinterpret_cast<char*>(buffer.data()), buffer.size());
+
+ if(!is) {
+ throw UnexpectedEOS(name);
+ }
+}
+
+} \ No newline at end of file