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
// information taken from https://wiki.vg/NBT
// This is an attempt at creating a uniform model for all NBT tags to allow for a uniform interface based on subclassing a single NBT tag super class.
2022-06-25 13:37:57 +02:00
// NBT tags have a type, optionally a name which consists of the name size and the name string, optionally content type, and optionally a payload which can consist of optionally content type, optionally a content size,
// and the stored content. The format in which they are stored is as follows: <type><name size><name><payload>. All numbers are stored in big endian representation.
2022-06-24 12:15:34 +02:00
// All tag types:
2022-06-28 14:25:32 +02:00
// generic representation: Tag(uint8:tag_type, String:name, uint16:name_size, byte[]:content, int32:size)
2022-06-25 13:37:57 +02:00
// None (compound end): Tag( 0, "", 0, None, 0) => used to determine the end of a compound tag, only the type gets stored
2022-06-28 14:25:32 +02:00
// int8: Tag( 1, String:name, uint16:name_size, int8:content, 1) => a single signed byte, size not stored
2022-06-26 01:23:58 +02:00
// 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
2022-06-28 14:25:32 +02:00
// 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
2022-06-25 13:37:57 +02:00
// 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
2022-06-26 01:23:58 +02:00
// Tag[] (compound): Tag(10, String:name, uint16:name_size, Tag[]:content, int32:size) => list of tags, last tag is always an end tag, size not stored
// int32[]: Tag(11, String:name, uint16:name_size, int32[]:content,int32:size) => list of 32 bit signed integers prefixed with its size, endianness not verified at this point
// int64[]: Tag(12, String:name, uint16:name_size, int64[]:content,int32:size) => list of 64 bit signed integers prefixed with its size, endianness not verified at this point
2022-06-27 04:50:32 +02:00
# pragma once
# include <cstdint>
# include <vector>
# include "error.h++"
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-06-28 15:19:47 +02:00
2022-06-28 16:51:52 +02:00
ErrorOr < int16_t > readInt16 ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) ;
2022-06-28 15:19:47 +02:00
2022-06-28 16:51:52 +02:00
ErrorOr < int32_t > readInt32 ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) ;
2022-06-28 15:19:47 +02:00
2022-06-28 16:51:52 +02:00
ErrorOr < int64_t > readInt64 ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) ;
2022-06-28 15:19:47 +02:00
//FIXME: we just assume that float is a single-precision IEEE754
// floating point number
2022-06-28 16:51:52 +02:00
ErrorOr < float > readFloat32 ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) ;
2022-06-28 15:19:47 +02:00
//FIXME: we just assume that double is a double-precision IEEE754
// floating point number
2022-06-28 16:51:52 +02:00
ErrorOr < double > readFloat64 ( uint8_t data [ ] , uint64_t dataSize , uint64_t currentPosition ) ;
2022-06-28 15:19:47 +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-28 15:19:47 +02:00
2022-06-28 16:51:52 +02:00
//ErrorOr<> readString(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
2022-06-28 15:19:47 +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-28 15:19:47 +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-28 15:19:47 +02:00
}
2022-06-28 16:51:52 +02:00
bool validateRawNBTData ( uint8_t data [ ] , int length ) ;
2022-06-27 04:50:32 +02:00
}