summaryrefslogtreecommitdiffstats
path: root/src/nbt
diff options
context:
space:
mode:
Diffstat (limited to 'src/nbt')
-rw-r--r--src/nbt/compound.c111
-rw-r--r--src/nbt/list.c80
2 files changed, 166 insertions, 25 deletions
diff --git a/src/nbt/compound.c b/src/nbt/compound.c
new file mode 100644
index 0000000..decae6c
--- /dev/null
+++ b/src/nbt/compound.c
@@ -0,0 +1,111 @@
+#include "../nbt.internal.h"
+#include "nbt.h"
+
+#define NBT__RETURN1(_r) return _r
+#define NBT__RETURN0() return
+#define NBT__CHECK(_tag, _ret) NBT__CHECK_TYPE(_tag, NBT_TAG_COMPOUND, NBT__RETURN1, _ret)
+#define NBT__CHECK0(_tag) NBT__CHECK_TYPE(_tag, NBT_TAG_COMPOUND, NBT__RETURN0)
+
+nbt_size_t nbt_compound_length(nbt_tag_t *compound)
+{
+ NBT__CHECK(compound, (nbt_size_t)-1);
+ return nbt__ht_length(compound->value.nbt_compound.hash);
+}
+
+nbt_tag_t *nbt_compound_find(nbt_tag_t *compound, const char *key)
+{
+ NBT__CHECK(compound, NULL);
+ bool found = false;
+ nbt_tag_t *tag = nbt__ht_get(compound->value.nbt_compound.hash, key, &found);
+
+ if (!found) return NULL;
+ return tag;
+}
+
+nbt_tag_t *nbt_compound_findn(nbt_tag_t *compound, const char *key, nbt_size_t keylen)
+{
+ NBT__CHECK(compound, NULL);
+ bool found = false;
+ nbt_tag_t *tag = nbt__ht_getn(compound->value.nbt_compound.hash, key, keylen, &found);
+
+ if (!found) return NULL;
+ return tag;
+}
+
+/* returns NBT_TAG_END if there is no value present */
+nbt_type_t nbt_compound_type(nbt_tag_t *compound, const char *key)
+{
+ nbt_tag_t *tag = nbt_compound_find(compound, key);
+ if (!tag) return NBT_TAG_END;
+ return nbt_tag_type(tag);
+}
+
+nbt_type_t nbt_compound_typen(nbt_tag_t *compound, const char *key, nbt_size_t keylen)
+{
+ nbt_tag_t *tag = nbt_compound_findn(compound, key, keylen);
+ if (!tag) return NBT_TAG_END;
+ return nbt_tag_type(tag);
+}
+
+int nbt_compound_put(nbt_tag_t *compound, const char *key, nbt_tag_t *value)
+{
+ NBT__CHECK(compound, -1);
+ if (!value) return -1;
+
+ if (nbt__ht_put(compound->value.nbt_compound.hash, key, value) < 0) return -1;
+
+ nbt_incref(value);
+ return 0;
+}
+
+int nbt_compound_putn(nbt_tag_t *compound, const char *key, nbt_size_t sz, nbt_tag_t *value)
+{
+ NBT__CHECK(compound, -1);
+ if (!value) return -1;
+
+ if (nbt__ht_putn(compound->value.nbt_compound.hash, key, sz, value) < 0)
+ return -1;
+
+ nbt_incref(value);
+ return 0;
+}
+
+int nbt_compound_remove(nbt_tag_t *compound, const char *key)
+{
+ NBT__CHECK(compound, -1);
+
+ return nbt__ht_remove(compound->value.nbt_compound.hash, key);
+}
+
+int nbt_compound_removen(nbt_tag_t *compound, const char *key, nbt_size_t sz)
+{
+ NBT__CHECK(compound, -1);
+
+ return nbt__ht_removen(compound->value.nbt_compound.hash, key, sz);
+}
+
+nbt_tag_t *nbt_compound_pop(nbt_tag_t *compound, const char *key)
+{
+ NBT__CHECK(compound, NULL);
+
+ return nbt__ht_pop(compound->value.nbt_compound.hash, key, NULL); /* TODO: use found pointer*/
+}
+
+nbt_tag_t *nbt_compound_popn(nbt_tag_t *compound, const char *key, nbt_size_t sz)
+{
+ NBT__CHECK(compound, NULL);
+
+ return nbt__ht_popn(compound->value.nbt_compound.hash, key, sz, NULL);
+}
+
+void nbt_compound_clear(nbt_tag_t *compound)
+{
+ NBT__CHECK0(compound);
+ nbt__ht_clear(compound->value.nbt_compound.hash);
+}
+
+int nbt_compound_merge(nbt_tag_t *target, nbt_tag_t *srccomp)
+{
+ /* TODO */
+ return -1;
+}
diff --git a/src/nbt/list.c b/src/nbt/list.c
index df12844..7c5ed7c 100644
--- a/src/nbt/list.c
+++ b/src/nbt/list.c
@@ -31,49 +31,79 @@ nbt_tag_t *nbt_list_get(nbt_tag_t *list, nbt_size_t idx)
return list->value.nbt_list.ptags[idx];
}
-#define NBT__APPEND_BODY(_list, _tag, _ex) \
-{ \
- NBT__CHECK(list, -1); \
- if (!tag) return -1; \
+int nbt_list__check_tag(nbt_tag_t *list, nbt_tag_t *tag)
+{
+ if (!tag) return -1;
+ nbt_type_t lt = nbt_list_type(list);
+
+ if (lt != NBT_TAG_END && lt != nbt_tag_type(tag)) return -1;
+
+ return 0;
+}
+
+#define NBT__APPEND_BODY(_list, _tag, _ex, _err) \
+ NBT__CHECK(list, -1); \
+ if (nbt_list__check_tag(_list, _tag) < 0) \
+ goto _err; \
\
- int ret = nbt_list_reserve_more(list, 1); \
- if (ret < 0) return ret; \
+ int ret = nbt_list_reserve_more(list, 1); \
+ if (ret < 0) goto _err; \
\
list->value.nbt_list.ptags[list->value.nbt_list.len++] = _ex(tag); \
- return 0; \
-}
+ return 0;
#define NBT__LEAVE_ALONE(_t) _t
int nbt_list_append(nbt_tag_t *list, nbt_tag_t *tag)
- NBT__APPEND_BODY(list, tag, nbt_incref)
+{
+ NBT__APPEND_BODY(list, tag, nbt_incref, error)
+
+error:
+ return -1;
+}
int nbt_list_append_move(nbt_tag_t *list, nbt_tag_t *tag)
- NBT__APPEND_BODY(list, tag, NBT__LEAVE_ALONE)
+{
+ NBT__APPEND_BODY(list, tag, NBT__LEAVE_ALONE, error)
+
+error:
+ nbt_decref(tag);
+ return -1;
+}
-#define NBT__INSERT_BODY(_list, _tag, _at, _ex) \
-{ \
- NBT__CHECK(list, -1); \
- if (!tag) return -1; \
+#define NBT__INSERT_BODY(_list, _tag, _at, _ex, _err) \
+ NBT__CHECK(list, -1); \
+ if (nbt_list__check_tag(_list, _tag) < 0) \
+ goto _err; \
\
- int ret = nbt_list_reserve_more(list, 1); \
- if (ret < 0) return ret; \
+ int ret = nbt_list_reserve_more(list, 1); \
+ if (ret < 0) goto _err; \
\
- memmove(list->value.nbt_list.ptags + _at + 1, \
- list->value.nbt_list.ptags + _at, \
- list->value.nbt_list.len - _at); \
+ memmove(list->value.nbt_list.ptags + _at + 1, \
+ list->value.nbt_list.ptags + _at, \
+ list->value.nbt_list.len - _at); \
\
- list->value.nbt_list.ptags[at] = _ex(tag); \
+ list->value.nbt_list.ptags[at] = _ex(tag); \
\
- ++list->value.nbt_list.len; \
- return 0; \
-}
+ ++list->value.nbt_list.len; \
+ return 0;
int nbt_list_insert(nbt_tag_t *list, nbt_tag_t *tag, size_t at)
- NBT__INSERT_BODY(list, tag, at, nbt_incref)
+{
+ NBT__INSERT_BODY(list, tag, at, nbt_incref, error)
+
+error:
+ return -1;
+}
int nbt_list_insert_move(nbt_tag_t *list, nbt_tag_t *tag, size_t at)
- NBT__INSERT_BODY(list, tag, at, NBT__LEAVE_ALONE)
+{
+ NBT__INSERT_BODY(list, tag, at, NBT__LEAVE_ALONE, error)
+
+error:
+ nbt_decref(tag);
+ return -1;
+}
int nbt_list_remove(nbt_tag_t *list, nbt_size_t idx)
{