diff options
Diffstat (limited to 'depends/libnbtplusplus/include')
18 files changed, 1855 insertions, 0 deletions
diff --git a/depends/libnbtplusplus/include/crtp_tag.h b/depends/libnbtplusplus/include/crtp_tag.h new file mode 100644 index 00000000..82b41907 --- /dev/null +++ b/depends/libnbtplusplus/include/crtp_tag.h @@ -0,0 +1,66 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef CRTP_TAG_H_INCLUDED +#define CRTP_TAG_H_INCLUDED + +#include "tag.h" +#include "nbt_visitor.h" +#include "make_unique.h" + +#include "nbt++_export.h" + +namespace nbt +{ + +namespace detail +{ + + template<class Sub> + class NBT___EXPORT crtp_tag : public tag + { + public: + //Pure virtual destructor to make the class abstract + virtual ~crtp_tag() noexcept = 0; + + tag_type get_type() const noexcept override final { return Sub::type; }; + + std::unique_ptr<tag> clone() const& override final { return make_unique<Sub>(sub_this()); } + std::unique_ptr<tag> move_clone() && override final { return make_unique<Sub>(std::move(sub_this())); } + + tag& assign(tag&& rhs) override final { return sub_this() = dynamic_cast<Sub&&>(rhs); } + + void accept(nbt_visitor& visitor) override final { visitor.visit(sub_this()); } + void accept(const_nbt_visitor& visitor) const override final { visitor.visit(sub_this()); } + + private: + bool equals(const tag& rhs) const override final { return sub_this() == static_cast<const Sub&>(rhs); } + + Sub& sub_this() { return static_cast<Sub&>(*this); } + const Sub& sub_this() const { return static_cast<const Sub&>(*this); } + }; + + template<class Sub> + crtp_tag<Sub>::~crtp_tag() noexcept {} + +} + +} + +#endif // CRTP_TAG_H_INCLUDED diff --git a/depends/libnbtplusplus/include/endian_str.h b/depends/libnbtplusplus/include/endian_str.h new file mode 100644 index 00000000..ac8e8986 --- /dev/null +++ b/depends/libnbtplusplus/include/endian_str.h @@ -0,0 +1,113 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef ENDIAN_STR_H_INCLUDED +#define ENDIAN_STR_H_INCLUDED + +#include <cstdint> +#include <iosfwd> + +#include "nbt++_export.h" + +/** + * @brief Reading and writing numbers from and to streams + * in binary format with different byte orders. + */ +namespace endian +{ + +enum endian { little, big }; + +///Reads number from stream in specified endian +template<class T> +NBT___EXPORT void read(std::istream& is, T& x, endian e); + +///Reads number from stream in little endian +NBT___EXPORT void read_little(std::istream& is, uint8_t& x); +NBT___EXPORT void read_little(std::istream& is, uint16_t& x); +NBT___EXPORT void read_little(std::istream& is, uint32_t& x); +NBT___EXPORT void read_little(std::istream& is, uint64_t& x); +NBT___EXPORT void read_little(std::istream& is, int8_t& x); +NBT___EXPORT void read_little(std::istream& is, int16_t& x); +NBT___EXPORT void read_little(std::istream& is, int32_t& x); +NBT___EXPORT void read_little(std::istream& is, int64_t& x); +NBT___EXPORT void read_little(std::istream& is, float& x); +NBT___EXPORT void read_little(std::istream& is, double& x); + +///Reads number from stream in big endian +NBT___EXPORT void read_big(std::istream& is, uint8_t& x); +NBT___EXPORT void read_big(std::istream& is, uint16_t& x); +NBT___EXPORT void read_big(std::istream& is, uint32_t& x); +NBT___EXPORT void read_big(std::istream& is, uint64_t& x); +NBT___EXPORT void read_big(std::istream& is, int8_t& x); +NBT___EXPORT void read_big(std::istream& is, int16_t& x); +NBT___EXPORT void read_big(std::istream& is, int32_t& x); +NBT___EXPORT void read_big(std::istream& is, int64_t& x); +NBT___EXPORT void read_big(std::istream& is, float& x); +NBT___EXPORT void read_big(std::istream& is, double& x); + +///Writes number to stream in specified endian +template<class T> +NBT___EXPORT void write(std::ostream& os, T x, endian e); + +///Writes number to stream in little endian +NBT___EXPORT void write_little(std::ostream& os, uint8_t x); +NBT___EXPORT void write_little(std::ostream& os, uint16_t x); +NBT___EXPORT void write_little(std::ostream& os, uint32_t x); +NBT___EXPORT void write_little(std::ostream& os, uint64_t x); +NBT___EXPORT void write_little(std::ostream& os, int8_t x); +NBT___EXPORT void write_little(std::ostream& os, int16_t x); +NBT___EXPORT void write_little(std::ostream& os, int32_t x); +NBT___EXPORT void write_little(std::ostream& os, int64_t x); +NBT___EXPORT void write_little(std::ostream& os, float x); +NBT___EXPORT void write_little(std::ostream& os, double x); + +///Writes number to stream in big endian +NBT___EXPORT void write_big(std::ostream& os, uint8_t x); +NBT___EXPORT void write_big(std::ostream& os, uint16_t x); +NBT___EXPORT void write_big(std::ostream& os, uint32_t x); +NBT___EXPORT void write_big(std::ostream& os, uint64_t x); +NBT___EXPORT void write_big(std::ostream& os, int8_t x); +NBT___EXPORT void write_big(std::ostream& os, int16_t x); +NBT___EXPORT void write_big(std::ostream& os, int32_t x); +NBT___EXPORT void write_big(std::ostream& os, int64_t x); +NBT___EXPORT void write_big(std::ostream& os, float x); +NBT___EXPORT void write_big(std::ostream& os, double x); + +template<class T> +NBT___EXPORT void read(std::istream& is, T& x, endian e) +{ + if(e == little) + read_little(is, x); + else + read_big(is, x); +} + +template<class T> +NBT___EXPORT void write(std::ostream& os, T x, endian e) +{ + if(e == little) + write_little(os, x); + else + write_big(os, x); +} + +} + +#endif // ENDIAN_STR_H_INCLUDED diff --git a/depends/libnbtplusplus/include/io/stream_reader.h b/depends/libnbtplusplus/include/io/stream_reader.h new file mode 100644 index 00000000..81255783 --- /dev/null +++ b/depends/libnbtplusplus/include/io/stream_reader.h @@ -0,0 +1,138 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef STREAM_READER_H_INCLUDED +#define STREAM_READER_H_INCLUDED + +#include "endian_str.h" +#include "tag.h" +#include "tag_compound.h" +#include <iosfwd> +#include <memory> +#include <stdexcept> +#include <utility> + +#include "nbt++_export.h" + +namespace nbt +{ +namespace io +{ + +///Exception that gets thrown when reading is not successful +class NBT___EXPORT input_error : public std::runtime_error +{ + using std::runtime_error::runtime_error; +}; + +/** +* @brief Reads a named tag from the stream, making sure that it is a compound +* @param is the stream to read from +* @param e the byte order of the source data. The Java edition +* of Minecraft uses Big Endian, the Pocket edition uses Little Endian +* @throw input_error on failure, or if the tag in the stream is not a compound +*/ +NBT___EXPORT std::pair<std::string, std::unique_ptr<tag_compound>> read_compound(std::istream& is, endian::endian e = endian::big); + +/** +* @brief Reads a named tag from the stream +* @param is the stream to read from +* @param e the byte order of the source data. The Java edition +* of Minecraft uses Big Endian, the Pocket edition uses Little Endian +* @throw input_error on failure +*/ +NBT___EXPORT std::pair<std::string, std::unique_ptr<tag>> read_tag(std::istream& is, endian::endian e = endian::big); + +/** + * @brief Helper class for reading NBT tags from input streams + * + * Can be reused to read multiple tags + */ +class NBT___EXPORT stream_reader +{ +public: + /** + * @param is the stream to read from + * @param e the byte order of the source data. The Java edition + * of Minecraft uses Big Endian, the Pocket edition uses Little Endian + */ + explicit stream_reader(std::istream& is, endian::endian e = endian::big) noexcept; + + ///Returns the stream + std::istream& get_istr() const; + ///Returns the byte order + endian::endian get_endian() const; + + /** + * @brief Reads a named tag from the stream, making sure that it is a compound + * @throw input_error on failure, or if the tag in the stream is not a compound + */ + std::pair<std::string, std::unique_ptr<tag_compound>> read_compound(); + + /** + * @brief Reads a named tag from the stream + * @throw input_error on failure + */ + std::pair<std::string, std::unique_ptr<tag>> read_tag(); + + /** + * @brief Reads a tag of the given type without name from the stream + * @throw input_error on failure + */ + std::unique_ptr<tag> read_payload(tag_type type); + + /** + * @brief Reads a tag type from the stream + * @param allow_end whether to consider tag_type::End valid + * @throw input_error on failure + */ + tag_type read_type(bool allow_end = false); + + /** + * @brief Reads a binary number from the stream + * + * On failure, will set the failbit on the stream. + */ + template<class T> + void read_num(T& x); + + /** + * @brief Reads an NBT string from the stream + * + * An NBT string consists of two bytes indicating the length, followed by + * the characters encoded in modified UTF-8. + * @throw input_error on failure + */ + std::string read_string(); + +private: + std::istream& is; + const endian::endian endian; +}; + +template<class T> +void stream_reader::read_num(T& x) +{ + endian::read(is, x, endian); +} + +} +} + +#endif // STREAM_READER_H_INCLUDED diff --git a/depends/libnbtplusplus/include/io/stream_writer.h b/depends/libnbtplusplus/include/io/stream_writer.h new file mode 100644 index 00000000..8938b73b --- /dev/null +++ b/depends/libnbtplusplus/include/io/stream_writer.h @@ -0,0 +1,122 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef STREAM_WRITER_H_INCLUDED +#define STREAM_WRITER_H_INCLUDED + +#include "tag.h" +#include "endian_str.h" +#include <iosfwd> + +#include "nbt++_export.h" + +namespace nbt +{ +namespace io +{ + +/* Not sure if that is even needed +///Exception that gets thrown when writing is not successful +class output_error : public std::runtime_error +{ + using std::runtime_error::runtime_error; +};*/ + +/** +* @brief Writes a named tag into the stream, including the tag type +* @param key the name of the tag +* @param t the tag +* @param os the stream to write to +* @param e the byte order of the written data. The Java edition +* of Minecraft uses Big Endian, the Pocket edition uses Little Endian +*/ +NBT___EXPORT void write_tag(const std::string& key, const tag& t, std::ostream& os, endian::endian e = endian::big); + +/** + * @brief Helper class for writing NBT tags to output streams + * + * Can be reused to write multiple tags + */ +class NBT___EXPORT stream_writer +{ +public: + ///Maximum length of an NBT string (16 bit unsigned) + static constexpr size_t max_string_len = UINT16_MAX; + ///Maximum length of an NBT list or array (32 bit signed) + static constexpr uint32_t max_array_len = INT32_MAX; + + /** + * @param os the stream to write to + * @param e the byte order of the written data. The Java edition + * of Minecraft uses Big Endian, the Pocket edition uses Little Endian + */ + explicit stream_writer(std::ostream& os, endian::endian e = endian::big) noexcept: + os(os), endian(e) + {} + + ///Returns the stream + std::ostream& get_ostr() const { return os; } + ///Returns the byte order + endian::endian get_endian() const { return endian; } + + /** + * @brief Writes a named tag into the stream, including the tag type + */ + void write_tag(const std::string& key, const tag& t); + + /** + * @brief Writes the given tag's payload into the stream + */ + void write_payload(const tag& t) { t.write_payload(*this); } + + /** + * @brief Writes a tag type to the stream + */ + void write_type(tag_type tt) { write_num(static_cast<int8_t>(tt)); } + + /** + * @brief Writes a binary number to the stream + */ + template<class T> + void write_num(T x); + + /** + * @brief Writes an NBT string to the stream + * + * An NBT string consists of two bytes indicating the length, followed by + * the characters encoded in modified UTF-8. + * @throw std::length_error if the string is too long for NBT + */ + void write_string(const std::string& str); + +private: + std::ostream& os; + const endian::endian endian; +}; + +template<class T> +void stream_writer::write_num(T x) +{ + endian::write(os, x, endian); +} + +} +} + +#endif // STREAM_WRITER_H_INCLUDED diff --git a/depends/libnbtplusplus/include/make_unique.h b/depends/libnbtplusplus/include/make_unique.h new file mode 100644 index 00000000..9a929543 --- /dev/null +++ b/depends/libnbtplusplus/include/make_unique.h @@ -0,0 +1,37 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef MAKE_UNIQUE_H_INCLUDED +#define MAKE_UNIQUE_H_INCLUDED + +#include <memory> + +namespace nbt +{ + +///Creates a new object of type T and returns a std::unique_ptr to it +template<class T, class... Args> +std::unique_ptr<T> make_unique(Args&&... args) +{ + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); +} + +} + +#endif // MAKE_UNIQUE_H_INCLUDED diff --git a/depends/libnbtplusplus/include/nbt_tags.h b/depends/libnbtplusplus/include/nbt_tags.h new file mode 100644 index 00000000..810bf0d6 --- /dev/null +++ b/depends/libnbtplusplus/include/nbt_tags.h @@ -0,0 +1,29 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef NBT_TAGS_H_INCLUDED +#define NBT_TAGS_H_INCLUDED + +#include "tag_primitive.h" +#include "tag_string.h" +#include "tag_array.h" +#include "tag_list.h" +#include "tag_compound.h" + +#endif // NBT_TAGS_H_INCLUDED diff --git a/depends/libnbtplusplus/include/nbt_visitor.h b/depends/libnbtplusplus/include/nbt_visitor.h new file mode 100644 index 00000000..6cd51f65 --- /dev/null +++ b/depends/libnbtplusplus/include/nbt_visitor.h @@ -0,0 +1,82 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef NBT_VISITOR_H_INCLUDED +#define NBT_VISITOR_H_INCLUDED + +#include "tagfwd.h" + +#include "nbt++_export.h" + +namespace nbt +{ + +/** + * @brief Base class for visitors of tags + * + * Implementing the Visitor pattern + */ +class NBT___EXPORT nbt_visitor +{ +public: + virtual ~nbt_visitor() noexcept = 0; //Abstract class + + virtual void visit(tag_byte&) {} + virtual void visit(tag_short&) {} + virtual void visit(tag_int&) {} + virtual void visit(tag_long&) {} + virtual void visit(tag_float&) {} + virtual void visit(tag_double&) {} + virtual void visit(tag_byte_array&) {} + virtual void visit(tag_string&) {} + virtual void visit(tag_list&) {} + virtual void visit(tag_compound&) {} + virtual void visit(tag_int_array&) {} +}; + +/** + * @brief Base class for visitors of constant tags + * + * Implementing the Visitor pattern + */ +class NBT___EXPORT const_nbt_visitor +{ +public: + virtual ~const_nbt_visitor() noexcept = 0; //Abstract class + + virtual void visit(const tag_byte&) {} + virtual void visit(const tag_short&) {} + virtual void visit(const tag_int&) {} + virtual void visit(const tag_long&) {} + virtual void visit(const tag_float&) {} + virtual void visit(const tag_double&) {} + virtual void visit(const tag_byte_array&) {} + virtual void visit(const tag_string&) {} + virtual void visit(const tag_list&) {} + virtual void visit(const tag_compound&) {} + virtual void visit(const tag_int_array&) {} +}; + +inline nbt_visitor::~nbt_visitor() noexcept {} + +inline const_nbt_visitor::~const_nbt_visitor() noexcept {} + +} + +#endif // NBT_VISITOR_H_INCLUDED diff --git a/depends/libnbtplusplus/include/primitive_detail.h b/depends/libnbtplusplus/include/primitive_detail.h new file mode 100644 index 00000000..4715ee7e --- /dev/null +++ b/depends/libnbtplusplus/include/primitive_detail.h @@ -0,0 +1,46 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef PRIMITIVE_DETAIL_H_INCLUDED +#define PRIMITIVE_DETAIL_H_INCLUDED + +#include <type_traits> + +///@cond +namespace nbt +{ + +namespace detail +{ + ///Meta-struct that holds the tag_type value for a specific primitive type + template<class T> struct get_primitive_type + { static_assert(sizeof(T) != sizeof(T), "Invalid type paramter for tag_primitive, can only use types that NBT uses"); }; + + template<> struct get_primitive_type<int8_t> : public std::integral_constant<tag_type, tag_type::Byte> {}; + template<> struct get_primitive_type<int16_t> : public std::integral_constant<tag_type, tag_type::Short> {}; + template<> struct get_primitive_type<int32_t> : public std::integral_constant<tag_type, tag_type::Int> {}; + template<> struct get_primitive_type<int64_t> : public std::integral_constant<tag_type, tag_type::Long> {}; + template<> struct get_primitive_type<float> : public std::integral_constant<tag_type, tag_type::Float> {}; + template<> struct get_primitive_type<double> : public std::integral_constant<tag_type, tag_type::Double> {}; +} + +} +///@endcond + +#endif // PRIMITIVE_DETAIL_H_INCLUDED diff --git a/depends/libnbtplusplus/include/tag.h b/depends/libnbtplusplus/include/tag.h new file mode 100644 index 00000000..9a9f5858 --- /dev/null +++ b/depends/libnbtplusplus/include/tag.h @@ -0,0 +1,159 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TAG_H_INCLUDED +#define TAG_H_INCLUDED + +#include <cstdint> +#include <iosfwd> +#include <memory> + +#include "nbt++_export.h" + +namespace nbt +{ + +///Tag type values used in the binary format +enum class tag_type : int8_t +{ + End = 0, + Byte = 1, + Short = 2, + Int = 3, + Long = 4, + Float = 5, + Double = 6, + Byte_Array = 7, + String = 8, + List = 9, + Compound = 10, + Int_Array = 11, + Null = -1 ///< Used to denote empty @ref value s +}; + +/** + * @brief Returns whether the given number falls within the range of valid tag types + * @param allow_end whether to consider tag_type::End (0) valid + */ +NBT___EXPORT bool is_valid_type(int type, bool allow_end = false); + +//Forward declarations +class nbt_visitor; +class const_nbt_visitor; +namespace io +{ + class stream_reader; + class stream_writer; +} + +///Base class for all NBT tag classes +class NBT___EXPORT tag +{ +public: + //Virtual destructor + virtual ~tag() noexcept {} + + ///Returns the type of the tag + virtual tag_type get_type() const noexcept = 0; + + //Polymorphic clone methods + virtual std::unique_ptr<tag> clone() const& = 0; + virtual std::unique_ptr<tag> move_clone() && = 0; + std::unique_ptr<tag> clone() &&; + + /** + * @brief Returns a reference to the tag as an instance of T + * @throw std::bad_cast if the tag is not of type T + */ + template<class T> + T& as(); + template<class T> + const T& as() const; + + /** + * @brief Move-assigns the given tag if the class is the same + * @throw std::bad_cast if @c rhs is not the same type as @c *this + */ + virtual tag& assign(tag&& rhs) = 0; + + /** + * @brief Calls the appropriate overload of @c visit() on the visitor with + * @c *this as argument + * + * Implementing the Visitor pattern + */ + virtual void accept(nbt_visitor& visitor) = 0; + virtual void accept(const_nbt_visitor& visitor) const = 0; + + /** + * @brief Reads the tag's payload from the stream + * @throw io::stream_reader::input_error on failure + */ + virtual void read_payload(io::stream_reader& reader) = 0; + + /** + * @brief Writes the tag's payload into the stream + */ + virtual void write_payload(io::stream_writer& writer) const = 0; + + /** + * @brief Default-constructs a new tag of the given type + * @throw std::invalid_argument if the type is not valid (e.g. End or Null) + */ + static std::unique_ptr<tag> create(tag_type type); + + friend bool operator==(const tag& lhs, const tag& rhs); + friend bool operator!=(const tag& lhs, const tag& rhs); + +private: + /** + * @brief Checks for equality to a tag of the same type + * @param rhs an instance of the same class as @c *this + */ + virtual bool equals(const tag& rhs) const = 0; +}; + +///Output operator for tag types +NBT___EXPORT std::ostream& operator<<(std::ostream& os, tag_type tt); + +/** + * @brief Output operator for tags + * + * Uses @ref text::json_formatter + * @relates tag + */ +NBT___EXPORT std::ostream& operator<<(std::ostream& os, const tag& t); + +template<class T> +T& tag::as() +{ + static_assert(std::is_base_of<tag, T>::value, "T must be a subclass of tag"); + return dynamic_cast<T&>(*this); +} + +template<class T> +const T& tag::as() const +{ + static_assert(std::is_base_of<tag, T>::value, "T must be a subclass of tag"); + return dynamic_cast<const T&>(*this); +} + +} + +#endif // TAG_H_INCLUDED diff --git a/depends/libnbtplusplus/include/tag_array.h b/depends/libnbtplusplus/include/tag_array.h new file mode 100644 index 00000000..77b77d7d --- /dev/null +++ b/depends/libnbtplusplus/include/tag_array.h @@ -0,0 +1,131 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TAG_ARRAY_H_INCLUDED +#define TAG_ARRAY_H_INCLUDED + +#include "crtp_tag.h" +#include <type_traits> +#include <vector> + +#include "nbt++_export.h" + +namespace nbt +{ + +///@cond +namespace detail +{ + ///Meta-struct that holds the tag_type value for a specific array type + template<class T> struct get_array_type + { static_assert(sizeof(T) != sizeof(T), "Invalid type paramter for tag_primitive, can only use byte or int"); }; + + template<> struct get_array_type<int8_t> : public std::integral_constant<tag_type, tag_type::Byte_Array> {}; + template<> struct get_array_type<int32_t> : public std::integral_constant<tag_type, tag_type::Int_Array> {}; +} +///@cond + +/** + * @brief Tag that contains an array of byte or int values + * + * Common class for tag_byte_array and tag_int_array. + */ +template<class T> +class NBT___EXPORT tag_array final : public detail::crtp_tag<tag_array<T>> +{ +public: + //Iterator types + typedef typename std::vector<T>::iterator iterator; + typedef typename std::vector<T>::const_iterator const_iterator; + + ///The type of the contained values + typedef T value_type; + + ///The type of the tag + static constexpr tag_type type = detail::get_array_type<T>::value; + + ///Constructs an empty array + tag_array() {} + + ///Constructs an array with the given values + tag_array(std::initializer_list<T> init): data(init) {} + tag_array(std::vector<T>&& vec) noexcept: data(std::move(vec)) {} + + ///Returns a reference to the vector that contains the values + std::vector<T>& get() { return data; } + const std::vector<T>& get() const { return data; } + + /** + * @brief Accesses a value by index with bounds checking + * @throw std::out_of_range if the index is out of range + */ + T& at(size_t i); + T at(size_t i) const; + + /** + * @brief Accesses a value by index + * + * No bounds checking is performed. + */ + T& operator[](size_t i) { return data[i]; } + T operator[](size_t i) const { return data[i]; } + + ///Appends a value at the end of the array + void push_back(T val) { data.push_back(val); } + + ///Removes the last element from the array + void pop_back() { data.pop_back(); } + + ///Returns the number of values in the array + size_t size() const { return data.size(); } + + ///Erases all values from the array. + void clear() { data.clear(); } + + //Iterators + iterator begin() { return data.begin(); } + iterator end() { return data.end(); } + const_iterator begin() const { return data.begin(); } + const_iterator end() const { return data.end(); } + const_iterator cbegin() const { return data.cbegin(); } + const_iterator cend() const { return data.cend(); } + + 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: + std::vector<T> data; +}; + +template<class T> bool operator==(const tag_array<T>& lhs, const tag_array<T>& rhs) +{ return lhs.get() == rhs.get(); } +template<class T> bool operator!=(const tag_array<T>& lhs, const tag_array<T>& rhs) +{ return !(lhs == rhs); } + +//Typedefs that should be used instead of the template tag_array. +typedef tag_array<int8_t> tag_byte_array; +typedef tag_array<int32_t> tag_int_array; + +} + +#endif // TAG_ARRAY_H_INCLUDED diff --git a/depends/libnbtplusplus/include/tag_compound.h b/depends/libnbtplusplus/include/tag_compound.h new file mode 100644 index 00000000..5ec818a3 --- /dev/null +++ b/depends/libnbtplusplus/include/tag_compound.h @@ -0,0 +1,144 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TAG_COMPOUND_H_INCLUDED +#define TAG_COMPOUND_H_INCLUDED + +#include "crtp_tag.h" +#include "value_initializer.h" +#include <map> +#include <string> + +#include "nbt++_export.h" + +namespace nbt +{ + +///Tag that contains multiple unordered named tags of arbitrary types +class NBT___EXPORT tag_compound final : public detail::crtp_tag<tag_compound> +{ + typedef std::map<std::string, value> map_t_; + +public: + //Iterator types + typedef map_t_::iterator iterator; + typedef map_t_::const_iterator const_iterator; + + ///The type of the tag + static constexpr tag_type type = tag_type::Compound; + + ///Constructs an empty compound + tag_compound() {} + + ///Constructs a compound with the given key-value pairs + tag_compound(std::initializer_list<std::pair<std::string, value_initializer>> init); + + /** + * @brief Accesses a tag by key with bounds checking + * + * Returns a value to the tag with the specified key, or throws an + * exception if it does not exist. + * @throw std::out_of_range if given key does not exist + */ + value& at(const std::string& key); + const value& at(const std::string& key) const; + + /** + * @brief Accesses a tag by key + * + * Returns a value to the tag with the specified key. If it does not exist, + * creates a new uninitialized entry under the key. + */ + value& operator[](const std::string& key) { return tags[key]; } + + /** + * @brief Inserts or assigns a tag + * + * If the given key already exists, assigns the tag to it. + * Otherwise, it is inserted under the given key. + * @return a pair of the iterator to the value and a bool indicating + * whether the key did not exist + */ + std::pair<iterator, bool> put(const std::string& key, value_initializer&& val); + + /** + * @brief Inserts a tag if the key does not exist + * @return a pair of the iterator to the value with the key and a bool + * indicating whether the value was actually inserted + */ + std::pair<iterator, bool> insert(const std::string& key, value_initializer&& val); + + /** + * @brief Constructs and assigns or inserts a tag into the compound + * + * Constructs a new tag of type @c T with the given args and inserts + * or assigns it to the given key. + * @note Unlike std::map::emplace, this will overwrite existing values + * @return a pair of the iterator to the value and a bool indicating + * whether the key did not exist + */ + template<class T, class... Args> + std::pair<iterator, bool> emplace(const std::string& key, Args&&... args); + + /** + * @brief Erases a tag from the compound + * @return true if a tag was erased + */ + bool erase(const std::string& key); + + ///Returns true if the given key exists in the compound + bool has_key(const std::string& key) const; + ///Returns true if the given key exists and the tag has the given type + bool has_key(const std::string& key, tag_type type) const; + + ///Returns the number of tags in the compound + size_t size() const { return tags.size(); } + + ///Erases all tags from the compound + void clear() { tags.clear(); } + + //Iterators + iterator begin() { return tags.begin(); } + iterator end() { return tags.end(); } + const_iterator begin() const { return tags.begin(); } + const_iterator end() const { return tags.end(); } + const_iterator cbegin() const { return tags.cbegin(); } + const_iterator cend() const { return tags.cend(); } + + void read_payload(io::stream_reader& reader) override; + void write_payload(io::stream_writer& writer) const override; + + friend bool operator==(const tag_compound& lhs, const tag_compound& rhs) + { return lhs.tags == rhs.tags; } + friend bool operator!=(const tag_compound& lhs, const tag_compound& rhs) + { return !(lhs == rhs); } + +private: + map_t_ tags; +}; + +template<class T, class... Args> +std::pair<tag_compound::iterator, bool> tag_compound::emplace(const std::string& key, Args&&... args) +{ + return put(key, value(make_unique<T>(std::forward<Args>(args)...))); +} + +} + +#endif // TAG_COMPOUND_H_INCLUDED diff --git a/depends/libnbtplusplus/include/tag_list.h b/depends/libnbtplusplus/include/tag_list.h new file mode 100644 index 00000000..5b0ba873 --- /dev/null +++ b/depends/libnbtplusplus/include/tag_list.h @@ -0,0 +1,224 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TAG_LIST_H_INCLUDED +#define TAG_LIST_H_INCLUDED + +#include "crtp_tag.h" +#include "tagfwd.h" +#include "value_initializer.h" +#include <stdexcept> +#include <vector> + +#include "nbt++_export.h" + +namespace nbt +{ + +/** + * @brief Tag that contains multiple unnamed tags of the same type + * + * All the tags contained in the list have the same type, which can be queried + * with el_type(). The types of the values contained in the list should not + * be changed to mismatch the element type. + * + * If the list is empty, the type can be undetermined, in which case el_type() + * will return tag_type::Null. The type will then be set when the first tag + * is added to the list. + */ +class NBT___EXPORT tag_list final : public detail::crtp_tag<tag_list> +{ +public: + //Iterator types + typedef std::vector<value>::iterator iterator; + typedef std::vector<value>::const_iterator const_iterator; + + ///The type of the tag + static constexpr tag_type type = tag_type::List; + + /** + * @brief Constructs a list of type T with the given values + * + * Example: @code tag_list::of<tag_byte>({3, 4, 5}) @endcode + * @param init list of values from which the elements are constructed + */ + template<class T> + static tag_list of(std::initializer_list<T> init); + + /** + * @brief Constructs an empty list + * + * The content type is determined when the first tag is added. + */ + tag_list(): tag_list(tag_type::Null) {} + + ///Constructs an empty list with the given content type + explicit tag_list(tag_type type): el_type_(type) {} + + ///Constructs a list with the given contents + tag_list(std::initializer_list<int8_t> init); + tag_list(std::initializer_list<int16_t> init); + tag_list(std::initializer_list<int32_t> init); + tag_list(std::initializer_list<int64_t> init); + tag_list(std::initializer_list<float> init); + tag_list(std::initializer_list<double> init); + tag_list(std::initializer_list<std::string> init); + tag_list(std::initializer_list<tag_byte_array> init); + tag_list(std::initializer_list<tag_list> init); + tag_list(std::initializer_list<tag_compound> init); + tag_list(std::initializer_list<tag_int_array> init); + + /** + * @brief Constructs a list with the given contents + * @throw std::invalid_argument if the tags are not all of the same type + */ + tag_list(std::initializer_list<value> init); + + /** + * @brief Accesses a tag by index with bounds checking + * + * Returns a value to the tag at the specified index, or throws an + * exception if it is out of range. + * @throw std::out_of_range if the index is out of range + */ + value& at(size_t i); + const value& at(size_t i) const; + + /** + * @brief Accesses a tag by index + * + * Returns a value to the tag at the specified index. No bounds checking + * is performed. + */ + value& operator[](size_t i) { return tags[i]; } + const value& operator[](size_t i) const { return tags[i]; } + + /** + * @brief Assigns a value at the given index + * @throw std::invalid_argument if the type of the value does not match the list's + * content type + * @throw std::out_of_range if the index is out of range + */ + void set(size_t i, value&& val); + + /** + * @brief Appends the tag to the end of the list + * @throw std::invalid_argument if the type of the tag does not match the list's + * content type + */ + void push_back(value_initializer&& val); + + /** + * @brief Constructs and appends a tag to the end of the list + * @throw std::invalid_argument if the type of the tag does not match the list's + * content type + */ + template<class T, class... Args> + void emplace_back(Args&&... args); + + ///Removes the last element of the list + void pop_back() { tags.pop_back(); } + + ///Returns the content type of the list, or tag_type::Null if undetermined + tag_type el_type() const { return el_type_; } + + ///Returns the number of tags in the list + size_t size() const { return tags.size(); } + + ///Erases all tags from the list. Preserves the content type. + void clear() { tags.clear(); } + + /** + * @brief Erases all tags from the list and changes the content type. + * @param type the new content type. Can be tag_type::Null to leave it undetermined. + */ + void reset(tag_type type = tag_type::Null); + + //Iterators + iterator begin() { return tags.begin(); } + iterator end() { return tags.end(); } + const_iterator begin() const { return tags.begin(); } + const_iterator end() const { return tags.end(); } + const_iterator cbegin() const { return tags.cbegin(); } + const_iterator cend() const { return tags.cend(); } + + /** + * @inheritdoc + * In case of a list of tag_end, the content type will be undetermined. + */ + void read_payload(io::stream_reader& reader) override; + /** + * @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; + + /** + * @brief Equality comparison for lists + * + * Lists are considered equal if their content types and the contained tags + * are equal. + */ + NBT___EXPORT friend bool operator==(const tag_list& lhs, const tag_list& rhs); + NBT___EXPORT friend bool operator!=(const tag_list& lhs, const tag_list& rhs); + +private: + std::vector<value> tags; + tag_type el_type_; + + /** + * Internally used initialization function that initializes the list with + * tags of type T, with the constructor arguments of each T given by il. + * @param il list of values that are, one by one, given to a constructor of T + */ + template<class T, class Arg> + void init(std::initializer_list<Arg> il); +}; + +template<class T> +tag_list tag_list::of(std::initializer_list<T> il) +{ + tag_list result; + result.init<T, T>(il); + return result; +} + +template<class T, class... Args> +void tag_list::emplace_back(Args&&... args) +{ + if(el_type_ == tag_type::Null) //set content type if undetermined + el_type_ = T::type; + else if(el_type_ != T::type) + throw std::invalid_argument("The tag type does not match the list's content type"); + tags.emplace_back(make_unique<T>(std::forward<Args>(args)...)); +} + +template<class T, class Arg> +void tag_list::init(std::initializer_list<Arg> init) +{ + el_type_ = T::type; + tags.reserve(init.size()); + for(const Arg& arg: init) + tags.emplace_back(make_unique<T>(arg)); +} + +} + +#endif // TAG_LIST_H_INCLUDED diff --git a/depends/libnbtplusplus/include/tag_primitive.h b/depends/libnbtplusplus/include/tag_primitive.h new file mode 100644 index 00000000..8b70c147 --- /dev/null +++ b/depends/libnbtplusplus/include/tag_primitive.h @@ -0,0 +1,102 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TAG_PRIMITIVE_H_INCLUDED +#define TAG_PRIMITIVE_H_INCLUDED + +#include "crtp_tag.h" +#include "primitive_detail.h" +#include "io/stream_reader.h" +#include "io/stream_writer.h" +#include <istream> +#include <sstream> + +#include "nbt++_export.h" + +namespace nbt +{ + +/** + * @brief Tag that contains an integral or floating-point value + * + * Common class for tag_byte, tag_short, tag_int, tag_long, tag_float and tag_double. + */ +template<class T> +class tag_primitive final : public detail::crtp_tag<tag_primitive<T>> +{ +public: + ///The type of the value + typedef T value_type; + + ///The type of the tag + static constexpr tag_type type = detail::get_primitive_type<T>::value; + + //Constructor + constexpr tag_primitive(T val = 0) noexcept: value(val) {} + + //Getters + operator T&() { return value; } + constexpr operator T() const { return value; } + constexpr T get() const { return value; } + + //Setters + tag_primitive& operator=(T val) { value = val; return *this; } + void set(T val) { value = val; } + + void read_payload(io::stream_reader& reader) override; + void write_payload(io::stream_writer& writer) const override; + +private: + T value; +}; + +template<class T> bool operator==(const tag_primitive<T>& lhs, const tag_primitive<T>& rhs) +{ return lhs.get() == rhs.get(); } +template<class T> bool operator!=(const tag_primitive<T>& lhs, const tag_primitive<T>& rhs) +{ return !(lhs == rhs); } + +//Typedefs that should be used instead of the template tag_primitive. +typedef tag_primitive<int8_t> tag_byte; +typedef tag_primitive<int16_t> tag_short; +typedef tag_primitive<int32_t> tag_int; +typedef tag_primitive<int64_t> tag_long; +typedef tag_primitive<float> tag_float; +typedef tag_primitive<double> tag_double; + +template<class T> +void tag_primitive<T>::read_payload(io::stream_reader& reader) +{ + reader.read_num(value); + if(!reader.get_istr()) + { + std::ostringstream str; + str << "Error reading tag_" << type; + throw io::input_error(str.str()); + } +} + +template<class T> +void tag_primitive<T>::write_payload(io::stream_writer& writer) const +{ + writer.write_num(value); +} + +} + +#endif // TAG_PRIMITIVE_H_INCLUDED diff --git a/depends/libnbtplusplus/include/tag_string.h b/depends/libnbtplusplus/include/tag_string.h new file mode 100644 index 00000000..6f74fd52 --- /dev/null +++ b/depends/libnbtplusplus/include/tag_string.h @@ -0,0 +1,74 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TAG_STRING_H_INCLUDED +#define TAG_STRING_H_INCLUDED + +#include "crtp_tag.h" +#include <string> + +#include "nbt++_export.h" + +namespace nbt +{ + +///Tag that contains a UTF-8 string +class NBT___EXPORT tag_string final : public detail::crtp_tag<tag_string> +{ +public: + ///The type of the tag + static constexpr tag_type type = tag_type::String; + + //Constructors + tag_string() {} + tag_string(const std::string& str): value(str) {} + tag_string(std::string&& str) noexcept: value(std::move(str)) {} + tag_string(const char* str): value(str) {} + + //Getters + operator std::string&() { return value; } + operator const std::string&() const { return value; } + const std::string& get() const { return value; } + + //Setters + tag_string& operator=(const std::string& str) { value = str; return *this; } + tag_string& operator=(std::string&& str) { value = std::move(str); return *this; } + tag_string& operator=(const char* str) { value = str; return *this; } + void set(const std::string& str) { value = str; } + void set(std::string&& str) { value = std::move(str); } + + void read_payload(io::stream_reader& reader) override; + /** + * @inheritdoc + * @throw std::length_error if the string is too long for NBT + */ + void write_payload(io::stream_writer& writer) const override; + +private: + std::string value; +}; + +inline bool operator==(const tag_string& lhs, const tag_string& rhs) +{ return lhs.get() == rhs.get(); } +inline bool operator!=(const tag_string& lhs, const tag_string& rhs) +{ return !(lhs == rhs); } + +} + +#endif // TAG_STRING_H_INCLUDED diff --git a/depends/libnbtplusplus/include/tagfwd.h b/depends/libnbtplusplus/include/tagfwd.h new file mode 100644 index 00000000..178edd7e --- /dev/null +++ b/depends/libnbtplusplus/include/tagfwd.h @@ -0,0 +1,51 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +/** @file + * @brief Provides forward declarations for all tag classes + */ +#ifndef TAGFWD_H_INCLUDED +#define TAGFWD_H_INCLUDED +#include <cstdint> + +namespace nbt +{ + +class tag; + +template<class T> class tag_primitive; +typedef tag_primitive<int8_t> tag_byte; +typedef tag_primitive<int16_t> tag_short; +typedef tag_primitive<int32_t> tag_int; +typedef tag_primitive<int64_t> tag_long; +typedef tag_primitive<float> tag_float; +typedef tag_primitive<double> tag_double; + +class tag_string; + +template<class T> class tag_array; +typedef tag_array<int8_t> tag_byte_array; +typedef tag_array<int32_t> tag_int_array; + +class tag_list; +class tag_compound; + +} + +#endif // TAGFWD_H_INCLUDED diff --git a/depends/libnbtplusplus/include/text/json_formatter.h b/depends/libnbtplusplus/include/text/json_formatter.h new file mode 100644 index 00000000..1762e910 --- /dev/null +++ b/depends/libnbtplusplus/include/text/json_formatter.h @@ -0,0 +1,47 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef JSON_FORMATTER_H_INCLUDED +#define JSON_FORMATTER_H_INCLUDED + +#include "tagfwd.h" +#include <ostream> + +#include "nbt++_export.h" + +namespace nbt +{ +namespace text +{ + +/** + * @brief Prints tags in a JSON-like syntax into a stream + * + * @todo Make it configurable and able to produce actual standard-conformant JSON + */ +class NBT___EXPORT json_formatter +{ +public: + void print(std::ostream& os, const tag& t) const; +}; + +} +} + +#endif // JSON_FORMATTER_H_INCLUDED diff --git a/depends/libnbtplusplus/include/value.h b/depends/libnbtplusplus/include/value.h new file mode 100644 index 00000000..a2db2957 --- /dev/null +++ b/depends/libnbtplusplus/include/value.h @@ -0,0 +1,223 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TAG_REF_PROXY_H_INCLUDED +#define TAG_REF_PROXY_H_INCLUDED + +#include "tag.h" +#include <string> +#include <type_traits> + +#include "nbt++_export.h" + +namespace nbt +{ + +/** + * @brief Contains an NBT value of fixed type + * + * This class is a convenience wrapper for @c std::unique_ptr<tag>. + * A value can contain any kind of tag or no tag (nullptr) and provides + * operations for handling tags of which the type is not known at compile time. + * Assignment or the set method on a value with no tag will fill in the value. + * + * The rationale for the existance of this class is to provide a type-erasured + * means of storing tags, especially when they are contained in tag_compound + * or tag_list. The alternative would be directly using @c std::unique_ptr<tag> + * and @c tag&, which is how it was done in libnbt++1. The main drawback is that + * it becomes very cumbersome to deal with tags of unknown type. + * + * For example, in this case it would not be possible to allow a syntax like + * <tt>compound["foo"] = 42</tt>. If the key "foo" does not exist beforehand, + * the left hand side could not have any sensible value if it was of type + * @c tag&. + * Firstly, the compound tag would have to create a new tag_int there, but it + * cannot know that the new tag is going to be assigned an integer. + * Also, if the type was @c tag& and it allowed assignment of integers, that + * would mean the tag base class has assignments and conversions like this. + * Which means that all other tag classes would inherit them from the base + * class, even though it does not make any sense to allow converting a + * tag_compound into an integer. Attempts like this should be caught at + * compile time. + * + * This is why all the syntactic sugar for tags is contained in the value class + * while the tag class only contains common operations for all tag types. + */ +class NBT___EXPORT value +{ +public: + //Constructors + value() noexcept {} + explicit value(std::unique_ptr<tag>&& t) noexcept: tag_(std::move(t)) {} + explicit value(tag&& t); + + //Moving + value(value&&) noexcept = default; + value& operator=(value&&) noexcept = default; + + //Copying + explicit value(const value& rhs); + value& operator=(const value& rhs); + + /** + * @brief Assigns the given value to the tag if the type matches + * @throw std::bad_cast if the type of @c t is not the same as the type + * of this value + */ + value& operator=(tag&& t); + void set(tag&& t); + + //Conversion to tag + /** + * @brief Returns the contained tag + * + * If the value is uninitialized, the behavior is undefined. + */ + operator tag&() { return get(); } + operator const tag&() const { return get(); } + tag& get() { return *tag_; } + const tag& get() const { return *tag_; } + + /** + * @brief Returns a reference to the contained tag as an instance of T + * @throw std::bad_cast if the tag is not of type T + */ + template<class T> + T& as(); + template<class T> + const T& as() const; + + //Assignment of primitives and string + /** + * @brief Assigns the given value to the tag if the type is compatible + * @throw std::bad_cast if the value is not convertible to the tag type + * via a widening conversion + */ + value& operator=(int8_t val); + value& operator=(int16_t val); + value& operator=(int32_t val); + value& operator=(int64_t val); + value& operator=(float val); + value& operator=(double val); + + /** + * @brief Assigns the given string to the tag if it is a tag_string + * @throw std::bad_cast if the contained tag is not a tag_string + */ + value& operator=(const std::string& str); + value& operator=(std::string&& str); + + //Conversions to primitives and string + /** + * @brief Returns the contained value if the type is compatible + * @throw std::bad_cast if the tag type is not convertible to the desired + * type via a widening conversion + */ + explicit operator int8_t() const; + explicit operator int16_t() const; + explicit operator int32_t() const; + explicit operator int64_t() const; + explicit operator float() const; + explicit operator double() const; + + /** + * @brief Returns the contained string if the type is tag_string + * + * If the value is uninitialized, the behavior is undefined. + * @throw std::bad_cast if the tag type is not tag_string + */ + explicit operator const std::string&() const; + + ///Returns true if the value is not uninitialized + explicit operator bool() const { return tag_ != nullptr; } + + /** + * @brief In case of a tag_compound, accesses a tag by key with bounds checking + * + * If the value is uninitialized, the behavior is undefined. + * @throw std::bad_cast if the tag type is not tag_compound + * @throw std::out_of_range if given key does not exist + * @sa tag_compound::at + */ + value& at(const std::string& key); + const value& at(const std::string& key) const; + + /** + * @brief In case of a tag_compound, accesses a tag by key + * + * If the value is uninitialized, the behavior is undefined. + * @throw std::bad_cast if the tag type is not tag_compound + * @sa tag_compound::operator[] + */ + value& operator[](const std::string& key); + value& operator[](const char* key); //need this overload because of conflict with built-in operator[] + + /** + * @brief In case of a tag_list, accesses a tag by index with bounds checking + * + * If the value is uninitialized, the behavior is undefined. + * @throw std::bad_cast if the tag type is not tag_list + * @throw std::out_of_range if the index is out of range + * @sa tag_list::at + */ + value& at(size_t i); + const value& at(size_t i) const; + + /** + * @brief In case of a tag_list, accesses a tag by index + * + * No bounds checking is performed. If the value is uninitialized, the + * behavior is undefined. + * @throw std::bad_cast if the tag type is not tag_list + * @sa tag_list::operator[] + */ + value& operator[](size_t i); + const value& operator[](size_t i) const; + + ///Returns a reference to the underlying std::unique_ptr<tag> + std::unique_ptr<tag>& get_ptr() { return tag_; } + const std::unique_ptr<tag>& get_ptr() const { return tag_; } + ///Resets the underlying std::unique_ptr<tag> to a different value + void set_ptr(std::unique_ptr<tag>&& t) { tag_ = std::move(t); } + + ///@sa tag::get_type + tag_type get_type() const; + + NBT___EXPORT friend bool operator==(const value& lhs, const value& rhs); + NBT___EXPORT friend bool operator!=(const value& lhs, const value& rhs); + +private: + std::unique_ptr<tag> tag_; +}; + +template<class T> +T& value::as() +{ + return tag_->as<T>(); +} + +template<class T> +const T& value::as() const +{ + return tag_->as<T>(); +} + +} + +#endif // TAG_REF_PROXY_H_INCLUDED diff --git a/depends/libnbtplusplus/include/value_initializer.h b/depends/libnbtplusplus/include/value_initializer.h new file mode 100644 index 00000000..5cda58cd --- /dev/null +++ b/depends/libnbtplusplus/include/value_initializer.h @@ -0,0 +1,67 @@ +/* + * libnbt++ - A library for the Minecraft Named Binary Tag format. + * Copyright (C) 2013, 2015 ljfa-ag + * + * This file is part of libnbt++. + * + * libnbt++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libnbt++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnbt++. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef VALUE_INITIALIZER_H_INCLUDED +#define VALUE_INITIALIZER_H_INCLUDED + +#include "value.h" + +#include "nbt++_export.h" + +namespace nbt +{ + +/** + * @brief Helper class for implicitly constructing value objects + * + * This type is a subclass of @ref value. However the only difference to value + * is that this class has additional constructors which allow implicit + * conversion of various types to value objects. These constructors are not + * part of the value class itself because implicit conversions like this + * (especially from @c tag&& to @c value) can cause problems and ambiguities + * in some cases. + * + * value_initializer is especially useful as function parameter type, it will + * allow convenient conversion of various values to tags on function call. + * + * As value_initializer objects are in no way different than value objects, + * they can just be converted to value after construction. + */ +class NBT___EXPORT value_initializer : public value +{ +public: + value_initializer(std::unique_ptr<tag>&& t) noexcept: value(std::move(t)) {} + value_initializer(std::nullptr_t) noexcept : value(nullptr) {} + value_initializer(value&& val) noexcept : value(std::move(val)) {} + value_initializer(tag&& t) : value(std::move(t)) {} + + value_initializer(int8_t val); + value_initializer(int16_t val); + value_initializer(int32_t val); + value_initializer(int64_t val); + value_initializer(float val); + value_initializer(double val); + value_initializer(const std::string& str); + value_initializer(std::string&& str); + value_initializer(const char* str); +}; + +} + +#endif // VALUE_INITIALIZER_H_INCLUDED |