lib/nbt: Split serializer into two components
One for serializing full tags and one for serializing tags without their header. The former is what used to be `toRawData` - though a bunch of duplicated code has been removed by just moving it to the Generic type class instead of having an implementation on the sub-classes. The latter is useful for serializing lists. The previous warning that all of this is untested still applies.Soda
parent
5920d1d004
commit
4ef1d2c44f
109
src/lib/nbt.cpp
109
src/lib/nbt.cpp
|
@ -550,10 +550,20 @@ namespace NBT {
|
||||||
|
|
||||||
Generic::~Generic() {}
|
Generic::~Generic() {}
|
||||||
|
|
||||||
ErrorOrVoid Generic::toRawData([[maybe_unused]] std::vector<uint8_t>* rawData) {
|
ErrorOrVoid Generic::serializeWithoutHeader([[maybe_unused]] std::vector<uint8_t>* rawData) {
|
||||||
return ErrorOrVoid(true, ErrorCodes::INVALID_TYPE);
|
return ErrorOrVoid(true, ErrorCodes::INVALID_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorOrVoid Generic::serialize(std::vector<uint8_t>* rawData) {
|
||||||
|
rawData->push_back(this->type);
|
||||||
|
|
||||||
|
if (Helper::writeString(rawData, this->name).isError) {
|
||||||
|
return ErrorOrVoid(true, ErrorCodes::OVERRUN);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->serializeWithoutHeader(rawData);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t Generic::getTagType(){
|
uint8_t Generic::getTagType(){
|
||||||
return this->type;
|
return this->type;
|
||||||
}
|
}
|
||||||
|
@ -563,7 +573,11 @@ namespace NBT {
|
||||||
this->type = TagType::END;
|
this->type = TagType::END;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOrVoid End::toRawData(std::vector<uint8_t>* rawData) {
|
ErrorOrVoid End::serializeWithoutHeader([[maybe_unused]] std::vector<uint8_t>* rawData) {
|
||||||
|
return ErrorOrVoid();
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOrVoid End::serialize(std::vector<uint8_t>* rawData) {
|
||||||
rawData->push_back(this->type);
|
rawData->push_back(this->type);
|
||||||
return ErrorOrVoid();
|
return ErrorOrVoid();
|
||||||
}
|
}
|
||||||
|
@ -578,15 +592,8 @@ namespace NBT {
|
||||||
this->value = value;
|
this->value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOrVoid Int8::toRawData(std::vector<uint8_t>* rawData) {
|
ErrorOrVoid Int8::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
|
||||||
rawData->push_back(this->type);
|
|
||||||
|
|
||||||
if (Helper::writeString(rawData, this->name).isError) {
|
|
||||||
return ErrorOrVoid(true, ErrorCodes::OVERRUN);
|
|
||||||
}
|
|
||||||
|
|
||||||
Helper::writeInt8(rawData, this->value);
|
Helper::writeInt8(rawData, this->value);
|
||||||
|
|
||||||
return ErrorOrVoid();
|
return ErrorOrVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,15 +620,8 @@ namespace NBT {
|
||||||
this->value = value;
|
this->value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOrVoid Int16::toRawData(std::vector<uint8_t>* rawData) {
|
ErrorOrVoid Int16::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
|
||||||
rawData->push_back(this->type);
|
|
||||||
|
|
||||||
if (Helper::writeString(rawData, this->name).isError) {
|
|
||||||
return ErrorOrVoid(true, ErrorCodes::OVERRUN);
|
|
||||||
}
|
|
||||||
|
|
||||||
Helper::writeInt16(rawData, this->value);
|
Helper::writeInt16(rawData, this->value);
|
||||||
|
|
||||||
return ErrorOrVoid();
|
return ErrorOrVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,15 +648,8 @@ namespace NBT {
|
||||||
this->value = value;
|
this->value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOrVoid Int32::toRawData(std::vector<uint8_t>* rawData) {
|
ErrorOrVoid Int32::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
|
||||||
rawData->push_back(this->type);
|
|
||||||
|
|
||||||
if (Helper::writeString(rawData, this->name).isError) {
|
|
||||||
return ErrorOrVoid(true, ErrorCodes::OVERRUN);
|
|
||||||
}
|
|
||||||
|
|
||||||
Helper::writeInt32(rawData, this->value);
|
Helper::writeInt32(rawData, this->value);
|
||||||
|
|
||||||
return ErrorOrVoid();
|
return ErrorOrVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,15 +676,8 @@ namespace NBT {
|
||||||
this->value = value;
|
this->value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOrVoid Int64::toRawData(std::vector<uint8_t>* rawData) {
|
ErrorOrVoid Int64::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
|
||||||
rawData->push_back(this->type);
|
|
||||||
|
|
||||||
if (Helper::writeString(rawData, this->name).isError) {
|
|
||||||
return ErrorOrVoid(true, ErrorCodes::OVERRUN);
|
|
||||||
}
|
|
||||||
|
|
||||||
Helper::writeInt64(rawData, this->value);
|
Helper::writeInt64(rawData, this->value);
|
||||||
|
|
||||||
return ErrorOrVoid();
|
return ErrorOrVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,15 +704,8 @@ namespace NBT {
|
||||||
this->value = value;
|
this->value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOrVoid Float::toRawData(std::vector<uint8_t>* rawData) {
|
ErrorOrVoid Float::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
|
||||||
rawData->push_back(this->type);
|
|
||||||
|
|
||||||
if (Helper::writeString(rawData, this->name).isError) {
|
|
||||||
return ErrorOrVoid(true, ErrorCodes::OVERRUN);
|
|
||||||
}
|
|
||||||
|
|
||||||
Helper::writeFloat(rawData, this->value);
|
Helper::writeFloat(rawData, this->value);
|
||||||
|
|
||||||
return ErrorOrVoid();
|
return ErrorOrVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,15 +732,8 @@ namespace NBT {
|
||||||
this->value = value;
|
this->value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOrVoid Double::toRawData(std::vector<uint8_t>* rawData) {
|
ErrorOrVoid Double::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
|
||||||
rawData->push_back(this->type);
|
|
||||||
|
|
||||||
if (Helper::writeString(rawData, this->name).isError) {
|
|
||||||
return ErrorOrVoid(true, ErrorCodes::OVERRUN);
|
|
||||||
}
|
|
||||||
|
|
||||||
Helper::writeDouble(rawData, this->value);
|
Helper::writeDouble(rawData, this->value);
|
||||||
|
|
||||||
return ErrorOrVoid();
|
return ErrorOrVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,15 +765,8 @@ namespace NBT {
|
||||||
this->data = std::vector<int8_t>(data, data+length);
|
this->data = std::vector<int8_t>(data, data+length);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOrVoid Int8Array::toRawData(std::vector<uint8_t>* rawData) {
|
ErrorOrVoid Int8Array::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
|
||||||
rawData->push_back(this->type);
|
|
||||||
|
|
||||||
if (Helper::writeString(rawData, this->name).isError) {
|
|
||||||
return ErrorOrVoid(true, ErrorCodes::OVERRUN);
|
|
||||||
}
|
|
||||||
|
|
||||||
Helper::writeInt8Array(rawData, this->data);
|
Helper::writeInt8Array(rawData, this->data);
|
||||||
|
|
||||||
return ErrorOrVoid();
|
return ErrorOrVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -855,13 +820,7 @@ namespace NBT {
|
||||||
this->value = value;
|
this->value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOrVoid String::toRawData(std::vector<uint8_t>* rawData) {
|
ErrorOrVoid String::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
|
||||||
rawData->push_back(this->type);
|
|
||||||
|
|
||||||
if (Helper::writeString(rawData, this->name).isError) {
|
|
||||||
return ErrorOrVoid(true, ErrorCodes::OVERRUN);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Helper::writeString(rawData, this->value);
|
return Helper::writeString(rawData, this->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -905,9 +864,23 @@ namespace NBT {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOrVoid List::toRawData(std::vector<uint8_t>* rawData) {
|
ErrorOrVoid List::serializeWithoutHeader(std::vector<uint8_t>* rawData) {
|
||||||
#pragma message("TODO: Implement.")
|
rawData->push_back(this->containedType);
|
||||||
return ErrorOrVoid(true, ErrorCodes::UNIMPLEMENTED);
|
|
||||||
|
// 32 bit signed integer max
|
||||||
|
if (this->tags.size() > 0x7FFFFFFF) {
|
||||||
|
return ErrorOrVoid(true, ErrorCodes::OVERRUN);
|
||||||
|
}
|
||||||
|
Helper::writeInt32(rawData, this->tags.size());
|
||||||
|
|
||||||
|
for (int32_t i=0; i<this->tags.size(); i++) {
|
||||||
|
ErrorOrVoid result = this->tags.at(i)->serializeWithoutHeader(rawData);
|
||||||
|
if (result.isError) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrorOrVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<Generic*> List::getElementPointer(uint64_t position) {
|
ErrorOr<Generic*> List::getElementPointer(uint64_t position) {
|
||||||
|
|
|
@ -103,7 +103,8 @@ namespace NBT {
|
||||||
Generic();
|
Generic();
|
||||||
virtual ~Generic();
|
virtual ~Generic();
|
||||||
|
|
||||||
virtual ErrorOrVoid toRawData(std::vector<uint8_t>* rawData);
|
virtual ErrorOrVoid serialize(std::vector<uint8_t>* rawData);
|
||||||
|
virtual ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData);
|
||||||
uint8_t getTagType();
|
uint8_t getTagType();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -111,7 +112,10 @@ namespace NBT {
|
||||||
public:
|
public:
|
||||||
End();
|
End();
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serialize(std::vector<uint8_t>* rawData) override;
|
||||||
|
// This needs a separate serializer because
|
||||||
|
// END tags have a special header.
|
||||||
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Int8: public Generic {
|
class Int8: public Generic {
|
||||||
|
@ -121,7 +125,7 @@ namespace NBT {
|
||||||
Int8();
|
Int8();
|
||||||
Int8(tiny_utf8::string name, int8_t value);
|
Int8(tiny_utf8::string name, int8_t value);
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
int8_t getValue();
|
int8_t getValue();
|
||||||
void setValue(int8_t value);
|
void setValue(int8_t value);
|
||||||
};
|
};
|
||||||
|
@ -133,7 +137,7 @@ namespace NBT {
|
||||||
Int16();
|
Int16();
|
||||||
Int16(tiny_utf8::string name, int16_t value);
|
Int16(tiny_utf8::string name, int16_t value);
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
int16_t getValue();
|
int16_t getValue();
|
||||||
void setValue(int16_t value);
|
void setValue(int16_t value);
|
||||||
};
|
};
|
||||||
|
@ -145,7 +149,7 @@ namespace NBT {
|
||||||
Int32();
|
Int32();
|
||||||
Int32(tiny_utf8::string name, int32_t value);
|
Int32(tiny_utf8::string name, int32_t value);
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
int32_t getValue();
|
int32_t getValue();
|
||||||
void setValue(int32_t value);
|
void setValue(int32_t value);
|
||||||
};
|
};
|
||||||
|
@ -157,7 +161,7 @@ namespace NBT {
|
||||||
Int64();
|
Int64();
|
||||||
Int64(tiny_utf8::string name, int64_t value);
|
Int64(tiny_utf8::string name, int64_t value);
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
int64_t getValue();
|
int64_t getValue();
|
||||||
void setValue(int64_t value);
|
void setValue(int64_t value);
|
||||||
};
|
};
|
||||||
|
@ -169,7 +173,7 @@ namespace NBT {
|
||||||
Float();
|
Float();
|
||||||
Float(tiny_utf8::string name, float value);
|
Float(tiny_utf8::string name, float value);
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
float getValue();
|
float getValue();
|
||||||
void setValue(float value);
|
void setValue(float value);
|
||||||
};
|
};
|
||||||
|
@ -181,7 +185,7 @@ namespace NBT {
|
||||||
Double();
|
Double();
|
||||||
Double(tiny_utf8::string name, double value);
|
Double(tiny_utf8::string name, double value);
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
double getValue();
|
double getValue();
|
||||||
void setValue(double value);
|
void setValue(double value);
|
||||||
};
|
};
|
||||||
|
@ -194,7 +198,7 @@ namespace NBT {
|
||||||
Int8Array(tiny_utf8::string name, std::vector<int8_t> data);
|
Int8Array(tiny_utf8::string name, std::vector<int8_t> data);
|
||||||
Int8Array(tiny_utf8::string name, uint64_t length, int8_t data[]);
|
Int8Array(tiny_utf8::string name, uint64_t length, int8_t data[]);
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
|
|
||||||
std::vector<int8_t> getData();
|
std::vector<int8_t> getData();
|
||||||
ErrorOr<int8_t> getValue(uint64_t position);
|
ErrorOr<int8_t> getValue(uint64_t position);
|
||||||
|
@ -212,7 +216,7 @@ namespace NBT {
|
||||||
String();
|
String();
|
||||||
String(tiny_utf8::string name, tiny_utf8::string value);
|
String(tiny_utf8::string name, tiny_utf8::string value);
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
tiny_utf8::string getValue();
|
tiny_utf8::string getValue();
|
||||||
void setValue(tiny_utf8::string value);
|
void setValue(tiny_utf8::string value);
|
||||||
};
|
};
|
||||||
|
@ -228,7 +232,7 @@ namespace NBT {
|
||||||
|
|
||||||
~List() override;
|
~List() override;
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
|
|
||||||
ErrorOr<Generic*> getElementPointer(uint64_t position);
|
ErrorOr<Generic*> getElementPointer(uint64_t position);
|
||||||
ErrorOrVoid setElementPointerAt(uint64_t position, Generic*);
|
ErrorOrVoid setElementPointerAt(uint64_t position, Generic*);
|
||||||
|
@ -247,7 +251,7 @@ namespace NBT {
|
||||||
|
|
||||||
~Compound() override;
|
~Compound() override;
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
|
|
||||||
ErrorOr<Generic*> getElementPointer(uint64_t position);
|
ErrorOr<Generic*> getElementPointer(uint64_t position);
|
||||||
ErrorOrVoid setElementPointerAt(uint64_t position, Generic*);
|
ErrorOrVoid setElementPointerAt(uint64_t position, Generic*);
|
||||||
|
@ -264,7 +268,7 @@ namespace NBT {
|
||||||
Int32Array(tiny_utf8::string name, std::vector<int32_t> data);
|
Int32Array(tiny_utf8::string name, std::vector<int32_t> data);
|
||||||
Int32Array(tiny_utf8::string name, uint64_t length, int32_t data[]);
|
Int32Array(tiny_utf8::string name, uint64_t length, int32_t data[]);
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
|
|
||||||
std::vector<int32_t> getData();
|
std::vector<int32_t> getData();
|
||||||
ErrorOr<int32_t> getValue(uint64_t position);
|
ErrorOr<int32_t> getValue(uint64_t position);
|
||||||
|
@ -283,7 +287,7 @@ namespace NBT {
|
||||||
Int64Array(tiny_utf8::string name, std::vector<int64_t> data);
|
Int64Array(tiny_utf8::string name, std::vector<int64_t> data);
|
||||||
Int64Array(tiny_utf8::string name, uint64_t length, int64_t data[]);
|
Int64Array(tiny_utf8::string name, uint64_t length, int64_t data[]);
|
||||||
|
|
||||||
ErrorOrVoid toRawData(std::vector<uint8_t>* rawData) override;
|
ErrorOrVoid serializeWithoutHeader(std::vector<uint8_t>* rawData) override;
|
||||||
|
|
||||||
std::vector<int64_t> getData();
|
std::vector<int64_t> getData();
|
||||||
ErrorOr<int64_t> getValue(uint64_t position);
|
ErrorOr<int64_t> getValue(uint64_t position);
|
||||||
|
|
Loading…
Reference in New Issue