mirror of
https://github.com/thepigeongenerator/mcaselector-lite.git
synced 2025-12-20 02:45:46 +01:00
69 lines
3.2 KiB
C
69 lines
3.2 KiB
C
// Copyright (c) 2025 Quinn
|
|
// Licensed under the MIT Licence. See LICENSE for details
|
|
#pragma once
|
|
|
|
#include <assert.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "../util/atrb.h"
|
|
#include "../util/compat/endian.h"
|
|
#include "../util/intdef.h"
|
|
|
|
/* NBT (named binary tag) is a tree data structure. Tags have a numeric type ID, name and a payload.
|
|
* NBT files are a compressed `compound` tag. GZip is the compression used in most cases,
|
|
* in some (rare) cases it's stored uncompressed.
|
|
* A tag is an individual part of the data tree.
|
|
* The first byte is the ID, followed by a `u16`, for the length of the name.
|
|
* Then the name as `UTF-8`. (end tag does not contain name) */
|
|
|
|
|
|
/* specifies the NBT tag IDs.
|
|
* NOTE: every type is stored as BE (big-endian) in the file. */
|
|
enum nbt_tagid {
|
|
NBT_END = 0x00, // signifies the end of a compound tag
|
|
NBT_I8 = 0x01, // next byte is for an 8 bit signed integer.
|
|
NBT_I16 = 0x02, // next 2 bytes are for a 16 bit signed integer
|
|
NBT_I32 = 0x03, // next 4 bytes are for a 32 bit signed integer
|
|
NBT_I64 = 0x04, // next 8 bytes are for a 64 bit signed integer
|
|
NBT_F32 = 0x05, // next 4 bytes are for a single-precision floating-point
|
|
NBT_F64 = 0x06, // next 8 bytes are for a double-precision floating-point
|
|
NBT_ARR_I8 = 0x07, // starts with a i32, denoting size, followed by the i8 data
|
|
NBT_STR = 0x08, // starts with a u16, denoting size, followed by the UTF-8 data
|
|
NBT_LIST = 0x09, // starts with an ID, followed by a 32 bit signed integer denoting the size
|
|
NBT_COMPOUND = 0x0A, // compound tag, contains tags and is delimited by `NBT_END`
|
|
NBT_ARR_I32 = 0x0B, // starts with a i32, denoting size, followed by the i32 data
|
|
NBT_ARR_I64 = 0x0C, // starts with a i32, denoting size, followed by the u32 data
|
|
};
|
|
|
|
/* TODO: write doc */
|
|
struct nbt_path {
|
|
const char **restrict pat; // specifies the NBT path components as separate elements
|
|
i16 len; // specifies the length of the NBT elements
|
|
};
|
|
|
|
/* TODO: write doc */
|
|
struct nbt_procdat {
|
|
const struct nbt_path *pats;
|
|
const char *restrict *cpat;
|
|
u32 npats;
|
|
i16 dpt, mdpt;
|
|
};
|
|
|
|
/* searches for the end of a compound tag without processing data, the final pointer is returned.
|
|
* `NULL` is returned upon failure, the otherwise returned pointer is not guaranteed to be valid.
|
|
* `cdat` is assumed to be the start of the **compound tag's data**. */
|
|
PURE NONNULL((1)) const u8 *nbt_nextcompound(const u8 *restrict cdat);
|
|
|
|
/* searches for the end of a list tag without processing data, the final pointer is returned.
|
|
* `NULL` is returned upon failure, the otherwise returned pointer is not guaranteed to be valid.
|
|
* `ldat` is assumed to be the start of the **list tag's data.** */
|
|
PURE NONNULL((1)) const u8 *nbt_nextlist(const u8 *restrict ldat);
|
|
|
|
/* searches for the end of a named tag without processing data, the final pointer is returned.
|
|
* `NULL` is returned upon failure, the otherwise returned pointer is not guaranteed to be valid. */
|
|
PURE NONNULL((1)) const u8 *nbt_nexttag(const u8 *restrict buf, u16 naml);
|
|
|
|
/* initialises a data structure used whilst processing the tags */
|
|
PURE NONNULL((1)) struct nbt_procdat nbt_initproc(struct nbt_path const *restrict pats, uint npats);
|