#ifndef LIBNBT_TAG_H #define LIBNBT_TAG_H #include #include #include #include #include "EndTag.h" #include "ByteTag.h" #include "ByteArrayTag.h" #include "DoubleTag.h" #include "FloatTag.h" #include "CompoundTag.h" #include "IntArrayTag.h" #include "IntTag.h" #include "ListTag.h" #include "LongArrayTag.h" #include "LongTag.h" #include "ShortTag.h" #include "../utils/ByteLayer.h" #include "../utils/StringBuilder.h" #include "../utils/StringReader.h" #include "../types/dynamic.h" using namespace libac; using namespace std; namespace nbt { enum class TagType { End = 0, Byte = 1, Short = 2, Int = 3, Long = 4, Float = 5, Double = 6, ByteArray = 7, String = 8, List = 9, Compound = 10, IntArray = 11, LongArray = 12 }; class Tag { public: virtual ~Tag() = default; int getType() const { return static_cast(getTagType()); } virtual TagType getTagType() const = 0; bool hasParent() const { return _parentTag != nullptr; } static TagType getStringifiedTagType(StringReader &str); void updateParent(Tag *tag) { if (tag == nullptr) { _parentTag = nullptr; setParentTagType(TagType::End); } else { _parentTag = tag; setParentTagType(tag->getTagType()); } } Tag *getParent() const { return _parentTag; } TagType getParentTagType() const { return _parentTagType; } void setParentTagType(TagType type) { _parentTagType = type; } virtual void readValue(ByteLayer &data); std::string getKey() const { return _key.empty() ? "" : _key; } void setKey(const std::string &key) { _key = key; } virtual void writeStringifiedValue(StringBuilder &stream, int indent, bool isList) const = 0; virtual void writeValue(ByteLayer &data) const; virtual void setValue(const dynamic &val); virtual void prettyPrint(int indent, bool recurse) const; virtual void readStringifiedValue(StringReader &reader); virtual dynamic getValue() const; virtual void setValue(int val); virtual bool equals(const Tag &other) const { return getType() == other.getType() && getKey() == other.getKey(); } static Tag *readNamedTag(ByteLayer &data); static void writeNamedTag(Tag &tag, ByteLayer &data); static Tag *readStringifiedNamedTag(StringReader &string); static void writeStringifiedNamedTag(Tag &tag, StringBuilder &builder, int indents); static Tag *makeTagOfType(TagType type); static std::string getCanonicalName(TagType type); bool shouldQuoteName(); static bool shouldQuote(const string &value); ByteTag asByte() const; ByteArrayTag asByteArray() const; CompoundTag asCompound() const; DoubleTag asDouble() const; FloatTag asFloat() const; IntArrayTag asIntArray() const; IntTag asInt() const; LongArrayTag asLongArray() const; LongTag asLong() const; ShortTag asShort() const; ListTag asList() const; protected: Tag *_parentTag; TagType _parentTagType = TagType::End; std::string _key; }; } #endif