From 86f1ef596f596374680dd5ee76485d583ac381ea Mon Sep 17 00:00:00 2001 From: BodgeMaster <> Date: Sat, 13 Aug 2022 15:46:06 +0200 Subject: [PATCH] lib/nbt: Begin implementing nextTagDataLength --- src/lib/nbt.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++------- src/lib/nbt.hpp | 2 +- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/lib/nbt.cpp b/src/lib/nbt.cpp index b6ec029..be63d68 100644 --- a/src/lib/nbt.cpp +++ b/src/lib/nbt.cpp @@ -451,22 +451,62 @@ namespace NBT { } } - ErrorOr 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 nextTagDataLength(uint8_t data[], uint64_t dataSize, uint64_t currentPosition){ uint8_t nextTag; if (dataSize <= currentPosition) { - return ErrorOr(true, ErrorCodes::OVERRUN); + return ErrorOr(true, ErrorCodes::OVERRUN); } else { nextTag = data[currentPosition]; } // deal with compound tags separately - if (nextTag == TagType::COMPOUND) return ErrorOr(true, ErrorCodes::NOT_YET_KNOWN); + if (nextTag == TagType::COMPOUND) { + return ErrorOr(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(true, ErrorCodes::UNKNOWN); + if (nextTag == TagType::END) { + return ErrorOr(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(1); + } + + ErrorOr nameSize = helper::readInt16(data, dataSize, currentPosition+1); + if (nameSize.isError) { + return ErrorOr(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 stringSize = helper::readInt16(data, dataSize, currentPosition+prefixSize); + if (stringSize.isError) { + return ErrorOr(true, stringSize.errorCode); + } + return ErrorOr((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(true, ErrorCodes::UNKNOWN); + } } } diff --git a/src/lib/nbt.hpp b/src/lib/nbt.hpp index 578a1f2..c7174d8 100644 --- a/src/lib/nbt.hpp +++ b/src/lib/nbt.hpp @@ -68,7 +68,7 @@ namespace NBT { void writeInt64Array(std::vector* destination, int64_t data[], uint32_t dataSize); ErrorOr nextTagTotalSize(uint8_t data[], uint64_t dataSize, uint64_t currentPosition); - ErrorOr nextTagDataSize(uint8_t data[], uint64_t dataSize, uint64_t currentPosition); + ErrorOr nextTagDataLength(uint8_t data[], uint64_t dataSize, uint64_t currentPosition); } namespace TagType {