stream_writer.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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 STREAM_WRITER_H_INCLUDED
  21. #define STREAM_WRITER_H_INCLUDED
  22. #include "tag.h"
  23. #include "endian_str.h"
  24. #include <iosfwd>
  25. #include <string>
  26. namespace nbt
  27. {
  28. namespace io
  29. {
  30. /* Not sure if that is even needed
  31. ///Exception that gets thrown when writing is not successful
  32. class output_error : public std::runtime_error
  33. {
  34. using std::runtime_error::runtime_error;
  35. };*/
  36. /**
  37. * @brief Writes a named tag into the stream, including the tag type
  38. * @param key the name of the tag
  39. * @param t the tag
  40. * @param os the stream to write to
  41. * @param e the byte order of the written data. The Java edition
  42. * of Minecraft uses Big Endian, the Pocket edition uses Little Endian
  43. */
  44. NBT_EXPORT void write_tag(const std::string& key, const tag& t, std::ostream& os, endian::endian e = endian::big);
  45. /**
  46. * @brief Helper class for writing NBT tags to output streams
  47. *
  48. * Can be reused to write multiple tags
  49. */
  50. class NBT_EXPORT stream_writer
  51. {
  52. public:
  53. ///Maximum length of an NBT string (16 bit unsigned)
  54. static constexpr size_t max_string_len = UINT16_MAX;
  55. ///Maximum length of an NBT list or array (32 bit signed)
  56. static constexpr uint32_t max_array_len = INT32_MAX;
  57. /**
  58. * @param os the stream to write to
  59. * @param e the byte order of the written data. The Java edition
  60. * of Minecraft uses Big Endian, the Pocket edition uses Little Endian
  61. */
  62. explicit stream_writer(std::ostream& os, endian::endian e = endian::big) noexcept:
  63. os(os), endian(e)
  64. {}
  65. ///Returns the stream
  66. std::ostream& get_ostr() const { return os; }
  67. ///Returns the byte order
  68. endian::endian get_endian() const { return endian; }
  69. /**
  70. * @brief Writes a named tag into the stream, including the tag type
  71. */
  72. void write_tag(const std::string& key, const tag& t);
  73. /**
  74. * @brief Writes the given tag's payload into the stream
  75. */
  76. void write_payload(const tag& t) { t.write_payload(*this); }
  77. /**
  78. * @brief Writes a tag type to the stream
  79. */
  80. void write_type(tag_type tt) { write_num(static_cast<int8_t>(tt)); }
  81. /**
  82. * @brief Writes a binary number to the stream
  83. */
  84. template<class T>
  85. void write_num(T x);
  86. /**
  87. * @brief Writes an NBT string to the stream
  88. *
  89. * An NBT string consists of two bytes indicating the length, followed by
  90. * the characters encoded in modified UTF-8.
  91. * @throw std::length_error if the string is too long for NBT
  92. */
  93. void write_string(const std::string& str);
  94. private:
  95. std::ostream& os;
  96. const endian::endian endian;
  97. };
  98. template<class T>
  99. void stream_writer::write_num(T x)
  100. {
  101. endian::write(os, x, endian);
  102. }
  103. }
  104. }
  105. #endif // STREAM_WRITER_H_INCLUDED