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 "Tag.h"
#include "CompoundTag.h"
#include <iostream>
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()));
for (int i : value)

View file

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

View file

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

View file

@ -21,7 +21,7 @@ namespace nbt
// Override functions from the Tag class
void readValue(ByteLayer &data) override;
void writeValue(ByteLayer &data) override;
void writeValue(ByteLayer &data) const override;
TagType getTagType() const override;
dynamic getValue() const 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();
}
void DoubleTag::writeValue(ByteLayer &data)
void DoubleTag::writeValue(ByteLayer &data) const
{
data.writeDouble(value);
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -52,11 +52,11 @@ namespace nbt
static TagType getStringifiedTagType(StringReader &str);
void updateParent(std::shared_ptr<Tag> tag)
void updateParent(Tag* tag)
{
if (tag == nullptr)
{
_parentTag.reset();
_parentTag = nullptr;
setParentTagType(TagType::End);
}
else
@ -66,7 +66,7 @@ namespace nbt
}
}
std::shared_ptr<Tag> getParent() const
Tag* getParent() const
{
return _parentTag;
}
@ -96,7 +96,7 @@ namespace nbt
virtual void writeStringifiedValue(StringBuilder &stream, int indent, bool isList) const = 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 prettyPrint(int indent, bool recurse) const;
virtual void readStringifiedValue(StringReader &reader);
@ -108,19 +108,19 @@ namespace nbt
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 std::shared_ptr<Tag> readStringifiedNamedTag(StringReader &string);
static Tag* readStringifiedNamedTag(StringReader &string);
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);
bool shouldQuoteName();
static bool shouldQuote(const string &value);
protected:
std::shared_ptr<Tag> _parentTag;
Tag* _parentTag;
TagType _parentTagType = TagType::End;
std::string _key;
};