2022-06-27 11:46:13 +02:00
// Copyright 2022, FOSS-VG Developers and Contributers
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// version 3 along with this program.
// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
2022-06-24 12:15:34 +02:00
# include <bit>
2022-06-27 04:50:32 +02:00
# include <cstdint>
# include <vector>
2022-07-20 08:38:04 +02:00
# include <tinyutf8/tinyutf8.h>
2022-07-28 13:45:04 +02:00
# include <iostream>
2022-06-24 12:15:34 +02:00
2022-08-02 03:35:08 +02:00
# include "nbt.hpp"
# include "error.hpp"
# include "javacompat.hpp"
2022-07-20 08:38:04 +02:00
2022-06-27 04:50:32 +02:00
2022-07-01 21:15:18 +02:00
# 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
2022-06-24 12:15:34 +02:00
2022-06-27 04:50:32 +02:00
namespace NBT {
2022-06-28 15:19:47 +02:00
namespace helper {
2022-06-28 16:51:52 +02:00
ErrorOr < int8_t > readInt8 ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) {
2022-07-13 21:00:42 +02:00
if ( dataSize < currentPosition + 1 ) return ErrorOr < int8_t > ( true , ErrorCodes : : OUT_OF_RANGE ) ;
2022-06-28 16:58:31 +02:00
return ErrorOr < int8_t > ( ( int8_t ) data [ currentPosition ] ) ;
2022-06-27 04:50:32 +02:00
}
2022-06-28 16:51:52 +02:00
ErrorOr < int16_t > readInt16 ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) {
2022-07-13 21:00:42 +02:00
if ( dataSize < currentPosition + 2 ) return ErrorOr < int16_t > ( true , ErrorCodes : : OUT_OF_RANGE ) ;
2022-06-28 22:04:04 +02:00
return ErrorOr < int16_t > ( ( int16_t ) ( ( static_cast < int16_t > ( data [ currentPosition ] ) < < 8 ) | static_cast < int16_t > ( data [ currentPosition + 1 ] ) ) ) ;
2022-06-27 04:50:32 +02:00
}
2022-06-28 16:51:52 +02:00
ErrorOr < int32_t > readInt32 ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) {
2022-07-13 21:00:42 +02:00
if ( dataSize < currentPosition + 4 ) return ErrorOr < int32_t > ( true , ErrorCodes : : OUT_OF_RANGE ) ;
2022-06-29 00:05:02 +02:00
return ErrorOr < int32_t > ( ( int32_t ) (
( static_cast < int32_t > ( data [ currentPosition ] ) < < 24 ) |
( static_cast < int32_t > ( data [ currentPosition + 1 ] ) < < 16 ) |
( static_cast < int32_t > ( data [ currentPosition + 2 ] ) < < 8 ) |
static_cast < int32_t > ( data [ currentPosition + 3 ] )
) ) ;
2022-06-27 04:50:32 +02:00
}
2022-06-28 16:51:52 +02:00
ErrorOr < int64_t > readInt64 ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) {
2022-07-13 21:00:42 +02:00
if ( dataSize < currentPosition + 8 ) return ErrorOr < int64_t > ( true , ErrorCodes : : OUT_OF_RANGE ) ;
2022-06-29 00:05:02 +02:00
return ErrorOr < int64_t > ( ( int64_t ) (
( static_cast < int64_t > ( data [ currentPosition ] ) < < 56 ) |
( static_cast < int64_t > ( data [ currentPosition + 1 ] ) < < 48 ) |
( static_cast < int64_t > ( data [ currentPosition + 2 ] ) < < 40 ) |
( static_cast < int64_t > ( data [ currentPosition + 3 ] ) < < 32 ) |
( static_cast < int64_t > ( data [ currentPosition + 4 ] ) < < 24 ) |
( static_cast < int64_t > ( data [ currentPosition + 5 ] ) < < 16 ) |
( static_cast < int64_t > ( data [ currentPosition + 6 ] ) < < 8 ) |
static_cast < int64_t > ( data [ currentPosition + 7 ] )
) ) ;
2022-06-27 04:50:32 +02:00
}
2022-08-04 07:42:40 +02:00
//FIXME: endian-dependent implementations
ErrorOr < float > readFloat ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) {
2022-07-01 21:15:18 +02:00
float * value = new float ;
uint8_t * valueAsBytes = reinterpret_cast < uint8_t * > ( value ) ;
2022-07-13 21:00:42 +02:00
if ( dataSize < = currentPosition ) return ErrorOr < float > ( true , ErrorCodes : : OUT_OF_RANGE ) ;
if ( dataSize < currentPosition + 4 ) return ErrorOr < float > ( true , ErrorCodes : : OVERRUN ) ;
2022-07-01 21:15:18 +02:00
# 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 ] ;
2022-07-02 16:41:54 +02:00
# else
2022-08-04 07:42:40 +02:00
# error "NBT::helper::readFloat: An implementation for your endianness is unavailable."
2022-07-01 21:15:18 +02:00
# endif
# endif
float dereferencedValue = * value ;
delete value ;
return ErrorOr < float > ( dereferencedValue ) ;
2022-06-27 04:50:32 +02:00
}
2022-08-04 07:42:40 +02:00
//FIXME: endian-dependent implementations
ErrorOr < double > readDouble ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) {
2022-07-01 21:15:18 +02:00
double * value = new double ;
uint8_t * valueAsBytes = reinterpret_cast < uint8_t * > ( value ) ;
2022-07-13 21:00:42 +02:00
if ( dataSize < = currentPosition ) return ErrorOr < double > ( true , ErrorCodes : : OUT_OF_RANGE ) ;
if ( dataSize < currentPosition + 8 ) return ErrorOr < double > ( true , ErrorCodes : : OVERRUN ) ;
2022-07-01 21:15:18 +02:00
# 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 ] ;
2022-07-02 16:41:54 +02:00
# else
2022-08-04 07:42:40 +02:00
# error "NBT::helper::readDouble: An implementation for your endianness is unavailable."
2022-07-01 21:15:18 +02:00
# endif
# endif
double dereferencedValue = * value ;
delete value ;
return ErrorOr < double > ( dereferencedValue ) ;
2022-06-27 04:50:32 +02:00
}
2022-06-28 16:51:52 +02:00
ErrorOr < std : : vector < int8_t > > readInt8Array ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) {
2022-06-29 12:22:54 +02:00
// get size prefix
ErrorOr < int32_t > size = readInt32 ( data , dataSize , currentPosition ) ;
if ( size . isError ) return ErrorOr < std : : vector < int8_t > > ( true , size . errorCode ) ;
// get content
2022-07-13 21:00:42 +02:00
if ( currentPosition + 4 + size . value > dataSize ) return ErrorOr < std : : vector < int8_t > > ( true , ErrorCodes : : OVERRUN ) ;
2022-06-29 12:22:54 +02:00
std : : vector < int8_t > result = std : : vector < int8_t > ( ) ;
for ( int i = 0 ; i < size . value ; i + + ) {
result . push_back ( data [ currentPosition + 4 + i ] ) ;
}
return ErrorOr < std : : vector < int8_t > > ( result ) ;
2022-06-27 04:50:32 +02:00
}
2022-07-20 08:38:04 +02:00
ErrorOr < tiny_utf8 : : string > readString ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) {
if ( dataSize > 0xFFFF ) {
return ErrorOr < tiny_utf8 : : string > ( true , ErrorCodes : : OVERRUN ) ;
}
2022-08-02 03:35:08 +02:00
2022-07-20 08:38:04 +02:00
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 ;
}
2022-06-27 04:50:32 +02:00
2022-06-28 16:51:52 +02:00
ErrorOr < std : : vector < int32_t > > readInt32Array ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) {
2022-06-30 10:45:12 +02:00
// get size prefix
ErrorOr < int32_t > size = readInt32 ( data , dataSize , currentPosition ) ;
if ( size . isError ) return ErrorOr < std : : vector < int32_t > > ( true , size . errorCode ) ;
// get content
2022-07-13 21:00:42 +02:00
if ( currentPosition + 4 + ( size . value * 4 ) > dataSize ) return ErrorOr < std : : vector < int32_t > > ( true , ErrorCodes : : OVERRUN ) ;
2022-06-30 10:45:12 +02:00
std : : vector < int32_t > result = std : : vector < int32_t > ( ) ;
for ( int i = 0 ; i < size . value ; i + + ) {
ErrorOr < int32_t > nextInt32 = readInt32 ( data , dataSize , currentPosition + 4 + ( i * 4 ) ) ;
if ( nextInt32 . isError ) return ErrorOr < std : : vector < int32_t > > ( true , nextInt32 . errorCode ) ;
result . push_back ( nextInt32 . value ) ;
}
return ErrorOr < std : : vector < int32_t > > ( result ) ;
2022-06-27 04:50:32 +02:00
}
2022-06-28 16:51:52 +02:00
ErrorOr < std : : vector < int64_t > > readInt64Array ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) {
2022-06-30 11:02:30 +02:00
// get size prefix
ErrorOr < int32_t > size = readInt32 ( data , dataSize , currentPosition ) ;
if ( size . isError ) return ErrorOr < std : : vector < int64_t > > ( true , size . errorCode ) ;
// get content
2022-07-13 21:00:42 +02:00
if ( currentPosition + 4 + ( size . value * 8 ) > dataSize ) return ErrorOr < std : : vector < int64_t > > ( true , ErrorCodes : : OVERRUN ) ;
2022-06-30 11:02:30 +02:00
std : : vector < int64_t > result = std : : vector < int64_t > ( ) ;
for ( int i = 0 ; i < size . value ; i + + ) {
ErrorOr < int64_t > nextInt64 = readInt64 ( data , dataSize , currentPosition + 4 + ( i * 8 ) ) ;
if ( nextInt64 . isError ) return ErrorOr < std : : vector < int64_t > > ( true , nextInt64 . errorCode ) ;
result . push_back ( nextInt64 . value ) ;
}
return ErrorOr < std : : vector < int64_t > > ( result ) ;
2022-06-27 04:50:32 +02:00
}
2022-07-02 02:08:32 +02:00
void writeInt8 ( std : : vector < uint8_t > * destination , int8_t data ) {
2022-07-04 18:03:40 +02:00
destination - > push_back ( ( uint8_t ) data ) ;
2022-07-02 02:08:32 +02:00
}
2022-07-04 18:03:40 +02:00
//FIXME: endian dependent implementation
2022-07-02 02:08:32 +02:00
void writeInt16 ( std : : vector < uint8_t > * destination , int16_t data ) {
2022-07-04 18:03:40 +02:00
int16_t * value = new int16_t ;
uint8_t * valueAsBytes = reinterpret_cast < uint8_t * > ( value ) ;
* value = data ;
# ifdef FOSSVG_BIG_ENDIAN
destination - > push_back ( * valueAsBytes ) ;
destination - > push_back ( * ( valueAsBytes + 1 ) ) ;
# else
# ifdef FOSSVG_LITTLE_ENDIAN
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 ;
2022-07-02 02:08:32 +02:00
}
2022-07-04 18:27:51 +02:00
//FIXME: endian dependent implementation
2022-07-02 02:08:32 +02:00
void writeInt32 ( std : : vector < uint8_t > * destination , int32_t data ) {
2022-07-04 18:27:51 +02:00
int32_t * value = new int32_t ;
uint8_t * valueAsBytes = reinterpret_cast < uint8_t * > ( 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 ;
2022-07-02 02:08:32 +02:00
}
2022-07-04 18:27:51 +02:00
//FIXME: endian dependent implementation
2022-07-02 02:08:32 +02:00
void writeInt64 ( std : : vector < uint8_t > * destination , int64_t data ) {
2022-07-04 18:27:51 +02:00
int64_t * value = new int64_t ;
uint8_t * valueAsBytes = reinterpret_cast < uint8_t * > ( 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 ;
2022-07-02 02:08:32 +02:00
}
2022-08-04 07:42:40 +02:00
//FIXME: endian-specific implementations
void writeFloat ( std : : vector < uint8_t > * destination , float data ) {
2022-07-04 19:43:31 +02:00
float * value = new float ;
uint8_t * valueAsBytes = reinterpret_cast < uint8_t * > ( 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 ;
2022-07-02 02:08:32 +02:00
}
2022-08-04 07:42:40 +02:00
//FIXME: endian-specific implementations
void writeDouble ( std : : vector < uint8_t > * destination , double data ) {
2022-07-04 19:43:31 +02:00
double * value = new double ;
uint8_t * valueAsBytes = reinterpret_cast < uint8_t * > ( 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 ;
2022-07-02 02:08:32 +02:00
}
void writeInt8Array ( std : : vector < uint8_t > * destination , std : : vector < int8_t > data ) {
2022-07-06 13:46:47 +02:00
writeInt32 ( destination , data . size ( ) ) ;
for ( int8_t datum : data ) {
destination - > push_back ( datum ) ;
}
2022-07-02 02:08:32 +02:00
}
2022-07-06 12:57:32 +02:00
void writeInt8Array ( std : : vector < uint8_t > * destination , int8_t data [ ] , uint32_t dataSize ) {
writeInt32 ( destination , dataSize ) ;
for ( uint32_t i = 0 ; i < dataSize ; i + + ) {
destination - > push_back ( data [ i ] ) ;
}
2022-07-02 02:08:32 +02:00
}
2022-07-28 13:45:04 +02:00
void writeString ( std : : vector < uint8_t > * destination , tiny_utf8 : : string data ) {
ErrorOr < std : : vector < uint8_t > > exportedString = JavaCompat : : exportJavaString ( data ) ;
if ( exportedString . isError ) {
std : : cerr < < " NBT::helpers::writeString encountered an error: " < < ( int ) exportedString . errorCode < < std : : endl ;
std : : abort ( ) ;
}
* destination = exportedString . value ;
}
2022-07-02 02:08:32 +02:00
void writeInt32Array ( std : : vector < uint8_t > * destination , std : : vector < int32_t > data ) {
2022-07-06 14:58:02 +02:00
writeInt32 ( destination , data . size ( ) ) ;
for ( int32_t element : data ) {
writeInt32 ( destination , element ) ;
}
2022-07-02 02:08:32 +02:00
}
2022-07-06 14:58:02 +02:00
void writeInt32Array ( std : : vector < uint8_t > * destination , int32_t data [ ] , uint32_t dataSize ) {
writeInt32 ( destination , dataSize ) ;
for ( uint32_t i = 0 ; i < dataSize ; i + + ) {
writeInt32 ( destination , data [ i ] ) ;
}
2022-07-02 02:08:32 +02:00
}
void writeInt64Array ( std : : vector < uint8_t > * destination , std : : vector < int64_t > data ) {
2022-07-06 14:58:02 +02:00
writeInt32 ( destination , data . size ( ) ) ;
for ( int64_t element : data ) {
writeInt64 ( destination , element ) ;
}
2022-07-02 02:08:32 +02:00
}
2022-07-06 14:58:02 +02:00
void writeInt64Array ( std : : vector < uint8_t > * destination , int64_t data [ ] , uint32_t dataSize ) {
writeInt32 ( destination , dataSize ) ;
for ( uint32_t i = 0 ; i < dataSize ; i + + ) {
writeInt64 ( destination , data [ i ] ) ;
}
2022-07-02 02:08:32 +02:00
}
2022-06-27 04:50:32 +02:00
}
2022-08-03 20:31:12 +02:00
//Tag constructors
template < typename T >
Tag < T > : : Tag ( uint8_t tagType , tiny_utf8 : : string name , uint16_t nameSize , T content , uint32_t size )
: tagType ( tagType ) , name ( name ) , nameSize ( nameSize ) , content ( content ) , size ( size )
{ }
End : : End ( ) : Tag : : Tag ( 0 , " " , 0 , 0 , 0 ) { }
Byte : : Byte ( tiny_utf8 : : string name , uint16_t nameSize , int8_t content )
: Tag : : Tag ( 1 , name , nameSize , content , 1 )
{ }
Byte : : Byte ( uint8_t data [ ] ) {
if ( validate ( data ) ) {
this - > tagType = 1 ;
uint8_t nameSizeSlice [ ] = { data [ 1 ] , data [ 2 ] } ;
ErrorOr < int16_t > readIntResult = helper : : readInt16 ( nameSizeSlice , 2 , 0 ) ;
if ( ! readIntResult . isError ) {
this - > nameSize = readIntResult . value ;
} else {
throw readIntResult . errorCode ;
}
uint8_t nameSlice [ this - > nameSize + 2 ] ;
for ( int i = 0 ; i < this - > nameSize + 2 ; i + + ) {
nameSlice [ i ] = data [ i + 1 ] ;
}
ErrorOr < tiny_utf8 : : string > readStringResult = helper : : readString ( nameSlice , this - > nameSize , 0 ) ;
if ( ! readStringResult . isError ) {
this - > name = readStringResult . value ;
} else {
throw readStringResult . errorCode ;
}
//int8 needs only one byte
this - > content = data [ this - > nameSize + 4 ] ;
}
}
//more conditions will be added
bool Byte : : validate ( uint8_t data [ ] ) {
if ( data [ 0 ] = = 0x01 ) {
return true ;
} else {
return false ;
}
}
2022-06-28 16:51:52 +02:00
bool validateRawNBTData ( uint8_t data [ ] , uint64_t dataSize ) {
2022-06-27 04:50:32 +02:00
//state machine?
//TODO: implement
return false ;
}
}