Compare commits

..

No commits in common. "4f9577eb36eebe1951a8d14239a6416c36e8d7ed" and "1dcf37c0fc6fc75e04a691796e7cbcc9771227f7" have entirely different histories.

3 changed files with 37 additions and 100 deletions

View File

@ -21,8 +21,6 @@ int main() {
*testInteger = 0x04030201;
auto data = reinterpret_cast<std::uint8_t*>(testInteger);
std::cout << "#pragma once" << std::endl;
if (
*data == 0x01 &&
*(data+1)==0x02 &&

View File

@ -20,16 +20,33 @@
#include "nbt.h++"
#include "error.h++"
#include "../../.endianness"
#ifdef FOSSVG_ENDIAN_BIG_WORD
#error "Honeywell-316-style endianness is not supported. If you feel like it should, feel free to participate in the project to maintain it."
#endif
#ifdef FOSSVG_ENDIAN_LITTLE_WORD
#error "PDP-11-style endianness is not supported. If you feel like it should, feel free to participate in the project to maintain it."
#endif
#ifdef FOSSVG_ENDIAN_UNKNOWN
#error "The endianness of your system could not be determined. Please set it manually. FOSS-VG is currently implemented using some endian-specific functions."
#endif
// This is just an example for how to find out if the system is big endian
// or little endian.
//int endianness_example() {
// if constexpr (std::endian::native == std::endian::big)
// {
// // Big-endian system
// return 0;
// }
// else if constexpr (std::endian::native == std::endian::little)
// {
// // Little-endian system
// return 1;
// }
// else
// {
// // Something else
// return 2;
// // How did we even end up here?
// }
//}
// There is supposedly also a function htobe64 and be64toh to deal with
// converting 64 bit integers between host order and big endian.
// Though converting between host order and BE may not be necessary if the
// raw NBT data is to be used as instructions for rebuilding the data in memory.
// Doing the opposite may just be very painful.
namespace NBT {
namespace helper {
@ -68,63 +85,21 @@ namespace NBT {
}
//FIXME: we just assume that float is a single-precision IEEE754
// floating point number, also we are using endian-dependent
// implementations
// floating point number
ErrorOr<float> readFloat32(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
float* value = new float;
uint8_t* valueAsBytes = reinterpret_cast<uint8_t*>(value);
if (dataSize<=currentPosition) return ErrorOr<float>(true, ErrorCodes::RANGE_ERROR);
if (dataSize<currentPosition+4) return ErrorOr<float>(true, ErrorCodes::OVERRUN_ERROR);
#ifdef FOSSVG_BIG_ENDIAN
*valueAsBytes = data[currentPosition];
*(valueAsBytes+1) = data[currentPosition+1];
*(valueAsBytes+2) = data[currentPosition+2];
*(valueAsBytes+3) = data[currentPosition+3];
#else
#ifdef FOSSVG_LITTLE_ENDIAN
*valueAsBytes = data[currentPosition+3];
*(valueAsBytes+1) = data[currentPosition+2];
*(valueAsBytes+2) = data[currentPosition+1];
*(valueAsBytes+3) = data[currentPosition];
#endif
#endif
float dereferencedValue = *value;
delete value;
return ErrorOr<float>(dereferencedValue);
//TODO: implement assuming standard single-precision IEEE754 float
// Alternatively, maybe calculate a floating point number by using
// the stored value as math instructions?
return ErrorOr<float>(0.0f);
}
//FIXME: we just assume that double is a double-precision IEEE754
// floating point number, also we are using endian-dependent
// implementations
// floating point number
ErrorOr<double> readFloat64(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
double* value = new double;
uint8_t* valueAsBytes = reinterpret_cast<uint8_t*>(value);
if (dataSize<=currentPosition) return ErrorOr<double>(true, ErrorCodes::RANGE_ERROR);
if (dataSize<currentPosition+8) return ErrorOr<double>(true, ErrorCodes::OVERRUN_ERROR);
#ifdef FOSSVG_BIG_ENDIAN
*valueAsBytes = data[currentPosition];
*(valueAsBytes+1) = data[currentPosition+1];
*(valueAsBytes+2) = data[currentPosition+2];
*(valueAsBytes+3) = data[currentPosition+3];
*(valueAsBytes+4) = data[currentPosition+4];
*(valueAsBytes+5) = data[currentPosition+5];
*(valueAsBytes+6) = data[currentPosition+6];
*(valueAsBytes+7) = data[currentPosition+7];
#else
#ifdef FOSSVG_LITTLE_ENDIAN
*valueAsBytes = data[currentPosition+7];
*(valueAsBytes+1) = data[currentPosition+6];
*(valueAsBytes+2) = data[currentPosition+5];
*(valueAsBytes+3) = data[currentPosition+4];
*(valueAsBytes+4) = data[currentPosition+3];
*(valueAsBytes+5) = data[currentPosition+2];
*(valueAsBytes+6) = data[currentPosition+1];
*(valueAsBytes+7) = data[currentPosition];
#endif
#endif
double dereferencedValue = *value;
delete value;
return ErrorOr<double>(dereferencedValue);
//TODO: implement assuming standard double-precision IEEE754 float
// Alternatively, maybe calculate a floating point number by using
// the stored value as math instructions?
return ErrorOr<double>(0.0);
}
ErrorOr<std::vector<int8_t>> readInt8Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {

View File

@ -208,41 +208,5 @@ int main(){
std::cout << "Passed int64[] NBT helper test" << std::endl;
// float32 ["float" in the current implementation :( ] #############
uint8_t dataForFloat32Test[] = {0xC7, 0x77, 0x77, 0x77};
dataSize = 4;
currentPosition = 0;
// read successfully
ASSERT(NBT::helper::readFloat32(dataForFloat32Test, dataSize, currentPosition).value == -63351.46484375f);
ASSERT(NBT::helper::readFloat32(dataForFloat32Test, dataSize, currentPosition).isError == false);
// read overrun
currentPosition = 1;
ASSERT(NBT::helper::readFloat32(dataForFloat32Test, dataSize, currentPosition).isError == true);
ASSERT(NBT::helper::readFloat32(dataForFloat32Test, dataSize, currentPosition).errorCode == ErrorCodes::OVERRUN_ERROR);
// read out of bounds
currentPosition = 4;
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;
// float64 ["double" in the current implementation :( ] ############
uint8_t dataForFloat64Test[] = {0xC0, 0x34, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00};
dataSize = 8;
currentPosition = 0;
// read successfully
ASSERT(NBT::helper::readFloat64(dataForFloat64Test, dataSize, currentPosition).value == -20.015625476837158203125);
ASSERT(NBT::helper::readFloat64(dataForFloat64Test, dataSize, currentPosition).isError == false);
// read overrun
currentPosition = 1;
ASSERT(NBT::helper::readFloat64(dataForFloat64Test, dataSize, currentPosition).isError == true);
ASSERT(NBT::helper::readFloat64(dataForFloat64Test, dataSize, currentPosition).errorCode == ErrorCodes::OVERRUN_ERROR);
// read out of bounds
currentPosition = 8;
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;
return 0;
}