Compare commits
3 Commits
704b440d5a
...
c59a1ac723
Author | SHA1 | Date |
---|---|---|
BodgeMaster | c59a1ac723 | |
BodgeMaster | aef91fe7cd | |
BodgeMaster | 4af9003761 |
|
@ -48,11 +48,6 @@ universally used.
|
|||
Use explicitly sized data types where possible.
|
||||
For example, use `int32_t` instead of `int`.
|
||||
|
||||
When coming up with names, refer to data types by category and size.
|
||||
For example, refer to double precision floating point numbers as `float64`
|
||||
instead of `double`.
|
||||
|
||||
|
||||
## Shell Script
|
||||
|
||||
Use the hash bang `#!/usr/bin/env bash`.
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -23,11 +23,11 @@ A simple tool written in Java that takes an input as UTF-8 and outputs it in Jav
|
|||
Usage example: `echo -ne "\x00" | java JavaStringGenerator > output_file`
|
||||
|
||||
|
||||
## servers.dat
|
||||
## NBT_data
|
||||
|
||||
My current servers.dat as pulled from my Minecraft installation. Used for testing the NBT library until we have something better.
|
||||
Data used to test the NBT library.
|
||||
|
||||
|
||||
## servers.dat_nbt_decoded.txt
|
||||
|
||||
The same file manually decoded. I did this to get a better understanding how NBT works, might come in handy in the future.
|
||||
`servers.dat`: My current servers.dat as pulled from my Minecraft installation
|
||||
`servers.dat_nbt_decoded.txt`: The same file manually decoded (I did this to get a better understanding how NBT works, might come in handy in the future.)
|
||||
`simple_nbt`: A simple NBT file containing all tags
|
||||
`nested_compounds_and_lists`: A combination of nested compound and list tags intended to be challenging to parse
|
||||
|
|
|
@ -71,10 +71,8 @@ namespace NBT {
|
|||
));
|
||||
}
|
||||
|
||||
//FIXME: we just assume that float is a single-precision IEEE754
|
||||
// floating point number, also we are using endian-dependent
|
||||
// implementations
|
||||
ErrorOr<float> readFloat32(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
|
||||
//FIXME: endian-dependent implementations
|
||||
ErrorOr<float> readFloat(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::OUT_OF_RANGE);
|
||||
|
@ -91,7 +89,7 @@ namespace NBT {
|
|||
*(valueAsBytes+2) = data[currentPosition+1];
|
||||
*(valueAsBytes+3) = data[currentPosition];
|
||||
#else
|
||||
#error "NBT::helper::readFloat32: An implementation for your endianness is unavailable."
|
||||
#error "NBT::helper::readFloat: An implementation for your endianness is unavailable."
|
||||
#endif
|
||||
#endif
|
||||
float dereferencedValue = *value;
|
||||
|
@ -99,10 +97,8 @@ namespace NBT {
|
|||
return ErrorOr<float>(dereferencedValue);
|
||||
}
|
||||
|
||||
//FIXME: we just assume that double is a double-precision IEEE754
|
||||
// floating point number, also we are using endian-dependent
|
||||
// implementations
|
||||
ErrorOr<double> readFloat64(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
|
||||
//FIXME: endian-dependent implementations
|
||||
ErrorOr<double> readDouble(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::OUT_OF_RANGE);
|
||||
|
@ -127,7 +123,7 @@ namespace NBT {
|
|||
*(valueAsBytes+6) = data[currentPosition+1];
|
||||
*(valueAsBytes+7) = data[currentPosition];
|
||||
#else
|
||||
#error "NBT::helper::readFloat64: An implementation for your endianness is unavailable."
|
||||
#error "NBT::helper::readDouble: An implementation for your endianness is unavailable."
|
||||
#endif
|
||||
#endif
|
||||
double dereferencedValue = *value;
|
||||
|
@ -270,9 +266,8 @@ namespace NBT {
|
|||
delete value;
|
||||
}
|
||||
|
||||
//FIXME: we just assume that float is a single-precision IEEE754
|
||||
// floating point number, also endian specific implementation
|
||||
void writeFloat32(std::vector<uint8_t>* destination, float data) {
|
||||
//FIXME: endian-specific implementations
|
||||
void writeFloat(std::vector<uint8_t>* destination, float data) {
|
||||
float* value = new float;
|
||||
uint8_t* valueAsBytes = reinterpret_cast<uint8_t*>(value);
|
||||
*value = data;
|
||||
|
@ -294,9 +289,8 @@ namespace NBT {
|
|||
delete value;
|
||||
}
|
||||
|
||||
//FIXME: we just assume that double is a single-precision IEEE754
|
||||
// floating point number, also endian specific implementation
|
||||
void writeFloat64(std::vector<uint8_t>* destination, double data) {
|
||||
//FIXME: endian-specific implementations
|
||||
void writeDouble(std::vector<uint8_t>* destination, double data) {
|
||||
double* value = new double;
|
||||
uint8_t* valueAsBytes = reinterpret_cast<uint8_t*>(value);
|
||||
*value = data;
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
// int16: Tag( 2, String:name, uint16:name_size, int16:content, 2) => 16 bit signed integer, size not stored
|
||||
// int32: Tag( 3, String:name, uint16:name_size, int32:content, 4) => 32 bit signed integer, size not stored
|
||||
// int64: Tag( 4, String:name, uint16:name_size, int64:content, 8) => 64 bit signed integer, size not stored
|
||||
// float32: Tag( 5, String:name, uint16:name_size, float32:content,4) => 32 bit IEEE754 floating point number, size not stored
|
||||
// float64: Tag( 6, String:name, uint16:name_size, float64:content,8) => 64 bit IEEE754 floating point number, size not stored
|
||||
// float: Tag( 5, String:name, uint16:name_size, float:content, 4) => 32 bit IEEE754 floating point number, size not stored
|
||||
// double: Tag( 6, String:name, uint16:name_size, double:content, 8) => 64 bit IEEE754 floating point number, size not stored
|
||||
// int8[]: Tag( 7, String:name, uint16:name_size, int8[]:content, int32:size) => content stored prefixed with size
|
||||
// String: Tag( 8, String:name, uint16:name_size, String:content, uint16:size) => Java style modified UTF-8 string, content stored prefixed with size
|
||||
// Tag[] (list): Tag<Tag:type>( 9, String:name, uint16:name_size, Tag[]:content, int32:size) => list of tags of the same type with tag type and name information omitted prefixed by (in order) content type and size
|
||||
|
@ -46,12 +46,8 @@ namespace NBT {
|
|||
ErrorOr<int16_t> readInt16(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
ErrorOr<int32_t> readInt32(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
ErrorOr<int64_t> readInt64(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
//FIXME: we just assume that float is a single-precision IEEE754
|
||||
// floating point number
|
||||
ErrorOr<float> readFloat32(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
//FIXME: we just assume that double is a double-precision IEEE754
|
||||
// floating point number
|
||||
ErrorOr<double> readFloat64(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
ErrorOr<float> readFloat(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
ErrorOr<double> readDouble(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
ErrorOr<std::vector<int8_t>> readInt8Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
ErrorOr<tiny_utf8::string> readString(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
ErrorOr<std::vector<int32_t>> readInt32Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
|
@ -61,12 +57,8 @@ namespace NBT {
|
|||
void writeInt16(std::vector<uint8_t>* destination, int16_t data);
|
||||
void writeInt32(std::vector<uint8_t>* destination, int32_t data);
|
||||
void writeInt64(std::vector<uint8_t>* destination, int64_t data);
|
||||
//FIXME: we just assume that float is a single-precision IEEE754
|
||||
// floating point number
|
||||
void writeFloat32(std::vector<uint8_t>* destination, float data);
|
||||
//FIXME: we just assume that double is a single-precision IEEE754
|
||||
// floating point number
|
||||
void writeFloat64(std::vector<uint8_t>* destination, double data);
|
||||
void writeFloat(std::vector<uint8_t>* destination, float data);
|
||||
void writeDouble(std::vector<uint8_t>* destination, double data);
|
||||
void writeInt8Array(std::vector<uint8_t>* destination, std::vector<int8_t> data);
|
||||
void writeInt8Array(std::vector<uint8_t>* destination, int8_t data[], uint32_t dataSize);
|
||||
void writeString(std::vector<uint8_t>* destination, tiny_utf8::string data);
|
||||
|
|
|
@ -376,73 +376,73 @@ int main(){
|
|||
);
|
||||
delete int64ArrayTestOutput;
|
||||
|
||||
std::cout << "Passed writeInt32Array NBT helper test" << std::endl;
|
||||
std::cout << "Passed writeInt64Array NBT helper test" << std::endl;
|
||||
|
||||
// float32 ["float" in the current implementation :( ] #############
|
||||
uint8_t dataForFloat32Test[] = {0xC7, 0x77, 0x77, 0x77};
|
||||
// float ###########################################################
|
||||
uint8_t dataForFloatTest[] = {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);
|
||||
ASSERT(NBT::helper::readFloat(dataForFloatTest, dataSize, currentPosition).value == -63351.46484375f);
|
||||
ASSERT(NBT::helper::readFloat(dataForFloatTest, 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);
|
||||
ASSERT(NBT::helper::readFloat(dataForFloatTest, dataSize, currentPosition).isError == true);
|
||||
ASSERT(NBT::helper::readFloat(dataForFloatTest, dataSize, currentPosition).errorCode == ErrorCodes::OVERRUN);
|
||||
// read out of bounds
|
||||
currentPosition = 4;
|
||||
ASSERT(NBT::helper::readFloat32(dataForFloat32Test, dataSize, currentPosition).isError == true);
|
||||
ASSERT(NBT::helper::readFloat32(dataForFloat32Test, dataSize, currentPosition).errorCode == ErrorCodes::OUT_OF_RANGE);
|
||||
ASSERT(NBT::helper::readFloat(dataForFloatTest, dataSize, currentPosition).isError == true);
|
||||
ASSERT(NBT::helper::readFloat(dataForFloatTest, dataSize, currentPosition).errorCode == ErrorCodes::OUT_OF_RANGE);
|
||||
|
||||
std::cout << "Passed readFloat32 NBT helper test" << std::endl;
|
||||
std::cout << "Passed readFloat NBT helper test" << std::endl;
|
||||
|
||||
std::vector<uint8_t>* writeFloat32TestResult = new std::vector<uint8_t>();
|
||||
NBT::helper::writeFloat32(writeFloat32TestResult, (float) -63351.46484375f);
|
||||
std::vector<uint8_t> dereferencedWriteFloat32TestResult = *writeFloat32TestResult;
|
||||
delete writeFloat32TestResult;
|
||||
std::vector<uint8_t>* writeFloatTestResult = new std::vector<uint8_t>();
|
||||
NBT::helper::writeFloat(writeFloatTestResult, (float) -63351.46484375f);
|
||||
std::vector<uint8_t> dereferencedWriteFloatTestResult = *writeFloatTestResult;
|
||||
delete writeFloatTestResult;
|
||||
ASSERT(
|
||||
dereferencedWriteFloat32TestResult[0] == (uint8_t) 0xC7 &&
|
||||
dereferencedWriteFloat32TestResult[1] == (uint8_t) 0x77 &&
|
||||
dereferencedWriteFloat32TestResult[2] == (uint8_t) 0x77 &&
|
||||
dereferencedWriteFloat32TestResult[3] == (uint8_t) 0x77
|
||||
dereferencedWriteFloatTestResult[0] == (uint8_t) 0xC7 &&
|
||||
dereferencedWriteFloatTestResult[1] == (uint8_t) 0x77 &&
|
||||
dereferencedWriteFloatTestResult[2] == (uint8_t) 0x77 &&
|
||||
dereferencedWriteFloatTestResult[3] == (uint8_t) 0x77
|
||||
);
|
||||
|
||||
std::cout << "Passed writeFloat32 NBT helper test" << std::endl;
|
||||
std::cout << "Passed writeFloat NBT helper test" << std::endl;
|
||||
|
||||
// float64 ["double" in the current implementation :( ] ############
|
||||
uint8_t dataForFloat64Test[] = {0xC0, 0x34, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00};
|
||||
// double ##########################################################
|
||||
uint8_t dataForDoubleTest[] = {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);
|
||||
ASSERT(NBT::helper::readDouble(dataForDoubleTest, dataSize, currentPosition).value == -20.015625476837158203125);
|
||||
ASSERT(NBT::helper::readDouble(dataForDoubleTest, 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);
|
||||
ASSERT(NBT::helper::readDouble(dataForDoubleTest, dataSize, currentPosition).isError == true);
|
||||
ASSERT(NBT::helper::readDouble(dataForDoubleTest, dataSize, currentPosition).errorCode == ErrorCodes::OVERRUN);
|
||||
// read out of bounds
|
||||
currentPosition = 8;
|
||||
ASSERT(NBT::helper::readFloat64(dataForFloat64Test, dataSize, currentPosition).isError == true);
|
||||
ASSERT(NBT::helper::readFloat64(dataForFloat64Test, dataSize, currentPosition).errorCode == ErrorCodes::OUT_OF_RANGE);
|
||||
ASSERT(NBT::helper::readDouble(dataForDoubleTest, dataSize, currentPosition).isError == true);
|
||||
ASSERT(NBT::helper::readDouble(dataForDoubleTest, dataSize, currentPosition).errorCode == ErrorCodes::OUT_OF_RANGE);
|
||||
|
||||
std::cout << "Passed readFloat64 NBT helper test" << std::endl;
|
||||
std::cout << "Passed readDouble NBT helper test" << std::endl;
|
||||
|
||||
std::vector<uint8_t>* writeFloat64TestResult = new std::vector<uint8_t>();
|
||||
NBT::helper::writeFloat64(writeFloat64TestResult, (double) -20.015625476837158203125);
|
||||
std::vector<uint8_t> dereferencedWriteFloat64TestResult = *writeFloat64TestResult;
|
||||
delete writeFloat64TestResult;
|
||||
std::vector<uint8_t>* writeDoubleTestResult = new std::vector<uint8_t>();
|
||||
NBT::helper::writeDouble(writeDoubleTestResult, (double) -20.015625476837158203125);
|
||||
std::vector<uint8_t> dereferencedWriteDoubleTestResult = *writeDoubleTestResult;
|
||||
delete writeDoubleTestResult;
|
||||
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
|
||||
dereferencedWriteDoubleTestResult[0] == (uint8_t) 0xC0 &&
|
||||
dereferencedWriteDoubleTestResult[1] == (uint8_t) 0x34 &&
|
||||
dereferencedWriteDoubleTestResult[2] == (uint8_t) 0x04 &&
|
||||
dereferencedWriteDoubleTestResult[3] == (uint8_t) 0x00 &&
|
||||
dereferencedWriteDoubleTestResult[4] == (uint8_t) 0x08 &&
|
||||
dereferencedWriteDoubleTestResult[5] == (uint8_t) 0x00 &&
|
||||
dereferencedWriteDoubleTestResult[6] == (uint8_t) 0x00 &&
|
||||
dereferencedWriteDoubleTestResult[7] == (uint8_t) 0x00
|
||||
);
|
||||
|
||||
std::cout << "Passed writeInt64 NBT helper test" << std::endl;
|
||||
std::cout << "Passed writeDouble NBT helper test" << std::endl;
|
||||
|
||||
//readString test
|
||||
char* nextChar = new char;
|
||||
|
@ -532,7 +532,7 @@ int main(){
|
|||
ASSERT(byte.nameSize == 2);
|
||||
ASSERT(byte.content = 0x32);
|
||||
ASSERT(byte.name == tiny_utf8::string("hi"));
|
||||
|
||||
|
||||
std::cout << "Passed Byte Tag constructor test." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue