diff --git a/src/dat/nbt.c b/src/dat/nbt.c index f8baa56..1a6d7bd 100644 --- a/src/dat/nbt.c +++ b/src/dat/nbt.c @@ -7,6 +7,59 @@ #include "../util/compat/endian.h" #include "../util/types.h" +int nbt_isprim(u8 tag) { + switch (tag) { + case NBT_I8: + case NBT_I16: + case NBT_I32: + case NBT_F32: + case NBT_I64: + case NBT_F64: + return 1; + default: + return 0; + } +} + +int nbt_primsize(u8 tag) { + switch (tag) { + case NBT_I8: return 1; + case NBT_I16: return 2; + case NBT_I32: // fall through + case NBT_F32: return 4; + case NBT_I64: // fall through + case NBT_F64: return 8; + default: return -1; + } +} + +size_t nbt_tagdatlen(const u8 *restrict buf) { + size_t mems = 0; + + switch (*buf) { + case NBT_I8: + case NBT_I16: + case NBT_I32: + case NBT_F32: + case NBT_I64: + case NBT_F64: + mems = nbt_primsize(*buf); + return -(mems >= 0) & mems; + + case NBT_ARR_I64: mems += sizeof(i64) - sizeof(i32); __attribute__((fallthrough)); + case NBT_ARR_I32: mems += sizeof(i32) - sizeof(i8); __attribute__((fallthrough)); + case NBT_ARR_I8: return +mems * (i32)be32toh(*(u32 *)(buf)) + 4; + + case NBT_STR: return be16toh(*(u16 *)buf) + 2; + + case NBT_LIST: + mems = nbt_primsize(*buf); + if (mems > 0) return mems * (i32)be32toh(*(u32 *)(buf + 1)) + 5; + return 0; + default: return 0; + } +} + const u8 *nbt_nexttag(const u8 *restrict buf, u16 naml) { size_t len = nbt_tagdatlen(buf); if (!len) return NULL; // TODO: compound tags should be handled here @@ -95,56 +148,3 @@ int nbt_proc(struct nbt_path const *restrict pats, uint npats, const u8 *restric // TODO: finish function return !dpt; } - -int nbt_primsize(u8 tag) { - switch (tag) { - case NBT_I8: return 1; - case NBT_I16: return 2; - case NBT_I32: // fall through - case NBT_F32: return 4; - case NBT_I64: // fall through - case NBT_F64: return 8; - default: return -1; - } -} - -size_t nbt_tagdatlen(const u8 *restrict buf) { - size_t mems = 0; - - switch (*buf) { - case NBT_I8: - case NBT_I16: - case NBT_I32: - case NBT_F32: - case NBT_I64: - case NBT_F64: - mems = nbt_primsize(*buf); - return -(mems >= 0) & mems; - - case NBT_ARR_I64: mems += sizeof(i64) - sizeof(i32); __attribute__((fallthrough)); - case NBT_ARR_I32: mems += sizeof(i32) - sizeof(i8); __attribute__((fallthrough)); - case NBT_ARR_I8: return +mems * (i32)be32toh(*(u32 *)(buf)) + 4; - - case NBT_STR: return be16toh(*(u16 *)buf) + 2; - - case NBT_LIST: - mems = nbt_primsize(*buf); - if (mems > 0) return mems * (i32)be32toh(*(u32 *)(buf + 1)) + 5; - return 0; - default: return 0; - } -} - -int nbt_isprim(u8 tag) { - switch (tag) { - case NBT_I8: - case NBT_I16: - case NBT_I32: - case NBT_F32: - case NBT_I64: - case NBT_F64: - return 1; - default: - return 0; - } -}