|
libclod
C library for interacting with NBTs, region files, LOD data and other things.
|
Classes | |
| struct | clod_nbt_iter |
Macros | |
| #define | CLOD_NBT_ZERO (uint8_t)(0) |
| #define | CLOD_NBT_INT8 (uint8_t)(1) |
| #define | CLOD_NBT_INT16 (uint8_t)(2) |
| #define | CLOD_NBT_INT32 (uint8_t)(3) |
| #define | CLOD_NBT_INT64 (uint8_t)(4) |
| #define | CLOD_NBT_FLOAT32 (uint8_t)(5) |
| #define | CLOD_NBT_FLOAT64 (uint8_t)(6) |
| #define | CLOD_NBT_INT8_ARRAY (uint8_t)(7) |
| #define | CLOD_NBT_INT32_ARRAY (uint8_t)(11) |
| #define | CLOD_NBT_INT64_ARRAY (uint8_t)(12) |
| #define | CLOD_NBT_STRING (uint8_t)(8) |
| #define | CLOD_NBT_LIST (uint8_t)(9) |
| #define | CLOD_NBT_COMPOUND (uint8_t)(10) |
| #define | CLOD_NBT_ROOT_COMPOUND_INIT ((uint8_t[]){CLOD_NBT_COMPOUND, 0, 0, 0}) |
| #define | CLOD_NBT_ROOT_LIST_INIT(type) |
| #define | CLOD_NBT_ITER_ZERO { .type = CLOD_NBT_ZERO } |
Functions | |
| size_t | clod_nbt_payload_size (const uint8_t *restrict payload, const void *end, uint8_t payload_type) |
| size_t | clod_nbt_tag_size (const uint8_t *restrict tag, const void *end) |
| uint8_t * | clod_nbt_tag_payload (const uint8_t *restrict tag, const void *end) |
| struct clod_string | clod_nbt_tag_name (const uint8_t *tag, const void *end) |
| bool | clod_nbt_iter_next (const uint8_t *restrict payload, const void *end, uint8_t payload_type, struct clod_nbt_iter *iter) |
| uint8_t * | clod_nbt_compound_get (const uint8_t *restrict compound, const void *end, struct clod_string name) |
| uint8_t * | clod_nbt_compound_add (uint8_t *restrict compound, const void **end, ptrdiff_t *free, struct clod_string name, uint8_t type) |
| bool | clod_nbt_compound_del (uint8_t *restrict compound, const void **end, ptrdiff_t *free, struct clod_string name) |
| bool | clod_nbt_list_resize (uint8_t *restrict list, const uint8_t **end, ptrdiff_t *free, uint8_t type, uint32_t length) |
The NBT format is a serialised depth-first tree with no indexing. The primary limitation of interacting with such a structure is simply figuring out where the nodes actually are. To find a given NBT, every single tag before it must be recursively parsed to find the wanted NBT's offset. The majority of the entire tree must be parsed for most operations. As such, traversing the tree becomes the core limitation of any NBT operation and the primary focus for optimisation. This traversal method is clod_nbt_payload_size.
The library only performs some basic sanity checks on top of ensuring memory safety. Implementing complex data analysis to discern the likelihood that a given set of NBT data has been modified from its original state is an insane alternative to using a checksum and out of scope for this library. Please, for the love of good code, rely on dedicated verification methods instead of incidental parsing errors.
| #define CLOD_NBT_ROOT_COMPOUND_INIT ((uint8_t[]){CLOD_NBT_COMPOUND, 0, 0, 0}) |
| #define CLOD_NBT_ROOT_LIST_INIT | ( | type | ) |
| size_t clod_nbt_payload_size | ( | const uint8_t *restrict | payload, |
| const void * | end, | ||
| uint8_t | payload_type ) |
Get the size of a payload. This is the primary NBT traversing function; everything else is built on top of this.
| [in] | payload | The payload to get the size of. |
| [in] | payload_type | The type of the payload. |
| [in] | end | End of the NBT data. |
| size_t clod_nbt_tag_size | ( | const uint8_t *restrict | tag, |
| const void * | end ) |
| uint8_t * clod_nbt_tag_payload | ( | const uint8_t *restrict | tag, |
| const void * | end ) |
| struct clod_string clod_nbt_tag_name | ( | const uint8_t * | tag, |
| const void * | end ) |
Get the name of a tag.
| [in] | tag | The tag to get the name of. |
| [in] | end | Point past which the method will never read. |
| bool clod_nbt_iter_next | ( | const uint8_t *restrict | payload, |
| const void * | end, | ||
| uint8_t | payload_type, | ||
| struct clod_nbt_iter * | iter ) |
Iterate over elements in a payload.
| [in] | payload | The payload whose elements are to be iterated over. |
| [in] | end | End of NBT data. |
| [in] | payload_type | Type of the payload. An invalid payload_type makes the function a false-returning no-op. |
| [in,out] | iter | Iterator. Upon completion (false return), iter.tag is always set to |
iter.payload field indicates error. | uint8_t * clod_nbt_compound_get | ( | const uint8_t *restrict | compound, |
| const void * | end, | ||
| struct clod_string | name ) |
| uint8_t * clod_nbt_compound_add | ( | uint8_t *restrict | compound, |
| const void ** | end, | ||
| ptrdiff_t * | free, | ||
| struct clod_string | name, | ||
| uint8_t | type ) |
Get or create an element in a compound payload.
| [in] | compound | Payload to find or create element in. If compound is null, then the size that would be written on creation is subtracted from free. |
| [in,out] | end | End of the NBT data. |
| [in,out] | free | Free space in the buffer. It is modified to reflect the change in NBT data size. A negative value after return indicates the writing failed due to lack of space. |
| [in] | name | Name of the element to search for. |
| [in] | type | Type of the new element if creation occurs. |
| bool clod_nbt_compound_del | ( | uint8_t *restrict | compound, |
| const void ** | end, | ||
| ptrdiff_t * | free, | ||
| struct clod_string | name ) |
| bool clod_nbt_list_resize | ( | uint8_t *restrict | list, |
| const uint8_t ** | end, | ||
| ptrdiff_t * | free, | ||
| uint8_t | type, | ||
| uint32_t | length ) |
Resize a list payload.
| [in] | list | The list payload to resize. |
| [in,out] | end | End of NBT data. |
| [in,out] | free | Free space in the buffer. |
| [in] | type | If non-zero, the type of list elements will be set to this. Changing types forces wiping all existing elements in the list. |
| [in] | length | New length. |