diff options
| author | ljfa-ag <ljfa-ag@web.de> | 2015-08-12 19:17:59 +0200 |
|---|---|---|
| committer | ljfa-ag <ljfa-ag@web.de> | 2015-08-12 19:17:59 +0200 |
| commit | 1b9fd75fad70da33ad6b31a0da5f6b1c6d074849 (patch) | |
| tree | 03f15b72765a054ff51d98d7d9c43fa11c3147e6 | |
| parent | 8b792c2a968fed130c9869db37db658e92a0a587 (diff) | |
| download | Project-Tick-1b9fd75fad70da33ad6b31a0da5f6b1c6d074849.tar.gz Project-Tick-1b9fd75fad70da33ad6b31a0da5f6b1c6d074849.zip | |
Implement write_payload and write_tag
| -rw-r--r-- | include/io/stream_writer.h | 4 | ||||
| -rw-r--r-- | include/tag_array.h | 4 | ||||
| -rw-r--r-- | include/tag_list.h | 1 | ||||
| -rw-r--r-- | src/io/stream_writer.cpp | 6 | ||||
| -rw-r--r-- | src/tag_array.cpp | 22 | ||||
| -rw-r--r-- | src/tag_compound.cpp | 8 | ||||
| -rw-r--r-- | src/tag_list.cpp | 18 | ||||
| -rw-r--r-- | src/tag_string.cpp | 6 |
8 files changed, 65 insertions, 4 deletions
diff --git a/include/io/stream_writer.h b/include/io/stream_writer.h index 8c354cceba..1502593055 100644 --- a/include/io/stream_writer.h +++ b/include/io/stream_writer.h @@ -68,12 +68,12 @@ public: /** * @brief Writes the given tag's payload into the stream */ - void write_payload(const tag& t); + void write_payload(const tag& t) { t.write_payload(*this); } /** * @brief Writes a tag type to the stream */ - void write_type(tag_type tt); + void write_type(tag_type tt) { write_num(static_cast<int8_t>(tt)); } /** * @brief Writes a binary number to the stream diff --git a/include/tag_array.h b/include/tag_array.h index f2163f6486..14dd4d4480 100644 --- a/include/tag_array.h +++ b/include/tag_array.h @@ -105,6 +105,10 @@ public: const_iterator cend() const; void read_payload(io::stream_reader& reader) override; + /** + * @inheritdoc + * @throw std::length_error if the array is too large for NBT + */ void write_payload(io::stream_writer& writer) const override; private: diff --git a/include/tag_list.h b/include/tag_list.h index 61ada4a5b9..66f63e6ed9 100644 --- a/include/tag_list.h +++ b/include/tag_list.h @@ -166,6 +166,7 @@ public: /** * @inheritdoc * In case of a list of undetermined content type, the written type will be tag_end. + * @throw std::length_error if the list is too long for NBT */ void write_payload(io::stream_writer& writer) const override; diff --git a/src/io/stream_writer.cpp b/src/io/stream_writer.cpp index 26a6a7eb65..f21fdb701c 100644 --- a/src/io/stream_writer.cpp +++ b/src/io/stream_writer.cpp @@ -25,9 +25,11 @@ namespace nbt namespace io { -void stream_writer::write_type(tag_type tt) +void stream_writer::write_tag(const std::string& key, const tag& t) { - write_num(static_cast<int8_t>(tt)); + write_type(t.get_type()); + write_string(key); + write_payload(t); } void stream_writer::write_string(const std::string& str) diff --git a/src/tag_array.cpp b/src/tag_array.cpp index f83bce11f7..124c470bd1 100644 --- a/src/tag_array.cpp +++ b/src/tag_array.cpp @@ -19,6 +19,7 @@ */ #include "tag_array.h" #include "io/stream_reader.h" +#include "io/stream_writer.h" #include <istream> namespace nbt @@ -102,6 +103,7 @@ template<class T> auto tag_array<T>::cbegin() const -> const_iterator { return d template<class T> auto tag_array<T>::cend() const -> const_iterator { return data.cend(); } //Slightly different between byte_array and int_array +//Reading template<> void tag_array<int8_t>::read_payload(io::stream_reader& reader) { @@ -140,6 +142,26 @@ void tag_array<int32_t>::read_payload(io::stream_reader& reader) throw io::input_error("Error reading contents of tag_int_array"); } +//Writing +template<> +void tag_array<int8_t>::write_payload(io::stream_writer& writer) const +{ + if(size() > INT32_MAX) + throw std::length_error("Byte array is too large for NBT"); + writer.write_num(static_cast<int32_t>(size())); + writer.get_ostr().write(reinterpret_cast<const char*>(data.data()), data.size()); +} + +template<> +void tag_array<int32_t>::write_payload(io::stream_writer& writer) const +{ + if(size() > INT32_MAX) + throw std::length_error("Int array is too large for NBT"); + writer.write_num(static_cast<int32_t>(size())); + for(int32_t i: data) + writer.write_num(i); +} + template<class T> bool operator==(const tag_array<T>& lhs, const tag_array<T>& rhs) { diff --git a/src/tag_compound.cpp b/src/tag_compound.cpp index 3581dd149b..d0f20512ae 100644 --- a/src/tag_compound.cpp +++ b/src/tag_compound.cpp @@ -19,6 +19,7 @@ */ #include "tag_compound.h" #include "io/stream_reader.h" +#include "io/stream_writer.h" #include <istream> #include <sstream> @@ -120,6 +121,13 @@ void tag_compound::read_payload(io::stream_reader& reader) } } +void tag_compound::write_payload(io::stream_writer& writer) const +{ + for(const auto& pair: tags) + writer.write_tag(pair.first, pair.second); + writer.write_type(tag_type::End); +} + bool operator==(const tag_compound& lhs, const tag_compound& rhs) { return lhs.tags == rhs.tags; diff --git a/src/tag_list.cpp b/src/tag_list.cpp index f5a5b91758..dbdda2db77 100644 --- a/src/tag_list.cpp +++ b/src/tag_list.cpp @@ -20,6 +20,7 @@ #include "tag_list.h" #include "nbt_tags.h" #include "io/stream_reader.h" +#include "io/stream_writer.h" #include <istream> namespace nbt @@ -158,6 +159,23 @@ void tag_list::read_payload(io::stream_reader& reader) } } +void tag_list::write_payload(io::stream_writer& writer) const +{ + if(size() > INT32_MAX) + throw std::length_error("List is too large for NBT"); + writer.write_type(el_type_ != tag_type::Null + ? el_type_ + : tag_type::End); + writer.write_num(static_cast<int32_t>(size())); + for(const auto& val: tags) + { + //check if the value is of the correct type + if(val.get_type() != el_type_) + throw std::bad_cast(); + writer.write_payload(val); + } +} + bool operator==(const tag_list& lhs, const tag_list& rhs) { return lhs.el_type_ == rhs.el_type_ && lhs.tags == rhs.tags; diff --git a/src/tag_string.cpp b/src/tag_string.cpp index 83cb815c52..1a8f1cd5d2 100644 --- a/src/tag_string.cpp +++ b/src/tag_string.cpp @@ -19,6 +19,7 @@ */ #include "tag_string.h" #include "io/stream_reader.h" +#include "io/stream_writer.h" namespace nbt { @@ -90,6 +91,11 @@ void tag_string::read_payload(io::stream_reader& reader) } } +void tag_string::write_payload(io::stream_writer& writer) const +{ + writer.write_string(value); +} + bool operator==(const tag_string& lhs, const tag_string& rhs) { return lhs.get() == rhs.get(); |
