tag.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * libnbt++ - A library for the Minecraft Named Binary Tag format.
  3. * Copyright (C) 2013, 2015 ljfa-ag
  4. *
  5. * This file is part of libnbt++.
  6. *
  7. * libnbt++ is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * libnbt++ is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with libnbt++. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef TAG_H_INCLUDED
  21. #define TAG_H_INCLUDED
  22. #include <cstdint>
  23. #include <iosfwd>
  24. #include <memory>
  25. #include "nbt_export.h"
  26. namespace nbt
  27. {
  28. ///Tag type values used in the binary format
  29. enum class tag_type : int8_t
  30. {
  31. End = 0,
  32. Byte = 1,
  33. Short = 2,
  34. Int = 3,
  35. Long = 4,
  36. Float = 5,
  37. Double = 6,
  38. Byte_Array = 7,
  39. String = 8,
  40. List = 9,
  41. Compound = 10,
  42. Int_Array = 11,
  43. Long_Array = 12,
  44. Null = -1 ///< Used to denote empty @ref value s
  45. };
  46. /**
  47. * @brief Returns whether the given number falls within the range of valid tag types
  48. * @param allow_end whether to consider tag_type::End (0) valid
  49. */
  50. NBT_EXPORT bool is_valid_type(int type, bool allow_end = false);
  51. //Forward declarations
  52. class nbt_visitor;
  53. class const_nbt_visitor;
  54. namespace io
  55. {
  56. class stream_reader;
  57. class stream_writer;
  58. }
  59. ///Base class for all NBT tag classes
  60. class NBT_EXPORT tag
  61. {
  62. public:
  63. //Virtual destructor
  64. virtual ~tag() noexcept {}
  65. ///Returns the type of the tag
  66. virtual tag_type get_type() const noexcept = 0;
  67. //Polymorphic clone methods
  68. virtual std::unique_ptr<tag> clone() const& = 0;
  69. virtual std::unique_ptr<tag> move_clone() && = 0;
  70. std::unique_ptr<tag> clone() &&;
  71. /**
  72. * @brief Returns a reference to the tag as an instance of T
  73. * @throw std::bad_cast if the tag is not of type T
  74. */
  75. template<class T>
  76. T& as();
  77. template<class T>
  78. const T& as() const;
  79. /**
  80. * @brief Move-assigns the given tag if the class is the same
  81. * @throw std::bad_cast if @c rhs is not the same type as @c *this
  82. */
  83. virtual tag& assign(tag&& rhs) = 0;
  84. /**
  85. * @brief Calls the appropriate overload of @c visit() on the visitor with
  86. * @c *this as argument
  87. *
  88. * Implementing the Visitor pattern
  89. */
  90. virtual void accept(nbt_visitor& visitor) = 0;
  91. virtual void accept(const_nbt_visitor& visitor) const = 0;
  92. /**
  93. * @brief Reads the tag's payload from the stream
  94. * @throw io::stream_reader::input_error on failure
  95. */
  96. virtual void read_payload(io::stream_reader& reader) = 0;
  97. /**
  98. * @brief Writes the tag's payload into the stream
  99. */
  100. virtual void write_payload(io::stream_writer& writer) const = 0;
  101. /**
  102. * @brief Default-constructs a new tag of the given type
  103. * @throw std::invalid_argument if the type is not valid (e.g. End or Null)
  104. */
  105. static std::unique_ptr<tag> create(tag_type type);
  106. friend NBT_EXPORT bool operator==(const tag& lhs, const tag& rhs);
  107. friend NBT_EXPORT bool operator!=(const tag& lhs, const tag& rhs);
  108. private:
  109. /**
  110. * @brief Checks for equality to a tag of the same type
  111. * @param rhs an instance of the same class as @c *this
  112. */
  113. virtual bool equals(const tag& rhs) const = 0;
  114. };
  115. ///Output operator for tag types
  116. NBT_EXPORT std::ostream& operator<<(std::ostream& os, tag_type tt);
  117. /**
  118. * @brief Output operator for tags
  119. *
  120. * Uses @ref text::json_formatter
  121. * @relates tag
  122. */
  123. NBT_EXPORT std::ostream& operator<<(std::ostream& os, const tag& t);
  124. template<class T>
  125. T& tag::as()
  126. {
  127. static_assert(std::is_base_of<tag, T>::value, "T must be a subclass of tag");
  128. return dynamic_cast<T&>(*this);
  129. }
  130. template<class T>
  131. const T& tag::as() const
  132. {
  133. static_assert(std::is_base_of<tag, T>::value, "T must be a subclass of tag");
  134. return dynamic_cast<const T&>(*this);
  135. }
  136. }
  137. #endif // TAG_H_INCLUDED