Botcraft 1.21.4
Loading...
Searching...
No Matches
Tag.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <variant>
4#include <vector>
5#include <string>
6#include <map>
7
10
11namespace ProtocolCraft
12{
13 namespace NBT
14 {
15 using TagEnd = std::monostate;
16 using TagByte = char;
17 using TagShort = short;
18 using TagInt = int;
19 using TagLong = long long int;
20 using TagFloat = float;
21 using TagDouble = double;
22 using TagByteArray = std::vector<char>;
23 using TagString = std::string;
24 class TagList;
25 class TagCompound;
26 using TagIntArray = std::vector<int>;
27 using TagLongArray = std::vector<long long int>;
28
29 namespace Internal
30 {
31 using TagVariant = std::variant<
32 TagEnd,
33 TagByte,
35 TagInt,
36 TagLong,
45 >;
46
47 using TagListVariant = std::variant<
48 std::vector<TagEnd>,
49 std::vector<TagByte>,
50 std::vector<TagShort>,
51 std::vector<TagInt>,
52 std::vector<TagLong>,
53 std::vector<TagFloat>,
54 std::vector<TagDouble>,
55 std::vector<TagByteArray>,
56 std::vector<TagString>,
57 std::vector<TagList>,
58 std::vector<TagCompound>,
59 std::vector<TagIntArray>,
60 std::vector<TagLongArray>
61 >;
62 }
63
64 class Tag : public NetworkType
65 {
66 public:
67 const std::string& GetName() const;
68
69 template<typename T>
70 bool is() const;
71
72 template<
73 typename T,
74 std::enable_if_t<std::is_convertible_v<std::vector<T>, Internal::TagListVariant>, bool> = true
75 >
76 bool is_list_of() const;
77
78 template<
79 typename T,
80 std::enable_if_t<
81 std::is_same_v<T, TagByte> ||
82 std::is_same_v<T, TagShort> ||
83 std::is_same_v<T, TagInt> ||
84 std::is_same_v<T, TagLong> ||
85 std::is_same_v<T, TagFloat> ||
86 std::is_same_v<T, TagDouble>, bool
87 > = true
88 >
89 T get() const;
90
91 template<
92 typename T,
93 std::enable_if_t<
94 std::is_same_v<T, TagByteArray> ||
95 std::is_same_v<T, TagString> ||
96 std::is_same_v<T, TagList> ||
97 std::is_same_v<T, TagCompound> ||
98 std::is_same_v<T, TagIntArray> ||
99 std::is_same_v<T, TagLongArray>, bool
100 > = true
101 >
102 const T& get() const;
103
104 template<
105 typename T,
106 std::enable_if_t<std::is_convertible_v<std::vector<T>, Internal::TagListVariant>, bool> = true
107 >
108 const std::vector<T>& as_list_of() const;
109
110 const Tag& operator[](const std::string& s) const;
111
112 size_t size() const;
113 bool contains(const std::string& s) const;
114
115 protected:
116 void ReadUnnamedImpl(ReadIterator& iter, size_t& length);
117 void WriteUnnamedImpl(WriteContainer& container) const;
118 virtual void ReadImpl(ReadIterator& iter, size_t& length) override;
119 virtual void WriteImpl(WriteContainer& container) const override;
120 virtual Json::Value SerializeImpl() const override;
121
122 private:
124 std::string name;
125 };
126
127
128 class TagList : public NetworkType
129 {
130 public:
131 size_t size() const;
132
133 template<
134 typename T,
135 std::enable_if_t<std::is_convertible_v<std::vector<T>, Internal::TagListVariant>, bool> = true
136 >
137 bool is_of() const;
138
139 template<
140 typename T,
141 std::enable_if_t<std::is_convertible_v<std::vector<T>, Internal::TagListVariant>, bool> = true
142 >
143 const std::vector<T>& as_list_of() const;
144
145 protected:
146 virtual void ReadImpl(ReadIterator& iter, size_t& length) override;
147 virtual void WriteImpl(WriteContainer& container) const override;
148 virtual Json::Value SerializeImpl() const override;
149
150 private:
152 };
153
154
155 class TagCompound : public std::map<std::string, Tag>, public NetworkType
156 {
157 using std::map<std::string, Tag>::map;
158
159 public:
160 const Tag& operator[](const std::string& s) const;
161 bool contains(const std::string& s) const;
162
163 protected:
164 virtual void ReadImpl(ReadIterator& iter, size_t& length) override;
165 virtual void WriteImpl(WriteContainer& container) const override;
166 virtual Json::Value SerializeImpl() const override;
167 };
168
169
170
171
172 template<typename T>
173 bool Tag::is() const
174 {
175 if constexpr (std::is_same_v<T, TagList>)
176 {
177 return std::holds_alternative<ProtocolCraft::Internal::RecursiveWrapper<TagList>>(val);
178 }
179 else if constexpr (std::is_same_v<T, TagCompound>)
180 {
181 return std::holds_alternative<ProtocolCraft::Internal::RecursiveWrapper<TagCompound>>(val);
182 }
183 else
184 {
185 return std::holds_alternative<T>(val);
186 }
187 }
188
189 template<
190 typename T,
191 std::enable_if_t<std::is_convertible_v<std::vector<T>, Internal::TagListVariant>, bool>
192 >
193 bool Tag::is_list_of() const
194 {
195 return is<TagList>() && get<TagList>().is_of<T>();
196 }
197
198 template<
199 typename T,
200 std::enable_if_t<
201 std::is_same_v<T, TagByte> ||
202 std::is_same_v<T, TagShort> ||
203 std::is_same_v<T, TagInt> ||
204 std::is_same_v<T, TagLong> ||
205 std::is_same_v<T, TagFloat> ||
206 std::is_same_v<T, TagDouble>, bool
207 >
208 >
209 T Tag::get() const
210 {
211 if (!std::holds_alternative<T>(val))
212 {
213 throw std::runtime_error("Trying to get the wrong type from NBT::Tag");
214 }
215 return std::get<T>(val);
216 }
217
218 template<
219 typename T,
220 std::enable_if_t<
221 std::is_same_v<T, TagByteArray> ||
222 std::is_same_v<T, TagString> ||
223 std::is_same_v<T, TagList> ||
224 std::is_same_v<T, TagCompound> ||
225 std::is_same_v<T, TagIntArray> ||
226 std::is_same_v<T, TagLongArray>, bool
227 >
228 >
229 const T& Tag::get() const
230 {
231 // special case for TagCompound (removing the RecursiveWrapper)
232 if constexpr (std::is_same_v<T, TagCompound>)
233 {
235 {
236 throw std::runtime_error("Trying to get the wrong type from NBT::Tag");
237 }
238 return std::get<ProtocolCraft::Internal::RecursiveWrapper<TagCompound>>(val).get();
239 }
240 // special case for TagList (removing the RecursiveWrapper)
241 else if constexpr (std::is_same_v<T, TagList>)
242 {
243 if (!std::holds_alternative<ProtocolCraft::Internal::RecursiveWrapper<TagList>>(val))
244 {
245 throw std::runtime_error("Trying to get the wrong type from NBT::Tag");
246 }
247 return std::get<ProtocolCraft::Internal::RecursiveWrapper<TagList>>(val).get();
248 }
249 // all other cases should work with generic template
250 else
251 {
252 if (!std::holds_alternative<T>(val))
253 {
254 throw std::runtime_error("Trying to get the wrong type from NBT::Tag");
255 }
256 return std::get<T>(val);
257 }
258 }
259
260 template<
261 typename T,
262 std::enable_if_t<std::is_convertible_v<std::vector<T>, Internal::TagListVariant>, bool>
263 >
264 const std::vector<T>& Tag::as_list_of() const
265 {
266 if (!std::holds_alternative<ProtocolCraft::Internal::RecursiveWrapper<TagList>>(val))
267 {
268 throw std::runtime_error("Trying to get a list from another NBT::Tag type");
269 }
270 return get<TagList>().as_list_of<T>();
271 }
272
273
274
275 template<
276 typename T,
277 std::enable_if_t<std::is_convertible_v<std::vector<T>, Internal::TagListVariant>, bool>
278 >
279 bool TagList::is_of() const
280 {
281 return std::holds_alternative<std::vector<T>>(vals);
282 }
283
284 template<
285 typename T,
286 std::enable_if_t<std::is_convertible_v<std::vector<T>, Internal::TagListVariant>, bool>
287 >
288 const std::vector<T>& TagList::as_list_of() const
289 {
290 if (!std::holds_alternative<std::vector<T>>(vals))
291 {
292 throw std::runtime_error("Trying to get the wrong type from NBT::TagList");
293 }
294 return std::get<std::vector<T>>(vals);
295 }
296 }
297}
Template magic to have a full type instead of an incomplete one as required for example by std::varia...
Main class, basically a JsonVariant with extra utility functions it doesn't inherit JsonVariant direc...
Definition Json.hpp:45
virtual Json::Value SerializeImpl() const override
Definition Tag.cpp:601
virtual void WriteImpl(WriteContainer &container) const override
Definition Tag.cpp:589
virtual void ReadImpl(ReadIterator &iter, size_t &length) override
Definition Tag.cpp:572
bool contains(const std::string &s) const
Definition Tag.cpp:567
const Tag & operator[](const std::string &s) const
Definition Tag.cpp:562
virtual Json::Value SerializeImpl() const override
Definition Tag.cpp:524
virtual void WriteImpl(WriteContainer &container) const override
Definition Tag.cpp:481
virtual void ReadImpl(ReadIterator &iter, size_t &length) override
Definition Tag.cpp:410
Internal::TagListVariant vals
Definition Tag.hpp:151
size_t size() const
Definition Tag.cpp:549
const std::vector< T > & as_list_of() const
Definition Tag.hpp:288
std::string name
Definition Tag.hpp:124
bool contains(const std::string &s) const
Definition Tag.cpp:404
size_t size() const
Definition Tag.cpp:374
bool is() const
Definition Tag.hpp:173
void WriteUnnamedImpl(WriteContainer &container) const
Definition Tag.cpp:159
virtual void WriteImpl(WriteContainer &container) const override
Definition Tag.cpp:276
virtual void ReadImpl(ReadIterator &iter, size_t &length) override
Definition Tag.cpp:215
const std::string & GetName() const
Definition Tag.cpp:89
virtual Json::Value SerializeImpl() const override
Definition Tag.cpp:329
void ReadUnnamedImpl(ReadIterator &iter, size_t &length)
Definition Tag.cpp:94
bool is_list_of() const
Definition Tag.hpp:193
const Tag & operator[](const std::string &s) const
Definition Tag.cpp:364
Internal::TagVariant val
Definition Tag.hpp:123
const std::vector< T > & as_list_of() const
Definition Tag.hpp:264
std::variant< TagEnd, TagByte, TagShort, TagInt, TagLong, TagFloat, TagDouble, TagByteArray, TagString, ProtocolCraft::Internal::RecursiveWrapper< TagList >, ProtocolCraft::Internal::RecursiveWrapper< TagCompound >, TagIntArray, TagLongArray > TagVariant
Definition Tag.hpp:45
std::variant< std::vector< TagEnd >, std::vector< TagByte >, std::vector< TagShort >, std::vector< TagInt >, std::vector< TagLong >, std::vector< TagFloat >, std::vector< TagDouble >, std::vector< TagByteArray >, std::vector< TagString >, std::vector< TagList >, std::vector< TagCompound >, std::vector< TagIntArray >, std::vector< TagLongArray > > TagListVariant
Definition Tag.hpp:61
double TagDouble
Definition Tag.hpp:21
std::string TagString
Definition Tag.hpp:23
std::vector< long long int > TagLongArray
Definition Tag.hpp:27
long long int TagLong
Definition Tag.hpp:19
std::vector< int > TagIntArray
Definition Tag.hpp:26
std::monostate TagEnd
Definition Tag.hpp:15
std::vector< char > TagByteArray
Definition Tag.hpp:22
std::vector< unsigned char > WriteContainer
std::vector< unsigned char >::const_iterator ReadIterator