From c87c519bb55791c834d69bba9ea0f235d8e09331 Mon Sep 17 00:00:00 2001 From: BodgeMaster <> Date: Wed, 29 Jun 2022 12:22:54 +0200 Subject: [PATCH] NBT: implement NBT::helper::readInt8Array --- src/lib/nbt.cpp | 13 ++++- src/test/nbt_helpers.cpp | 119 ++++++++++++++++++++++++++------------- 2 files changed, 91 insertions(+), 41 deletions(-) diff --git a/src/lib/nbt.cpp b/src/lib/nbt.cpp index 938dde8..93b6ca9 100644 --- a/src/lib/nbt.cpp +++ b/src/lib/nbt.cpp @@ -103,8 +103,17 @@ namespace NBT { } ErrorOr> readInt8Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) { - //TODO: implement - return ErrorOr>({0}); + // get size prefix + ErrorOr size = readInt32(data, dataSize, currentPosition); + if (size.isError) return ErrorOr>(true, size.errorCode); + + // get content + if (currentPosition+4+size.value > dataSize) return ErrorOr>(true, ErrorCodes::OVERRUN_ERROR); + std::vector result = std::vector(); + for (int i=0; i>(result); } // Maybe use a struct that holds decoded (de-Java-fied) string diff --git a/src/test/nbt_helpers.cpp b/src/test/nbt_helpers.cpp index b576460..e3e9286 100644 --- a/src/test/nbt_helpers.cpp +++ b/src/test/nbt_helpers.cpp @@ -15,6 +15,7 @@ #include #include +#include #include "assert.h++" @@ -24,100 +25,140 @@ int main(){ // used for all integer tests - uint8_t data[] = {30, 31, 32, 33, 34, 35, 36, 37, 38, 39}; + uint8_t dataForIntTest[] = {30, 31, 32, 33, 34, 35, 36, 37, 38, 39}; uint64_t dataSize = 10; // int8 ############################################################ // read successfully uint64_t currentPosition = 5; - ASSERT(NBT::helper::readInt8(data, dataSize, currentPosition).value == 35); - ASSERT(NBT::helper::readInt8(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt8(dataForIntTest, dataSize, currentPosition).value == 35); + ASSERT(NBT::helper::readInt8(dataForIntTest, dataSize, currentPosition).isError == false); // begin of data currentPosition = 0; - ASSERT(NBT::helper::readInt8(data, dataSize, currentPosition).value == 30); - ASSERT(NBT::helper::readInt8(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt8(dataForIntTest, dataSize, currentPosition).value == 30); + ASSERT(NBT::helper::readInt8(dataForIntTest, dataSize, currentPosition).isError == false); // end of data currentPosition = 9; - ASSERT(NBT::helper::readInt8(data, dataSize, currentPosition).value == 39); - ASSERT(NBT::helper::readInt8(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt8(dataForIntTest, dataSize, currentPosition).value == 39); + ASSERT(NBT::helper::readInt8(dataForIntTest, dataSize, currentPosition).isError == false); // out of bounds currentPosition = 10; - ASSERT(NBT::helper::readInt8(data, dataSize, currentPosition).isError == true); - ASSERT(NBT::helper::readInt8(data, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); + ASSERT(NBT::helper::readInt8(dataForIntTest, dataSize, currentPosition).isError == true); + ASSERT(NBT::helper::readInt8(dataForIntTest, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); std::cout << "Passed readInt8 NBT helper test" << std::endl; // int16 ########################################################### // read successfully currentPosition = 5; - ASSERT(NBT::helper::readInt16(data, dataSize, currentPosition).value == 8996); - ASSERT(NBT::helper::readInt16(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt16(dataForIntTest, dataSize, currentPosition).value == 8996); + ASSERT(NBT::helper::readInt16(dataForIntTest, dataSize, currentPosition).isError == false); // begin of data currentPosition = 0; - ASSERT(NBT::helper::readInt16(data, dataSize, currentPosition).value == 7711); - ASSERT(NBT::helper::readInt16(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt16(dataForIntTest, dataSize, currentPosition).value == 7711); + ASSERT(NBT::helper::readInt16(dataForIntTest, dataSize, currentPosition).isError == false); // end of data currentPosition = 8; - ASSERT(NBT::helper::readInt16(data, dataSize, currentPosition).value == 9767); - ASSERT(NBT::helper::readInt16(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt16(dataForIntTest, dataSize, currentPosition).value == 9767); + ASSERT(NBT::helper::readInt16(dataForIntTest, dataSize, currentPosition).isError == false); // partially out of bounds currentPosition = 9; - ASSERT(NBT::helper::readInt16(data, dataSize, currentPosition).isError == true); - ASSERT(NBT::helper::readInt16(data, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); + ASSERT(NBT::helper::readInt16(dataForIntTest, dataSize, currentPosition).isError == true); + ASSERT(NBT::helper::readInt16(dataForIntTest, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); // fully out of bounds currentPosition = 10; - ASSERT(NBT::helper::readInt16(data, dataSize, currentPosition).isError == true); - ASSERT(NBT::helper::readInt16(data, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); + ASSERT(NBT::helper::readInt16(dataForIntTest, dataSize, currentPosition).isError == true); + ASSERT(NBT::helper::readInt16(dataForIntTest, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); std::cout << "Passed readInt16 NBT helper test" << std::endl; // int32 ########################################################### // read successfully currentPosition = 5; - ASSERT(NBT::helper::readInt32(data, dataSize, currentPosition).value == 589571366); - ASSERT(NBT::helper::readInt32(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt32(dataForIntTest, dataSize, currentPosition).value == 589571366); + ASSERT(NBT::helper::readInt32(dataForIntTest, dataSize, currentPosition).isError == false); // begin of data currentPosition = 0; - ASSERT(NBT::helper::readInt32(data, dataSize, currentPosition).value == 505356321); - ASSERT(NBT::helper::readInt32(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt32(dataForIntTest, dataSize, currentPosition).value == 505356321); + ASSERT(NBT::helper::readInt32(dataForIntTest, dataSize, currentPosition).isError == false); // end of data currentPosition = 6; - ASSERT(NBT::helper::readInt32(data, dataSize, currentPosition).value == 606414375); - ASSERT(NBT::helper::readInt32(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt32(dataForIntTest, dataSize, currentPosition).value == 606414375); + ASSERT(NBT::helper::readInt32(dataForIntTest, dataSize, currentPosition).isError == false); // partially out of bounds currentPosition = 7; - ASSERT(NBT::helper::readInt32(data, dataSize, currentPosition).isError == true); - ASSERT(NBT::helper::readInt32(data, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); + ASSERT(NBT::helper::readInt32(dataForIntTest, dataSize, currentPosition).isError == true); + ASSERT(NBT::helper::readInt32(dataForIntTest, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); // fully out of bounds currentPosition = 10; - ASSERT(NBT::helper::readInt32(data, dataSize, currentPosition).isError == true); - ASSERT(NBT::helper::readInt32(data, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); + ASSERT(NBT::helper::readInt32(dataForIntTest, dataSize, currentPosition).isError == true); + ASSERT(NBT::helper::readInt32(dataForIntTest, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); std::cout << "Passed readInt32 NBT helper test" << std::endl; // int64 ########################################################### // read successfully currentPosition = 1; - ASSERT(NBT::helper::readInt64(data, dataSize, currentPosition).value == 2242829044932683046); - ASSERT(NBT::helper::readInt64(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt64(dataForIntTest, dataSize, currentPosition).value == 2242829044932683046); + ASSERT(NBT::helper::readInt64(dataForIntTest, dataSize, currentPosition).isError == false); // begin of data currentPosition = 0; - ASSERT(NBT::helper::readInt64(data, dataSize, currentPosition).value == 2170488872094606373); - ASSERT(NBT::helper::readInt64(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt64(dataForIntTest, dataSize, currentPosition).value == 2170488872094606373); + ASSERT(NBT::helper::readInt64(dataForIntTest, dataSize, currentPosition).isError == false); // end of data currentPosition = 2; - ASSERT(NBT::helper::readInt64(data, dataSize, currentPosition).value == 2315169217770759719); - ASSERT(NBT::helper::readInt64(data, dataSize, currentPosition).isError == false); + ASSERT(NBT::helper::readInt64(dataForIntTest, dataSize, currentPosition).value == 2315169217770759719); + ASSERT(NBT::helper::readInt64(dataForIntTest, dataSize, currentPosition).isError == false); // partially out of bounds currentPosition = 3; - ASSERT(NBT::helper::readInt64(data, dataSize, currentPosition).isError == true); - ASSERT(NBT::helper::readInt64(data, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); + ASSERT(NBT::helper::readInt64(dataForIntTest, dataSize, currentPosition).isError == true); + ASSERT(NBT::helper::readInt64(dataForIntTest, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); // fully out of bounds currentPosition = 10; - ASSERT(NBT::helper::readInt64(data, dataSize, currentPosition).isError == true); - ASSERT(NBT::helper::readInt64(data, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); + ASSERT(NBT::helper::readInt64(dataForIntTest, dataSize, currentPosition).isError == true); + ASSERT(NBT::helper::readInt64(dataForIntTest, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); std::cout << "Passed int64 NBT helper test" << std::endl; + //################################################################## + + // used for integer "array" tests + uint8_t dataForIntArrayTest[] = { + 0, 0, 0, 20, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 0, 0, 0, 5, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 0, 0, 0, 10, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100, + 0, 0, 0, 0 + }; + dataSize = 116; + + // int8 "array" #################################################### + // read successfully + currentPosition = 0; + ASSERT(NBT::helper::readInt8Array(dataForIntArrayTest, dataSize, currentPosition).value == std::vector({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20})); + ASSERT(NBT::helper::readInt8Array(dataForIntArrayTest, dataSize, currentPosition).isError == false); + // read empty + currentPosition = 112; + ASSERT(NBT::helper::readInt8Array(dataForIntArrayTest, dataSize, currentPosition).value == std::vector()); + ASSERT(NBT::helper::readInt8Array(dataForIntArrayTest, dataSize, currentPosition).isError == false); + // read overrun + currentPosition = 20; + ASSERT(NBT::helper::readInt8Array(dataForIntArrayTest, dataSize, currentPosition).isError == true); + ASSERT(NBT::helper::readInt8Array(dataForIntArrayTest, dataSize, currentPosition).errorCode == ErrorCodes::OVERRUN_ERROR); + // read with size partially out of bounds + currentPosition = 114; + ASSERT(NBT::helper::readInt8Array(dataForIntArrayTest, dataSize, currentPosition).isError == true); + ASSERT(NBT::helper::readInt8Array(dataForIntArrayTest, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); + // read out of bounds + currentPosition = 200; + ASSERT(NBT::helper::readInt8Array(dataForIntArrayTest, dataSize, currentPosition).isError == true); + ASSERT(NBT::helper::readInt8Array(dataForIntArrayTest, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); + + std::cout << "Passed int8[] NBT helper test" << std::endl; + return 0; }