lib/nbt: Implement the rest of the functions outline in the header

This concludes the implementation of the in-memory NBT representation.
This is still all untested code so it might just blow up in your face.
The next step will be writing tests (and probably a lot of cursing and
debugging)...
Soda
BodgeMaster 2022-10-05 01:12:38 +02:00
parent 2d2b67373c
commit 79650e390e
2 changed files with 212 additions and 9 deletions

View File

@ -805,9 +805,12 @@ namespace NBT {
}
ErrorOrVoid Int8Array::removeElement(uint64_t position) {
#pragma message("TODO: implement")
//this->data.erase(position);
return ErrorOrVoid(true, ErrorCodes::UNIMPLEMENTED);
if (position >= this->data.size()) {
return ErrorOrVoid(true, ErrorCodes::OUT_OF_RANGE);
}
this->data.erase(this->data.begin()+position);
return ErrorOrVoid();
}
String::String() {
@ -916,17 +919,217 @@ namespace NBT {
}
ErrorOrVoid List::deleteElement(uint64_t position) {
#pragma message("TODO: Implement.")
if (position >= this->tags.size()) {
return ErrorOrVoid(true, ErrorCodes::OUT_OF_RANGE);
}
// Step 1) delete pointer
// Step 2) remove element from vector
delete this->tags[position];
this->tags.erase(this->tags.begin()+position);
return ErrorOrVoid(true, ErrorCodes::UNIMPLEMENTED);
return ErrorOrVoid();
}
uint64_t List::length() {
return this->tags.size();
}
Compound::Compound() {
this->type = TagType::COMPOUND;
}
Compound::Compound(tiny_utf8::string name) {
this->type = TagType::COMPOUND;
this->name = name;
}
Compound::Compound(tiny_utf8::string name, std::vector<Generic*> data) {
this->type = TagType::COMPOUND;
this->name = name;
this->tags = data;
}
Compound::~Compound() {
for (uint64_t i=0; i<this->tags.size(); i++) {
delete this->tags.at(i);
}
}
ErrorOrVoid Compound::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
for (uint64_t i=0; i<this->tags.size(); i++) {
ErrorOrVoid result = this->tags.at(i)->serialize(rawData);
if (result.isError) {
return result;
}
}
return ErrorOrVoid();
}
ErrorOr<Generic*> Compound::getElementPointer(uint64_t position) {
if (position >= this->tags.size()) {
return ErrorOr<Generic*>(true, ErrorCodes::OUT_OF_RANGE);
}
return ErrorOr<Generic*>(this->tags.at(position));
}
ErrorOrVoid Compound::setElementPointerAt(uint64_t position, Generic* pointer) {
if (position >= this->tags.size()) {
return ErrorOrVoid(true, ErrorCodes::OUT_OF_RANGE);
}
delete this->tags[position];
this->tags[position] = pointer;
return ErrorOrVoid();
}
void Compound::appendPointer(Generic* pointer) {
this->tags.push_back(pointer);
}
ErrorOrVoid Compound::deleteElement(uint64_t position) {
if (position >= this->tags.size()) {
return ErrorOrVoid(true, ErrorCodes::OUT_OF_RANGE);
}
delete this->tags[position];
this->tags.erase(this->tags.begin()+position);
return ErrorOrVoid();
}
uint64_t Compound::length() {
return this->tags.size();
}
Int32Array::Int32Array() {
this->type = TagType::INT32_ARRAY;
}
Int32Array::Int32Array(tiny_utf8::string name, std::vector<int32_t> data) {
this->type = TagType::INT32_ARRAY;
this->name = name;
this->data = data;
}
Int32Array::Int32Array(tiny_utf8::string name, uint64_t length, int32_t data[]) {
this->type = TagType::INT32_ARRAY;
this->name = name;
this->data = std::vector(data, data+length);
}
ErrorOrVoid Int32Array::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
Helper::writeInt32Array(rawData, this->data);
return ErrorOrVoid();
}
std::vector<int32_t> Int32Array::getData() {
return this->data;
}
ErrorOr<int32_t> Int32Array::getValue(uint64_t position) {
if (position >= this->data.size()) {
return ErrorOr<int32_t>(true, ErrorCodes::OVERRUN);
}
return ErrorOr<int32_t>(this->data.at(position));
}
void Int32Array::setData(std::vector<int32_t> newData) {
this->data = newData;
}
ErrorOrVoid Int32Array::setValue(uint64_t position, int32_t value) {
if (position >= this->data.size()) {
return ErrorOrVoid(true, ErrorCodes::OVERRUN);
}
this->data[position] = value;
return ErrorOrVoid();
}
uint64_t Int32Array::length() {
return this->data.size();
}
void Int32Array::addElement(int32_t element) {
this->data.push_back(element);
}
ErrorOrVoid Int32Array::removeElement(uint64_t position) {
if (position >= this->data.size()) {
return ErrorOrVoid(true, ErrorCodes::OUT_OF_RANGE);
}
this->data.erase(this->data.begin()+position);
return ErrorOrVoid();
}
Int64Array::Int64Array() {
this->type = TagType::INT64_ARRAY;
}
Int64Array::Int64Array(tiny_utf8::string name, std::vector<int64_t> data) {
this->type = TagType::INT64_ARRAY;
this->name = name;
this->data = data;
}
Int64Array::Int64Array(tiny_utf8::string name, uint64_t length, int64_t data[]) {
this->type = TagType::INT64_ARRAY;
this->name = name;
this->data = std::vector(data, data+length);
}
ErrorOrVoid Int64Array::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
Helper::writeInt64Array(rawData, this->data);
return ErrorOrVoid();
}
std::vector<int64_t> Int64Array::getData() {
return this->data;
}
ErrorOr<int64_t> Int64Array::getValue(uint64_t position) {
if (position >= this->data.size()) {
return ErrorOr<int64_t>(true, ErrorCodes::OUT_OF_RANGE);
}
return ErrorOr<int64_t>(this->data[position]);
}
void Int64Array::setData(std::vector<int64_t> newData) {
this->data = newData;
}
ErrorOrVoid Int64Array::setValue(uint64_t position, int64_t value) {
if (position >= this->data.size()) {
return ErrorOrVoid(true, ErrorCodes::OUT_OF_RANGE);
}
this->data[position] = value;
return ErrorOrVoid();
}
uint64_t Int64Array::length() {
return this->data.size();
}
void Int64Array::addElement(int64_t element) {
this->data.push_back(element);
}
ErrorOrVoid Int64Array::removeElement(uint64_t position) {
if (position >= this->data.size()) {
return ErrorOrVoid(true, ErrorCodes::OUT_OF_RANGE);
}
this->data.erase(this->data.begin()+position);
return ErrorOrVoid();
}
}
bool validateRawListContents(uint8_t data[], uint64_t dataSize, uint64_t initialPosition, uint64_t* processedDataSize) {

View File

@ -254,8 +254,8 @@ namespace NBT {
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
ErrorOr<Generic*> getElementPointer(uint64_t position);
ErrorOrVoid setElementPointerAt(uint64_t position, Generic*);
ErrorOrVoid appendPointer(Generic*);
ErrorOrVoid setElementPointerAt(uint64_t position, Generic* pointer);
void appendPointer(Generic* pointer);
ErrorOrVoid deleteElement(uint64_t position);
uint64_t length();
};