Squashed 'third_party/rawrtc/re/' content from commit f3163ce8b
Change-Id: I6a235e6ac0f03269d951026f9d195da05c40fdab
git-subtree-dir: third_party/rawrtc/re
git-subtree-split: f3163ce8b526a13b35ef71ce4dd6f43585064d8a
diff --git a/src/odict/entry.c b/src/odict/entry.c
new file mode 100644
index 0000000..53daf2b
--- /dev/null
+++ b/src/odict/entry.c
@@ -0,0 +1,152 @@
+/**
+ * @file odict/entry.c Ordered Dictionary -- entry
+ *
+ * Copyright (C) 2010 - 2015 Creytiv.com
+ */
+
+#include "re_types.h"
+#include "re_fmt.h"
+#include "re_mem.h"
+#include "re_list.h"
+#include "re_hash.h"
+#include "re_odict.h"
+
+
+static void destructor(void *arg)
+{
+ struct odict_entry *e = arg;
+
+ switch (e->type) {
+
+ case ODICT_OBJECT:
+ case ODICT_ARRAY:
+ mem_deref(e->u.odict);
+ break;
+
+ case ODICT_STRING:
+ mem_deref(e->u.str);
+ break;
+
+ default:
+ break;
+ }
+
+ hash_unlink(&e->he);
+ list_unlink(&e->le);
+ mem_deref(e->key);
+}
+
+
+int odict_entry_add(struct odict *o, const char *key,
+ int type, ...)
+{
+ struct odict_entry *e;
+ va_list ap;
+ int err;
+
+ if (!o || !key)
+ return EINVAL;
+
+ e = mem_zalloc(sizeof(*e), destructor);
+ if (!e)
+ return ENOMEM;
+
+ e->type = type;
+
+ err = str_dup(&e->key, key);
+ if (err)
+ goto out;
+
+ va_start(ap, type);
+
+ switch (e->type) {
+
+ case ODICT_OBJECT:
+ case ODICT_ARRAY:
+ e->u.odict = mem_ref(va_arg(ap, struct odict *));
+ break;
+
+ case ODICT_STRING:
+ err = str_dup(&e->u.str, va_arg(ap, const char *));
+ break;
+
+ case ODICT_INT:
+ e->u.integer = va_arg(ap, int64_t);
+ break;
+
+ case ODICT_DOUBLE:
+ e->u.dbl = va_arg(ap, double);
+ break;
+
+ case ODICT_BOOL:
+ e->u.boolean = va_arg(ap, int);
+ break;
+
+ case ODICT_NULL:
+ break;
+
+ default:
+ err = EINVAL;
+ break;
+ }
+
+ va_end(ap);
+
+ if (err)
+ goto out;
+
+ list_append(&o->lst, &e->le, e);
+ hash_append(o->ht, hash_fast_str(e->key), &e->he, e);
+
+ out:
+ if (err)
+ mem_deref(e);
+
+ return err;
+}
+
+
+void odict_entry_del(struct odict *o, const char *key)
+{
+ mem_deref((struct odict_entry *)odict_lookup(o, key));
+}
+
+
+int odict_entry_debug(struct re_printf *pf, const struct odict_entry *e)
+{
+ int err;
+
+ if (!e)
+ return 0;
+
+ err = re_hprintf(pf, "%s", e->key);
+
+ switch (e->type) {
+
+ case ODICT_OBJECT:
+ case ODICT_ARRAY:
+ err |= re_hprintf(pf, ":%H", odict_debug, e->u.odict);
+ break;
+
+ case ODICT_STRING:
+ err |= re_hprintf(pf, ":%s", e->u.str);
+ break;
+
+ case ODICT_INT:
+ err |= re_hprintf(pf, ":%lli", e->u.integer);
+ break;
+
+ case ODICT_DOUBLE:
+ err |= re_hprintf(pf, ":%f", e->u.dbl);
+ break;
+
+ case ODICT_BOOL:
+ err |= re_hprintf(pf, ":%s", e->u.boolean ? "true" : "false");
+ break;
+
+ case ODICT_NULL:
+ break;
+ }
+
+ return err;
+}