diff options
Diffstat (limited to 'include/io/stream_reader.h')
| -rw-r--r-- | include/io/stream_reader.h | 213 |
1 files changed, 110 insertions, 103 deletions
diff --git a/include/io/stream_reader.h b/include/io/stream_reader.h index 821a9ff8d3..05f8d99c92 100644 --- a/include/io/stream_reader.h +++ b/include/io/stream_reader.h @@ -36,108 +36,115 @@ 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; - int depth = 0; - const endian::endian endian; -}; - -template<class T> -void stream_reader::read_num(T& x) -{ - endian::read(is, x, endian); -} - -} -} + 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; + int depth = 0; + const endian::endian endian; + }; + + template <class T> void stream_reader::read_num(T& x) + { + endian::read(is, x, endian); + } + + } // namespace io +} // namespace nbt #endif // STREAM_READER_H_INCLUDED |
