filename:
src/nbt/Value.cpp
branch:
feature/world
back to repo
/*
*
* _____ _ _
* / ___|| | | |
* \ `--. | |_ _ __ __ _ | |_ ___ ___
* `--. \| __|| '__| / _` || __| / _ \ / __|
* /\__/ /| |_ | | | (_| || |_ | (_) |\__ \
* \____/ \__||_| \__,_| \__| \___/ |___/
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2025 Armen Deroian
*
*/
#include "CompoundTag.h"
#include "ListTag.h"
#include "PrimitiveTag.h"
#include "StringTag.h"
#include "Value.h"
namespace stratos::nbt {
TagValue::TagValue(Tag&& t) { tag = std::move(t).moveClone(); }
TagValue::TagValue(const TagValue& rhs) { rhs.tag ? tag = rhs.tag->clone() : tag = nullptr; }
TagValue& TagValue::operator=(const TagValue& rhs) {
if (this != &rhs)
tag = rhs.tag ? rhs.tag->clone() : nullptr;
return *this;
}
TagValue& TagValue::operator=(Tag&& t) {
set(std::move(t));
return *this;
}
void TagValue::set(Tag&& t) {
if (tag) {
tag->assign(std::move(t));
} else {
tag = std::move(t).moveClone();
}
}
TagValue& TagValue::operator=(const int8_t val) {
if (!tag) {
set(ByteTag(val));
} else switch (tag->getType()) {
case TagType::Byte:
static_cast<ByteTag&>(*tag).set(val);
break;
case TagType::Short:
static_cast<ShortTag&>(*tag).set(val);
break;
case TagType::Int:
static_cast<IntTag&>(*tag).set(val);
break;
case TagType::Long:
static_cast<LongTag&>(*tag).set(val);
break;
case TagType::Float:
static_cast<FloatTag&>(*tag).set(val);
break;
case TagType::Double:
static_cast<DoubleTag&>(*tag).set(val);
break;
default:
throw std::bad_cast();
}
return *this;
}
TagValue& TagValue::operator=(const int16_t val) {
if (!tag) {
set(ShortTag(val));
} else switch (tag->getType()) {
case TagType::Short:
static_cast<ShortTag&>(*tag).set(val);
break;
case TagType::Int:
static_cast<IntTag&>(*tag).set(val);
break;
case TagType::Long:
static_cast<LongTag&>(*tag).set(val);
break;
case TagType::Float:
static_cast<FloatTag&>(*tag).set(val);
break;
case TagType::Double:
static_cast<DoubleTag&>(*tag).set(val);
break;
default:
throw std::bad_cast();
}
return *this;
}
TagValue& TagValue::operator=(const int32_t val) {
if (!tag) {
set(IntTag(val));
} else switch (tag->getType()) {
case TagType::Int:
static_cast<IntTag&>(*tag).set(val);
break;
case TagType::Long:
static_cast<LongTag&>(*tag).set(val);
break;
case TagType::Float:
static_cast<FloatTag&>(*tag).set(val);
break;
case TagType::Double:
static_cast<DoubleTag&>(*tag).set(val);
break;
default:
throw std::bad_cast();
}
return *this;
}
TagValue& TagValue::operator=(const int64_t val) {
if (!tag) {
set(LongTag(val));
} else switch (tag->getType()) {
case TagType::Long:
static_cast<LongTag&>(*tag).set(val);
break;
case TagType::Float:
static_cast<FloatTag&>(*tag).set(val);
break;
case TagType::Double:
static_cast<DoubleTag&>(*tag).set(val);
break;
default:
throw std::bad_cast();
}
return *this;
}
TagValue& TagValue::operator=(const float val) {
if (!tag) {
set(FloatTag(val));
} else switch (tag->getType()) {
case TagType::Float:
static_cast<FloatTag&>(*tag).set(val);
break;
case TagType::Double:
static_cast<DoubleTag&>(*tag).set(val);
break;
default:
throw std::bad_cast();
}
return *this;
}
TagValue& TagValue::operator=(const double val) {
if (!tag) {
set(DoubleTag(val));
} else switch (tag->getType()) {
case TagType::Double:
static_cast<DoubleTag&>(*tag).set(val);
break;
default:
throw std::bad_cast();
}
return *this;
}
TagValue& TagValue::operator=(const std::string& str) {
if (!tag) {
set(StringTag(str));
} else {
dynamic_cast<StringTag&>(*tag).set(str);
}
return *this;
}
TagValue& TagValue::operator=(std::string&& str) {
if (!tag) {
set(StringTag(str));
} else {
dynamic_cast<StringTag&>(*tag).set(std::move(str));
}
return *this;
}
TagValue::operator signed char() const {
switch(tag->getType())
{
case TagType::Byte:
return static_cast<ByteTag&>(*tag).get();
default:
throw std::bad_cast();
}
}
TagValue::operator short() const {
switch(tag->getType())
{
case TagType::Byte:
return static_cast<ByteTag&>(*tag).get();
case TagType::Short:
return static_cast<ShortTag&>(*tag).get();
default:
throw std::bad_cast();
}
}
TagValue::operator int() const {
switch(tag->getType())
{
case TagType::Byte:
return static_cast<ByteTag&>(*tag).get();
case TagType::Short:
return static_cast<ShortTag&>(*tag).get();
case TagType::Int:
return static_cast<IntTag&>(*tag).get();
default:
throw std::bad_cast();
}
}
TagValue::operator long long() const {
switch(tag->getType())
{
case TagType::Byte:
return static_cast<ByteTag&>(*tag).get();
case TagType::Short:
return static_cast<ShortTag&>(*tag).get();
case TagType::Int:
return static_cast<IntTag&>(*tag).get();
case TagType::Long:
return static_cast<LongTag&>(*tag).get();
default:
throw std::bad_cast();
}
}
TagValue::operator float() const {
switch(tag->getType())
{
case TagType::Byte:
return static_cast<ByteTag&>(*tag).get();
case TagType::Short:
return static_cast<ShortTag&>(*tag).get();
case TagType::Int:
return static_cast<IntTag&>(*tag).get();
case TagType::Long:
return static_cast<LongTag&>(*tag).get();
case TagType::Float:
return static_cast<FloatTag&>(*tag).get();
default:
throw std::bad_cast();
}
}
TagValue::operator double() const {
switch(tag->getType())
{
case TagType::Byte:
return static_cast<ByteTag&>(*tag).get();
case TagType::Short:
return static_cast<ShortTag&>(*tag).get();
case TagType::Int:
return static_cast<IntTag&>(*tag).get();
case TagType::Long:
return static_cast<LongTag&>(*tag).get();
case TagType::Float:
return static_cast<FloatTag&>(*tag).get();
case TagType::Double:
return static_cast<DoubleTag&>(*tag).get();
default:
throw std::bad_cast();
}
}
TagValue::operator const std::string&() const { return dynamic_cast<std::string&>(*tag); }
TagValue& TagValue::at(const std::string& key) { return dynamic_cast<CompoundTag&>(*tag).at(key); }
const TagValue& TagValue::at(const std::string& key) const { return dynamic_cast<const CompoundTag&>(*tag).at(key); }
TagValue& TagValue::operator[](const std::string& key) { return dynamic_cast<CompoundTag&>(*tag)[key]; }
TagValue& TagValue::operator[](const char* key) { return (*this)[std::string(key)]; }
TagValue& TagValue::at(size_t i) { return dynamic_cast<ListTag&>(*tag).at(i); }
const TagValue& TagValue::at(size_t i) const { return dynamic_cast<const ListTag&>(*tag).at(i); }
TagValue& TagValue::operator[](size_t i) { return dynamic_cast<ListTag&>(*tag).at(i); }
const TagValue& TagValue::operator[](size_t i) const { return dynamic_cast<const ListTag&>(*tag).at(i); }
TagType TagValue::getType() const {
return tag ? tag->getType() : TagType::Null;
}
TagValueInitializer::TagValueInitializer(const int8_t val) : TagValue(ByteTag(val)) {}
TagValueInitializer::TagValueInitializer(const int16_t val) : TagValue(ShortTag(val)) {}
TagValueInitializer::TagValueInitializer(const int32_t val) : TagValue(IntTag(val)) {}
TagValueInitializer::TagValueInitializer(const int64_t val) : TagValue(LongTag(val)) {}
TagValueInitializer::TagValueInitializer(const float val) : TagValue(FloatTag(val)) {}
TagValueInitializer::TagValueInitializer(const double val) : TagValue(DoubleTag(val)) {}
TagValueInitializer::TagValueInitializer(const std::string& str) : TagValue(StringTag(str)) {}
TagValueInitializer::TagValueInitializer(std::string&& str) : TagValue(StringTag(std::move(str))) {}
TagValueInitializer::TagValueInitializer(const char* str) : TagValue(StringTag(str)) {}
bool operator==(const TagValue& lhs, const TagValue& rhs) {
if (lhs.tag != nullptr && rhs.tag != nullptr)
return *lhs.tag == *rhs.tag;
return lhs.tag == nullptr && rhs.tag == nullptr;
}
bool operator!=(const TagValue& lhs, const TagValue& rhs) {
return !(lhs == rhs);
}
} // namespace stratos ::nbt