Start hooking stuff up!

This commit is contained in:
zontreck 2024-07-30 22:59:35 -07:00
parent e5a3717e64
commit 7744e18d8c
15 changed files with 368 additions and 23 deletions

View file

@ -1,5 +1,6 @@
#include "Accountant.h" #include "Accountant.h"
#include "Tag.h" #include "Tag.h"
#include "CompoundTag.h"
#include <iostream> #include <iostream>
using namespace nbt; using namespace nbt;

View file

@ -27,7 +27,7 @@ namespace nbt
} }
} }
void ByteArrayTag::writeValue(ByteLayer &data) void ByteArrayTag::writeValue(ByteLayer &data) const
{ {
data.writeInt(static_cast<int>(value.size())); data.writeInt(static_cast<int>(value.size()));
for (int i : value) for (int i : value)

View file

@ -21,7 +21,7 @@ namespace nbt
// Override functions from the Tag class // Override functions from the Tag class
void readValue(ByteLayer &data) override; void readValue(ByteLayer &data) override;
void writeValue(ByteLayer &data) override; void writeValue(ByteLayer &data) const override;
TagType getTagType() const override; TagType getTagType() const override;
dynamic getValue() const; dynamic getValue() const;
void setValue(const dynamic &val) override; void setValue(const dynamic &val) override;

View file

@ -24,7 +24,7 @@ namespace nbt
value = data.readByte(); value = data.readByte();
} }
void ByteTag::writeValue(ByteLayer &data) void ByteTag::writeValue(ByteLayer &data) const
{ {
data.writeByte(value); data.writeByte(value);
} }

View file

@ -21,7 +21,7 @@ namespace nbt
// Override functions from the Tag class // Override functions from the Tag class
void readValue(ByteLayer &data) override; void readValue(ByteLayer &data) override;
void writeValue(ByteLayer &data) override; void writeValue(ByteLayer &data) const override;
TagType getTagType() const override; TagType getTagType() const override;
dynamic getValue() const override; dynamic getValue() const override;
void setValue(const dynamic &val) override; void setValue(const dynamic &val) override;

263
src/nbt/CompoundTag.cpp Normal file
View file

@ -0,0 +1,263 @@
#include "CompoundTag.h"
#include "Tag.h"
#include <stdexcept>
#include <sstream>
#include <iostream>
#include <string>
using namespace nbt;
using namespace std;
namespace nbt {
CompoundTag::CompoundTag() : Tag() {
// Constructor implementation
}
CompoundTag::~CompoundTag() {
}
void CompoundTag::readValue(ByteLayer& data) {
value.clear();
while (true) {
Tag* tag = Tag::readNamedTag(data);
if (tag->getTagType() == TagType::End) {
return;
}
tag->setParentTagType(TagType::Compound);
put(tag->getKey(), tag);
}
}
void CompoundTag::writeValue(ByteLayer& data) const {
for (auto& [key, tag] : value) {
Tag::writeNamedTag(*tag, data);
}
data.writeByte(static_cast<int>(TagType::End));
}
void CompoundTag::put(const std::string& name, Tag* tag) {
value[name] = tag;
tag->setKey(name);
tag->updateParent(this);
}
Tag* CompoundTag::get(const std::string& name) const {
auto it = value.find(name);
if (it != value.end()) {
return it->second;
}
return nullptr;
}
TagType CompoundTag::getTagType() const {
return TagType::Compound;
}
void CompoundTag::setValue(const dynamic& val) {
// No specific implementation needed for this example
}
dynamic CompoundTag::getValue() const {
return dynamic(); // Returning a default dynamic instance
}
void CompoundTag::prettyPrint(int indent, bool recurse) const {
std::string indentStr(indent, '\t');
std::cout << indentStr << Tag::getCanonicalName(getTagType()) << ": [" << value.size() << " entries]" << std::endl;
std::cout << indentStr << "{" << std::endl;
if (recurse) {
for (const auto& [key, tag] : value) {
tag->prettyPrint(indent + 1, true);
}
}
}
void CompoundTag::endPrettyPrint(int indent) const {
std::cout << std::string(indent, '\t') << "}" << std::endl;
}
void CompoundTag::writeStringifiedValue(StringBuilder& builder, int indent, bool isList) const {
builder.append(isList ? std::string(indent - 1, '\t') + "{\n" : "{\n");
bool firstEntry = true;
for (const auto& [key, tag] : value) {
if (!firstEntry) {
builder.append(",\n");
}
Tag::writeStringifiedNamedTag(tag, builder, indent);
firstEntry = false;
}
builder.append("\n" + std::string(indent - 1, '\t') + "}");
}
void CompoundTag::readStringifiedValue(StringReader& reader) {
reader.expect("{");
while (reader.peek() != "}") {
Tag* tag = Tag::readStringifiedNamedTag(reader);
put(tag->getKey(), tag);
if (reader.peek() == ",") reader.next();
}
reader.expect("}");
}
Tag* CompoundTag::operator[](const std::string& key) const {
auto it = value.find(key);
return (it != value.end()) ? it->second : nullptr;
}
void CompoundTag::operator[]=(const std::string& key, Tag* tag) {
put(key, tag);
}
void CompoundTag::addAll(const std::map<std::string, Tag*>& other) {
value.insert(other.begin(), other.end());
for (auto& [key, tag] : other) {
tag->updateParent(this);
}
}
void CompoundTag::addEntries(const std::map<std::string, Tag*>& newEntries) {
value.insert(newEntries.begin(), newEntries.end());
for (auto& [key, tag] : newEntries) {
tag->updateParent(this);
}
}
template <typename RK, typename RV>
std::map<RK, RV> CompoundTag::cast() const {
std::map<RK, RV> result;
for (const auto& [key, tag] : value) {
result[static_cast<RK>(key)] = static_cast<RV>(tag);
}
return result;
}
void CompoundTag::clear() {
unsetParent();
value.clear();
}
void CompoundTag::unsetParent() {
for (auto& [key, tag] : value) {
tag->setParentTagType(TagType::End);
tag->updateParent(nullptr);
}
}
bool CompoundTag::containsKey(const std::string& key) const {
return value.find(key) != value.end();
}
bool CompoundTag::containsValue(const Tag* tag) const {
for (const auto& [key, valueTag] : value) {
if (valueTag == tag) {
return true;
}
}
return false;
}
std::map<std::string, Tag*>::const_iterator CompoundTag::begin() const {
return value.begin();
}
std::map<std::string, Tag*>::const_iterator CompoundTag::end() const {
return value.end();
}
void CompoundTag::forEach(void (*action)(const std::string&, Tag*)) const {
for (const auto& [key, tag] : value) {
action(key, tag);
}
}
bool CompoundTag::isEmpty() const {
return value.empty();
}
bool CompoundTag::isNotEmpty() const {
return !value.empty();
}
std::map<std::string, Tag*>::const_iterator CompoundTag::keys() const {
return value.begin();
}
int CompoundTag::length() const {
return static_cast<int>(value.size());
}
std::map<std::string, Tag*> CompoundTag::map(std::pair<std::string, Tag*>(*)(const std::string&, Tag*)) const {
std::map<std::string, Tag*> result;
for (const auto& [key, tag] : value) {
result[key] = tag;
}
return result;
}
Tag* CompoundTag::putIfAbsent(const std::string& key, Tag* (*ifAbsent)()) {
auto [it, inserted] = value.emplace(key, ifAbsent());
Tag* tag = it->second;
tag->updateParent(this);
return tag;
}
Tag* CompoundTag::remove(const std::string& key) {
auto it = value.find(key);
if (it != value.end()) {
Tag* tag = it->second;
tag->updateParent(nullptr);
value.erase(it);
return tag;
}
return nullptr;
}
void CompoundTag::removeWhere(bool (*test)(const std::string&, Tag*)) {
for (auto it = value.begin(); it != value.end();) {
if (test(it->first, it->second)) {
it->second->updateParent(nullptr);
it = value.erase(it);
} else {
++it;
}
}
}
Tag* CompoundTag::update(const std::string& key, Tag* (*update)(Tag*), Tag* (*ifAbsent)()) {
auto it = value.find(key);
if (it != value.end()) {
Tag* updatedTag = update(it->second);
it->second->updateParent(nullptr);
value[key] = updatedTag;
updatedTag->updateParent(this);
return updatedTag;
} else if (ifAbsent) {
Tag* newTag = ifAbsent();
put(key, newTag);
return newTag;
}
return nullptr;
}
void CompoundTag::updateAll(Tag* (*update)(const std::string&, Tag*)) {
for (auto& [key, tag] : value) {
Tag* updatedTag = update(key, tag);
tag->updateParent(nullptr);
value[key] = updatedTag;
updatedTag->updateParent(this);
}
}
std::map<std::string, Tag*>::const_iterator CompoundTag::values() const {
return value.begin();
}
}

77
src/nbt/CompoundTag.h Normal file
View file

@ -0,0 +1,77 @@
#ifndef COMPOUNDTAG_H
#define COMPOUNDTAG_H
#include <iostream>
#include <map>
#include <string>
#include "Tag.h"
#include "ByteLayer.h"
#include "StringBuilder.h"
#include "StringReader.h"
namespace nbt {
class CompoundTag : public Tag {
public:
CompoundTag();
~CompoundTag();
void readValue(ByteLayer& data) override;
void writeValue(ByteLayer& data) const override;
void put(const std::string& name, Tag* tag);
Tag* get(const std::string& name) const;
TagType getTagType() const override;
void setValue(const dynamic& val) override;
dynamic getValue() const override;
void prettyPrint(int indent, bool recurse) const override;
void endPrettyPrint(int indent) const;
void writeStringifiedValue(StringBuilder& builder, int indent, bool isList) const override;
void readStringifiedValue(StringReader& reader) override;
Tag* operator[](const std::string& key) const;
void addAll(const std::map<std::string, Tag*>& other);
void addEntries(const std::map<std::string, Tag*>& newEntries);
template <typename RK, typename RV>
std::map<RK, RV> cast() const;
void clear();
void unsetParent();
bool containsKey(const std::string& key) const;
bool containsValue(const Tag* value) const;
std::map<std::string, Tag*>::const_iterator begin() const;
std::map<std::string, Tag*>::const_iterator end() const;
void forEach(void (*action)(const std::string&, Tag*)) const;
bool isEmpty() const;
bool isNotEmpty() const;
std::map<std::string, Tag*>::const_iterator keys() const;
int length() const;
std::map<std::string, Tag*> map(std::pair<std::string, Tag*>(*)(const std::string&, Tag*)) const;
Tag* putIfAbsent(const std::string& key, Tag* (*ifAbsent)());
Tag* remove(const std::string& key);
void removeWhere(bool (*test)(const std::string&, Tag*));
Tag* update(const std::string& key, Tag* (*update)(Tag*), Tag* (*ifAbsent)() = nullptr);
void updateAll(Tag* (*update)(const std::string&, Tag*));
std::map<std::string, Tag*>::const_iterator values() const;
private:
std::map<std::string, Tag*> value;
};
}
#endif // COMPOUNDTAG_H

View file

@ -22,7 +22,7 @@ namespace nbt
value = data.readDouble(); value = data.readDouble();
} }
void DoubleTag::writeValue(ByteLayer &data) void DoubleTag::writeValue(ByteLayer &data) const
{ {
data.writeDouble(value); data.writeDouble(value);
} }

View file

@ -14,7 +14,7 @@ namespace nbt
// Function overrides // Function overrides
void readValue(ByteLayer &data) override; void readValue(ByteLayer &data) override;
void writeValue(ByteLayer &data) override; void writeValue(ByteLayer &data) const override;
TagType getTagType() const override; TagType getTagType() const override;
dynamic getValue() const override; dynamic getValue() const override;
void setValue(const dynamic &val) override; void setValue(const dynamic &val) override;

View file

@ -20,7 +20,7 @@ namespace nbt
// Implementation here // Implementation here
} }
void EndTag::writeValue(ByteLayer &data) void EndTag::writeValue(ByteLayer &data) const
{ {
// Implementation here // Implementation here
} }

View file

@ -16,7 +16,7 @@ namespace nbt
// Override functions from the Tag class // Override functions from the Tag class
void readValue(ByteLayer &data) override; void readValue(ByteLayer &data) override;
void writeValue(ByteLayer &data) override; void writeValue(ByteLayer &data) const override;
TagType getTagType() const override; TagType getTagType() const override;
void setValue(const dynamic &val) override; void setValue(const dynamic &val) override;
dynamic getValue() const override; dynamic getValue() const override;

View file

@ -22,7 +22,7 @@ namespace nbt
value = data.readFloat(); value = data.readFloat();
} }
void FloatTag::writeValue(ByteLayer &data) void FloatTag::writeValue(ByteLayer &data) const
{ {
data.writeFloat(value); data.writeFloat(value);
} }

View file

@ -14,7 +14,7 @@ namespace nbt
// Function overrides // Function overrides
void readValue(ByteLayer &data) override; void readValue(ByteLayer &data) override;
void writeValue(ByteLayer &data) override; void writeValue(ByteLayer &data) const override;
TagType getTagType() const override; TagType getTagType() const override;
dynamic getValue() const override; dynamic getValue() const override;
void setValue(const dynamic &val) override; void setValue(const dynamic &val) override;

View file

@ -1,5 +1,7 @@
#include "Tag.h" #include "Tag.h"
#include "EndTag.h" #include "EndTag.h"
#include "ByteTag.h"
#include "ByteArrayTag.h"
#include <cctype> #include <cctype>
#include <algorithm> #include <algorithm>
@ -12,15 +14,17 @@ using namespace libac;
namespace nbt namespace nbt
{ {
std::shared_ptr<Tag> Tag::readNamedTag(ByteLayer &data) Tag *Tag::readNamedTag(ByteLayer &data)
{ {
int type = data.readByte(); int type = data.readByte();
switch (static_cast<TagType>(type)) switch (static_cast<TagType>(type))
{ {
case TagType::End: case TagType::End:
return std::make_shared<EndTag>(); return new EndTag();
case TagType::Byte: case TagType::Byte:
// handle other cases similarly return new ByteTag();
case TagType::ByteArray:
return new ByteArrayTag();
default: default:
// default handling // default handling
return nullptr; return nullptr;
@ -82,7 +86,7 @@ namespace nbt
} }
} }
std::shared_ptr<Tag> Tag::readStringifiedNamedTag(StringReader &string) Tag *Tag::readStringifiedNamedTag(StringReader &string)
{ {
std::string name; std::string name;
if (string.peek() == '{' || string.peek() == '[') if (string.peek() == '{' || string.peek() == '[')
@ -95,7 +99,7 @@ namespace nbt
string.expect(':'); string.expect(':');
} }
TagType type = Tag::getStringifiedTagType(string); TagType type = Tag::getStringifiedTagType(string);
std::shared_ptr<Tag> tag = makeTagOfType(type); Tag *tag = makeTagOfType(type);
tag->setKey(name); tag->setKey(name);
tag->readStringifiedValue(string); tag->readStringifiedValue(string);

View file

@ -52,11 +52,11 @@ namespace nbt
static TagType getStringifiedTagType(StringReader &str); static TagType getStringifiedTagType(StringReader &str);
void updateParent(std::shared_ptr<Tag> tag) void updateParent(Tag* tag)
{ {
if (tag == nullptr) if (tag == nullptr)
{ {
_parentTag.reset(); _parentTag = nullptr;
setParentTagType(TagType::End); setParentTagType(TagType::End);
} }
else else
@ -66,7 +66,7 @@ namespace nbt
} }
} }
std::shared_ptr<Tag> getParent() const Tag* getParent() const
{ {
return _parentTag; return _parentTag;
} }
@ -96,7 +96,7 @@ namespace nbt
virtual void writeStringifiedValue(StringBuilder &stream, int indent, bool isList) const = 0; virtual void writeStringifiedValue(StringBuilder &stream, int indent, bool isList) const = 0;
virtual void readStringifiedValue(StringReader &reader) = 0; virtual void readStringifiedValue(StringReader &reader) = 0;
virtual void writeValue(ByteLayer &data); virtual void writeValue(ByteLayer &data) const;
virtual void setValue(const dynamic &val); virtual void setValue(const dynamic &val);
virtual void prettyPrint(int indent, bool recurse) const; virtual void prettyPrint(int indent, bool recurse) const;
virtual void readStringifiedValue(StringReader &reader); virtual void readStringifiedValue(StringReader &reader);
@ -108,19 +108,19 @@ namespace nbt
return getType() == other.getType() && getKey() == other.getKey(); return getType() == other.getType() && getKey() == other.getKey();
} }
static std::shared_ptr<Tag> readNamedTag(ByteLayer &data); static Tag* readNamedTag(ByteLayer &data);
static void writeNamedTag(Tag &tag, ByteLayer &data); static void writeNamedTag(Tag &tag, ByteLayer &data);
static std::shared_ptr<Tag> readStringifiedNamedTag(StringReader &string); static Tag* readStringifiedNamedTag(StringReader &string);
static void writeStringifiedNamedTag(Tag &tag, StringBuilder &builder, int indents); static void writeStringifiedNamedTag(Tag &tag, StringBuilder &builder, int indents);
static std::shared_ptr<Tag> makeTagOfType(TagType type); static Tag* makeTagOfType(TagType type);
static std::string getCanonicalName(TagType type); static std::string getCanonicalName(TagType type);
bool shouldQuoteName(); bool shouldQuoteName();
static bool shouldQuote(const string &value); static bool shouldQuote(const string &value);
protected: protected:
std::shared_ptr<Tag> _parentTag; Tag* _parentTag;
TagType _parentTagType = TagType::End; TagType _parentTagType = TagType::End;
std::string _key; std::string _key;
}; };