diff --git a/src/lib/nbt.cpp b/src/lib/nbt.cpp index 1d53efa..b6ec029 100644 --- a/src/lib/nbt.cpp +++ b/src/lib/nbt.cpp @@ -377,7 +377,7 @@ namespace NBT { // // Does not work for compound tags and lists. This is an intended // feature as compound tags and lists need to be dealt with - // separately to avoid unnecessarily complex code. + // separately to avoid unnecessarily long and complex code. // // Regardinng lists specifically: The size of some lists can can // be determined easily by looking at the contained data type and @@ -397,81 +397,53 @@ namespace NBT { if (nextTag == TagType::COMPOUND || nextTag == TagType::LIST) return ErrorOr(false, ErrorCodes::NOT_YET_KNOWN); // deal with end tag before trying to access the name if (nextTag == TagType::END) return ErrorOr(1); - // get name size + 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: - // type byte + name size + data byte -> 4 bytes - return ErrorOr((uint64_t) nameSize.value+4); + return ErrorOr(prefixSize+1); case TagType::INT16: - // type byte + name size + 2 data bytes -> 5 bytes - return ErrorOr((uint64_t) nameSize.value+5); + return ErrorOr(prefixSize+2); case TagType::INT32: - // type byte + name size + 4 data bytes -> 7 bytes - return ErrorOr((uint64_t) nameSize.value+7); + return ErrorOr(prefixSize+4); case TagType::INT64: - // type byte + name size + 8 data bytes -> 11 bytes - return ErrorOr((uint64_t) nameSize.value+11); + return ErrorOr(prefixSize+8); case TagType::FLOAT: - // type byte + name size + 4 data bytes -> 7 bytes - return ErrorOr((uint64_t) nameSize.value+7); + return ErrorOr(prefixSize+4); case TagType::DOUBLE: - // type byte + name size + 8 data bytes -> 11 bytes - return ErrorOr((uint64_t) nameSize.value+11); + return ErrorOr(prefixSize+8); case TagType::INT8_ARRAY: { - // type byte + name size + 4 size bytes -> 7 bytes - uint64_t totalSize = (uint64_t) nameSize.value+7; - - // add size of actual data (1 byte per entry) - ErrorOr arraySize = helper::readInt32(data, dataSize, currentPosition+totalSize); - if (arraySize.isError) { - return ErrorOr(true, arraySize.errorCode); + ErrorOr arrayLength = helper::readInt32(data, dataSize, currentPosition+prefixSize); + if (arrayLength.isError) { + return ErrorOr(true, arrayLength.errorCode); } - totalSize += (uint64_t) arraySize.value; - - return ErrorOr(totalSize); + return ErrorOr((uint64_t) arrayLength.value + prefixSize + 4); } case TagType::STRING: { - // type byte + name size + 2 size bytes -> 5 bytes - uint64_t totalSize = (uint64_t) nameSize.value+5; - - // add size of actual data - ErrorOr stringSize = helper::readInt16(data, dataSize, currentPosition+totalSize); + ErrorOr stringSize = helper::readInt16(data, dataSize, currentPosition+prefixSize); if (stringSize.isError) { return ErrorOr(true, stringSize.errorCode); } - totalSize += (uint64_t) stringSize.value; - - return ErrorOr(totalSize); + return ErrorOr((uint64_t) stringSize.value + prefixSize + 2); } case TagType::INT32_ARRAY: { - // type byte + name size + 4 size bytes -> 7 bytes - uint64_t totalSize = (uint64_t) nameSize.value+7; - - // add size of actual data (4 bytes per entry) - ErrorOr arraySize = helper::readInt16(data, dataSize, currentPosition+totalSize); - if (arraySize.isError) { - return ErrorOr(true, arraySize.errorCode); + ErrorOr arrayLength = helper::readInt32(data, dataSize, currentPosition+prefixSize); + if (arrayLength.isError) { + return ErrorOr(true, arrayLength.errorCode); } - totalSize += (uint64_t) arraySize.value*4; - - return ErrorOr(totalSize); + return ErrorOr((uint64_t) arrayLength.value*4 + prefixSize + 4); } case TagType::INT64_ARRAY: { - // type byte + name size + 4 size bytes -> 7 bytes - uint64_t totalSize = (uint64_t) nameSize.value+7; - - // add size of actual data (8 bytes per entry) - ErrorOr arraySize = helper::readInt16(data, dataSize, currentPosition+totalSize); - if (arraySize.isError) { - return ErrorOr(true, arraySize.errorCode); + ErrorOr arrayLength = helper::readInt32(data, dataSize, currentPosition+prefixSize); + if (arrayLength.isError) { + return ErrorOr(true, arrayLength.errorCode); } - totalSize += (uint64_t) arraySize.value*8; - - return ErrorOr(totalSize); + return ErrorOr((uint64_t) arrayLength.value*8 + prefixSize + 4); } // unknown tag or parsing error default: