lib/nbt: implement readString NBT helper function
parent
9562ae7be9
commit
b5312aeb58
|
@ -72,7 +72,7 @@ echo "Building tools..."
|
||||||
mkdir -pv bin/tools
|
mkdir -pv bin/tools
|
||||||
# add compile commands to this array
|
# add compile commands to this array
|
||||||
COMPILE_COMMANDS=(
|
COMPILE_COMMANDS=(
|
||||||
"$CXX_WITH_FLAGS src/tools/dumpnbt.cpp -Lbin/lib -l:nbt.so -o bin/tools/dumpnbt"
|
"$CXX_WITH_FLAGS src/tools/dumpnbt.cpp -I dependencies/tiny-utf8-4.4.3/include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/tools/dumpnbt"
|
||||||
"$CXX_WITH_FLAGS src/tools/hexnet.cpp -Lbin/lib -l:cli.so -l:libsockpp.so -Idependencies/sockpp-0.7.1/include -o bin/tools/hexnet"
|
"$CXX_WITH_FLAGS src/tools/hexnet.cpp -Lbin/lib -l:cli.so -l:libsockpp.so -Idependencies/sockpp-0.7.1/include -o bin/tools/hexnet"
|
||||||
)
|
)
|
||||||
for command in ${!COMPILE_COMMANDS[@]}; do
|
for command in ${!COMPILE_COMMANDS[@]}; do
|
||||||
|
|
|
@ -37,7 +37,7 @@ echo "Building tests..."
|
||||||
|
|
||||||
# add compile commands to this array
|
# add compile commands to this array
|
||||||
COMPILE_COMMANDS=(
|
COMPILE_COMMANDS=(
|
||||||
"$CXX_WITH_FLAGS src/test/nbt_helpers.cpp -Lbin/lib -l:nbt.so -o bin/test/nbt_helpers"
|
"$CXX_WITH_FLAGS src/test/nbt_helpers.cpp -Idependencies/tiny-utf8-4.4.3/include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_helpers"
|
||||||
"$CXX_WITH_FLAGS src/test/cli_argument_parser.cpp -Lbin/lib -l:cli.so -o bin/test/cli_argument_parser"
|
"$CXX_WITH_FLAGS src/test/cli_argument_parser.cpp -Lbin/lib -l:cli.so -o bin/test/cli_argument_parser"
|
||||||
"$CXX_WITH_FLAGS src/test/javacompat.cpp -Idependencies/tiny-utf8-4.4.3/include -Lbin/lib -l:javacompat.so -o bin/test/javacompat"
|
"$CXX_WITH_FLAGS src/test/javacompat.cpp -Idependencies/tiny-utf8-4.4.3/include -Lbin/lib -l:javacompat.so -o bin/test/javacompat"
|
||||||
)
|
)
|
||||||
|
|
|
@ -81,4 +81,7 @@ namespace ErrorCodes {
|
||||||
const uint8_t UNIMPLEMENTED = 254;
|
const uint8_t UNIMPLEMENTED = 254;
|
||||||
|
|
||||||
const uint8_t UNKNOWN = 255;
|
const uint8_t UNKNOWN = 255;
|
||||||
|
|
||||||
|
//mismatched size in java strings
|
||||||
|
const uint8_t MISMATCHEDSIZE = 6;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,13 @@
|
||||||
namespace JavaCompat {
|
namespace JavaCompat {
|
||||||
//FIXME: contrary to what I said, we need to explicitly pass the data
|
//FIXME: contrary to what I said, we need to explicitly pass the data
|
||||||
// size because files could have been tampered with or corrupted
|
// size because files could have been tampered with or corrupted
|
||||||
tiny_utf8::string importJavaString(uint8_t data[]) {
|
ErrorOr<tiny_utf8::string> importJavaString(uint8_t data[], uint16_t size) {
|
||||||
std::string stdString;
|
std::string stdString;
|
||||||
uint16_t size = static_cast<uint16_t>(data[0])<<8 | static_cast<uint16_t>(data[1]);
|
uint16_t encodedSize = static_cast<uint16_t>(data[0])<<8 | static_cast<uint16_t>(data[1]);
|
||||||
|
|
||||||
|
if(encodedSize != size){
|
||||||
|
return ErrorOr<tiny_utf8::string>(true, ErrorCodes::MISMATCHEDSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
for(uint8_t i=2; i<size+2; i++){
|
for(uint8_t i=2; i<size+2; i++){
|
||||||
if(i != 0){
|
if(i != 0){
|
||||||
|
@ -45,7 +49,7 @@ namespace JavaCompat {
|
||||||
}
|
}
|
||||||
stdString.push_back((char) data[i]);
|
stdString.push_back((char) data[i]);
|
||||||
}
|
}
|
||||||
return tiny_utf8::string(stdString);
|
return ErrorOr<tiny_utf8::string>(tiny_utf8::string(stdString));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<std::vector<uint8_t>> exportJavaString(tiny_utf8::string data) {
|
ErrorOr<std::vector<uint8_t>> exportJavaString(tiny_utf8::string data) {
|
||||||
|
@ -54,6 +58,10 @@ namespace JavaCompat {
|
||||||
std::vector<uint8_t> output = std::vector<uint8_t>();
|
std::vector<uint8_t> output = std::vector<uint8_t>();
|
||||||
std::string stdString = data.cpp_str();
|
std::string stdString = data.cpp_str();
|
||||||
|
|
||||||
|
if(stdString.size() > 0xFFFF){
|
||||||
|
return ErrorOr<std::vector<uint8_t>>(true, ErrorCodes::OVERRUN);
|
||||||
|
}
|
||||||
|
|
||||||
*size = (uint16_t) stdString.size();
|
*size = (uint16_t) stdString.size();
|
||||||
|
|
||||||
//placeholder size bytes
|
//placeholder size bytes
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace JavaCompat {
|
namespace JavaCompat {
|
||||||
//FIXME: contrary to what I said, we need to explicitly pass the data
|
ErrorOr<tiny_utf8::string> importJavaString(uint8_t data[], uint16_t size);
|
||||||
// size because files could have been tampered with or corrupted
|
|
||||||
tiny_utf8::string importJavaString(uint8_t data[]);
|
|
||||||
ErrorOr<std::vector<uint8_t>> exportJavaString(tiny_utf8::string data);
|
ErrorOr<std::vector<uint8_t>> exportJavaString(tiny_utf8::string data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,12 @@
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <tinyutf8/tinyutf8.h>
|
||||||
|
|
||||||
#include "nbt.h++"
|
#include "nbt.h++"
|
||||||
#include "error.h++"
|
#include "error.h++"
|
||||||
|
#include "javacompat.h++"
|
||||||
|
|
||||||
|
|
||||||
#include "../../.endianness"
|
#include "../../.endianness"
|
||||||
#ifdef FOSSVG_ENDIAN_BIG_WORD
|
#ifdef FOSSVG_ENDIAN_BIG_WORD
|
||||||
|
@ -148,10 +151,17 @@ namespace NBT {
|
||||||
// Maybe use a struct that holds decoded (de-Java-fied) string
|
// Maybe use a struct that holds decoded (de-Java-fied) string
|
||||||
// data, decoded size, and original size? Original size is needed
|
// data, decoded size, and original size? Original size is needed
|
||||||
// so the parser knows where to continue.
|
// so the parser knows where to continue.
|
||||||
//ErrorOr<> readString(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
|
ErrorOr<tiny_utf8::string> readString(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
|
||||||
//TODO: implement
|
if(dataSize > 0xFFFF){
|
||||||
// return ErrorOr<>("");
|
return ErrorOr<tiny_utf8::string>(true, ErrorCodes::OVERRUN);
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
ErrorOr<tiny_utf8::string> output = JavaCompat::importJavaString(data+currentPosition, (uint16_t) dataSize);
|
||||||
|
if(output.isError){
|
||||||
|
return ErrorOr<tiny_utf8::string>(true, output.errorCode);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<std::vector<int32_t>> readInt32Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
|
ErrorOr<std::vector<int32_t>> readInt32Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
|
||||||
// get size prefix
|
// get size prefix
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "error.h++"
|
#include "error.h++"
|
||||||
|
#include <tinyutf8/tinyutf8.h>
|
||||||
|
|
||||||
namespace NBT {
|
namespace NBT {
|
||||||
namespace helper {
|
namespace helper {
|
||||||
|
@ -52,7 +53,7 @@ namespace NBT {
|
||||||
// floating point number
|
// floating point number
|
||||||
ErrorOr<double> readFloat64(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
ErrorOr<double> readFloat64(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<std::vector<int8_t>> readInt8Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||||
//ErrorOr<> readString(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);
|
ErrorOr<std::vector<int32_t>> readInt32Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||||
ErrorOr<std::vector<int64_t>> readInt64Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
ErrorOr<std::vector<int64_t>> readInt64Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ int main(){
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
tiny_utf8::string importedString = JavaCompat::importJavaString(reinterpret_cast<uint8_t*>(javaStdString.data()));
|
tiny_utf8::string importedString = JavaCompat::importJavaString(reinterpret_cast<uint8_t*>(javaStdString.data()), 0x75).value;
|
||||||
|
|
||||||
std::streampos normalSize;
|
std::streampos normalSize;
|
||||||
std::string normalStdString;
|
std::string normalStdString;
|
||||||
|
|
|
@ -16,11 +16,13 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include "assert.h++"
|
#include "assert.h++"
|
||||||
|
|
||||||
#include "../lib/nbt.h++"
|
#include "../lib/nbt.h++"
|
||||||
#include "../lib/error.h++"
|
#include "../lib/error.h++"
|
||||||
|
#include "../lib/javacompat.h++"
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
std::cout << "################################################################################" << std::endl;
|
std::cout << "################################################################################" << std::endl;
|
||||||
|
@ -442,5 +444,56 @@ int main(){
|
||||||
|
|
||||||
std::cout << "Passed writeInt64 NBT helper test" << std::endl;
|
std::cout << "Passed writeInt64 NBT helper test" << std::endl;
|
||||||
|
|
||||||
|
//readString test
|
||||||
|
char* nextChar = new char;
|
||||||
|
|
||||||
|
//reading data from the java modified utf8 file
|
||||||
|
std::streampos javaSize;
|
||||||
|
std::string javaStdString;
|
||||||
|
const char* javaFilePath = "./resources/unicode_data/java-style_unicode";
|
||||||
|
std::ifstream javaFile(javaFilePath, std::ios::in | std::ios::binary | std::ios::ate);
|
||||||
|
if(javaFile.is_open()){
|
||||||
|
javaSize = javaFile.tellg();
|
||||||
|
javaFile.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
|
for (int i=0; i<javaSize; i++) {
|
||||||
|
javaFile.read(nextChar, 1);
|
||||||
|
javaStdString.push_back(*nextChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
javaFile.close();
|
||||||
|
} else {
|
||||||
|
std::cerr << "Failed to open file: " << javaFilePath << std::endl;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//reading data from the normal utf8 file
|
||||||
|
std::streampos normalSize;
|
||||||
|
std::string normalStdString;
|
||||||
|
const char* normalFilePath = "./resources/unicode_data/normal_utf-8";
|
||||||
|
std::ifstream normalFile(normalFilePath, std::ios::in | std::ios::binary | std::ios::ate);
|
||||||
|
if(normalFile.is_open()){
|
||||||
|
normalSize = normalFile.tellg();
|
||||||
|
normalFile.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
|
for (int i=0; i<normalSize; i++) {
|
||||||
|
normalFile.read(nextChar, 1);
|
||||||
|
normalStdString.push_back(*nextChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
normalFile.close();
|
||||||
|
} else {
|
||||||
|
std::cerr << "Failed to open file: " << normalFilePath << std::endl;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
tiny_utf8::string normalString = tiny_utf8::string(normalStdString);
|
||||||
|
|
||||||
|
ASSERT(normalString == NBT::helper::readString(reinterpret_cast<uint8_t*>(javaStdString.data()), 0x75, 0).value)
|
||||||
|
ASSERT(NBT::helper::readString(reinterpret_cast<uint8_t*>(javaStdString.data()), 0xFFFFF, 0).errorCode == ErrorCodes::OVERRUN);
|
||||||
|
ASSERT(NBT::helper::readString(reinterpret_cast<uint8_t*>(javaStdString.data()), 0xF, 0).errorCode == ErrorCodes::MISMATCHEDSIZE);
|
||||||
|
std::cout << "Passed readString NBT helper test." << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue