From 762ba7f089ddf491910bc31621e4bcc97c082d96 Mon Sep 17 00:00:00 2001 From: BodgeMaster <> Date: Mon, 4 Jul 2022 19:43:31 +0200 Subject: [PATCH] NBT: add write helpers for float types --- src/lib/nbt.cpp | 50 ++++++++++++++++++++++++++++++++++++++-- src/test/nbt_helpers.cpp | 36 ++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/src/lib/nbt.cpp b/src/lib/nbt.cpp index 603f768..45c5d82 100644 --- a/src/lib/nbt.cpp +++ b/src/lib/nbt.cpp @@ -263,13 +263,59 @@ namespace NBT { } //FIXME: we just assume that float is a single-precision IEEE754 - // floating point number + // floating point number, also endian specific implementation void writeFloat32(std::vector* destination, float data) { + float* value = new float; + uint8_t* valueAsBytes = reinterpret_cast(value); + *value = data; + #ifdef FOSSVG_BIG_ENDIAN + destination->push_back(*valueAsBytes); + destination->push_back(*(valueAsBytes+1)); + destination->push_back(*(valueAsBytes+2)); + destination->push_back(*(valueAsBytes+3)); + #else + #ifdef FOSSVG_LITTLE_ENDIAN + destination->push_back(*(valueAsBytes+3)); + destination->push_back(*(valueAsBytes+2)); + destination->push_back(*(valueAsBytes+1)); + destination->push_back(*valueAsBytes); + #else + #error "NBT::helper::writeInt16: An implementation for your endianness is unavailable." + #endif + #endif + delete value; } //FIXME: we just assume that double is a single-precision IEEE754 - // floating point number + // floating point number, also endian specific implementation void writeFloat64(std::vector* destination, double data) { + double* value = new double; + uint8_t* valueAsBytes = reinterpret_cast(value); + *value = data; + #ifdef FOSSVG_BIG_ENDIAN + destination->push_back(*valueAsBytes); + destination->push_back(*(valueAsBytes+1)); + destination->push_back(*(valueAsBytes+2)); + destination->push_back(*(valueAsBytes+3)); + destination->push_back(*(valueAsBytes+4)); + destination->push_back(*(valueAsBytes+5)); + destination->push_back(*(valueAsBytes+6)); + destination->push_back(*(valueAsBytes+7)); + #else + #ifdef FOSSVG_LITTLE_ENDIAN + destination->push_back(*(valueAsBytes+7)); + destination->push_back(*(valueAsBytes+6)); + destination->push_back(*(valueAsBytes+5)); + destination->push_back(*(valueAsBytes+4)); + destination->push_back(*(valueAsBytes+3)); + destination->push_back(*(valueAsBytes+2)); + destination->push_back(*(valueAsBytes+1)); + destination->push_back(*valueAsBytes); + #else + #error "NBT::helper::writeInt16: An implementation for your endianness is unavailable." + #endif + #endif + delete value; } void writeInt8Array(std::vector* destination, std::vector data) { diff --git a/src/test/nbt_helpers.cpp b/src/test/nbt_helpers.cpp index 9b35b27..4e6675d 100644 --- a/src/test/nbt_helpers.cpp +++ b/src/test/nbt_helpers.cpp @@ -164,7 +164,7 @@ int main(){ dereferencedWriteInt64TestResult[7] == (uint8_t) 0xEF ); - std::cout << "Passed writeInt32 NBT helper test" << std::endl; + std::cout << "Passed writeInt64 NBT helper test" << std::endl; //################################################################## @@ -270,7 +270,20 @@ int main(){ ASSERT(NBT::helper::readFloat32(dataForFloat32Test, dataSize, currentPosition).isError == true); ASSERT(NBT::helper::readFloat32(dataForFloat32Test, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); - std::cout << "Passed float32 NBT helper test" << std::endl; + std::cout << "Passed readFloat32 NBT helper test" << std::endl; + + std::vector* writeFloat32TestResult = new std::vector(); + NBT::helper::writeFloat32(writeFloat32TestResult, (float) -63351.46484375f); + std::vector dereferencedWriteFloat32TestResult = *writeFloat32TestResult; + delete writeFloat32TestResult; + ASSERT( + dereferencedWriteFloat32TestResult[0] == (uint8_t) 0xC7 && + dereferencedWriteFloat32TestResult[1] == (uint8_t) 0x77 && + dereferencedWriteFloat32TestResult[2] == (uint8_t) 0x77 && + dereferencedWriteFloat32TestResult[3] == (uint8_t) 0x77 + ); + + std::cout << "Passed writeFloat32 NBT helper test" << std::endl; // float64 ["double" in the current implementation :( ] ############ uint8_t dataForFloat64Test[] = {0xC0, 0x34, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00}; @@ -288,7 +301,24 @@ int main(){ ASSERT(NBT::helper::readFloat64(dataForFloat64Test, dataSize, currentPosition).isError == true); ASSERT(NBT::helper::readFloat64(dataForFloat64Test, dataSize, currentPosition).errorCode == ErrorCodes::RANGE_ERROR); - std::cout << "Passed float64 NBT helper test" << std::endl; + std::cout << "Passed readFloat64 NBT helper test" << std::endl; + + std::vector* writeFloat64TestResult = new std::vector(); + NBT::helper::writeFloat64(writeFloat64TestResult, (double) -20.015625476837158203125); + std::vector dereferencedWriteFloat64TestResult = *writeFloat64TestResult; + delete writeFloat64TestResult; + ASSERT( + dereferencedWriteFloat64TestResult[0] == (uint8_t) 0xC0 && + dereferencedWriteFloat64TestResult[1] == (uint8_t) 0x34 && + dereferencedWriteFloat64TestResult[2] == (uint8_t) 0x04 && + dereferencedWriteFloat64TestResult[3] == (uint8_t) 0x00 && + dereferencedWriteFloat64TestResult[4] == (uint8_t) 0x08 && + dereferencedWriteFloat64TestResult[5] == (uint8_t) 0x00 && + dereferencedWriteFloat64TestResult[6] == (uint8_t) 0x00 && + dereferencedWriteFloat64TestResult[7] == (uint8_t) 0x00 + ); + + std::cout << "Passed writeInt64 NBT helper test" << std::endl; return 0; }