lib/nbt: Begin implementing nextTagDataLength

BodgeMaster-unfinished
BodgeMaster 2022-08-13 15:46:06 +02:00
parent 027f324f03
commit 86f1ef596f
2 changed files with 48 additions and 8 deletions

View File

@ -451,22 +451,62 @@ namespace NBT {
}
}
ErrorOr<uint32_t> nextTagDataSize(uint8_t data[], uint64_t dataSize, uint64_t currentPosition){
//FIXME: instead of blindly passing the error code upwards, choose
// one that is applicable to the situation (for example replace
// OUT_OF_RANGE with OVERRUN where appropriate)
ErrorOr<int32_t> nextTagDataLength(uint8_t data[], uint64_t dataSize, uint64_t currentPosition){
uint8_t nextTag;
if (dataSize <= currentPosition) {
return ErrorOr<uint32_t>(true, ErrorCodes::OVERRUN);
return ErrorOr<int32_t>(true, ErrorCodes::OVERRUN);
} else {
nextTag = data[currentPosition];
}
// deal with compound tags separately
if (nextTag == TagType::COMPOUND) return ErrorOr<uint32_t>(true, ErrorCodes::NOT_YET_KNOWN);
if (nextTag == TagType::COMPOUND) {
return ErrorOr<int32_t>(true, ErrorCodes::NOT_YET_KNOWN);
}
// deal with end tag before trying to access the name
if (nextTag == TagType::END) return 0;
//TODO: implement for all the remaining types
// unknown tag or parsing error
return ErrorOr<uint32_t>(true, ErrorCodes::UNKNOWN);
if (nextTag == TagType::END) {
return ErrorOr<int32_t>(0);
}
// tags that only ever hold one value
if (nextTag == TagType::INT8 || nextTag == TagType::INT16 || nextTag == TagType::INT32 || nextTag == TagType::INT64 || nextTag == TagType::FLOAT || nextTag == TagType::DOUBLE) {
return ErrorOr<int32_t>(1);
}
ErrorOr<int16_t> nameSize = helper::readInt16(data, dataSize, currentPosition+1);
if (nameSize.isError) {
return ErrorOr<int32_t>(true, nameSize.errorCode);
}
// add type byte and name size bytes
uint64_t prefixSize = (uint64_t) nameSize.value + 3;
switch (nextTag) {
case TagType::INT8_ARRAY: {
return helper::readInt32(data, dataSize, currentPosition+prefixSize);
}
case TagType::STRING: {
ErrorOr<int16_t> stringSize = helper::readInt16(data, dataSize, currentPosition+prefixSize);
if (stringSize.isError) {
return ErrorOr<int32_t>(true, stringSize.errorCode);
}
return ErrorOr<int32_t>((int32_t) stringSize.value);
}
case TagType::LIST: {
}
case TagType::INT32_ARRAY: {
return helper::readInt32(data, dataSize, currentPosition+prefixSize);
}
case TagType::INT64_ARRAY: {
return helper::readInt32(data, dataSize, currentPosition+prefixSize);
}
default:
// unknown tag or parsing error
return ErrorOr<int32_t>(true, ErrorCodes::UNKNOWN);
}
}
}

View File

@ -68,7 +68,7 @@ namespace NBT {
void writeInt64Array(std::vector<uint8_t>* destination, int64_t data[], uint32_t dataSize);
ErrorOr<uint64_t> nextTagTotalSize(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
ErrorOr<uint32_t> nextTagDataSize(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
ErrorOr<int32_t> nextTagDataLength(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
}
namespace TagType {