#ifndef LIBNBT_TAG_H #define LIBNBT_TAG_H #include #include #include #include #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 writeValue(ByteLayer &data) const = 0; virtual void readValue(ByteLayer &data) = 0; 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 readStringifiedValue(StringReader &reader) = 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); protected: Tag* _parentTag; TagType _parentTagType = TagType::End; std::string _key; }; } #endif