mirror of
https://github.com/thepigeongenerator/mcaselector-lite.git
synced 2025-12-17 07:35:45 +01:00
modify the array bytelength function to get the bytelength of a single tag.
This commit is contained in:
@@ -29,60 +29,12 @@ static int nbt_cmpstr(char const *restrict matstr, u8 const *restrict buf) {
|
|||||||
return strncmp(str, matstr, len);
|
return strncmp(str, matstr, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* acquires the array's byte size (excluding name + size spec)
|
|
||||||
* returns `0` upon failure */
|
|
||||||
static size_t nbt_arrbsize(u8 const *restrict buf) {
|
|
||||||
i32 mems = 0;
|
|
||||||
|
|
||||||
switch (*buf) {
|
|
||||||
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 * nbt_arrlen(buf); // mems+1 multiplied by the array length
|
|
||||||
|
|
||||||
case NBT_STR: return nbt_strlen(buf);
|
|
||||||
|
|
||||||
case NBT_LIST:
|
|
||||||
mems = nbt_primsize(*buf);
|
|
||||||
if (mems > 0) return mems * nbt_arrlen(buf + 1);
|
|
||||||
return 0;
|
|
||||||
default: return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns the (expected) pointer of the tag following this one.
|
/* returns the (expected) pointer of the tag following this one.
|
||||||
* `NBT_COMPOUND` and `NBT_END` tags are not valid for this function and should be handled separately.
|
|
||||||
* `NULL` is returned if anything went wrong. */
|
* `NULL` is returned if anything went wrong. */
|
||||||
static u8 const *nbt_nexttag(u8 const *restrict buf) {
|
static u8 const *nbt_nexttag(u8 const *restrict buf, u16 naml) {
|
||||||
u8 const *nxt = buf + 1;
|
size_t len = nbt_tagdatlen(buf);
|
||||||
nxt += nbt_strlen(nxt) + 2;
|
if (!len) return NULL; // TODO: compound tags should be handled here
|
||||||
|
return buf + naml + len + 3;
|
||||||
i32 tmp;
|
|
||||||
switch (*buf) {
|
|
||||||
case NBT_I8: __attribute__((fallthrough));
|
|
||||||
case NBT_I16: __attribute__((fallthrough));
|
|
||||||
case NBT_I32: __attribute__((fallthrough));
|
|
||||||
case NBT_I64: __attribute__((fallthrough));
|
|
||||||
case NBT_F32: __attribute__((fallthrough));
|
|
||||||
case NBT_F64:
|
|
||||||
tmp = nbt_primsize(*buf);
|
|
||||||
return (tmp >= 0) ? (nxt + tmp) : 0;
|
|
||||||
|
|
||||||
case NBT_LIST: nxt += 5; break;
|
|
||||||
case NBT_STR: nxt += 2; break;
|
|
||||||
case NBT_ARR_I8: __attribute__((fallthrough));
|
|
||||||
case NBT_ARR_I32: __attribute__((fallthrough));
|
|
||||||
case NBT_ARR_I64: nxt += 4; break;
|
|
||||||
|
|
||||||
default: return NULL; // failure on compound/end tags; these require more nuanced logic
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = nbt_arrbsize(buf);
|
|
||||||
return (tmp >= 0) ? (nxt + tmp) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
default: return NULL; // failure on compound/end tags; these require more nuanced logic
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int nbt_proc(void **restrict datout, u8 const *restrict buf, size_t len) {
|
int nbt_proc(void **restrict datout, u8 const *restrict buf, size_t len) {
|
||||||
@@ -112,6 +64,33 @@ int nbt_primsize(u8 tag) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t nbt_tagdatlen(u8 const *restrict buf) {
|
||||||
|
size_t mems = 0;
|
||||||
|
|
||||||
|
switch (*buf) {
|
||||||
|
case NBT_I8: __attribute__((fallthrough));
|
||||||
|
case NBT_I16: __attribute__((fallthrough));
|
||||||
|
case NBT_I32: __attribute__((fallthrough));
|
||||||
|
case NBT_F32: __attribute__((fallthrough));
|
||||||
|
case NBT_I64: __attribute__((fallthrough));
|
||||||
|
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 * nbt_arrlen(buf) + 4;
|
||||||
|
|
||||||
|
case NBT_STR: return nbt_strlen(buf) + 2;
|
||||||
|
|
||||||
|
case NBT_LIST:
|
||||||
|
mems = nbt_primsize(*buf);
|
||||||
|
if (mems > 0) return mems * nbt_arrlen(buf + 1) + 5;
|
||||||
|
return 0;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int nbt_isprim(u8 tag) {
|
int nbt_isprim(u8 tag) {
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case NBT_I8: __attribute__((fallthrough));
|
case NBT_I8: __attribute__((fallthrough));
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ int nbt_proc(void **restrict datout, u8 const *restrict buf, size_t len);
|
|||||||
* returns a boolean value. */
|
* returns a boolean value. */
|
||||||
atrb_const int nbt_isprim(u8 tag);
|
atrb_const int nbt_isprim(u8 tag);
|
||||||
|
|
||||||
|
/* gets the byte size of an NBT tag's data (excluding id and name), returns `0` upon error. */
|
||||||
|
atrb_const size_t nbt_tagdatlen(u8 const *buf);
|
||||||
|
|
||||||
/* gets the tag size of primitive types, returns `>0` on success, `<0` on failure */
|
/* gets the tag size of primitive types, returns `>0` on success, `<0` on failure */
|
||||||
atrb_const int nbt_primsize(u8 tag);
|
atrb_const int nbt_primsize(u8 tag);
|
||||||
|
|||||||
Reference in New Issue
Block a user