summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/htgen.h53
-rw-r--r--src/libmain.c10
-rw-r--r--src/nbt/compound.c111
-rw-r--r--src/nbt/list.c80
4 files changed, 220 insertions, 34 deletions
diff --git a/src/htgen.h b/src/htgen.h
index 3e22329..3e384ee 100644
--- a/src/htgen.h
+++ b/src/htgen.h
@@ -116,17 +116,39 @@ void HT__NS(free)(HT__TYPE *ht);
void HT__NS(clear)(HT__TYPE *ht);
+#ifdef HT_KEY_STATIC_LEN
+#define HT__KEYARG(_kn, _kln) HT_KEYTYPE_CREF _kn
+#else
+#define HT__KEYARG(_kn, _kln) HT_KEYTYPE_CREF _kn, size_t _kln
+#endif
+
+#ifdef HT_VAL_STATIC_LEN
+#define HT__VALARG(_vn, _vln) HT_VALTYPE_CREF _vn
+#else
+#define HT__VALARG(_vn, _vln) HT_VALTYPE_CREF _vn, size_t _vln
+#endif
+
HT_VALTYPE HT__NS(get)(HT__TYPE *ht, HT_KEYTYPE_CREF key, bool *found);
-HT_VALTYPE HT__NS(getn)(HT__TYPE *ht, HT_KEYTYPE_CREF key, size_t keylen, bool *found);
+HT_VALTYPE HT__NS(getn)(HT__TYPE *ht, HT__KEYARG(key, keylen), bool *found);
int HT__NS(put)(HT__TYPE *ht, HT_KEYTYPE_CREF key, HT_VALTYPE_CREF val);
-int HT__NS(putn)(HT__TYPE *ht, HT_KEYTYPE_CREF key, size_t keylen, HT_VALTYPE_CREF val, size_t vallen);
+int HT__NS(putn)(HT__TYPE *ht, HT__KEYARG(key, keylen), HT__VALARG(val, vallen));
int HT__NS(remove)(HT__TYPE *ht, HT_KEYTYPE_CREF key);
-int HT__NS(removen)(HT__TYPE *ht, HT_KEYTYPE_CREF key, size_t keylen);
+int HT__NS(removen)(HT__TYPE *ht, HT__KEYARG(key, keylen));
HT_VALTYPE HT__NS(pop)(HT__TYPE *ht, HT_KEYTYPE_CREF key, bool *found);
-HT_VALTYPE HT__NS(popn)(HT__TYPE *ht, HT_KEYTYPE_CREF key, size_t keylen, bool *found);
+HT_VALTYPE HT__NS(popn)(HT__TYPE *ht, HT__KEYARG(key, keylen), bool *found);
+
+size_t HT__NS(length)(HT__TYPE *ht);
+
+struct HT__NS(iter_t) {
+ size_t internalsz;
+ void *internalptr;
+};
+
+struct HT__NS(iter_t) HT__NS(iter_begin)(HT__TYPE *ht);
+int HT__NS(iter_next)(struct HT__NS(iter_t) *iter);
/* implementations */
@@ -145,20 +167,24 @@ HT_VALTYPE HT__NS(popn)(HT__TYPE *ht, HT_KEYTYPE_CREF key, size_t keylen, bool *
#define HT__NODE_KEYLEN(_node) HT_KEY_STATIC_LEN
#define HT__NODE_KEYLEN_SET(_node, _unused)
#define HT__GUESS_KEYLEN(_node) HT_KEY_STATIC_LEN
+#define HT__DEFINE_KEYLEN(_n) size_t _n
#else
#define HT__NODE_KEYLEN(_node) ((_node)->keylen)
#define HT__NODE_KEYLEN_SET(_node, _len) (((_node)->keylen) = (_len))
#define HT__GUESS_KEYLEN(_key) HT_KEY_GUESS_LEN(_key)
+#define HT__DEFINE_KEYLEN(_n) ((void)0)
#endif
#ifdef HT_VAL_STATIC_LEN
#define HT__NODE_VALLEN(_node) HT_VAL_STATIC_LEN
#define HT__NODE_VALLEN_SET(_node, _unused)
#define HT__GUESS_VALLEN(_val) HT_VAL_STATIC_LEN
+#define HT__DEFINE_VALLEN(_n) size_t _n
#else
#define HT__NODE_VALLEN(_node) ((_node)->vallen)
#define HT__NODE_VALLEN_SET(_node, _len) (((_node)->vallen) = (_len))
#define HT__GUESS_VALLEN(_val) HT_VAL_GUESS_LEN(_val)
+#define HT__DEFINE_VALLEN(_n) ((void)0)
#endif
#ifndef HT_VAL_FREE
@@ -452,8 +478,11 @@ int HT__NS(put)(HT__TYPE *ht, HT_KEYTYPE_CREF key, HT_VALTYPE_CREF val)
return HT__NS(putn)(ht, key, 0, val, 0);
}
-int HT__NS(putn)(HT__TYPE *ht, HT_KEYTYPE_CREF key, size_t keylen, HT_VALTYPE_CREF val, size_t vallen)
+int HT__NS(putn)(HT__TYPE *ht, HT__KEYARG(key, keylen), HT__VALARG(val, vallen))
{
+ HT__DEFINE_KEYLEN(keylen);
+ HT__DEFINE_VALLEN(vallen);
+
if (ht->capacity * HT__LOADFACTOR(ht) < (ht->asize + 1)) {
if (HT__NS(_rehash)(ht, ht->capacity << 1) < 0) return -1;
}
@@ -477,8 +506,9 @@ HT_VALTYPE HT__NS(get)(HT__TYPE *ht, HT_KEYTYPE_CREF key, bool *found)
return HT__NS(getn)(ht, key, 0, found);
}
-HT_VALTYPE HT__NS(getn)(HT__TYPE *ht, HT_KEYTYPE_CREF key, size_t keylen, bool *found)
+HT_VALTYPE HT__NS(getn)(HT__TYPE *ht, HT__KEYARG(key, keylen), bool *found)
{
+ HT__DEFINE_KEYLEN(keylen);
if (!keylen) keylen = HT__GUESS_KEYLEN(key);
const HT__HASHTYPE hash = HT_KEY_HASH(key, keylen);
@@ -498,8 +528,9 @@ int HT__NS(remove)(HT__TYPE *ht, HT_KEYTYPE_CREF key)
return HT__NS(removen)(ht, key, 0);
}
-int HT__NS(removen)(HT__TYPE *ht, HT_KEYTYPE_CREF key, size_t keylen)
+int HT__NS(removen)(HT__TYPE *ht, HT__KEYARG(key, keylen))
{
+ HT__DEFINE_KEYLEN(keylen);
if (!keylen) keylen = HT__GUESS_KEYLEN(key);
const HT__HASHTYPE hash = HT_KEY_HASH(key, keylen);
@@ -515,8 +546,9 @@ HT_VALTYPE HT__NS(pop)(HT__TYPE *ht, HT_KEYTYPE_CREF key, bool *found)
return HT__NS(popn)(ht, key, 0, found);
}
-HT_VALTYPE HT__NS(popn)(HT__TYPE *ht, HT_KEYTYPE_CREF key, size_t keylen, bool *found)
+HT_VALTYPE HT__NS(popn)(HT__TYPE *ht, HT__KEYARG(key, keylen), bool *found)
{
+ HT__DEFINE_KEYLEN(keylen);
if (!keylen) keylen = HT__GUESS_KEYLEN(key);
const HT__HASHTYPE hash = HT_KEY_HASH(key, keylen);
@@ -535,6 +567,11 @@ HT_VALTYPE HT__NS(popn)(HT__TYPE *ht, HT_KEYTYPE_CREF key, size_t keylen, bool *
return val;
}
+size_t HT__NS(length)(HT__TYPE *ht)
+{
+ return ht->asize;
+}
+
void HT__NS(_debug_table)(HT__TYPE *ht)
{
fprintf(stderr, HT__STR(HT__TYPE) " debug: cap: %zu, asize: %zu, rsize: %zu, lf: %f\n",
diff --git a/src/libmain.c b/src/libmain.c
index c6d1c29..ec5de01 100644
--- a/src/libmain.c
+++ b/src/libmain.c
@@ -37,12 +37,20 @@ int main(int argc, char **argv) {
nbt_tag_t *list = nbt_list();
debug_list(list);
+ printf("%s\n", nbt_typestr(nbt_list_type(list)));
TEST_TRUE(nbt_list_append_move(list, nbt_byte(5)) >= 0);
- TEST_TRUE(nbt_list_append_move(list, nbt_string("somestr")) >= 0);
+ printf("%s\n", nbt_typestr(nbt_list_type(list)));
+ TEST_TRUE(nbt_list_append_move(list, nbt_string("somestr")) < 0);
+ printf("%s\n", nbt_typestr(nbt_list_type(list)));
+ nbt_list_clear(list);
+ TEST_TRUE(nbt_list_append_move(list, nbt_string("somestr2")) >= 0);
+ printf("%s\n", nbt_typestr(nbt_list_type(list)));
debug_list(list);
nbt_decref(list);
+ printf("%s\n", "test complete");
+
return 0;
}
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)
{