Rename bt_object to bt_value
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 23 Jul 2015 21:11:27 +0000 (17:11 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 28 Jul 2015 18:44:16 +0000 (14:44 -0400)
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
20 files changed:
formats/ctf/ir/attributes.c
formats/ctf/ir/event.c
formats/ctf/ir/trace.c
include/Makefile.am
include/babeltrace/ctf-ir/attributes-internal.h
include/babeltrace/ctf-ir/event-internal.h
include/babeltrace/ctf-ir/event.h
include/babeltrace/ctf-ir/trace-internal.h
include/babeltrace/ctf-ir/trace.h
include/babeltrace/ctf-ir/utils.h
include/babeltrace/objects.h [deleted file]
include/babeltrace/values.h [new file with mode: 0644]
lib/Makefile.am
lib/objects.c [deleted file]
lib/values.c [new file with mode: 0644]
tests/lib/Makefile.am
tests/lib/test_bt_objects.c [deleted file]
tests/lib/test_bt_values.c [new file with mode: 0644]
tests/lib/test_ctf_writer.c
tests/tests

index 619b28edba5abf9864a8d39420c40cd990136961..409ae6bb59b496f41f6c4ec819175b07401b8f8d 100644 (file)
  */
 
 #include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/objects.h>
+#include <babeltrace/values.h>
 
 #define BT_CTF_ATTR_NAME_INDEX         0
 #define BT_CTF_ATTR_VALUE_INDEX        1
 
 BT_HIDDEN
-struct bt_object *bt_ctf_attributes_create(void)
+struct bt_value *bt_ctf_attributes_create(void)
 {
        /*
-        * Attributes: array object of array objects, each one
-        * containing two entries: a string object (attributes field
-        * name), and an object (attributes field value).
+        * Attributes: array value object of array value objects, each one
+        * containing two entries: a string value object (attributes
+        * field name), and a value object (attributes field value).
         *
         * Example (JSON representation):
         *
@@ -48,96 +48,96 @@ struct bt_object *bt_ctf_attributes_create(void)
         *         ["tracer_minor", 5]
         *     ]
         */
-       return bt_object_array_create();
+       return bt_value_array_create();
 }
 
 BT_HIDDEN
-void bt_ctf_attributes_destroy(struct bt_object *attr_obj)
+void bt_ctf_attributes_destroy(struct bt_value *attr_obj)
 {
-       bt_object_put(attr_obj);
+       bt_value_put(attr_obj);
 }
 
 BT_HIDDEN
-int bt_ctf_attributes_get_count(struct bt_object *attr_obj)
+int bt_ctf_attributes_get_count(struct bt_value *attr_obj)
 {
-       return bt_object_array_size(attr_obj);
+       return bt_value_array_size(attr_obj);
 }
 
 BT_HIDDEN
-const char *bt_ctf_attributes_get_field_name(struct bt_object *attr_obj,
+const char *bt_ctf_attributes_get_field_name(struct bt_value *attr_obj,
                int index)
 {
        int rc;
        const char *ret = NULL;
-       struct bt_object *attr_field_obj = NULL;
-       struct bt_object *attr_field_name_obj = NULL;
+       struct bt_value *attr_field_obj = NULL;
+       struct bt_value *attr_field_name_obj = NULL;
 
        if (!attr_obj || index < 0) {
                goto end;
        }
 
-       attr_field_obj = bt_object_array_get(attr_obj, index);
+       attr_field_obj = bt_value_array_get(attr_obj, index);
 
        if (!attr_field_obj) {
                goto end;
        }
 
-       attr_field_name_obj = bt_object_array_get(attr_field_obj,
+       attr_field_name_obj = bt_value_array_get(attr_field_obj,
                BT_CTF_ATTR_NAME_INDEX);
 
        if (!attr_field_name_obj) {
                goto end;
        }
 
-       rc = bt_object_string_get(attr_field_name_obj, &ret);
+       rc = bt_value_string_get(attr_field_name_obj, &ret);
 
        if (rc) {
                ret = NULL;
        }
 
 end:
-       BT_OBJECT_PUT(attr_field_name_obj);
-       BT_OBJECT_PUT(attr_field_obj);
+       BT_VALUE_PUT(attr_field_name_obj);
+       BT_VALUE_PUT(attr_field_obj);
 
        return ret;
 }
 
 BT_HIDDEN
-struct bt_object *bt_ctf_attributes_get_field_value(struct bt_object *attr_obj,
+struct bt_value *bt_ctf_attributes_get_field_value(struct bt_value *attr_obj,
                int index)
 {
-       struct bt_object *value_obj = NULL;
-       struct bt_object *attr_field_obj = NULL;
+       struct bt_value *value_obj = NULL;
+       struct bt_value *attr_field_obj = NULL;
 
        if (!attr_obj || index < 0) {
                goto end;
        }
 
-       attr_field_obj = bt_object_array_get(attr_obj, index);
+       attr_field_obj = bt_value_array_get(attr_obj, index);
 
        if (!attr_field_obj) {
                goto end;
        }
 
-       value_obj = bt_object_array_get(attr_field_obj,
+       value_obj = bt_value_array_get(attr_field_obj,
                BT_CTF_ATTR_VALUE_INDEX);
 
 end:
-       BT_OBJECT_PUT(attr_field_obj);
+       BT_VALUE_PUT(attr_field_obj);
 
        return value_obj;
 }
 
 static
-struct bt_object *bt_ctf_attributes_get_field_by_name(
-               struct bt_object *attr_obj, const char *name)
+struct bt_value *bt_ctf_attributes_get_field_by_name(
+               struct bt_value *attr_obj, const char *name)
 {
        int i;
        int attr_size;
-       struct bt_object *value_obj = NULL;
-       struct bt_object *attr_field_name_obj = NULL;
+       struct bt_value *value_obj = NULL;
+       struct bt_value *attr_field_name_obj = NULL;
 
-       attr_size = bt_object_array_size(attr_obj);
+       attr_size = bt_value_array_size(attr_obj);
 
        if (attr_size < 0) {
                goto error;
@@ -147,47 +147,47 @@ struct bt_object *bt_ctf_attributes_get_field_by_name(
                int ret;
                const char *field_name;
 
-               value_obj = bt_object_array_get(attr_obj, i);
+               value_obj = bt_value_array_get(attr_obj, i);
 
                if (!value_obj) {
                        goto error;
                }
 
-               attr_field_name_obj = bt_object_array_get(value_obj, 0);
+               attr_field_name_obj = bt_value_array_get(value_obj, 0);
 
                if (!attr_field_name_obj) {
                        goto error;
                }
 
-               ret = bt_object_string_get(attr_field_name_obj, &field_name);
+               ret = bt_value_string_get(attr_field_name_obj, &field_name);
                if (ret) {
                        goto error;
                }
 
                if (!strcmp(field_name, name)) {
-                       BT_OBJECT_PUT(attr_field_name_obj);
+                       BT_VALUE_PUT(attr_field_name_obj);
                        break;
                }
 
-               BT_OBJECT_PUT(attr_field_name_obj);
-               BT_OBJECT_PUT(value_obj);
+               BT_VALUE_PUT(attr_field_name_obj);
+               BT_VALUE_PUT(value_obj);
        }
 
        return value_obj;
 
 error:
-       BT_OBJECT_PUT(attr_field_name_obj);
-       BT_OBJECT_PUT(value_obj);
+       BT_VALUE_PUT(attr_field_name_obj);
+       BT_VALUE_PUT(value_obj);
 
        return value_obj;
 }
 
 BT_HIDDEN
-int bt_ctf_attributes_set_field_value(struct bt_object *attr_obj,
-               const char *name, struct bt_object *value_obj)
+int bt_ctf_attributes_set_field_value(struct bt_value *attr_obj,
+               const char *name, struct bt_value *value_obj)
 {
        int ret = 0;
-       struct bt_object *attr_field_obj = NULL;
+       struct bt_value *attr_field_obj = NULL;
 
        if (!attr_obj || !name || !value_obj) {
                ret = -1;
@@ -197,39 +197,39 @@ int bt_ctf_attributes_set_field_value(struct bt_object *attr_obj,
        attr_field_obj = bt_ctf_attributes_get_field_by_name(attr_obj, name);
 
        if (attr_field_obj) {
-               ret = bt_object_array_set(attr_field_obj,
+               ret = bt_value_array_set(attr_field_obj,
                        BT_CTF_ATTR_VALUE_INDEX, value_obj);
                goto end;
        }
 
-       attr_field_obj = bt_object_array_create();
+       attr_field_obj = bt_value_array_create();
 
        if (!attr_field_obj) {
                ret = -1;
                goto end;
        }
 
-       ret = bt_object_array_append_string(attr_field_obj, name);
-       ret |= bt_object_array_append(attr_field_obj, value_obj);
+       ret = bt_value_array_append_string(attr_field_obj, name);
+       ret |= bt_value_array_append(attr_field_obj, value_obj);
 
        if (ret) {
                goto end;
        }
 
-       ret = bt_object_array_append(attr_obj, attr_field_obj);
+       ret = bt_value_array_append(attr_obj, attr_field_obj);
 
 end:
-       BT_OBJECT_PUT(attr_field_obj);
+       BT_VALUE_PUT(attr_field_obj);
 
        return ret;
 }
 
 BT_HIDDEN
-struct bt_object *bt_ctf_attributes_get_field_value_by_name(
-               struct bt_object *attr_obj, const char *name)
+struct bt_value *bt_ctf_attributes_get_field_value_by_name(
+               struct bt_value *attr_obj, const char *name)
 {
-       struct bt_object *value_obj = NULL;
-       struct bt_object *attr_field_obj = NULL;
+       struct bt_value *value_obj = NULL;
+       struct bt_value *attr_field_obj = NULL;
 
        if (!attr_obj || !name) {
                goto end;
@@ -241,17 +241,17 @@ struct bt_object *bt_ctf_attributes_get_field_value_by_name(
                goto end;
        }
 
-       value_obj = bt_object_array_get(attr_field_obj,
+       value_obj = bt_value_array_get(attr_field_obj,
                BT_CTF_ATTR_VALUE_INDEX);
 
 end:
-       BT_OBJECT_PUT(attr_field_obj);
+       BT_VALUE_PUT(attr_field_obj);
 
        return value_obj;
 }
 
 BT_HIDDEN
-int bt_ctf_attributes_freeze(struct bt_object *attr_obj)
+int bt_ctf_attributes_freeze(struct bt_value *attr_obj)
 {
        int i;
        int count;
@@ -262,7 +262,7 @@ int bt_ctf_attributes_freeze(struct bt_object *attr_obj)
                goto end;
        }
 
-       count = bt_object_array_size(attr_obj);
+       count = bt_value_array_size(attr_obj);
 
        if (count < 0) {
                ret = -1;
@@ -270,12 +270,12 @@ int bt_ctf_attributes_freeze(struct bt_object *attr_obj)
        }
 
        /*
-        * We do not freeze the array itself here, since internal
-        * stuff could need to modify/add attributes. Each attribute
-        * is frozen one by one.
+        * We do not freeze the array value object itself here, since
+        * internal stuff could need to modify/add attributes. Each
+        * attribute is frozen one by one.
         */
        for (i = 0; i < count; ++i) {
-               struct bt_object *obj = NULL;
+               struct bt_value *obj = NULL;
 
                obj = bt_ctf_attributes_get_field_value(attr_obj, i);
 
@@ -284,8 +284,8 @@ int bt_ctf_attributes_freeze(struct bt_object *attr_obj)
                        goto end;
                }
 
-               bt_object_freeze(obj);
-               BT_OBJECT_PUT(obj);
+               bt_value_freeze(obj);
+               BT_VALUE_PUT(obj);
        }
 
 end:
index 6cb9f2d5c33685b3d08c90fe12b299bcf2d44d4a..82499417477c977ae949bae9180219686e8e0ba7 100644 (file)
@@ -51,7 +51,7 @@ int set_integer_field_value(struct bt_ctf_field *field, uint64_t value);
 struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
 {
        int ret;
-       struct bt_object *obj = NULL;
+       struct bt_value *obj = NULL;
        struct bt_ctf_event_class *event_class = NULL;
 
        if (bt_ctf_validate_identifier(name)) {
@@ -74,7 +74,7 @@ struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
                goto error;
        }
 
-       obj = bt_object_integer_create_init(-1);
+       obj = bt_value_integer_create_init(-1);
        if (!obj) {
                goto error;
        }
@@ -85,9 +85,9 @@ struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
                goto error;
        }
 
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
-       obj = bt_object_string_create_init(name);
+       obj = bt_value_string_create_init(name);
        if (!obj) {
                goto error;
        }
@@ -98,7 +98,7 @@ struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
                goto error;
        }
 
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        return event_class;
 
@@ -107,14 +107,14 @@ error:
                bt_ctf_event_class_put(event_class);
        }
 
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        return NULL;
 }
 
 const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
 {
-       struct bt_object *obj = NULL;
+       struct bt_value *obj = NULL;
        const char *name = NULL;
 
        if (!event_class) {
@@ -127,19 +127,19 @@ const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
                goto end;
        }
 
-       if (bt_object_string_get(obj, &name)) {
+       if (bt_value_string_get(obj, &name)) {
                name = NULL;
        }
 
 end:
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        return name;
 }
 
 int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
 {
-       struct bt_object *obj = NULL;
+       struct bt_value *obj = NULL;
        int64_t ret = 0;
 
        if (!event_class) {
@@ -153,7 +153,7 @@ int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
                goto end;
        }
 
-       if (bt_object_integer_get(obj, &ret)) {
+       if (bt_value_integer_get(obj, &ret)) {
                ret = -1;
        }
 
@@ -164,7 +164,7 @@ int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
        }
 
 end:
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        return ret;
 }
@@ -173,7 +173,7 @@ int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
                uint32_t id)
 {
        int ret = 0;
-       struct bt_object *obj = NULL;
+       struct bt_value *obj = NULL;
 
        if (!event_class) {
                ret = -1;
@@ -195,20 +195,20 @@ int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
                goto end;
        }
 
-       if (bt_object_integer_set(obj, id)) {
+       if (bt_value_integer_set(obj, id)) {
                ret = -1;
                goto end;
        }
 
 end:
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        return ret;
 }
 
 int bt_ctf_event_class_set_attribute(
                struct bt_ctf_event_class *event_class, const char *name,
-               struct bt_object *value)
+               struct bt_value *value)
 {
        int ret = 0;
 
@@ -218,12 +218,12 @@ int bt_ctf_event_class_set_attribute(
        }
 
        if (!strcmp(name, "id") || !strcmp(name, "loglevel")) {
-               if (!bt_object_is_integer(value)) {
+               if (!bt_value_is_integer(value)) {
                        ret = -1;
                        goto end;
                }
        } else if (!strcmp(name, "name") || !strcmp(name, "model.emf.uri")) {
-               if (!bt_object_is_string(value)) {
+               if (!bt_value_is_string(value)) {
                        ret = -1;
                        goto end;
                }
@@ -237,7 +237,7 @@ int bt_ctf_event_class_set_attribute(
        if (!strcmp(name, "id")) {
                int64_t val;
 
-               ret = bt_object_integer_get(value, &val);
+               ret = bt_value_integer_get(value, &val);
 
                if (ret) {
                        goto end;
@@ -289,11 +289,11 @@ end:
        return ret;
 }
 
-struct bt_object *
+struct bt_value *
 bt_ctf_event_class_get_attribute_value(struct bt_ctf_event_class *event_class,
                int index)
 {
-       struct bt_object *ret;
+       struct bt_value *ret;
 
        if (!event_class) {
                ret = NULL;
@@ -306,11 +306,11 @@ end:
        return ret;
 }
 
-struct bt_object *
+struct bt_value *
 bt_ctf_event_class_get_attribute_value_by_name(
                struct bt_ctf_event_class *event_class, const char *name)
 {
-       struct bt_object *ret;
+       struct bt_value *ret;
 
        if (!event_class || !name) {
                ret = NULL;
@@ -525,9 +525,9 @@ int bt_ctf_event_class_set_stream_id(struct bt_ctf_event_class *event_class,
                uint32_t stream_id)
 {
        int ret = 0;
-       struct bt_object *obj;
+       struct bt_value *obj;
 
-       obj = bt_object_integer_create_init(stream_id);
+       obj = bt_value_integer_create_init(stream_id);
 
        if (!obj) {
                ret = -1;
@@ -538,7 +538,7 @@ int bt_ctf_event_class_set_stream_id(struct bt_ctf_event_class *event_class,
                "stream_id", obj);
 
 end:
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        return ret;
 }
@@ -1031,7 +1031,7 @@ int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
        int i;
        int count;
        int ret = 0;
-       struct bt_object *attr_value = NULL;
+       struct bt_value *attr_value = NULL;
 
        assert(event_class);
        assert(context);
@@ -1059,12 +1059,12 @@ int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
                        goto end;
                }
 
-               switch (bt_object_get_type(attr_value)) {
-               case BT_OBJECT_TYPE_INTEGER:
+               switch (bt_value_get_type(attr_value)) {
+               case BT_VALUE_TYPE_INTEGER:
                {
                        int64_t value;
 
-                       ret = bt_object_integer_get(attr_value, &value);
+                       ret = bt_value_integer_get(attr_value, &value);
 
                        if (ret) {
                                goto end;
@@ -1075,11 +1075,11 @@ int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
                        break;
                }
 
-               case BT_OBJECT_TYPE_STRING:
+               case BT_VALUE_TYPE_STRING:
                {
                        const char *value;
 
-                       ret = bt_object_string_get(attr_value, &value);
+                       ret = bt_value_string_get(attr_value, &value);
 
                        if (ret) {
                                goto end;
@@ -1096,7 +1096,7 @@ int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
                        break;
                }
 
-               BT_OBJECT_PUT(attr_value);
+               BT_VALUE_PUT(attr_value);
        }
 
        if (event_class->context) {
@@ -1121,7 +1121,7 @@ int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
        g_string_append(context->string, "};\n\n");
 end:
        context->current_indentation_level = 0;
-       BT_OBJECT_PUT(attr_value);
+       BT_VALUE_PUT(attr_value);
        return ret;
 }
 
index d5786d337251dff7c0e2f660ee5a5e7edad89ad2..8ff6371b516b20babfa25731e7c67ab80bde3b00 100644 (file)
@@ -38,7 +38,7 @@
 #include <babeltrace/ctf-ir/ref.h>
 #include <babeltrace/ctf-ir/common-internal.h>
 #include <babeltrace/compiler.h>
-#include <babeltrace/objects.h>
+#include <babeltrace/values.h>
 
 #define DEFAULT_IDENTIFIER_SIZE 128
 #define DEFAULT_METADATA_STRING_SIZE 4096
@@ -188,13 +188,13 @@ error:
 }
 
 int bt_ctf_trace_set_environment_field(struct bt_ctf_trace *trace,
-               const char *name, struct bt_object *value)
+               const char *name, struct bt_value *value)
 {
        int ret = 0;
 
        if (!trace || !name || !value ||
                bt_ctf_validate_identifier(name) ||
-               !(bt_object_is_integer(value) || bt_object_is_string(value))) {
+               !(bt_value_is_integer(value) || bt_value_is_string(value))) {
                ret = -1;
                goto end;
        }
@@ -211,17 +211,17 @@ int bt_ctf_trace_set_environment_field(struct bt_ctf_trace *trace,
                 *
                 * The object passed is frozen like all other attributes.
                 */
-               struct bt_object *attribute =
+               struct bt_value *attribute =
                        bt_ctf_attributes_get_field_value_by_name(
                                trace->environment, name);
 
                if (attribute) {
-                       BT_OBJECT_PUT(attribute);
+                       BT_VALUE_PUT(attribute);
                        ret = -1;
                        goto end;
                }
 
-               bt_object_freeze(value);
+               bt_value_freeze(value);
        }
 
        ret = bt_ctf_attributes_set_field_value(trace->environment, name,
@@ -235,7 +235,7 @@ int bt_ctf_trace_set_environment_field_string(struct bt_ctf_trace *trace,
                const char *name, const char *value)
 {
        int ret = 0;
-       struct bt_object *env_value_string_obj = NULL;
+       struct bt_value *env_value_string_obj = NULL;
 
        if (!trace || !name || !value) {
                ret = -1;
@@ -247,18 +247,18 @@ int bt_ctf_trace_set_environment_field_string(struct bt_ctf_trace *trace,
                 * New environment fields may be added to a frozen trace,
                 * but existing fields may not be changed.
                 */
-               struct bt_object *attribute =
+               struct bt_value *attribute =
                        bt_ctf_attributes_get_field_value_by_name(
                                trace->environment, name);
 
                if (attribute) {
-                       BT_OBJECT_PUT(attribute);
+                       BT_VALUE_PUT(attribute);
                        ret = -1;
                        goto end;
                }
        }
 
-       env_value_string_obj = bt_object_string_create_init(value);
+       env_value_string_obj = bt_value_string_create_init(value);
 
        if (!env_value_string_obj) {
                ret = -1;
@@ -266,13 +266,13 @@ int bt_ctf_trace_set_environment_field_string(struct bt_ctf_trace *trace,
        }
 
        if (trace->frozen) {
-               bt_object_freeze(env_value_string_obj);
+               bt_value_freeze(env_value_string_obj);
        }
        ret = bt_ctf_trace_set_environment_field(trace, name,
                env_value_string_obj);
 
 end:
-       BT_OBJECT_PUT(env_value_string_obj);
+       BT_VALUE_PUT(env_value_string_obj);
 
        return ret;
 }
@@ -281,7 +281,7 @@ int bt_ctf_trace_set_environment_field_integer(struct bt_ctf_trace *trace,
                const char *name, int64_t value)
 {
        int ret = 0;
-       struct bt_object *env_value_integer_obj = NULL;
+       struct bt_value *env_value_integer_obj = NULL;
 
        if (!trace || !name) {
                ret = -1;
@@ -293,18 +293,18 @@ int bt_ctf_trace_set_environment_field_integer(struct bt_ctf_trace *trace,
                 * New environment fields may be added to a frozen trace,
                 * but existing fields may not be changed.
                 */
-               struct bt_object *attribute =
+               struct bt_value *attribute =
                        bt_ctf_attributes_get_field_value_by_name(
                                trace->environment, name);
 
                if (attribute) {
-                       BT_OBJECT_PUT(attribute);
+                       BT_VALUE_PUT(attribute);
                        ret = -1;
                        goto end;
                }
        }
 
-       env_value_integer_obj = bt_object_integer_create_init(value);
+       env_value_integer_obj = bt_value_integer_create_init(value);
        if (!env_value_integer_obj) {
                ret = -1;
                goto end;
@@ -313,10 +313,10 @@ int bt_ctf_trace_set_environment_field_integer(struct bt_ctf_trace *trace,
        ret = bt_ctf_trace_set_environment_field(trace, name,
                env_value_integer_obj);
        if (trace->frozen) {
-               bt_object_freeze(env_value_integer_obj);
+               bt_value_freeze(env_value_integer_obj);
        }
 end:
-       BT_OBJECT_PUT(env_value_integer_obj);
+       BT_VALUE_PUT(env_value_integer_obj);
 
        return ret;
 }
@@ -352,10 +352,10 @@ end:
        return ret;
 }
 
-struct bt_object *bt_ctf_trace_get_environment_field_value(
+struct bt_value *bt_ctf_trace_get_environment_field_value(
                struct bt_ctf_trace *trace, int index)
 {
-       struct bt_object *ret = NULL;
+       struct bt_value *ret = NULL;
 
        if (!trace) {
                goto end;
@@ -367,10 +367,10 @@ end:
        return ret;
 }
 
-struct bt_object *bt_ctf_trace_get_environment_field_value_by_name(
+struct bt_value *bt_ctf_trace_get_environment_field_value_by_name(
                struct bt_ctf_trace *trace, const char *name)
 {
-       struct bt_object *ret = NULL;
+       struct bt_value *ret = NULL;
 
        if (!trace || !name) {
                goto end;
@@ -649,7 +649,7 @@ void append_env_metadata(struct bt_ctf_trace *trace,
        g_string_append(context->string, "env {\n");
 
        for (i = 0; i < env_size; ++i) {
-               struct bt_object *env_field_value_obj = NULL;
+               struct bt_value *env_field_value_obj = NULL;
                const char *entry_name;
 
                entry_name = bt_ctf_attributes_get_field_name(
@@ -661,13 +661,13 @@ void append_env_metadata(struct bt_ctf_trace *trace,
                        goto loop_next;
                }
 
-               switch (bt_object_get_type(env_field_value_obj)) {
-               case BT_OBJECT_TYPE_INTEGER:
+               switch (bt_value_get_type(env_field_value_obj)) {
+               case BT_VALUE_TYPE_INTEGER:
                {
                        int ret;
                        int64_t int_value;
 
-                       ret = bt_object_integer_get(env_field_value_obj,
+                       ret = bt_value_integer_get(env_field_value_obj,
                                &int_value);
 
                        if (ret) {
@@ -679,13 +679,13 @@ void append_env_metadata(struct bt_ctf_trace *trace,
                                int_value);
                        break;
                }
-               case BT_OBJECT_TYPE_STRING:
+               case BT_VALUE_TYPE_STRING:
                {
                        int ret;
                        const char *str_value;
                        char *escaped_str = NULL;
 
-                       ret = bt_object_string_get(env_field_value_obj,
+                       ret = bt_value_string_get(env_field_value_obj,
                                &str_value);
 
                        if (ret) {
@@ -709,7 +709,7 @@ void append_env_metadata(struct bt_ctf_trace *trace,
                }
 
 loop_next:
-               BT_OBJECT_PUT(env_field_value_obj);
+               BT_VALUE_PUT(env_field_value_obj);
        }
 
        g_string_append(context->string, "};\n\n");
index b70ee7e63c7462a634b32f8ed135d4fddebf5124..b852ed1587806cacd8bf3adb7ed4785f80946849 100644 (file)
@@ -6,7 +6,7 @@ babeltraceinclude_HEADERS = \
        babeltrace/trace-handle.h \
        babeltrace/list.h \
        babeltrace/clock-types.h \
-       babeltrace/objects.h
+       babeltrace/values.h
 
 babeltracectfinclude_HEADERS = \
        babeltrace/ctf/events.h \
index e383c28dcea094d992c84053101f52218f4aa992..b6a15a8c97e68b31775350b0e08a8eb746dc1652 100644 (file)
@@ -33,35 +33,35 @@ extern "C" {
 #endif
 
 #include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/objects.h>
+#include <babeltrace/values.h>
 
 BT_HIDDEN
-struct bt_object *bt_ctf_attributes_create(void);
+struct bt_value *bt_ctf_attributes_create(void);
 
 BT_HIDDEN
-void bt_ctf_attributes_destroy(struct bt_object *attr_obj);
+void bt_ctf_attributes_destroy(struct bt_value *attr_obj);
 
 BT_HIDDEN
-int bt_ctf_attributes_get_count(struct bt_object *attr_obj);
+int bt_ctf_attributes_get_count(struct bt_value *attr_obj);
 
 BT_HIDDEN
-const char *bt_ctf_attributes_get_field_name(struct bt_object *attr_obj,
+const char *bt_ctf_attributes_get_field_name(struct bt_value *attr_obj,
                int index);
 
 BT_HIDDEN
-struct bt_object *bt_ctf_attributes_get_field_value(struct bt_object *attr_obj,
+struct bt_value *bt_ctf_attributes_get_field_value(struct bt_value *attr_obj,
                int index);
 
 BT_HIDDEN
-int bt_ctf_attributes_set_field_value(struct bt_object *attr_obj,
-               const char *name, struct bt_object *value_obj);
+int bt_ctf_attributes_set_field_value(struct bt_value *attr_obj,
+               const char *name, struct bt_value *value_obj);
 
 BT_HIDDEN
-struct bt_object *bt_ctf_attributes_get_field_value_by_name(
-               struct bt_object *attr_obj, const char *name);
+struct bt_value *bt_ctf_attributes_get_field_value_by_name(
+               struct bt_value *attr_obj, const char *name);
 
 BT_HIDDEN
-int bt_ctf_attributes_freeze(struct bt_object *attr_obj);
+int bt_ctf_attributes_freeze(struct bt_value *attr_obj);
 
 #ifdef __cplusplus
 }
index 9b2e2075e77cb708313aa9d9926c5a259b8829a2..db98771f45e91f4d35774c00bae39da79e1a8747 100644 (file)
@@ -30,7 +30,7 @@
 #include <babeltrace/ctf-writer/event-types.h>
 #include <babeltrace/ctf-writer/event-fields.h>
 #include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/objects.h>
+#include <babeltrace/values.h>
 #include <babeltrace/ctf/types.h>
 #include <babeltrace/ctf-ir/stream-class.h>
 #include <babeltrace/ctf-ir/stream.h>
@@ -42,7 +42,7 @@
 
 struct bt_ctf_event_class {
        struct bt_ctf_base base;
-       struct bt_object *attributes;
+       struct bt_value *attributes;
        /*
         * Weak reference; an event class does not have ownership of a
         * stream class.
index 4c90a2eb5759c6bb2952de67bbe38dbcb03df4c2..e871902d043c096fb9be9515d3725d1b51751601 100644 (file)
@@ -32,7 +32,7 @@
 
 #include <stdint.h>
 #include <stddef.h>
-#include <babeltrace/objects.h>
+#include <babeltrace/values.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -118,7 +118,7 @@ extern int bt_ctf_event_class_set_id(
  */
 extern int bt_ctf_event_class_set_attribute(
                struct bt_ctf_event_class *event_class, const char *name,
-               struct bt_object *value);
+               struct bt_value *value);
 
 /*
  * bt_ctf_event_class_get_attribute_count: get the number of attributes
@@ -154,14 +154,14 @@ bt_ctf_event_class_get_attribute_name(
  *
  * Get an attribute's value (an object). The returned object's
  * reference count is incremented. When done with the object, the caller
- * must call bt_object_put() on it.
+ * must call bt_value_put() on it.
  *
  * @param event_class Event class.
  * @param index Index of the attribute.
  *
  * Returns the attribute's object value, NULL on error.
  */
-extern struct bt_object *
+extern struct bt_value *
 bt_ctf_event_class_get_attribute_value(struct bt_ctf_event_class *event_class,
                int index);
 
@@ -171,14 +171,14 @@ bt_ctf_event_class_get_attribute_value(struct bt_ctf_event_class *event_class,
  *
  * Get an attribute's value (an object) by its name. The returned object's
  * reference count is incremented. When done with the object, the caller
- * must call bt_object_put() on it.
+ * must call bt_value_put() on it.
  *
  * @param event_class Event class.
  * @param name Attribute's name
  *
  * Returns the attribute's object value, NULL on error.
  */
-extern struct bt_object *
+extern struct bt_value *
 bt_ctf_event_class_get_attribute_value_by_name(
                struct bt_ctf_event_class *event_class, const char *name);
 
index 4a76c1a187819342ea04268a6db8b69a37dc0c61..b8a3d8c821b024df11fa8c82b3f036d00b6db051 100644 (file)
@@ -32,7 +32,7 @@
 #include <babeltrace/ctf-ir/event-fields.h>
 #include <babeltrace/ctf-ir/common-internal.h>
 #include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/objects.h>
+#include <babeltrace/values.h>
 #include <glib.h>
 #include <sys/types.h>
 #include <uuid/uuid.h>
@@ -52,7 +52,7 @@ struct bt_ctf_trace {
        int frozen;
        uuid_t uuid;
        int byte_order; /* A value defined in Babeltrace's "endian.h" */
-       struct bt_object *environment;
+       struct bt_value *environment;
        GPtrArray *clocks; /* Array of pointers to bt_ctf_clock */
        GPtrArray *stream_classes; /* Array of ptrs to bt_ctf_stream_class */
        GPtrArray *streams; /* Array of ptrs to bt_ctf_stream */
index cc628a5b5240f804ab26666cabe0d7f2b938e72b..d85a4bead08185a57d2b01ac2d70c1a38766defc 100644 (file)
@@ -31,7 +31,7 @@
  */
 
 #include <babeltrace/ctf-ir/event-types.h>
-#include <babeltrace/objects.h>
+#include <babeltrace/values.h>
 #include <stdint.h>
 
 #ifdef __cplusplus
@@ -84,8 +84,8 @@ extern struct bt_ctf_stream *bt_ctf_trace_create_stream(
  * If a value exists in the environment for the specified name, it is
  * replaced by the new value.
  *
- * The value parameter _must_ be either an integer object or a
- * string object. Other object types are not supported.
+ * The value parameter _must_ be either an integer value object or a
+ * string value object. Other object types are not supported.
  *
  * @param trace Trace instance.
  * @param name Name of the environment field (will be copied).
@@ -95,7 +95,7 @@ extern struct bt_ctf_stream *bt_ctf_trace_create_stream(
  */
 extern int bt_ctf_trace_set_environment_field(
                struct bt_ctf_trace *trace, const char *name,
-               struct bt_object *value);
+               struct bt_value *value);
 
 /*
  * bt_ctf_trace_set_environment_field_string: sets a string environment
@@ -167,14 +167,14 @@ bt_ctf_trace_get_environment_field_name(struct bt_ctf_trace *trace,
  *
  * Get an environment field's value (an object). The returned object's
  * reference count is incremented. When done with the object, the caller
- * must call bt_object_put() on it.
+ * must call bt_value_put() on it.
  *
  * @param trace Trace instance.
  * @param index Index of the environment field.
  *
  * Returns the environment field's object value, NULL on error.
  */
-extern struct bt_object *
+extern struct bt_value *
 bt_ctf_trace_get_environment_field_value(struct bt_ctf_trace *trace,
                int index);
 
@@ -184,14 +184,14 @@ bt_ctf_trace_get_environment_field_value(struct bt_ctf_trace *trace,
  *
  * Get an environment field's value (an object) by its field name. The
  * returned object's reference count is incremented. When done with the
- * object, the caller must call bt_object_put() on it.
+ * object, the caller must call bt_value_put() on it.
  *
  * @param trace Trace instance.
  * @param name Environment field's name
  *
  * Returns the environment field's object value, NULL on error.
  */
-extern struct bt_object *
+extern struct bt_value *
 bt_ctf_trace_get_environment_field_value_by_name(struct bt_ctf_trace *trace,
                const char *name);
 
index e574bd60dd2517f5dead77dea85f876565543aa2..d661ed88f5f8dee4fa060fee506630209d2cc250 100644 (file)
@@ -34,8 +34,6 @@
 extern "C" {
 #endif
 
-#include <babeltrace/objects.h>
-
 /*
  * bt_ctf_validate_identifier: validate an identifier against the CTF spec.
  *
diff --git a/include/babeltrace/objects.h b/include/babeltrace/objects.h
deleted file mode 100644 (file)
index 420bd62..0000000
+++ /dev/null
@@ -1,1083 +0,0 @@
-#ifndef _BABELTRACE_OBJECTS_H
-#define _BABELTRACE_OBJECTS_H
-
-/*
- * Babeltrace
- *
- * Basic object system
- *
- * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
- * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/**
- * @file objects.h
- * @brief Basic object system
- *
- * This is a basic object system API. The following functions allow you
- * to create, modify, and destroy:
- *
- *   - \link bt_object_null null objects\endlink
- *   - \link bt_object_bool_create() boolean objects\endlink
- *   - \link bt_object_integer_create() integer objects\endlink
- *   - \link bt_object_float_create() floating point number
- *     objects\endlink
- *   - \link bt_object_string_create() string objects\endlink
- *   - \link bt_object_array_create() array objects\endlink,
- *     containing zero or more objects
- *   - \link bt_object_map_create() map objects\endlink, mapping
- *     string keys to objects
- *
- * All the object types above, except for null objects (which always
- * point to the same \link bt_object_null singleton\endlink), have a
- * reference count property. Once an object is created, its reference
- * count is set to 1. When \link bt_object_array_append() appending an
- * object to an array object\endlink, or \link bt_object_map_insert()
- * inserting an object into a map object\endlink, its reference count
- * is incremented, as well as when getting an object back from those
- * structures. The bt_object_get() and bt_object_put() functions exist
- * to deal with reference counting. Once you are done with an object,
- * pass it to bt_object_put().
- *
- * A common action with objects is to create or get one, do something
- * with it, and then put it. To avoid putting it a second time later
- * (if an error occurs, for example), the variable is often reset to
- * \c NULL after putting the object it points to. Since this is so
- * common, you can use the BT_OBJECT_PUT() macro, which does just that:
- *
- * \code{.c}
- *     struct bt_object *int_obj = bt_object_integer_create_init(34);
- *
- *     if (!int_obj) {
- *         goto error;
- *     }
- *
- *     // stuff, which could jump to error
- *
- *     BT_OBJECT_PUT(int_obj);
- *
- *     // stuff, which could jump to error
- *
- *     return 0;
- *
- * error:
- *     // safe, even if int_obj is NULL
- *     BT_OBJECT_PUT(int_obj);
- *
- *     // ...
- * \endcode
- *
- * Another common manipulation is to move the ownership of an object
- * from one variable to another: since the reference count is not
- * incremented, and since, to avoid errors, two variables should not
- * point to same object without each of them having their own reference,
- * it is best practice to set the original variable to \c NULL. This
- * too can be accomplished in a single step using the BT_OBJECT_MOVE()
- * macro:
- *
- * \code{.c}
- *     struct bt_object *int_obj2 = NULL;
- *     struct bt_object *int_obj = bt_object_integer_create_init(-23);
- *
- *     if (!int_obj) {
- *         goto error;
- *     }
- *
- *     // stuff, which could jump to error
- *
- *     BT_OBJECT_MOVE(int_obj2, int_obj);
- *
- *     // stuff, which could jump to error
- *
- *     return 0;
- *
- * error:
- *     // safe, since only one of int_obj/int_obj2 (or none)
- *     // points to the object
- *     BT_OBJECT_PUT(int_obj);
- *     BT_OBJECT_PUT(int_obj2);
- *
- *     // ...
- * \endcode
- *
- * Most functions return a status code, one of the values in
- * #bt_object_status.
- *
- * You can create a deep copy of any object using the bt_object_copy()
- * function. You can compare two given objects using
- * bt_object_compare().
- *
- * Any object may be frozen using bt_object_freeze(). You may get the
- * value of a frozen object, but you cannot modify it. Reference
- * counting still works on frozen objects. You may also copy and compare
- * frozen objects.
- *
- * @author     Philippe Proulx <pproulx@efficios.com>
- * @bug                No known bugs
- */
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Object type.
- */
-enum bt_object_type {
-       /** Unknown object, used as an error code. */
-       BT_OBJECT_TYPE_UNKNOWN =        -1,
-
-       /** Null object. */
-       BT_OBJECT_TYPE_NULL =           0,
-
-       /** Boolean object (holds \c true or \c false). */
-       BT_OBJECT_TYPE_BOOL =           1,
-
-       /** Integer object (holds a signed 64-bit integer value). */
-       BT_OBJECT_TYPE_INTEGER =        2,
-
-       /**
-        * Floating point number object (holds a \c double value).
-        */
-       BT_OBJECT_TYPE_FLOAT =          3,
-
-       /** String object. */
-       BT_OBJECT_TYPE_STRING =         4,
-
-       /** Array object. */
-       BT_OBJECT_TYPE_ARRAY =          5,
-
-       /** Map object. */
-       BT_OBJECT_TYPE_MAP =            6,
-};
-
-/**
- * Status code.
- */
-enum bt_object_status {
-       /** Object cannot be altered because it's frozen. */
-       BT_OBJECT_STATUS_FROZEN =       -4,
-
-       /** Operation cancelled. */
-       BT_OBJECT_STATUS_CANCELLED =    -3,
-
-       /** Invalid arguments. */
-       /* -22 for compatibility with -EINVAL */
-       BT_OBJECT_STATUS_INVAL =        -22,
-
-       /** General error. */
-       BT_OBJECT_STATUS_ERROR =        -1,
-
-       /** Okay, no error. */
-       BT_OBJECT_STATUS_OK =           0,
-};
-
-/**
- * Object.
- */
-struct bt_object;
-
-/**
- * The null object singleton.
- *
- * Use this everytime you need a null object.
- *
- * The null object singleton has no reference count; there's only one.
- * You may directly compare any object to the null object singleton to
- * find out if it's a null object, or otherwise use bt_object_is_null().
- *
- * The null object singleton is always frozen (see bt_object_freeze()
- * and bt_object_is_frozen()).
- *
- * Functions of this API return this when the object is actually a
- * null object (of type #BT_OBJECT_TYPE_NULL), whereas \c NULL means an
- * error of some sort.
- */
-extern struct bt_object *bt_object_null;
-
-/**
- * User function type for bt_object_map_foreach().
- *
- * \p object is a \em weak reference; you must pass it to
- * bt_object_get() to get your own reference.
- *
- * Return \c true to continue the loop, or \c false to break it.
- *
- * @param key          Key of map entry
- * @param object       Object of map entry (weak reference)
- * @param data         User data
- * @returns            \c true to continue the loop
- */
-typedef bool (* bt_object_map_foreach_cb)(const char *key,
-       struct bt_object *object, void *data);
-
-/**
- * Puts the object \p _object (calls bt_object_put() on it), and resets
- * the variable to \c NULL.
- *
- * This is something that is often done when putting and object;
- * resetting the variable to \c NULL makes sure it cannot be put a
- * second time later.
- *
- * @param _object      Object to put
- *
- * @see BT_OBJECT_MOVE() (moves an object from one variable to the other
- *                      without putting it)
- */
-#define BT_OBJECT_PUT(_object)                         \
-       do {                                            \
-               bt_object_put(_object);                 \
-               (_object) = NULL;                       \
-       } while (0)
-
-/**
- * Moves the object referenced by the variable \p _src_object to the
- * \p _dst_object variable, then resets \p _src_object to \c NULL.
- *
- * The object's reference count is <b>not changed</b>. Resetting
- * \p _src_object to \c NULL ensures the object will not be put
- * twice later; its ownership is indeed \em moved from the source
- * variable to the destination variable.
- *
- * @param _src_object  Source object variable
- * @param _dst_object  Destination object variable
- */
-#define BT_OBJECT_MOVE(_dst_object, _src_object)       \
-       do {                                            \
-               (_dst_object) = (_src_object);          \
-               (_src_object) = NULL;                   \
-       } while (0)
-
-/**
- * Increments the reference count of \p object.
- *
- * @param object       Object of which to increment the reference count
- *
- * @see bt_object_put()
- */
-extern void bt_object_get(struct bt_object *object);
-
-/**
- * Decrements the reference count of \p object, destroying it when this
- * count reaches 0.
- *
- * @param object       Object of which to decrement the reference count
- *
- * @see BT_OBJECT_PUT() (puts an object and resets the variable to
- *                     \c NULL)
- * @see bt_object_get()
- */
-extern void bt_object_put(struct bt_object *object);
-
-/**
- * Recursively freezes the object \p object.
- *
- * A frozen object cannot be modified; it is considered immutable.
- * Reference counting still works on a frozen object though: you may
- * pass a frozen object to bt_object_get() and bt_object_put().
- *
- * @param object       Object to freeze
- * @returns            One of #bt_object_status values; if \p object
- *                     is already frozen, though, #BT_OBJECT_STATUS_OK
- *                     is returned anyway (i.e. this function never
- *                     returns #BT_OBJECT_STATUS_FROZEN)
- *
- * @see bt_object_is_frozen()
- */
-extern enum bt_object_status bt_object_freeze(struct bt_object *object);
-
-/**
- * Checks whether \p object is frozen or not.
- *
- * @param object       Object to check
- * @returns            \c true if \p object is frozen
- *
- * @see bt_object_freeze()
- */
-extern bool bt_object_is_frozen(const struct bt_object *object);
-
-/**
- * Returns the type of \p object.
- *
- * @param object       Object of which to get the type
- * @returns            Object's type, or #BT_OBJECT_TYPE_UNKNOWN
- *                     on error
- *
- * @see #bt_object_type (object types)
- * @see bt_object_is_null()
- * @see bt_object_is_bool()
- * @see bt_object_is_integer()
- * @see bt_object_is_float()
- * @see bt_object_is_string()
- * @see bt_object_is_array()
- * @see bt_object_is_map()
- */
-extern enum bt_object_type bt_object_get_type(const struct bt_object *object);
-
-/**
- * Checks whether \p object is a null object. The only valid null
- * object is \ref bt_object_null.
- *
- * @param object       Object to check
- * @returns            \c true if \p object is a null object
- *
- * @see bt_object_get_type()
- */
-static inline
-bool bt_object_is_null(const struct bt_object *object)
-{
-       return bt_object_get_type(object) == BT_OBJECT_TYPE_NULL;
-}
-
-/**
- * Checks whether \p object is a boolean object.
- *
- * @param object       Object to check
- * @returns            \c true if \p object is a boolean object
- *
- * @see bt_object_get_type()
- */
-static inline
-bool bt_object_is_bool(const struct bt_object *object)
-{
-       return bt_object_get_type(object) == BT_OBJECT_TYPE_BOOL;
-}
-
-/**
- * Checks whether \p object is an integer object.
- *
- * @param object       Object to check
- * @returns            \c true if \p object is an integer object
- *
- * @see bt_object_get_type()
- */
-static inline
-bool bt_object_is_integer(const struct bt_object *object)
-{
-       return bt_object_get_type(object) == BT_OBJECT_TYPE_INTEGER;
-}
-
-/**
- * Checks whether \p object is a floating point number object.
- *
- * @param object       Object to check
- * @returns            \c true if \p object is a floating point
- *                     number object
- *
- * @see bt_object_get_type()
- */
-static inline
-bool bt_object_is_float(const struct bt_object *object)
-{
-       return bt_object_get_type(object) == BT_OBJECT_TYPE_FLOAT;
-}
-
-/**
- * Checks whether \p object is a string object.
- *
- * @param object       Object to check
- * @returns            \c true if \p object is a string object
- *
- * @see bt_object_get_type()
- */
-static inline
-bool bt_object_is_string(const struct bt_object *object)
-{
-       return bt_object_get_type(object) == BT_OBJECT_TYPE_STRING;
-}
-
-/**
- * Checks whether \p object is an array object.
- *
- * @param object       Object to check
- * @returns            \c true if \p object is an array object
- *
- * @see bt_object_get_type()
- */
-static inline
-bool bt_object_is_array(const struct bt_object *object)
-{
-       return bt_object_get_type(object) == BT_OBJECT_TYPE_ARRAY;
-}
-
-/**
- * Checks whether \p object is a map object.
- *
- * @param object       Object to check
- * @returns            \c true if \p object is a map object
- *
- * @see bt_object_get_type()
- */
-static inline
-bool bt_object_is_map(const struct bt_object *object)
-{
-       return bt_object_get_type(object) == BT_OBJECT_TYPE_MAP;
-}
-
-/**
- * Creates a boolean object. The created boolean object's initial value
- * is \c false.
- *
- * The created object's reference count is set to 1.
- *
- * @returns    Created object on success, or \c NULL on error
- *
- * @see bt_object_bool_create_init() (creates an initialized
- *                                  boolean object)
- */
-extern struct bt_object *bt_object_bool_create(void);
-
-/**
- * Creates a boolean object with its initial value set to \p val.
- *
- * The created object's reference count is set to 1.
- *
- * @param val  Initial value
- * @returns    Created object on success, or \c NULL on error
- */
-extern struct bt_object *bt_object_bool_create_init(bool val);
-
-/**
- * Creates an integer object. The created integer object's initial value
- * is 0.
- *
- * The created object's reference count is set to 1.
- *
- * @returns    Created object on success, or \c NULL on error
- *
- * @see bt_object_integer_create_init() (creates an initialized
- *                                     integer object)
- */
-extern struct bt_object *bt_object_integer_create(void);
-
-/**
- * Creates an integer object with its initial value set to \p val.
- *
- * The created object's reference count is set to 1.
- *
- * @param val  Initial value
- * @returns    Created object on success, or \c NULL on error
- */
-extern struct bt_object *bt_object_integer_create_init(int64_t val);
-
-/**
- * Creates a floating point number object. The created floating point
- * number object's initial value is 0.
- *
- * The created object's reference count is set to 1.
- *
- * @returns    Created object on success, or \c NULL on error
- *
- * @see bt_object_float_create_init() (creates an initialized floating
- *                                   point number object)
- */
-extern struct bt_object *bt_object_float_create(void);
-
-/**
- * Creates a floating point number object with its initial value set
- * to \p val.
- *
- * The created object's reference count is set to 1.
- *
- * @param val  Initial value
- * @returns    Created object on success, or \c NULL on error
- */
-extern struct bt_object *bt_object_float_create_init(double val);
-
-/**
- * Creates a string object. The string object is initially empty.
- *
- * The created object's reference count is set to 1.
- *
- * @returns    Created object on success, or \c NULL on error
- *
- * @see bt_object_string_create_init() (creates an initialized
- *                                    string object)
- */
-extern struct bt_object *bt_object_string_create(void);
-
-/**
- * Creates a string object with its initial value set to \p val.
- *
- * \p val is copied.
- *
- * The created object's reference count is set to 1.
- *
- * @param val  Initial value (will be copied)
- * @returns    Created object on success, or \c NULL on error
- */
-extern struct bt_object *bt_object_string_create_init(const char *val);
-
-/**
- * Creates an empty array object.
- *
- * The created object's reference count is set to 1.
- *
- * @returns    Created object on success, or \c NULL on error
- */
-extern struct bt_object *bt_object_array_create(void);
-
-/**
- * Creates an empty map object.
- *
- * The created object's reference count is set to 1.
- *
- * @returns    Created object on success, or \c NULL on error
- */
-extern struct bt_object *bt_object_map_create(void);
-
-/**
- * Gets the boolean value of the boolean object \p bool_obj.
- *
- * @param bool_obj     Boolean object
- * @param val          Returned boolean value
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_bool_set()
- */
-extern enum bt_object_status bt_object_bool_get(
-       const struct bt_object *bool_obj, bool *val);
-
-/**
- * Sets the boolean value of the boolean object \p bool_obj to \p val.
- *
- * @param bool_obj     Boolean object
- * @param val          New boolean value
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_bool_get()
- */
-extern enum bt_object_status bt_object_bool_set(struct bt_object *bool_obj,
-       bool val);
-
-/**
- * Gets the integer value of the integer object \p integer_obj.
- *
- * @param integer_obj  Integer object
- * @param val          Returned integer value
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_integer_set()
- */
-extern enum bt_object_status bt_object_integer_get(
-       const struct bt_object *integer_obj, int64_t *val);
-
-/**
- * Sets the integer value of the integer object \p integer_obj to
- * \p val.
- *
- * @param integer_obj  Integer object
- * @param val          New integer value
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_integer_get()
- */
-extern enum bt_object_status bt_object_integer_set(
-       struct bt_object *integer_obj, int64_t val);
-
-/**
- * Gets the floating point number value of the floating point number
- * object \p float_obj.
- *
- * @param float_obj    Floating point number object
- * @param val          Returned floating point number value
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_float_set()
- */
-extern enum bt_object_status bt_object_float_get(
-       const struct bt_object *float_obj, double *val);
-
-/**
- * Sets the floating point number value of the floating point number
- * object \p float_obj to \p val.
- *
- * @param float_obj    Floating point number object
- * @param val          New floating point number value
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_float_get()
- */
-extern enum bt_object_status bt_object_float_set(
-       struct bt_object *float_obj, double val);
-
-/**
- * Gets the string value of the string object \p string_obj. The
- * returned string is valid as long as this object exists and is not
- * modified. The ownership of the returned string is \em not
- * transferred to the caller.
- *
- * @param string_obj   String object
- * @param val          Returned string value
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_string_set()
- */
-extern enum bt_object_status bt_object_string_get(
-       const struct bt_object *string_obj, const char **val);
-
-/**
- * Sets the string value of the string object \p string_obj to
- * \p val.
- *
- * \p val is copied.
- *
- * @param string_obj   String object
- * @param val          New string value (copied)
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_string_get()
- */
-extern enum bt_object_status bt_object_string_set(struct bt_object *string_obj,
-       const char *val);
-
-/**
- * Gets the size of the array object \p array_obj, that is, the number
- * of elements contained in \p array_obj.
- *
- * @param array_obj    Array object
- * @returns            Array size if the return value is 0 (empty) or a
- *                     positive value, or one of
- *                     #bt_object_status negative values otherwise
- *
- * @see bt_object_array_is_empty()
- */
-extern int bt_object_array_size(const struct bt_object *array_obj);
-
-/**
- * Returns \c true if the array object \p array_obj.
- *
- * @param array_obj    Array object
- * @returns            \c true if \p array_obj is empty
- *
- * @see bt_object_array_size()
- */
-extern bool bt_object_array_is_empty(const struct bt_object *array_obj);
-
-/**
- * Gets the element object of the array object \p array_obj at the
- * index \p index.
- *
- * The returned object's reference count is incremented, unless it's
- * a null object.
- *
- * @param array_obj    Array object
- * @param index                Index of element to get
- * @returns            Element object at index \p index on success,
- *                     or \c NULL on error
- */
-extern struct bt_object *bt_object_array_get(const struct bt_object *array_obj,
-       size_t index);
-
-/**
- * Appends the element object \p element_obj to the array object
- * \p array_obj.
- *
- * The appended object's reference count is incremented, unless it's
- * a null object.
- *
- * @param array_obj    Array object
- * @param element_obj  Element object to append
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_array_append_bool()
- * @see bt_object_array_append_integer()
- * @see bt_object_array_append_float()
- * @see bt_object_array_append_string()
- * @see bt_object_array_append_array()
- * @see bt_object_array_append_map()
- */
-extern enum bt_object_status bt_object_array_append(struct bt_object *array_obj,
-       struct bt_object *element_obj);
-
-/**
- * Appends the boolean value \p val to the array object \p array_obj.
- * This is a convenience function which creates the underlying boolean
- * object before appending it.
- *
- * The created boolean object's reference count is set to 1.
- *
- * @param array_obj    Array object
- * @param val          Boolean value to append
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_array_append()
- */
-extern enum bt_object_status bt_object_array_append_bool(
-       struct bt_object *array_obj, bool val);
-
-/**
- * Appends the integer value \p val to the array object \p array_obj.
- * This is a convenience function which creates the underlying integer
- * object before appending it.
- *
- * The created integer object's reference count is set to 1.
- *
- * @param array_obj    Array object
- * @param val          Integer value to append
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_array_append()
- */
-extern enum bt_object_status bt_object_array_append_integer(
-       struct bt_object *array_obj, int64_t val);
-
-/**
- * Appends the floating point number value \p val to the array object
- * \p array_obj. This is a convenience function which creates the
- * underlying floating point number object before appending it.
- *
- * The created floating point number object's reference count is
- * set to 1.
- *
- * @param array_obj    Array object
- * @param val          Floating point number value to append
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_array_append()
- */
-extern enum bt_object_status bt_object_array_append_float(
-       struct bt_object *array_obj, double val);
-
-/**
- * Appends the string value \p val to the array object \p array_obj.
- * This is a convenience function which creates the underlying string
- * object before appending it.
- *
- * \p val is copied.
- *
- * The created string object's reference count is set to 1.
- *
- * @param array_obj    Array object
- * @param val          String value to append (copied)
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_array_append()
- */
-extern enum bt_object_status bt_object_array_append_string(
-       struct bt_object *array_obj, const char *val);
-
-/**
- * Appends an empty array object to the array object \p array_obj.
- * This is a convenience function which creates the underlying array
- * object before appending it.
- *
- * The created array object's reference count is set to 1.
- *
- * @param array_obj    Array object
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_array_append()
- */
-extern enum bt_object_status bt_object_array_append_array(
-       struct bt_object *array_obj);
-
-/**
- * Appends an empty map object to the array object \p array_obj. This
- * is a convenience function which creates the underlying map object
- * before appending it.
- *
- * The created map object's reference count is set to 1.
- *
- * @param array_obj    Array object
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_array_append()
- */
-extern enum bt_object_status bt_object_array_append_map(
-       struct bt_object *array_obj);
-
-/**
- * Replaces the element object at index \p index of the array object
- * \p array_obj by \p element_obj.
- *
- * The replaced object's reference count is decremented, unless it's
- * a null object. The reference count of \p element_obj is incremented,
- * unless it's a null object.
- *
- * @param array_obj    Array object
- * @param index                Index of element object to replace
- * @param element_obj  New element object at position \p index of
- *                     \p array_obj
- * @returns            One of #bt_object_status values
- */
-extern enum bt_object_status bt_object_array_set(struct bt_object *array_obj,
-       size_t index, struct bt_object *element_obj);
-
-/**
- * Gets the size of a map object, that is, the number of elements
- * contained in a map object.
- *
- * @param map_obj      Map object
- * @returns            Map size if the return value is 0 (empty) or a
- *                     positive value, or one of
- *                     #bt_object_status negative values otherwise
- *
- * @see bt_object_map_is_empty()
- */
-extern int bt_object_map_size(const struct bt_object *map_obj);
-
-/**
- * Returns \c true if the map object \p map_obj.
- *
- * @param map_obj      Map object
- * @returns            \c true if \p map_obj is empty
- *
- * @see bt_object_map_size()
- */
-extern bool bt_object_map_is_empty(const struct bt_object *map_obj);
-
-/**
- * Gets the element object associated with the key \p key within the
- * map object \p map_obj.
- *
- * The returned object's reference count is incremented, unless it's
- * a null object.
- *
- * @param map_obj      Map object
- * @param key          Key of the element to get
- * @returns            Element object associated with the key \p key
- *                     on success, or \c NULL on error
- */
-extern struct bt_object *bt_object_map_get(const struct bt_object *map_obj,
-       const char *key);
-
-/**
- * Calls a provided user function \p cb for each element of the map
- * object \p map_obj.
- *
- * The object passed to the user function is a <b>weak reference</b>:
- * you must call bt_object_get() on it to obtain your own reference.
- *
- * The key passed to the user function is only valid in the scope of
- * this user function.
- *
- * The user function must return \c true to continue the loop, or
- * \c false to break it.
- *
- * @param map_obj      Map object
- * @param cb           User function to call back
- * @param data         User data passed to the user function
- * @returns            One of #bt_object_status values; more
- *                     specifically, #BT_OBJECT_STATUS_CANCELLED is
- *                     returned if the loop was cancelled by the user
- *                     function
- */
-extern enum bt_object_status bt_object_map_foreach(
-       const struct bt_object *map_obj, bt_object_map_foreach_cb cb,
-       void *data);
-
-/**
- * Returns whether or not the map object \p map_obj contains the
- * key \p key.
- *
- * @param map_obj      Map object
- * @param key          Key to check
- * @returns            \c true if \p map_obj contains the key \p key,
- *                     or \c false if it doesn't have \p key or
- *                     on error
- */
-extern bool bt_object_map_has_key(const struct bt_object *map_obj,
-       const char *key);
-
-/**
- * Inserts the element object \p element_obj associated with the key
- * \p key into the map object \p map_obj. If \p key exists in
- * \p map_obj, the associated element object is first put, and then
- * replaced by \p element_obj.
- *
- * \p key is copied.
- *
- * The inserted object's reference count is incremented, unless it's
- * a null object.
- *
- * @param map_obj      Map object
- * @param key          Key (copied) of object to insert
- * @param element_obj  Element object to insert, associated with the
- *                     key \p key
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_map_insert_bool()
- * @see bt_object_map_insert_integer()
- * @see bt_object_map_insert_float()
- * @see bt_object_map_insert_string()
- * @see bt_object_map_insert_array()
- * @see bt_object_map_insert_map()
- */
-extern enum bt_object_status bt_object_map_insert(
-       struct bt_object *map_obj, const char *key,
-       struct bt_object *element_obj);
-
-/**
- * Inserts the boolean value \p val associated with the key \p key into
- * the map object \p map_obj. This is a convenience function which
- * creates the underlying boolean object before inserting it.
- *
- * \p key is copied.
- *
- * The created boolean object's reference count is set to 1.
- *
- * @param map_obj      Map object
- * @param key          Key (copied) of boolean value to insert
- * @param val          Boolean value to insert, associated with the
- *                     key \p key
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_map_insert()
- */
-extern enum bt_object_status bt_object_map_insert_bool(
-       struct bt_object *map_obj, const char *key, bool val);
-
-/**
- * Inserts the integer value \p val associated with the key \p key into
- * the map object \p map_obj. This is a convenience function which
- * creates the underlying integer object before inserting it.
- *
- * \p key is copied.
- *
- * The created integer object's reference count is set to 1.
- *
- * @param map_obj      Map object
- * @param key          Key (copied) of integer value to insert
- * @param val          Integer value to insert, associated with the
- *                     key \p key
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_map_insert()
- */
-extern enum bt_object_status bt_object_map_insert_integer(
-       struct bt_object *map_obj, const char *key, int64_t val);
-
-/**
- * Inserts the floating point number value \p val associated with the
- * key \p key into the map object \p map_obj. This is a convenience
- * function which creates the underlying floating point number object
- * before inserting it.
- *
- * \p key is copied.
- *
- * The created floating point number object's reference count is
- * set to 1.
- *
- * @param map_obj      Map object
- * @param key          Key (copied) of floating point number value to
- *                     insert
- * @param val          Floating point number value to insert,
- *                     associated with the key \p key
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_map_insert()
- */
-extern enum bt_object_status bt_object_map_insert_float(
-       struct bt_object *map_obj, const char *key, double val);
-
-/**
- * Inserts the string value \p val associated with the key \p key into
- * the map object \p map_obj. This is a convenience function which
- * creates the underlying string object before inserting it.
- *
- * \p val and \p key are copied.
- *
- * The created string object's reference count is set to 1.
- *
- * @param map_obj      Map object
- * @param key          Key (copied) of string value to insert
- * @param val          String value to insert, associated with the
- *                     key \p key
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_map_insert()
- */
-extern enum bt_object_status bt_object_map_insert_string(
-       struct bt_object *map_obj, const char *key, const char *val);
-
-/**
- * Inserts an empty array object associated with the key \p key into
- * the map object \p map_obj. This is a convenience function which
- * creates the underlying array object before inserting it.
- *
- * \p key is copied.
- *
- * The created array object's reference count is set to 1.
- *
- * @param map_obj      Map object
- * @param key          Key (copied) of empty array to insert
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_map_insert()
- */
-extern enum bt_object_status bt_object_map_insert_array(
-       struct bt_object *map_obj, const char *key);
-
-/**
- * Inserts an empty map object associated with the key \p key into
- * the map object \p map_obj. This is a convenience function which
- * creates the underlying map object before inserting it.
- *
- * \p key is copied.
- *
- * The created map object's reference count is set to 1.
- *
- * @param map_obj      Map object
- * @param key          Key (copied) of empty map to insert
- * @returns            One of #bt_object_status values
- *
- * @see bt_object_map_insert()
- */
-extern enum bt_object_status bt_object_map_insert_map(
-       struct bt_object *map_obj, const char *key);
-
-/**
- * Creates a deep copy of the object \p object.
- *
- * The created object's reference count is set to 1, unless
- * \p object is a null object.
- *
- * Copying a frozen object is allowed: the resulting copy is not frozen.
- *
- * @param object       Object to copy
- * @returns            Deep copy of \p object on success, or \c NULL
- *                     on error
- */
-extern struct bt_object *bt_object_copy(const struct bt_object *object);
-
-/**
- * Compares the objects \p object_a and \p object_b and returns \c true
- * if they have the same content.
- *
- * @param object_a     Object A
- * @param object_b     Object B
- * @returns            \c true if \p object_a and \p object_b have the
- *                     same content, or \c false if they differ or on
- *                     error
- */
-extern bool bt_object_compare(const struct bt_object *object_a,
-       const struct bt_object *object_b);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BABELTRACE_OBJECTS_H */
diff --git a/include/babeltrace/values.h b/include/babeltrace/values.h
new file mode 100644 (file)
index 0000000..c0a3fa4
--- /dev/null
@@ -0,0 +1,1032 @@
+#ifndef _BABELTRACE_VALUES_H
+#define _BABELTRACE_VALUES_H
+
+/*
+ * Babeltrace - Value objects
+ *
+ * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @file values.h
+ * @brief Value objects
+ *
+ * This is a set of value objects. The following functions allow you
+ * to create, modify, and destroy:
+ *
+ *   - \link bt_value_null null value objects\endlink
+ *   - \link bt_value_bool_create() boolean value objects\endlink
+ *   - \link bt_value_integer_create() integer value objects\endlink
+ *   - \link bt_value_float_create() floating point number
+ *     value objects\endlink
+ *   - \link bt_value_string_create() string value objects\endlink
+ *   - \link bt_value_array_create() array value objects\endlink,
+ *     containing zero or more value objects
+ *   - \link bt_value_map_create() map value objects\endlink, mapping
+ *     string keys to value objects
+ *
+ * All the value object types above, except for null values (which
+ * always point to the same \link bt_value_null singleton\endlink), have
+ * a reference count property. Once a value object is created, its
+ * reference count is set to 1. When \link bt_value_array_append()
+ * appending a value to an array value object\endlink, or
+ * \link bt_value_map_insert() inserting a value object into a map
+ * value object\endlink, its reference count is incremented, as well as
+ * when getting a value object back from those structures. The
+ * bt_value_get() and bt_value_put() functions exist to deal with
+ * reference counting. Once you are done with a value object, pass it to
+ * bt_value_put().
+ *
+ * Most functions of this API return a status code, one of the values in
+ * #bt_value_status.
+ *
+ * You can create a deep copy of any value object using the
+ * bt_value_copy() function. You can compare two given value objects
+ * using bt_value_compare().
+ *
+ * Any value object may be frozen using bt_value_freeze(). You may get
+ * the raw value of a frozen value object, but you cannot modify it.
+ * Reference counting still works on frozen value objects. You may also
+ * copy and compare frozen value objects.
+ *
+ * @author     Philippe Proulx <pproulx@efficios.com>
+ * @bug                No known bugs
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Value object type.
+ */
+enum bt_value_type {
+       /** Unknown value object, used as an error code. */
+       BT_VALUE_TYPE_UNKNOWN =         -1,
+
+       /** Null value object. */
+       BT_VALUE_TYPE_NULL =            0,
+
+       /** Boolean value object (holds \c true or \c false). */
+       BT_VALUE_TYPE_BOOL =            1,
+
+       /** Integer value object (holds a signed 64-bit integer raw value). */
+       BT_VALUE_TYPE_INTEGER =         2,
+
+       /** Floating point number value object (holds a \c double raw value). */
+       BT_VALUE_TYPE_FLOAT =           3,
+
+       /** String value object. */
+       BT_VALUE_TYPE_STRING =          4,
+
+       /** Array value object. */
+       BT_VALUE_TYPE_ARRAY =           5,
+
+       /** Map value object. */
+       BT_VALUE_TYPE_MAP =             6,
+};
+
+/**
+ * Status codes.
+ */
+enum bt_value_status {
+       /** Value object cannot be altered because it's frozen. */
+       BT_VALUE_STATUS_FROZEN =        -4,
+
+       /** Operation cancelled. */
+       BT_VALUE_STATUS_CANCELLED =     -3,
+
+       /** Invalid arguments. */
+       /* -22 for compatibility with -EINVAL */
+       BT_VALUE_STATUS_INVAL = -22,
+
+       /** General error. */
+       BT_VALUE_STATUS_ERROR = -1,
+
+       /** Okay, no error. */
+       BT_VALUE_STATUS_OK =            0,
+};
+
+/**
+ * Value object.
+ */
+struct bt_value;
+
+/**
+ * The null value object singleton.
+ *
+ * Use this everytime you need a null value object.
+ *
+ * The null value object singleton has no reference count; there's only
+ * one. You may directly compare any value object to the null value
+ * object singleton to find out if it's a null value object, or
+ * otherwise use bt_value_is_null().
+ *
+ * The null value object singleton is always frozen (see
+ * bt_value_freeze() and bt_value_is_frozen()).
+ *
+ * Functions of this API return this when the value object is actually a
+ * null value object (of type #BT_VALUE_TYPE_NULL), whereas \c NULL
+ * means an error of some sort.
+ */
+extern struct bt_value *bt_value_null;
+
+/**
+ * User function type for bt_value_map_foreach().
+ *
+ * \p object is a \em weak reference; you must pass it to
+ * bt_value_get() to get your own reference.
+ *
+ * Return \c true to continue the loop, or \c false to break it.
+ *
+ * @param key          Key of map entry
+ * @param object       Value object of map entry (weak reference)
+ * @param data         User data
+ * @returns            \c true to continue the loop
+ */
+typedef bool (* bt_value_map_foreach_cb)(const char *key,
+       struct bt_value *object, void *data);
+
+/**
+ * Puts the value object \p _object (calls bt_value_put() on it), and
+ * resets the variable to \c NULL.
+ *
+ * This is something that is often done when putting a value object;
+ * resetting the variable to \c NULL makes sure it cannot be put a
+ * second time later.
+ *
+ * @param _object      Value object to put
+ *
+ * @see BT_VALUE_MOVE() (moves a value object from one variable to the
+ *                     other without putting it)
+ */
+#define BT_VALUE_PUT(_object)                          \
+       do {                                            \
+               bt_value_put(_object);                  \
+               (_object) = NULL;                       \
+       } while (0)
+
+/**
+ * Moves the value object referenced by the variable \p _src_object to
+ * the \p _dst_object variable, then resets \p _src_object to \c NULL.
+ *
+ * The value object's reference count is <b>not changed</b>. Resetting
+ * \p _src_object to \c NULL ensures the value object will not be put
+ * twice later; its ownership is indeed \em moved from the source
+ * variable to the destination variable.
+ *
+ * @param _src_object  Source value object variable
+ * @param _dst_object  Destination value object variable
+ */
+#define BT_VALUE_MOVE(_dst_object, _src_object)        \
+       do {                                            \
+               (_dst_object) = (_src_object);          \
+               (_src_object) = NULL;                   \
+       } while (0)
+
+/**
+ * Increments the reference count of \p object.
+ *
+ * @param object       Value object of which to increment the reference count
+ *
+ * @see bt_value_put()
+ */
+extern void bt_value_get(struct bt_value *object);
+
+/**
+ * Decrements the reference count of \p object, destroying it when this
+ * count reaches 0.
+ *
+ * @param object       Value object of which to decrement the reference count
+ *
+ * @see bt_value_get()
+ */
+extern void bt_value_put(struct bt_value *object);
+
+/**
+ * Recursively freezes the value object \p object.
+ *
+ * A frozen value object cannot be modified; it is considered immutable.
+ * Reference counting still works on a frozen value object though: you
+ * may pass a frozen value object to bt_value_get() and bt_value_put().
+ *
+ * @param object       Value object to freeze
+ * @returns            One of #bt_value_status values; if \p object
+ *                     is already frozen, though, #BT_VALUE_STATUS_OK
+ *                     is returned anyway (i.e. this function never
+ *                     returns #BT_VALUE_STATUS_FROZEN)
+ *
+ * @see bt_value_is_frozen()
+ */
+extern enum bt_value_status bt_value_freeze(struct bt_value *object);
+
+/**
+ * Checks whether \p object is frozen or not.
+ *
+ * @param object       Value object to check
+ * @returns            \c true if \p object is frozen
+ *
+ * @see bt_value_freeze()
+ */
+extern bool bt_value_is_frozen(const struct bt_value *object);
+
+/**
+ * Returns the type of \p object.
+ *
+ * @param object       Value object of which to get the type
+ * @returns            Value object's type, or #BT_VALUE_TYPE_UNKNOWN
+ *                     on error
+ *
+ * @see #bt_value_type (value object types)
+ * @see bt_value_is_null()
+ * @see bt_value_is_bool()
+ * @see bt_value_is_integer()
+ * @see bt_value_is_float()
+ * @see bt_value_is_string()
+ * @see bt_value_is_array()
+ * @see bt_value_is_map()
+ */
+extern enum bt_value_type bt_value_get_type(const struct bt_value *object);
+
+/**
+ * Checks whether \p object is a null value object. The only valid null
+ * value object is \ref bt_value_null.
+ *
+ * @param object       Value object to check
+ * @returns            \c true if \p object is a null value object
+ *
+ * @see bt_value_get_type()
+ */
+static inline
+bool bt_value_is_null(const struct bt_value *object)
+{
+       return bt_value_get_type(object) == BT_VALUE_TYPE_NULL;
+}
+
+/**
+ * Checks whether \p object is a boolean value object.
+ *
+ * @param object       Value object to check
+ * @returns            \c true if \p object is a boolean value object
+ *
+ * @see bt_value_get_type()
+ */
+static inline
+bool bt_value_is_bool(const struct bt_value *object)
+{
+       return bt_value_get_type(object) == BT_VALUE_TYPE_BOOL;
+}
+
+/**
+ * Checks whether \p object is an integer value object.
+ *
+ * @param object       Value object to check
+ * @returns            \c true if \p object is an integer value object
+ *
+ * @see bt_value_get_type()
+ */
+static inline
+bool bt_value_is_integer(const struct bt_value *object)
+{
+       return bt_value_get_type(object) == BT_VALUE_TYPE_INTEGER;
+}
+
+/**
+ * Checks whether \p object is a floating point number value object.
+ *
+ * @param object       Value object to check
+ * @returns            \c true if \p object is a floating point
+ *                     number value object
+ *
+ * @see bt_value_get_type()
+ */
+static inline
+bool bt_value_is_float(const struct bt_value *object)
+{
+       return bt_value_get_type(object) == BT_VALUE_TYPE_FLOAT;
+}
+
+/**
+ * Checks whether \p object is a string value object.
+ *
+ * @param object       Value object to check
+ * @returns            \c true if \p object is a string value object
+ *
+ * @see bt_value_get_type()
+ */
+static inline
+bool bt_value_is_string(const struct bt_value *object)
+{
+       return bt_value_get_type(object) == BT_VALUE_TYPE_STRING;
+}
+
+/**
+ * Checks whether \p object is an array value object.
+ *
+ * @param object       Value object to check
+ * @returns            \c true if \p object is an array value object
+ *
+ * @see bt_value_get_type()
+ */
+static inline
+bool bt_value_is_array(const struct bt_value *object)
+{
+       return bt_value_get_type(object) == BT_VALUE_TYPE_ARRAY;
+}
+
+/**
+ * Checks whether \p object is a map value object.
+ *
+ * @param object       Value object to check
+ * @returns            \c true if \p object is a map value object
+ *
+ * @see bt_value_get_type()
+ */
+static inline
+bool bt_value_is_map(const struct bt_value *object)
+{
+       return bt_value_get_type(object) == BT_VALUE_TYPE_MAP;
+}
+
+/**
+ * Creates a boolean value object. The created boolean value object's
+ * initial raw value is \c false.
+ *
+ * The created value object's reference count is set to 1.
+ *
+ * @returns    Created value object on success, or \c NULL on error
+ *
+ * @see bt_value_bool_create_init() (creates an initialized
+ *                                  boolean value object)
+ */
+extern struct bt_value *bt_value_bool_create(void);
+
+/**
+ * Creates a boolean value object with its initial raw value set to
+ * \p val.
+ *
+ * The created value object's reference count is set to 1.
+ *
+ * @param val  Initial raw value
+ * @returns    Created value object on success, or \c NULL on error
+ */
+extern struct bt_value *bt_value_bool_create_init(bool val);
+
+/**
+ * Creates an integer value object. The created integer value object's
+ * initial raw value is 0.
+ *
+ * The created value object's reference count is set to 1.
+ *
+ * @returns    Created value object on success, or \c NULL on error
+ *
+ * @see bt_value_integer_create_init() (creates an initialized
+ *                                     integer value object)
+ */
+extern struct bt_value *bt_value_integer_create(void);
+
+/**
+ * Creates an integer value object with its initial raw value set to
+ * \p val.
+ *
+ * The created value object's reference count is set to 1.
+ *
+ * @param val  Initial raw value
+ * @returns    Created value object on success, or \c NULL on error
+ */
+extern struct bt_value *bt_value_integer_create_init(int64_t val);
+
+/**
+ * Creates a floating point number value object. The created floating
+ * point number value object's initial raw value is 0.
+ *
+ * The created value object's reference count is set to 1.
+ *
+ * @returns    Created value object on success, or \c NULL on error
+ *
+ * @see bt_value_float_create_init() (creates an initialized floating
+ *                                   point number value object)
+ */
+extern struct bt_value *bt_value_float_create(void);
+
+/**
+ * Creates a floating point number value object with its initial raw
+ * value set to \p val.
+ *
+ * The created value object's reference count is set to 1.
+ *
+ * @param val  Initial raw value
+ * @returns    Created value object on success, or \c NULL on error
+ */
+extern struct bt_value *bt_value_float_create_init(double val);
+
+/**
+ * Creates a string value object. The string value object is initially
+ * empty.
+ *
+ * The created value object's reference count is set to 1.
+ *
+ * @returns    Created value object on success, or \c NULL on error
+ *
+ * @see bt_value_string_create_init() (creates an initialized
+ *                                    string value object)
+ */
+extern struct bt_value *bt_value_string_create(void);
+
+/**
+ * Creates a string value object with its initial raw value set to
+ * \p val.
+ *
+ * On success, \p val is \em copied.
+ *
+ * The created value object's reference count is set to 1.
+ *
+ * @param val  Initial raw value (copied on success)
+ * @returns    Created value object on success, or \c NULL on error
+ */
+extern struct bt_value *bt_value_string_create_init(const char *val);
+
+/**
+ * Creates an empty array value object.
+ *
+ * The created value object's reference count is set to 1.
+ *
+ * @returns    Created value object on success, or \c NULL on error
+ */
+extern struct bt_value *bt_value_array_create(void);
+
+/**
+ * Creates an empty map value object.
+ *
+ * The created value object's reference count is set to 1.
+ *
+ * @returns    Created value object on success, or \c NULL on error
+ */
+extern struct bt_value *bt_value_map_create(void);
+
+/**
+ * Gets the boolean raw value of the boolean value object \p bool_obj.
+ *
+ * @param bool_obj     Boolean value object
+ * @param val          Returned boolean raw value
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_bool_set()
+ */
+extern enum bt_value_status bt_value_bool_get(
+       const struct bt_value *bool_obj, bool *val);
+
+/**
+ * Sets the boolean raw value of the boolean value object \p bool_obj
+ * to \p val.
+ *
+ * @param bool_obj     Boolean value object
+ * @param val          New boolean raw value
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_bool_get()
+ */
+extern enum bt_value_status bt_value_bool_set(struct bt_value *bool_obj,
+       bool val);
+
+/**
+ * Gets the integer raw value of the integer value object
+ * \p integer_obj.
+ *
+ * @param integer_obj  Integer value object
+ * @param val          Returned integer raw value
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_integer_set()
+ */
+extern enum bt_value_status bt_value_integer_get(
+       const struct bt_value *integer_obj, int64_t *val);
+
+/**
+ * Sets the integer raw value of the integer value object \p integer_obj
+ * to \p val.
+ *
+ * @param integer_obj  Integer value object
+ * @param val          New integer raw value
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_integer_get()
+ */
+extern enum bt_value_status bt_value_integer_set(
+       struct bt_value *integer_obj, int64_t val);
+
+/**
+ * Gets the floating point number raw value of the floating point number
+ * value object \p float_obj.
+ *
+ * @param float_obj    Floating point number value object
+ * @param val          Returned floating point number raw value
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_float_set()
+ */
+extern enum bt_value_status bt_value_float_get(
+       const struct bt_value *float_obj, double *val);
+
+/**
+ * Sets the floating point number raw value of the floating point number
+ * value object \p float_obj to \p val.
+ *
+ * @param float_obj    Floating point number value object
+ * @param val          New floating point number raw value
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_float_get()
+ */
+extern enum bt_value_status bt_value_float_set(
+       struct bt_value *float_obj, double val);
+
+/**
+ * Gets the string raw value of the string value object \p string_obj.
+ * The returned string is valid as long as this value object exists and
+ * is not modified. The ownership of the returned string is \em not
+ * transferred to the caller.
+ *
+ * @param string_obj   String value object
+ * @param val          Returned string raw value
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_string_set()
+ */
+extern enum bt_value_status bt_value_string_get(
+       const struct bt_value *string_obj, const char **val);
+
+/**
+ * Sets the string raw value of the string value object \p string_obj to
+ * \p val.
+ *
+ * On success, \p val is \em copied.
+ *
+ * @param string_obj   String value object
+ * @param val          New string raw value (copied on successf)
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_string_get()
+ */
+extern enum bt_value_status bt_value_string_set(struct bt_value *string_obj,
+       const char *val);
+
+/**
+ * Gets the size of the array value object \p array_obj, that is, the
+ * number of value objects contained in \p array_obj.
+ *
+ * @param array_obj    Array value object
+ * @returns            Array size if the return value is 0 (empty) or a
+ *                     positive value, or one of
+ *                     #bt_value_status negative values otherwise
+ *
+ * @see bt_value_array_is_empty()
+ */
+extern int bt_value_array_size(const struct bt_value *array_obj);
+
+/**
+ * Returns \c true if the array value object \p array_obj is empty.
+ *
+ * @param array_obj    Array value object
+ * @returns            \c true if \p array_obj is empty
+ *
+ * @see bt_value_array_size()
+ */
+extern bool bt_value_array_is_empty(const struct bt_value *array_obj);
+
+/**
+ * Gets the value object of the array value object \p array_obj at the
+ * index \p index.
+ *
+ * The returned value object's reference count is incremented, unless
+ * it's a null value object.
+ *
+ * @param array_obj    Array value object
+ * @param index                Index of value object to get
+ * @returns            Value object at index \p index on
+ *                     success, or \c NULL on error
+ */
+extern struct bt_value *bt_value_array_get(const struct bt_value *array_obj,
+       size_t index);
+
+/**
+ * Appends the value object \p element_obj to the array value
+ * object \p array_obj.
+ *
+ * The appended value object's reference count is incremented, unless
+ * it's a null object.
+ *
+ * @param array_obj    Array value object
+ * @param element_obj  Value object to append
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_array_append_bool()
+ * @see bt_value_array_append_integer()
+ * @see bt_value_array_append_float()
+ * @see bt_value_array_append_string()
+ * @see bt_value_array_append_array()
+ * @see bt_value_array_append_map()
+ */
+extern enum bt_value_status bt_value_array_append(struct bt_value *array_obj,
+       struct bt_value *element_obj);
+
+/**
+ * Appends the boolean raw value \p val to the array value object
+ * \p array_obj. This is a convenience function which creates the
+ * underlying boolean value object before appending it.
+ *
+ * The created boolean value object's reference count is set to 1.
+ *
+ * @param array_obj    Array value object
+ * @param val          Boolean raw value to append
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_array_append()
+ */
+extern enum bt_value_status bt_value_array_append_bool(
+       struct bt_value *array_obj, bool val);
+
+/**
+ * Appends the integer raw value \p val to the array value object
+ * \p array_obj. This is a convenience function which creates the
+ * underlying integer value object before appending it.
+ *
+ * The created integer value object's reference count is set to 1.
+ *
+ * @param array_obj    Array value object
+ * @param val          Integer raw value to append
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_array_append()
+ */
+extern enum bt_value_status bt_value_array_append_integer(
+       struct bt_value *array_obj, int64_t val);
+
+/**
+ * Appends the floating point number raw value \p val to the array value
+ * object \p array_obj. This is a convenience function which creates the
+ * underlying floating point number value object before appending it.
+ *
+ * The created floating point number value object's reference count is
+ * set to 1.
+ *
+ * @param array_obj    Array value object
+ * @param val          Floating point number raw value to append
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_array_append()
+ */
+extern enum bt_value_status bt_value_array_append_float(
+       struct bt_value *array_obj, double val);
+
+/**
+ * Appends the string raw value \p val to the array value object
+ * \p array_obj. This is a convenience function which creates the
+ * underlying string value object before appending it.
+ *
+ * On success, \p val is \em copied.
+ *
+ * The created string value object's reference count is set to 1.
+ *
+ * @param array_obj    Array value object
+ * @param val          String raw value to append (copied on success)
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_array_append()
+ */
+extern enum bt_value_status bt_value_array_append_string(
+       struct bt_value *array_obj, const char *val);
+
+/**
+ * Appends an empty array value object to the array value object
+ * \p array_obj. This is a convenience function which creates the
+ * underlying array value object before appending it.
+ *
+ * The created array value object's reference count is set to 1.
+ *
+ * @param array_obj    Array value object
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_array_append()
+ */
+extern enum bt_value_status bt_value_array_append_array(
+       struct bt_value *array_obj);
+
+/**
+ * Appends an empty map value object to the array value object
+ * \p array_obj. This is a convenience function which creates the
+ * underlying map value object before appending it.
+ *
+ * The created map value object's reference count is set to 1.
+ *
+ * @param array_obj    Array value object
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_array_append()
+ */
+extern enum bt_value_status bt_value_array_append_map(
+       struct bt_value *array_obj);
+
+/**
+ * Replaces the value object at index \p index of the array
+ * value object \p array_obj by \p element_obj.
+ *
+ * The replaced value object's reference count is decremented, unless
+ * it's a null value object. The reference count of \p element_obj is
+ * incremented, unless it's a null value object.
+ *
+ * @param array_obj    Array value object
+ * @param index                Index of value object to replace
+ * @param element_obj  New value object at position \p index of
+ *                     \p array_obj
+ * @returns            One of #bt_value_status values
+ */
+extern enum bt_value_status bt_value_array_set(struct bt_value *array_obj,
+       size_t index, struct bt_value *element_obj);
+
+/**
+ * Gets the size of a map value object, that is, the number of entries
+ * contained in a map value object.
+ *
+ * @param map_obj      Map value object
+ * @returns            Map size if the return value is 0 (empty) or a
+ *                     positive value, or one of
+ *                     #bt_value_status negative values otherwise
+ *
+ * @see bt_value_map_is_empty()
+ */
+extern int bt_value_map_size(const struct bt_value *map_obj);
+
+/**
+ * Returns \c true if the map value object \p map_obj is empty.
+ *
+ * @param map_obj      Map value object
+ * @returns            \c true if \p map_obj is empty
+ *
+ * @see bt_value_map_size()
+ */
+extern bool bt_value_map_is_empty(const struct bt_value *map_obj);
+
+/**
+ * Gets the value object associated with the key \p key within the
+ * map value object \p map_obj.
+ *
+ * The returned value object's reference count is incremented, unless
+ * it's a null value object.
+ *
+ * @param map_obj      Map value object
+ * @param key          Key of the value object to get
+ * @returns            Value object associated with the key \p key
+ *                     on success, or \c NULL on error
+ */
+extern struct bt_value *bt_value_map_get(const struct bt_value *map_obj,
+       const char *key);
+
+/**
+ * Calls a provided user function \p cb for each value object of the map
+ * value object \p map_obj.
+ *
+ * The value object passed to the user function is a
+ * <b>weak reference</b>: you must call bt_value_get() on it to obtain
+ * your own reference.
+ *
+ * The key passed to the user function is only valid in the scope of
+ * this user function call.
+ *
+ * The user function must return \c true to continue the loop, or
+ * \c false to break it.
+ *
+ * @param map_obj      Map value object
+ * @param cb           User function to call back
+ * @param data         User data passed to the user function
+ * @returns            One of #bt_value_status values; more
+ *                     specifically, #BT_VALUE_STATUS_CANCELLED is
+ *                     returned if the loop was cancelled by the user
+ *                     function
+ */
+extern enum bt_value_status bt_value_map_foreach(
+       const struct bt_value *map_obj, bt_value_map_foreach_cb cb,
+       void *data);
+
+/**
+ * Returns whether or not the map value object \p map_obj contains the
+ * key \p key.
+ *
+ * @param map_obj      Map value object
+ * @param key          Key to check
+ * @returns            \c true if \p map_obj contains the key \p key,
+ *                     or \c false if it doesn't have \p key or
+ *                     on error
+ */
+extern bool bt_value_map_has_key(const struct bt_value *map_obj,
+       const char *key);
+
+/**
+ * Inserts the value object \p element_obj associated with the key
+ * \p key into the map value object \p map_obj. If \p key exists in
+ * \p map_obj, the associated value object is first put, and then
+ * replaced by \p element_obj.
+ *
+ * On success, \p key is \em copied.
+ *
+ * The inserted value object's reference count is incremented, unless
+ * it's a null value object.
+ *
+ * @param map_obj      Map value object
+ * @param key          Key (copied on success) of value object to insert
+ * @param element_obj  Value object to insert, associated with the
+ *                     key \p key
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_map_insert_bool()
+ * @see bt_value_map_insert_integer()
+ * @see bt_value_map_insert_float()
+ * @see bt_value_map_insert_string()
+ * @see bt_value_map_insert_array()
+ * @see bt_value_map_insert_map()
+ */
+extern enum bt_value_status bt_value_map_insert(
+       struct bt_value *map_obj, const char *key,
+       struct bt_value *element_obj);
+
+/**
+ * Inserts the boolean raw value \p val associated with the key \p key
+ * into the map value object \p map_obj. This is a convenience function
+ * which creates the underlying boolean value object before
+ * inserting it.
+ *
+ * On success, \p key is \em copied.
+ *
+ * The created boolean value object's reference count is set to 1.
+ *
+ * @param map_obj      Map value object
+ * @param key          Key (copied on success) of boolean value object
+ *                     to insert
+ * @param val          Boolean raw value to insert, associated with
+ *                     the key \p key
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_map_insert()
+ */
+extern enum bt_value_status bt_value_map_insert_bool(
+       struct bt_value *map_obj, const char *key, bool val);
+
+/**
+ * Inserts the integer raw value \p val associated with the key \p key
+ * into the map value object \p map_obj. This is a convenience function
+ * which creates the underlying integer value object before inserting it.
+ *
+ * On success, \p key is \em copied.
+ *
+ * The created integer value object's reference count is set to 1.
+ *
+ * @param map_obj      Map value object
+ * @param key          Key (copied on success) of integer value object
+ *                     to insert
+ * @param val          Integer raw value to insert, associated with
+ *                     the key \p key
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_map_insert()
+ */
+extern enum bt_value_status bt_value_map_insert_integer(
+       struct bt_value *map_obj, const char *key, int64_t val);
+
+/**
+ * Inserts the floating point number raw value \p val associated with
+ * the key \p key into the map value object \p map_obj. This is a
+ * convenience function which creates the underlying floating point
+ * number value object before inserting it.
+ *
+ * On success, \p key is \em copied.
+ *
+ * The created floating point number value object's reference count is
+ * set to 1.
+ *
+ * @param map_obj      Map value object
+ * @param key          Key (copied on success) of floating point number
+ *                     value object to insert
+ * @param val          Floating point number raw value to insert,
+ *                     associated with the key \p key
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_map_insert()
+ */
+extern enum bt_value_status bt_value_map_insert_float(
+       struct bt_value *map_obj, const char *key, double val);
+
+/**
+ * Inserts the string raw value \p val associated with the key \p key
+ * into the map value object \p map_obj. This is a convenience function
+ * which creates the underlying string value object before inserting it.
+ *
+ * On success, \p val and \p key are \em copied.
+ *
+ * The created string value object's reference count is set to 1.
+ *
+ * @param map_obj      Map value object
+ * @param key          Key (copied on success) of string value object
+ *                     to insert
+ * @param val          String raw value to insert (copied on success),
+ *                     associated with the key \p key
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_map_insert()
+ */
+extern enum bt_value_status bt_value_map_insert_string(
+       struct bt_value *map_obj, const char *key, const char *val);
+
+/**
+ * Inserts an empty array value object associated with the key \p key
+ * into the map value object \p map_obj. This is a convenience function
+ * which creates the underlying array value object before inserting it.
+ *
+ * On success, \p key is \em copied.
+ *
+ * The created array value object's reference count is set to 1.
+ *
+ * @param map_obj      Map value object
+ * @param key          Key (copied on success) of empty array value
+ *                     object to insert
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_map_insert()
+ */
+extern enum bt_value_status bt_value_map_insert_array(
+       struct bt_value *map_obj, const char *key);
+
+/**
+ * Inserts an empty map value object associated with the key \p key into
+ * the map value object \p map_obj. This is a convenience function which
+ * creates the underlying map value object before inserting it.
+ *
+ * On success, \p key is \em copied.
+ *
+ * The created map value object's reference count is set to 1.
+ *
+ * @param map_obj      Map value object
+ * @param key          Key (copied on success) of empty map value
+ *                     object to insert
+ * @returns            One of #bt_value_status values
+ *
+ * @see bt_value_map_insert()
+ */
+extern enum bt_value_status bt_value_map_insert_map(
+       struct bt_value *map_obj, const char *key);
+
+/**
+ * Creates a deep copy of the value object \p object.
+ *
+ * The created value object's reference count is set to 1, unless
+ * \p object is a null value object.
+ *
+ * Copying a frozen value object is allowed: the resulting copy is
+ * \em not frozen.
+ *
+ * @param object       Value object to copy
+ * @returns            Deep copy of \p object on success, or \c NULL
+ *                     on error
+ */
+extern struct bt_value *bt_value_copy(const struct bt_value *object);
+
+/**
+ * Compares the value objects \p object_a and \p object_b and returns
+ * \c true if they have the same \em content (raw values).
+ *
+ * @param object_a     Value object A
+ * @param object_b     Value object B
+ * @returns            \c true if \p object_a and \p object_b have the
+ *                     same content, or \c false if they differ or on
+ *                     error
+ */
+extern bool bt_value_compare(const struct bt_value *object_a,
+       const struct bt_value *object_b);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BABELTRACE_VALUES_H */
index 8fe87f34fde01a7acdebcc5604b63168f1e8c0f4..54d065fbb271bd9e05d7ba87b31fda9634364c14 100644 (file)
@@ -10,7 +10,7 @@ libbabeltrace_la_SOURCES = babeltrace.c \
                           trace-handle.c \
                           trace-collection.c \
                           registry.c \
-                          objects.c
+                          values.c
 
 libbabeltrace_la_LDFLAGS = -version-info $(BABELTRACE_LIBRARY_VERSION)
 
diff --git a/lib/objects.c b/lib/objects.c
deleted file mode 100644 (file)
index 8a0bc65..0000000
+++ /dev/null
@@ -1,1217 +0,0 @@
-/*
- * objects.c: basic object system
- *
- * Babeltrace Library
- *
- * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
- * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <string.h>
-#include <babeltrace/ref-internal.h>
-#include <babeltrace/compiler.h>
-#include <babeltrace/objects.h>
-#include <glib.h>
-
-#define BT_OBJECT_FROM_CONCRETE(_concrete) ((struct bt_object *) (_concrete))
-#define BT_OBJECT_TO_BOOL(_base) ((struct bt_object_bool *) (_base))
-#define BT_OBJECT_TO_INTEGER(_base) ((struct bt_object_integer *) (_base))
-#define BT_OBJECT_TO_FLOAT(_base) ((struct bt_object_float *) (_base))
-#define BT_OBJECT_TO_STRING(_base) ((struct bt_object_string *) (_base))
-#define BT_OBJECT_TO_ARRAY(_base) ((struct bt_object_array *) (_base))
-#define BT_OBJECT_TO_MAP(_base) ((struct bt_object_map *) (_base))
-
-struct bt_object {
-       enum bt_object_type type;
-       struct bt_ref ref_count;
-       bool is_frozen;
-};
-
-static
-struct bt_object bt_object_null_instance = {
-       .type = BT_OBJECT_TYPE_NULL,
-       .is_frozen = true,
-};
-
-struct bt_object *bt_object_null = &bt_object_null_instance;
-
-struct bt_object_bool {
-       struct bt_object base;
-       bool value;
-};
-
-struct bt_object_integer {
-       struct bt_object base;
-       int64_t value;
-};
-
-struct bt_object_float {
-       struct bt_object base;
-       double value;
-};
-
-struct bt_object_string {
-       struct bt_object base;
-       GString *gstr;
-};
-
-struct bt_object_array {
-       struct bt_object base;
-       GPtrArray *garray;
-};
-
-struct bt_object_map {
-       struct bt_object base;
-       GHashTable *ght;
-};
-
-static
-void bt_object_destroy(struct bt_ref *ref_count);
-
-static
-void bt_object_string_destroy(struct bt_object *object)
-{
-       g_string_free(BT_OBJECT_TO_STRING(object)->gstr, TRUE);
-}
-
-static
-void bt_object_array_destroy(struct bt_object *object)
-{
-       /*
-        * Pointer array's registered value destructor will take care
-        * of putting each contained object.
-        */
-       g_ptr_array_free(BT_OBJECT_TO_ARRAY(object)->garray, TRUE);
-}
-
-static
-void bt_object_map_destroy(struct bt_object *object)
-{
-       /*
-        * Hash table's registered value destructor will take care of
-        * putting each contained object. Keys are GQuarks and cannot
-        * be destroyed anyway.
-        */
-       g_hash_table_destroy(BT_OBJECT_TO_MAP(object)->ght);
-}
-
-static
-void (* const destroy_funcs[])(struct bt_object *) = {
-       [BT_OBJECT_TYPE_NULL] =         NULL,
-       [BT_OBJECT_TYPE_BOOL] =         NULL,
-       [BT_OBJECT_TYPE_INTEGER] =      NULL,
-       [BT_OBJECT_TYPE_FLOAT] =        NULL,
-       [BT_OBJECT_TYPE_STRING] =       bt_object_string_destroy,
-       [BT_OBJECT_TYPE_ARRAY] =        bt_object_array_destroy,
-       [BT_OBJECT_TYPE_MAP] =          bt_object_map_destroy,
-};
-
-static
-struct bt_object *bt_object_null_copy(const struct bt_object *null_obj)
-{
-       return bt_object_null;
-}
-
-static
-struct bt_object *bt_object_bool_copy(const struct bt_object *bool_obj)
-{
-       return bt_object_bool_create_init(BT_OBJECT_TO_BOOL(bool_obj)->value);
-}
-
-static
-struct bt_object *bt_object_integer_copy(const struct bt_object *integer_obj)
-{
-       return bt_object_integer_create_init(
-               BT_OBJECT_TO_INTEGER(integer_obj)->value);
-}
-
-static
-struct bt_object *bt_object_float_copy(const struct bt_object *float_obj)
-{
-       return bt_object_float_create_init(
-               BT_OBJECT_TO_FLOAT(float_obj)->value);
-}
-
-static
-struct bt_object *bt_object_string_copy(const struct bt_object *string_obj)
-{
-       return bt_object_string_create_init(
-               BT_OBJECT_TO_STRING(string_obj)->gstr->str);
-}
-
-static
-struct bt_object *bt_object_array_copy(const struct bt_object *array_obj)
-{
-       int i;
-       int ret;
-       struct bt_object *copy_obj;
-       struct bt_object_array *typed_array_obj;
-
-       typed_array_obj = BT_OBJECT_TO_ARRAY(array_obj);
-       copy_obj = bt_object_array_create();
-
-       if (!copy_obj) {
-               goto end;
-       }
-
-       for (i = 0; i < typed_array_obj->garray->len; ++i) {
-               struct bt_object *element_obj_copy;
-               struct bt_object *element_obj =
-                       bt_object_array_get(array_obj, i);
-
-               if (!element_obj) {
-                       BT_OBJECT_PUT(copy_obj);
-                       goto end;
-               }
-
-               element_obj_copy = bt_object_copy(element_obj);
-               BT_OBJECT_PUT(element_obj);
-
-               if (!element_obj_copy) {
-                       BT_OBJECT_PUT(copy_obj);
-                       goto end;
-               }
-
-               ret = bt_object_array_append(copy_obj, element_obj_copy);
-               BT_OBJECT_PUT(element_obj_copy);
-
-               if (ret) {
-                       BT_OBJECT_PUT(copy_obj);
-                       goto end;
-               }
-       }
-
-end:
-       return copy_obj;
-}
-
-static
-struct bt_object *bt_object_map_copy(const struct bt_object *map_obj)
-{
-       int ret;
-       GHashTableIter iter;
-       gpointer key, element_obj;
-       struct bt_object *copy_obj;
-       struct bt_object *element_obj_copy;
-       struct bt_object_map *typed_map_obj;
-
-       typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
-       copy_obj = bt_object_map_create();
-
-       if (!copy_obj) {
-               goto end;
-       }
-
-       g_hash_table_iter_init(&iter, typed_map_obj->ght);
-
-       while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
-               const char *key_str = g_quark_to_string((unsigned long) key);
-
-               element_obj_copy = bt_object_copy(element_obj);
-
-               if (!element_obj_copy) {
-                       BT_OBJECT_PUT(copy_obj);
-                       goto end;
-               }
-
-               ret = bt_object_map_insert(copy_obj, key_str, element_obj_copy);
-               BT_OBJECT_PUT(element_obj_copy);
-
-               if (ret) {
-                       BT_OBJECT_PUT(copy_obj);
-                       goto end;
-               }
-       }
-
-end:
-       return copy_obj;
-}
-
-static
-struct bt_object *(* const copy_funcs[])(const struct bt_object *) = {
-       [BT_OBJECT_TYPE_NULL] =         bt_object_null_copy,
-       [BT_OBJECT_TYPE_BOOL] =         bt_object_bool_copy,
-       [BT_OBJECT_TYPE_INTEGER] =      bt_object_integer_copy,
-       [BT_OBJECT_TYPE_FLOAT] =        bt_object_float_copy,
-       [BT_OBJECT_TYPE_STRING] =       bt_object_string_copy,
-       [BT_OBJECT_TYPE_ARRAY] =        bt_object_array_copy,
-       [BT_OBJECT_TYPE_MAP] =          bt_object_map_copy,
-};
-
-static
-bool bt_object_null_compare(const struct bt_object *object_a,
-               const struct bt_object *object_b)
-{
-       /*
-        * Always true since bt_object_compare() already checks if both
-        * object_a and object_b have the same type, and in the case of
-        * null objects, they're always the same if it is so.
-        */
-       return true;
-}
-
-static
-bool bt_object_bool_compare(const struct bt_object *object_a,
-               const struct bt_object *object_b)
-{
-       return BT_OBJECT_TO_BOOL(object_a)->value ==
-               BT_OBJECT_TO_BOOL(object_b)->value;
-}
-
-static
-bool bt_object_integer_compare(const struct bt_object *object_a,
-               const struct bt_object *object_b)
-{
-       return BT_OBJECT_TO_INTEGER(object_a)->value ==
-               BT_OBJECT_TO_INTEGER(object_b)->value;
-}
-
-static
-bool bt_object_float_compare(const struct bt_object *object_a,
-               const struct bt_object *object_b)
-{
-       return BT_OBJECT_TO_FLOAT(object_a)->value ==
-               BT_OBJECT_TO_FLOAT(object_b)->value;
-}
-
-static
-bool bt_object_string_compare(const struct bt_object *object_a,
-               const struct bt_object *object_b)
-{
-       return !strcmp(BT_OBJECT_TO_STRING(object_a)->gstr->str,
-               BT_OBJECT_TO_STRING(object_b)->gstr->str);
-}
-
-static
-bool bt_object_array_compare(const struct bt_object *object_a,
-               const struct bt_object *object_b)
-{
-       int i;
-       bool ret = true;
-       const struct bt_object_array *array_obj_a =
-               BT_OBJECT_TO_ARRAY(object_a);
-
-       if (bt_object_array_size(object_a) != bt_object_array_size(object_b)) {
-               ret = false;
-               goto end;
-       }
-
-       for (i = 0; i < array_obj_a->garray->len; ++i) {
-               struct bt_object *element_obj_a;
-               struct bt_object *element_obj_b;
-
-               element_obj_a = bt_object_array_get(object_a, i);
-               element_obj_b = bt_object_array_get(object_b, i);
-
-               if (!bt_object_compare(element_obj_a, element_obj_b)) {
-                       BT_OBJECT_PUT(element_obj_a);
-                       BT_OBJECT_PUT(element_obj_b);
-                       ret = false;
-                       goto end;
-               }
-
-               BT_OBJECT_PUT(element_obj_a);
-               BT_OBJECT_PUT(element_obj_b);
-       }
-
-end:
-       return ret;
-}
-
-static
-bool bt_object_map_compare(const struct bt_object *object_a,
-               const struct bt_object *object_b)
-{
-       bool ret = true;
-       GHashTableIter iter;
-       gpointer key, element_obj_a;
-       const struct bt_object_map *map_obj_a = BT_OBJECT_TO_MAP(object_a);
-
-       if (bt_object_map_size(object_a) != bt_object_map_size(object_b)) {
-               ret = false;
-               goto end;
-       }
-
-       g_hash_table_iter_init(&iter, map_obj_a->ght);
-
-       while (g_hash_table_iter_next(&iter, &key, &element_obj_a)) {
-               struct bt_object *element_obj_b;
-               const char *key_str = g_quark_to_string((unsigned long) key);
-
-               element_obj_b = bt_object_map_get(object_b, key_str);
-
-               if (!bt_object_compare(element_obj_a, element_obj_b)) {
-                       BT_OBJECT_PUT(element_obj_b);
-                       ret = false;
-                       goto end;
-               }
-
-               BT_OBJECT_PUT(element_obj_b);
-       }
-
-end:
-       return ret;
-}
-
-static
-bool (* const compare_funcs[])(const struct bt_object *,
-               const struct bt_object *) = {
-       [BT_OBJECT_TYPE_NULL] =         bt_object_null_compare,
-       [BT_OBJECT_TYPE_BOOL] =         bt_object_bool_compare,
-       [BT_OBJECT_TYPE_INTEGER] =      bt_object_integer_compare,
-       [BT_OBJECT_TYPE_FLOAT] =        bt_object_float_compare,
-       [BT_OBJECT_TYPE_STRING] =       bt_object_string_compare,
-       [BT_OBJECT_TYPE_ARRAY] =        bt_object_array_compare,
-       [BT_OBJECT_TYPE_MAP] =          bt_object_map_compare,
-};
-
-void bt_object_null_freeze(struct bt_object *object)
-{
-}
-
-void bt_object_generic_freeze(struct bt_object *object)
-{
-       object->is_frozen = true;
-}
-
-void bt_object_array_freeze(struct bt_object *object)
-{
-       int i;
-       struct bt_object_array *typed_array_obj =
-               BT_OBJECT_TO_ARRAY(object);
-
-       for (i = 0; i < typed_array_obj->garray->len; ++i) {
-               struct bt_object *element_obj =
-                       g_ptr_array_index(typed_array_obj->garray, i);
-
-               bt_object_freeze(element_obj);
-       }
-
-       bt_object_generic_freeze(object);
-}
-
-void bt_object_map_freeze(struct bt_object *object)
-{
-       GHashTableIter iter;
-       gpointer key, element_obj;
-       const struct bt_object_map *map_obj = BT_OBJECT_TO_MAP(object);
-
-       g_hash_table_iter_init(&iter, map_obj->ght);
-
-       while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
-               bt_object_freeze(element_obj);
-       }
-
-       bt_object_generic_freeze(object);
-}
-
-static
-void (* const freeze_funcs[])(struct bt_object *) = {
-       [BT_OBJECT_TYPE_NULL] =         bt_object_null_freeze,
-       [BT_OBJECT_TYPE_BOOL] =         bt_object_generic_freeze,
-       [BT_OBJECT_TYPE_INTEGER] =      bt_object_generic_freeze,
-       [BT_OBJECT_TYPE_FLOAT] =        bt_object_generic_freeze,
-       [BT_OBJECT_TYPE_STRING] =       bt_object_generic_freeze,
-       [BT_OBJECT_TYPE_ARRAY] =        bt_object_array_freeze,
-       [BT_OBJECT_TYPE_MAP] =          bt_object_map_freeze,
-};
-
-static
-void bt_object_destroy(struct bt_ref *ref_count)
-{
-       struct bt_object *object;
-
-       object = container_of(ref_count, struct bt_object, ref_count);
-       assert(object->type != BT_OBJECT_TYPE_UNKNOWN);
-
-       if (bt_object_is_null(object)) {
-               return;
-       }
-
-       if (destroy_funcs[object->type]) {
-               destroy_funcs[object->type](object);
-       }
-
-       g_free(object);
-}
-
-void bt_object_get(struct bt_object *object)
-{
-       if (object && !bt_object_is_null(object)) {
-               bt_ref_get(&object->ref_count);
-       }
-
-       return;
-}
-
-void bt_object_put(struct bt_object *object)
-{
-       if (object && !bt_object_is_null(object)) {
-               bt_ref_put(&object->ref_count);
-       }
-}
-
-enum bt_object_status bt_object_freeze(struct bt_object *object)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-
-       if (!object) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       freeze_funcs[object->type](object);
-
-end:
-       return ret;
-}
-
-bool bt_object_is_frozen(const struct bt_object *object)
-{
-       return object && object->is_frozen;
-}
-
-enum bt_object_type bt_object_get_type(const struct bt_object *object)
-{
-       if (!object) {
-               return BT_OBJECT_TYPE_UNKNOWN;
-       }
-
-       return object->type;
-}
-
-static
-struct bt_object bt_object_create_base(enum bt_object_type type)
-{
-       struct bt_object base;
-
-       base.type = type;
-       base.is_frozen = false;
-       bt_ref_init(&base.ref_count, bt_object_destroy);
-
-       return base;
-}
-
-struct bt_object *bt_object_bool_create_init(bool val)
-{
-       struct bt_object_bool *bool_obj;
-
-       bool_obj = g_new0(struct bt_object_bool, 1);
-
-       if (!bool_obj) {
-               goto end;
-       }
-
-       bool_obj->base = bt_object_create_base(BT_OBJECT_TYPE_BOOL);
-       bool_obj->value = val;
-
-end:
-       return BT_OBJECT_FROM_CONCRETE(bool_obj);
-}
-
-struct bt_object *bt_object_bool_create(void)
-{
-       return bt_object_bool_create_init(false);
-}
-
-struct bt_object *bt_object_integer_create_init(int64_t val)
-{
-       struct bt_object_integer *integer_obj;
-
-       integer_obj = g_new0(struct bt_object_integer, 1);
-
-       if (!integer_obj) {
-               goto end;
-       }
-
-       integer_obj->base = bt_object_create_base(BT_OBJECT_TYPE_INTEGER);
-       integer_obj->value = val;
-
-end:
-       return BT_OBJECT_FROM_CONCRETE(integer_obj);
-}
-
-struct bt_object *bt_object_integer_create(void)
-{
-       return bt_object_integer_create_init(0);
-}
-
-struct bt_object *bt_object_float_create_init(double val)
-{
-       struct bt_object_float *float_obj;
-
-       float_obj = g_new0(struct bt_object_float, 1);
-
-       if (!float_obj) {
-               goto end;
-       }
-
-       float_obj->base = bt_object_create_base(BT_OBJECT_TYPE_FLOAT);
-       float_obj->value = val;
-
-end:
-       return BT_OBJECT_FROM_CONCRETE(float_obj);
-}
-
-struct bt_object *bt_object_float_create(void)
-{
-       return bt_object_float_create_init(0.);
-}
-
-struct bt_object *bt_object_string_create_init(const char *val)
-{
-       struct bt_object_string *string_obj = NULL;
-
-       if (!val) {
-               goto end;
-       }
-
-       string_obj = g_new0(struct bt_object_string, 1);
-
-       if (!string_obj) {
-               goto end;
-       }
-
-       string_obj->base = bt_object_create_base(BT_OBJECT_TYPE_STRING);
-       string_obj->gstr = g_string_new(val);
-
-       if (!string_obj->gstr) {
-               g_free(string_obj);
-               string_obj = NULL;
-               goto end;
-       }
-
-end:
-       return BT_OBJECT_FROM_CONCRETE(string_obj);
-}
-
-struct bt_object *bt_object_string_create(void)
-{
-       return bt_object_string_create_init("");
-}
-
-struct bt_object *bt_object_array_create(void)
-{
-       struct bt_object_array *array_obj;
-
-       array_obj = g_new0(struct bt_object_array, 1);
-
-       if (!array_obj) {
-               goto end;
-       }
-
-       array_obj->base = bt_object_create_base(BT_OBJECT_TYPE_ARRAY);
-       array_obj->garray = g_ptr_array_new_full(0,
-               (GDestroyNotify) bt_object_put);
-
-       if (!array_obj->garray) {
-               g_free(array_obj);
-               array_obj = NULL;
-               goto end;
-       }
-
-end:
-       return BT_OBJECT_FROM_CONCRETE(array_obj);
-}
-
-struct bt_object *bt_object_map_create(void)
-{
-       struct bt_object_map *map_obj;
-
-       map_obj = g_new0(struct bt_object_map, 1);
-
-       if (!map_obj) {
-               goto end;
-       }
-
-       map_obj->base = bt_object_create_base(BT_OBJECT_TYPE_MAP);
-       map_obj->ght = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-               NULL, (GDestroyNotify) bt_object_put);
-
-       if (!map_obj->ght) {
-               g_free(map_obj);
-               map_obj = NULL;
-               goto end;
-       }
-
-end:
-       return BT_OBJECT_FROM_CONCRETE(map_obj);
-}
-
-enum bt_object_status bt_object_bool_get(const struct bt_object *bool_obj,
-       bool *val)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       struct bt_object_bool *typed_bool_obj = BT_OBJECT_TO_BOOL(bool_obj);
-
-       if (!bool_obj || !bt_object_is_bool(bool_obj) || !val) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       *val = typed_bool_obj->value;
-
-end:
-       return ret;
-}
-
-enum bt_object_status bt_object_bool_set(struct bt_object *bool_obj, bool val)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       struct bt_object_bool *typed_bool_obj = BT_OBJECT_TO_BOOL(bool_obj);
-
-       if (!bool_obj || !bt_object_is_bool(bool_obj)) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       if (bool_obj->is_frozen) {
-               ret = BT_OBJECT_STATUS_FROZEN;
-               goto end;
-       }
-
-       typed_bool_obj->value = val;
-
-end:
-       return ret;
-}
-
-enum bt_object_status bt_object_integer_get(const struct bt_object *integer_obj,
-       int64_t *val)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       struct bt_object_integer *typed_integer_obj =
-               BT_OBJECT_TO_INTEGER(integer_obj);
-
-       if (!integer_obj || !bt_object_is_integer(integer_obj) || !val) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       *val = typed_integer_obj->value;
-
-end:
-       return ret;
-}
-
-enum bt_object_status bt_object_integer_set(struct bt_object *integer_obj,
-       int64_t val)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       struct bt_object_integer *typed_integer_obj =
-               BT_OBJECT_TO_INTEGER(integer_obj);
-
-       if (!integer_obj || !bt_object_is_integer(integer_obj)) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       if (integer_obj->is_frozen) {
-               ret = BT_OBJECT_STATUS_FROZEN;
-               goto end;
-       }
-
-       typed_integer_obj->value = val;
-
-end:
-       return ret;
-}
-
-enum bt_object_status bt_object_float_get(const struct bt_object *float_obj,
-       double *val)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       struct bt_object_float *typed_float_obj =
-               BT_OBJECT_TO_FLOAT(float_obj);
-
-       if (!float_obj || !bt_object_is_float(float_obj) || !val) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       *val = typed_float_obj->value;
-
-end:
-       return ret;
-}
-
-enum bt_object_status bt_object_float_set(struct bt_object *float_obj,
-       double val)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       struct bt_object_float *typed_float_obj =
-               BT_OBJECT_TO_FLOAT(float_obj);
-
-       if (!float_obj || !bt_object_is_float(float_obj)) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       if (float_obj->is_frozen) {
-               ret = BT_OBJECT_STATUS_FROZEN;
-               goto end;
-       }
-
-       typed_float_obj->value = val;
-
-end:
-       return ret;
-}
-
-enum bt_object_status bt_object_string_get(const struct bt_object *string_obj,
-       const char **val)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       struct bt_object_string *typed_string_obj =
-               BT_OBJECT_TO_STRING(string_obj);
-
-       if (!string_obj || !bt_object_is_string(string_obj) || !val) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       *val = typed_string_obj->gstr->str;
-
-end:
-       return ret;
-}
-
-enum bt_object_status bt_object_string_set(struct bt_object *string_obj,
-       const char *val)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       struct bt_object_string *typed_string_obj =
-               BT_OBJECT_TO_STRING(string_obj);
-
-       if (!string_obj || !bt_object_is_string(string_obj) || !val) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       if (string_obj->is_frozen) {
-               ret = BT_OBJECT_STATUS_FROZEN;
-               goto end;
-       }
-
-       g_string_assign(typed_string_obj->gstr, val);
-
-end:
-       return ret;
-}
-
-int bt_object_array_size(const struct bt_object *array_obj)
-{
-       int ret;
-       struct bt_object_array *typed_array_obj =
-               BT_OBJECT_TO_ARRAY(array_obj);
-
-       if (!array_obj || !bt_object_is_array(array_obj)) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       ret = (int) typed_array_obj->garray->len;
-
-end:
-       return ret;
-}
-
-bool bt_object_array_is_empty(const struct bt_object *array_obj)
-{
-       return bt_object_array_size(array_obj) == 0;
-}
-
-struct bt_object *bt_object_array_get(const struct bt_object *array_obj,
-       size_t index)
-{
-       struct bt_object *ret;
-       struct bt_object_array *typed_array_obj =
-               BT_OBJECT_TO_ARRAY(array_obj);
-
-       if (!array_obj || !bt_object_is_array(array_obj) ||
-                       index >= typed_array_obj->garray->len) {
-               ret = NULL;
-               goto end;
-       }
-
-       ret = g_ptr_array_index(typed_array_obj->garray, index);
-       bt_object_get(ret);
-
-end:
-       return ret;
-}
-
-enum bt_object_status bt_object_array_append(struct bt_object *array_obj,
-       struct bt_object *element_obj)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       struct bt_object_array *typed_array_obj =
-               BT_OBJECT_TO_ARRAY(array_obj);
-
-       if (!array_obj || !bt_object_is_array(array_obj) || !element_obj) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       if (array_obj->is_frozen) {
-               ret = BT_OBJECT_STATUS_FROZEN;
-               goto end;
-       }
-
-       g_ptr_array_add(typed_array_obj->garray, element_obj);
-       bt_object_get(element_obj);
-
-end:
-       return ret;
-}
-
-enum bt_object_status bt_object_array_append_bool(struct bt_object *array_obj,
-       bool val)
-{
-       enum bt_object_status ret;
-       struct bt_object *bool_obj = NULL;
-
-       bool_obj = bt_object_bool_create_init(val);
-       ret = bt_object_array_append(array_obj, bool_obj);
-       bt_object_put(bool_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_array_append_integer(
-       struct bt_object *array_obj, int64_t val)
-{
-       enum bt_object_status ret;
-       struct bt_object *integer_obj = NULL;
-
-       integer_obj = bt_object_integer_create_init(val);
-       ret = bt_object_array_append(array_obj, integer_obj);
-       bt_object_put(integer_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_array_append_float(struct bt_object *array_obj,
-       double val)
-{
-       enum bt_object_status ret;
-       struct bt_object *float_obj = NULL;
-
-       float_obj = bt_object_float_create_init(val);
-       ret = bt_object_array_append(array_obj, float_obj);
-       bt_object_put(float_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_array_append_string(struct bt_object *array_obj,
-       const char *val)
-{
-       enum bt_object_status ret;
-       struct bt_object *string_obj = NULL;
-
-       string_obj = bt_object_string_create_init(val);
-       ret = bt_object_array_append(array_obj, string_obj);
-       bt_object_put(string_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_array_append_array(struct bt_object *array_obj)
-{
-       enum bt_object_status ret;
-       struct bt_object *empty_array_obj = NULL;
-
-       empty_array_obj = bt_object_array_create();
-       ret = bt_object_array_append(array_obj, empty_array_obj);
-       bt_object_put(empty_array_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_array_append_map(struct bt_object *array_obj)
-{
-       enum bt_object_status ret;
-       struct bt_object *map_obj = NULL;
-
-       map_obj = bt_object_map_create();
-       ret = bt_object_array_append(array_obj, map_obj);
-       bt_object_put(map_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_array_set(struct bt_object *array_obj,
-       size_t index, struct bt_object *element_obj)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       struct bt_object_array *typed_array_obj =
-               BT_OBJECT_TO_ARRAY(array_obj);
-
-       if (!array_obj || !bt_object_is_array(array_obj) || !element_obj ||
-                       index >= typed_array_obj->garray->len) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       if (array_obj->is_frozen) {
-               ret = BT_OBJECT_STATUS_FROZEN;
-               goto end;
-       }
-
-       bt_object_put(g_ptr_array_index(typed_array_obj->garray, index));
-       g_ptr_array_index(typed_array_obj->garray, index) = element_obj;
-       bt_object_get(element_obj);
-
-end:
-       return ret;
-}
-
-int bt_object_map_size(const struct bt_object *map_obj)
-{
-       int ret;
-       struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
-
-       if (!map_obj || !bt_object_is_map(map_obj)) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       ret = (int) g_hash_table_size(typed_map_obj->ght);
-
-end:
-       return ret;
-}
-
-bool bt_object_map_is_empty(const struct bt_object *map_obj)
-{
-       return bt_object_map_size(map_obj) == 0;
-}
-
-struct bt_object *bt_object_map_get(const struct bt_object *map_obj,
-       const char *key)
-{
-       GQuark quark;
-       struct bt_object *ret;
-       struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
-
-       if (!map_obj || !bt_object_is_map(map_obj) || !key) {
-               ret = NULL;
-               goto end;
-       }
-
-       quark = g_quark_from_string(key);
-       ret = g_hash_table_lookup(typed_map_obj->ght, GUINT_TO_POINTER(quark));
-
-       if (ret) {
-               bt_object_get(ret);
-       }
-
-end:
-       return ret;
-}
-
-bool bt_object_map_has_key(const struct bt_object *map_obj, const char *key)
-{
-       bool ret;
-       GQuark quark;
-       struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
-
-       if (!map_obj || !bt_object_is_map(map_obj) || !key) {
-               ret = false;
-               goto end;
-       }
-
-       quark = g_quark_from_string(key);
-       ret = g_hash_table_contains(typed_map_obj->ght,
-               GUINT_TO_POINTER(quark));
-
-end:
-       return ret;
-}
-
-enum bt_object_status bt_object_map_insert(struct bt_object *map_obj,
-       const char *key, struct bt_object *element_obj)
-{
-       GQuark quark;
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
-
-       if (!map_obj || !bt_object_is_map(map_obj) || !key || !element_obj) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       if (map_obj->is_frozen) {
-               ret = BT_OBJECT_STATUS_FROZEN;
-               goto end;
-       }
-
-       quark = g_quark_from_string(key);
-       g_hash_table_insert(typed_map_obj->ght,
-               GUINT_TO_POINTER(quark), element_obj);
-       bt_object_get(element_obj);
-
-end:
-       return ret;
-}
-
-enum bt_object_status bt_object_map_insert_bool(struct bt_object *map_obj,
-       const char *key, bool val)
-{
-       enum bt_object_status ret;
-       struct bt_object *bool_obj = NULL;
-
-       bool_obj = bt_object_bool_create_init(val);
-       ret = bt_object_map_insert(map_obj, key, bool_obj);
-       bt_object_put(bool_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_map_insert_integer(struct bt_object *map_obj,
-       const char *key, int64_t val)
-{
-       enum bt_object_status ret;
-       struct bt_object *integer_obj = NULL;
-
-       integer_obj = bt_object_integer_create_init(val);
-       ret = bt_object_map_insert(map_obj, key, integer_obj);
-       bt_object_put(integer_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_map_insert_float(struct bt_object *map_obj,
-       const char *key, double val)
-{
-       enum bt_object_status ret;
-       struct bt_object *float_obj = NULL;
-
-       float_obj = bt_object_float_create_init(val);
-       ret = bt_object_map_insert(map_obj, key, float_obj);
-       bt_object_put(float_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_map_insert_string(struct bt_object *map_obj,
-       const char *key, const char *val)
-{
-       enum bt_object_status ret;
-       struct bt_object *string_obj = NULL;
-
-       string_obj = bt_object_string_create_init(val);
-       ret = bt_object_map_insert(map_obj, key, string_obj);
-       bt_object_put(string_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_map_insert_array(struct bt_object *map_obj,
-       const char *key)
-{
-       enum bt_object_status ret;
-       struct bt_object *array_obj = NULL;
-
-       array_obj = bt_object_array_create();
-       ret = bt_object_map_insert(map_obj, key, array_obj);
-       bt_object_put(array_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_map_insert_map(struct bt_object *map_obj,
-       const char *key)
-{
-       enum bt_object_status ret;
-       struct bt_object *empty_map_obj = NULL;
-
-       empty_map_obj = bt_object_map_create();
-       ret = bt_object_map_insert(map_obj, key, empty_map_obj);
-       bt_object_put(empty_map_obj);
-
-       return ret;
-}
-
-enum bt_object_status bt_object_map_foreach(const struct bt_object *map_obj,
-       bt_object_map_foreach_cb cb, void *data)
-{
-       enum bt_object_status ret = BT_OBJECT_STATUS_OK;
-       gpointer key, element_obj;
-       GHashTableIter iter;
-       struct bt_object_map *typed_map_obj = BT_OBJECT_TO_MAP(map_obj);
-
-       if (!map_obj || !bt_object_is_map(map_obj) || !cb) {
-               ret = BT_OBJECT_STATUS_INVAL;
-               goto end;
-       }
-
-       g_hash_table_iter_init(&iter, typed_map_obj->ght);
-
-       while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
-               const char *key_str = g_quark_to_string((unsigned long) key);
-
-               if (!cb(key_str, element_obj, data)) {
-                       ret = BT_OBJECT_STATUS_CANCELLED;
-                       break;
-               }
-       }
-
-end:
-       return ret;
-}
-
-struct bt_object *bt_object_copy(const struct bt_object *object)
-{
-       struct bt_object *copy_obj = NULL;
-
-       if (!object) {
-               goto end;
-       }
-
-       copy_obj = copy_funcs[object->type](object);
-
-end:
-       return copy_obj;
-}
-
-bool bt_object_compare(const struct bt_object *object_a,
-       const struct bt_object *object_b)
-{
-       bool ret = false;
-
-       if (!object_a || !object_b) {
-               goto end;
-       }
-
-       if (object_a->type != object_b->type) {
-               goto end;
-       }
-
-       ret = compare_funcs[object_a->type](object_a, object_b);
-
-end:
-       return ret;
-}
diff --git a/lib/values.c b/lib/values.c
new file mode 100644 (file)
index 0000000..f926ccb
--- /dev/null
@@ -0,0 +1,1216 @@
+/*
+ * values.c: value objects
+ *
+ * Babeltrace Library
+ *
+ * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <string.h>
+#include <babeltrace/ref-internal.h>
+#include <babeltrace/compiler.h>
+#include <babeltrace/values.h>
+#include <glib.h>
+
+#define BT_VALUE_FROM_CONCRETE(_concrete) ((struct bt_value *) (_concrete))
+#define BT_VALUE_TO_BOOL(_base) ((struct bt_value_bool *) (_base))
+#define BT_VALUE_TO_INTEGER(_base) ((struct bt_value_integer *) (_base))
+#define BT_VALUE_TO_FLOAT(_base) ((struct bt_value_float *) (_base))
+#define BT_VALUE_TO_STRING(_base) ((struct bt_value_string *) (_base))
+#define BT_VALUE_TO_ARRAY(_base) ((struct bt_value_array *) (_base))
+#define BT_VALUE_TO_MAP(_base) ((struct bt_value_map *) (_base))
+
+struct bt_value {
+       enum bt_value_type type;
+       struct bt_ref ref_count;
+       bool is_frozen;
+};
+
+static
+struct bt_value bt_value_null_instance = {
+       .type = BT_VALUE_TYPE_NULL,
+       .is_frozen = true,
+};
+
+struct bt_value *bt_value_null = &bt_value_null_instance;
+
+struct bt_value_bool {
+       struct bt_value base;
+       bool value;
+};
+
+struct bt_value_integer {
+       struct bt_value base;
+       int64_t value;
+};
+
+struct bt_value_float {
+       struct bt_value base;
+       double value;
+};
+
+struct bt_value_string {
+       struct bt_value base;
+       GString *gstr;
+};
+
+struct bt_value_array {
+       struct bt_value base;
+       GPtrArray *garray;
+};
+
+struct bt_value_map {
+       struct bt_value base;
+       GHashTable *ght;
+};
+
+static
+void bt_value_destroy(struct bt_ref *ref_count);
+
+static
+void bt_value_string_destroy(struct bt_value *object)
+{
+       g_string_free(BT_VALUE_TO_STRING(object)->gstr, TRUE);
+}
+
+static
+void bt_value_array_destroy(struct bt_value *object)
+{
+       /*
+        * Pointer array's registered value destructor will take care
+        * of putting each contained object.
+        */
+       g_ptr_array_free(BT_VALUE_TO_ARRAY(object)->garray, TRUE);
+}
+
+static
+void bt_value_map_destroy(struct bt_value *object)
+{
+       /*
+        * Hash table's registered value destructor will take care of
+        * putting each contained object. Keys are GQuarks and cannot
+        * be destroyed anyway.
+        */
+       g_hash_table_destroy(BT_VALUE_TO_MAP(object)->ght);
+}
+
+static
+void (* const destroy_funcs[])(struct bt_value *) = {
+       [BT_VALUE_TYPE_NULL] =          NULL,
+       [BT_VALUE_TYPE_BOOL] =          NULL,
+       [BT_VALUE_TYPE_INTEGER] =       NULL,
+       [BT_VALUE_TYPE_FLOAT] =         NULL,
+       [BT_VALUE_TYPE_STRING] =        bt_value_string_destroy,
+       [BT_VALUE_TYPE_ARRAY] =         bt_value_array_destroy,
+       [BT_VALUE_TYPE_MAP] =           bt_value_map_destroy,
+};
+
+static
+struct bt_value *bt_value_null_copy(const struct bt_value *null_obj)
+{
+       return bt_value_null;
+}
+
+static
+struct bt_value *bt_value_bool_copy(const struct bt_value *bool_obj)
+{
+       return bt_value_bool_create_init(BT_VALUE_TO_BOOL(bool_obj)->value);
+}
+
+static
+struct bt_value *bt_value_integer_copy(const struct bt_value *integer_obj)
+{
+       return bt_value_integer_create_init(
+               BT_VALUE_TO_INTEGER(integer_obj)->value);
+}
+
+static
+struct bt_value *bt_value_float_copy(const struct bt_value *float_obj)
+{
+       return bt_value_float_create_init(
+               BT_VALUE_TO_FLOAT(float_obj)->value);
+}
+
+static
+struct bt_value *bt_value_string_copy(const struct bt_value *string_obj)
+{
+       return bt_value_string_create_init(
+               BT_VALUE_TO_STRING(string_obj)->gstr->str);
+}
+
+static
+struct bt_value *bt_value_array_copy(const struct bt_value *array_obj)
+{
+       int i;
+       int ret;
+       struct bt_value *copy_obj;
+       struct bt_value_array *typed_array_obj;
+
+       typed_array_obj = BT_VALUE_TO_ARRAY(array_obj);
+       copy_obj = bt_value_array_create();
+
+       if (!copy_obj) {
+               goto end;
+       }
+
+       for (i = 0; i < typed_array_obj->garray->len; ++i) {
+               struct bt_value *element_obj_copy;
+               struct bt_value *element_obj = bt_value_array_get(array_obj, i);
+
+               if (!element_obj) {
+                       BT_VALUE_PUT(copy_obj);
+                       goto end;
+               }
+
+               element_obj_copy = bt_value_copy(element_obj);
+               BT_VALUE_PUT(element_obj);
+
+               if (!element_obj_copy) {
+                       BT_VALUE_PUT(copy_obj);
+                       goto end;
+               }
+
+               ret = bt_value_array_append(copy_obj, element_obj_copy);
+               BT_VALUE_PUT(element_obj_copy);
+
+               if (ret) {
+                       BT_VALUE_PUT(copy_obj);
+                       goto end;
+               }
+       }
+
+end:
+       return copy_obj;
+}
+
+static
+struct bt_value *bt_value_map_copy(const struct bt_value *map_obj)
+{
+       int ret;
+       GHashTableIter iter;
+       gpointer key, element_obj;
+       struct bt_value *copy_obj;
+       struct bt_value *element_obj_copy;
+       struct bt_value_map *typed_map_obj;
+
+       typed_map_obj = BT_VALUE_TO_MAP(map_obj);
+       copy_obj = bt_value_map_create();
+
+       if (!copy_obj) {
+               goto end;
+       }
+
+       g_hash_table_iter_init(&iter, typed_map_obj->ght);
+
+       while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
+               const char *key_str = g_quark_to_string((unsigned long) key);
+
+               element_obj_copy = bt_value_copy(element_obj);
+
+               if (!element_obj_copy) {
+                       BT_VALUE_PUT(copy_obj);
+                       goto end;
+               }
+
+               ret = bt_value_map_insert(copy_obj, key_str, element_obj_copy);
+               BT_VALUE_PUT(element_obj_copy);
+
+               if (ret) {
+                       BT_VALUE_PUT(copy_obj);
+                       goto end;
+               }
+       }
+
+end:
+       return copy_obj;
+}
+
+static
+struct bt_value *(* const copy_funcs[])(const struct bt_value *) = {
+       [BT_VALUE_TYPE_NULL] =          bt_value_null_copy,
+       [BT_VALUE_TYPE_BOOL] =          bt_value_bool_copy,
+       [BT_VALUE_TYPE_INTEGER] =       bt_value_integer_copy,
+       [BT_VALUE_TYPE_FLOAT] =         bt_value_float_copy,
+       [BT_VALUE_TYPE_STRING] =        bt_value_string_copy,
+       [BT_VALUE_TYPE_ARRAY] =         bt_value_array_copy,
+       [BT_VALUE_TYPE_MAP] =           bt_value_map_copy,
+};
+
+static
+bool bt_value_null_compare(const struct bt_value *object_a,
+               const struct bt_value *object_b)
+{
+       /*
+        * Always true since bt_value_compare() already checks if both
+        * object_a and object_b have the same type, and in the case of
+        * null value objects, they're always the same if it is so.
+        */
+       return true;
+}
+
+static
+bool bt_value_bool_compare(const struct bt_value *object_a,
+               const struct bt_value *object_b)
+{
+       return BT_VALUE_TO_BOOL(object_a)->value ==
+               BT_VALUE_TO_BOOL(object_b)->value;
+}
+
+static
+bool bt_value_integer_compare(const struct bt_value *object_a,
+               const struct bt_value *object_b)
+{
+       return BT_VALUE_TO_INTEGER(object_a)->value ==
+               BT_VALUE_TO_INTEGER(object_b)->value;
+}
+
+static
+bool bt_value_float_compare(const struct bt_value *object_a,
+               const struct bt_value *object_b)
+{
+       return BT_VALUE_TO_FLOAT(object_a)->value ==
+               BT_VALUE_TO_FLOAT(object_b)->value;
+}
+
+static
+bool bt_value_string_compare(const struct bt_value *object_a,
+               const struct bt_value *object_b)
+{
+       return !strcmp(BT_VALUE_TO_STRING(object_a)->gstr->str,
+               BT_VALUE_TO_STRING(object_b)->gstr->str);
+}
+
+static
+bool bt_value_array_compare(const struct bt_value *object_a,
+               const struct bt_value *object_b)
+{
+       int i;
+       bool ret = true;
+       const struct bt_value_array *array_obj_a =
+               BT_VALUE_TO_ARRAY(object_a);
+
+       if (bt_value_array_size(object_a) != bt_value_array_size(object_b)) {
+               ret = false;
+               goto end;
+       }
+
+       for (i = 0; i < array_obj_a->garray->len; ++i) {
+               struct bt_value *element_obj_a;
+               struct bt_value *element_obj_b;
+
+               element_obj_a = bt_value_array_get(object_a, i);
+               element_obj_b = bt_value_array_get(object_b, i);
+
+               if (!bt_value_compare(element_obj_a, element_obj_b)) {
+                       BT_VALUE_PUT(element_obj_a);
+                       BT_VALUE_PUT(element_obj_b);
+                       ret = false;
+                       goto end;
+               }
+
+               BT_VALUE_PUT(element_obj_a);
+               BT_VALUE_PUT(element_obj_b);
+       }
+
+end:
+       return ret;
+}
+
+static
+bool bt_value_map_compare(const struct bt_value *object_a,
+               const struct bt_value *object_b)
+{
+       bool ret = true;
+       GHashTableIter iter;
+       gpointer key, element_obj_a;
+       const struct bt_value_map *map_obj_a = BT_VALUE_TO_MAP(object_a);
+
+       if (bt_value_map_size(object_a) != bt_value_map_size(object_b)) {
+               ret = false;
+               goto end;
+       }
+
+       g_hash_table_iter_init(&iter, map_obj_a->ght);
+
+       while (g_hash_table_iter_next(&iter, &key, &element_obj_a)) {
+               struct bt_value *element_obj_b;
+               const char *key_str = g_quark_to_string((unsigned long) key);
+
+               element_obj_b = bt_value_map_get(object_b, key_str);
+
+               if (!bt_value_compare(element_obj_a, element_obj_b)) {
+                       BT_VALUE_PUT(element_obj_b);
+                       ret = false;
+                       goto end;
+               }
+
+               BT_VALUE_PUT(element_obj_b);
+       }
+
+end:
+       return ret;
+}
+
+static
+bool (* const compare_funcs[])(const struct bt_value *,
+               const struct bt_value *) = {
+       [BT_VALUE_TYPE_NULL] =          bt_value_null_compare,
+       [BT_VALUE_TYPE_BOOL] =          bt_value_bool_compare,
+       [BT_VALUE_TYPE_INTEGER] =       bt_value_integer_compare,
+       [BT_VALUE_TYPE_FLOAT] = bt_value_float_compare,
+       [BT_VALUE_TYPE_STRING] =        bt_value_string_compare,
+       [BT_VALUE_TYPE_ARRAY] = bt_value_array_compare,
+       [BT_VALUE_TYPE_MAP] =           bt_value_map_compare,
+};
+
+void bt_value_null_freeze(struct bt_value *object)
+{
+}
+
+void bt_value_generic_freeze(struct bt_value *object)
+{
+       object->is_frozen = true;
+}
+
+void bt_value_array_freeze(struct bt_value *object)
+{
+       int i;
+       struct bt_value_array *typed_array_obj =
+               BT_VALUE_TO_ARRAY(object);
+
+       for (i = 0; i < typed_array_obj->garray->len; ++i) {
+               struct bt_value *element_obj =
+                       g_ptr_array_index(typed_array_obj->garray, i);
+
+               bt_value_freeze(element_obj);
+       }
+
+       bt_value_generic_freeze(object);
+}
+
+void bt_value_map_freeze(struct bt_value *object)
+{
+       GHashTableIter iter;
+       gpointer key, element_obj;
+       const struct bt_value_map *map_obj = BT_VALUE_TO_MAP(object);
+
+       g_hash_table_iter_init(&iter, map_obj->ght);
+
+       while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
+               bt_value_freeze(element_obj);
+       }
+
+       bt_value_generic_freeze(object);
+}
+
+static
+void (* const freeze_funcs[])(struct bt_value *) = {
+       [BT_VALUE_TYPE_NULL] =          bt_value_null_freeze,
+       [BT_VALUE_TYPE_BOOL] =          bt_value_generic_freeze,
+       [BT_VALUE_TYPE_INTEGER] =       bt_value_generic_freeze,
+       [BT_VALUE_TYPE_FLOAT] =         bt_value_generic_freeze,
+       [BT_VALUE_TYPE_STRING] =        bt_value_generic_freeze,
+       [BT_VALUE_TYPE_ARRAY] =         bt_value_array_freeze,
+       [BT_VALUE_TYPE_MAP] =           bt_value_map_freeze,
+};
+
+static
+void bt_value_destroy(struct bt_ref *ref_count)
+{
+       struct bt_value *object;
+
+       object = container_of(ref_count, struct bt_value, ref_count);
+       assert(object->type != BT_VALUE_TYPE_UNKNOWN);
+
+       if (bt_value_is_null(object)) {
+               return;
+       }
+
+       if (destroy_funcs[object->type]) {
+               destroy_funcs[object->type](object);
+       }
+
+       g_free(object);
+}
+
+void bt_value_get(struct bt_value *object)
+{
+       if (object && !bt_value_is_null(object)) {
+               bt_ref_get(&object->ref_count);
+       }
+
+       return;
+}
+
+void bt_value_put(struct bt_value *object)
+{
+       if (object && !bt_value_is_null(object)) {
+               bt_ref_put(&object->ref_count);
+       }
+}
+
+enum bt_value_status bt_value_freeze(struct bt_value *object)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+
+       if (!object) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       freeze_funcs[object->type](object);
+
+end:
+       return ret;
+}
+
+bool bt_value_is_frozen(const struct bt_value *object)
+{
+       return object && object->is_frozen;
+}
+
+enum bt_value_type bt_value_get_type(const struct bt_value *object)
+{
+       if (!object) {
+               return BT_VALUE_TYPE_UNKNOWN;
+       }
+
+       return object->type;
+}
+
+static
+struct bt_value bt_value_create_base(enum bt_value_type type)
+{
+       struct bt_value base;
+
+       base.type = type;
+       base.is_frozen = false;
+       bt_ref_init(&base.ref_count, bt_value_destroy);
+
+       return base;
+}
+
+struct bt_value *bt_value_bool_create_init(bool val)
+{
+       struct bt_value_bool *bool_obj;
+
+       bool_obj = g_new0(struct bt_value_bool, 1);
+
+       if (!bool_obj) {
+               goto end;
+       }
+
+       bool_obj->base = bt_value_create_base(BT_VALUE_TYPE_BOOL);
+       bool_obj->value = val;
+
+end:
+       return BT_VALUE_FROM_CONCRETE(bool_obj);
+}
+
+struct bt_value *bt_value_bool_create(void)
+{
+       return bt_value_bool_create_init(false);
+}
+
+struct bt_value *bt_value_integer_create_init(int64_t val)
+{
+       struct bt_value_integer *integer_obj;
+
+       integer_obj = g_new0(struct bt_value_integer, 1);
+
+       if (!integer_obj) {
+               goto end;
+       }
+
+       integer_obj->base = bt_value_create_base(BT_VALUE_TYPE_INTEGER);
+       integer_obj->value = val;
+
+end:
+       return BT_VALUE_FROM_CONCRETE(integer_obj);
+}
+
+struct bt_value *bt_value_integer_create(void)
+{
+       return bt_value_integer_create_init(0);
+}
+
+struct bt_value *bt_value_float_create_init(double val)
+{
+       struct bt_value_float *float_obj;
+
+       float_obj = g_new0(struct bt_value_float, 1);
+
+       if (!float_obj) {
+               goto end;
+       }
+
+       float_obj->base = bt_value_create_base(BT_VALUE_TYPE_FLOAT);
+       float_obj->value = val;
+
+end:
+       return BT_VALUE_FROM_CONCRETE(float_obj);
+}
+
+struct bt_value *bt_value_float_create(void)
+{
+       return bt_value_float_create_init(0.);
+}
+
+struct bt_value *bt_value_string_create_init(const char *val)
+{
+       struct bt_value_string *string_obj = NULL;
+
+       if (!val) {
+               goto end;
+       }
+
+       string_obj = g_new0(struct bt_value_string, 1);
+
+       if (!string_obj) {
+               goto end;
+       }
+
+       string_obj->base = bt_value_create_base(BT_VALUE_TYPE_STRING);
+       string_obj->gstr = g_string_new(val);
+
+       if (!string_obj->gstr) {
+               g_free(string_obj);
+               string_obj = NULL;
+               goto end;
+       }
+
+end:
+       return BT_VALUE_FROM_CONCRETE(string_obj);
+}
+
+struct bt_value *bt_value_string_create(void)
+{
+       return bt_value_string_create_init("");
+}
+
+struct bt_value *bt_value_array_create(void)
+{
+       struct bt_value_array *array_obj;
+
+       array_obj = g_new0(struct bt_value_array, 1);
+
+       if (!array_obj) {
+               goto end;
+       }
+
+       array_obj->base = bt_value_create_base(BT_VALUE_TYPE_ARRAY);
+       array_obj->garray = g_ptr_array_new_full(0,
+               (GDestroyNotify) bt_value_put);
+
+       if (!array_obj->garray) {
+               g_free(array_obj);
+               array_obj = NULL;
+               goto end;
+       }
+
+end:
+       return BT_VALUE_FROM_CONCRETE(array_obj);
+}
+
+struct bt_value *bt_value_map_create(void)
+{
+       struct bt_value_map *map_obj;
+
+       map_obj = g_new0(struct bt_value_map, 1);
+
+       if (!map_obj) {
+               goto end;
+       }
+
+       map_obj->base = bt_value_create_base(BT_VALUE_TYPE_MAP);
+       map_obj->ght = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+               NULL, (GDestroyNotify) bt_value_put);
+
+       if (!map_obj->ght) {
+               g_free(map_obj);
+               map_obj = NULL;
+               goto end;
+       }
+
+end:
+       return BT_VALUE_FROM_CONCRETE(map_obj);
+}
+
+enum bt_value_status bt_value_bool_get(const struct bt_value *bool_obj,
+       bool *val)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       struct bt_value_bool *typed_bool_obj = BT_VALUE_TO_BOOL(bool_obj);
+
+       if (!bool_obj || !bt_value_is_bool(bool_obj) || !val) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       *val = typed_bool_obj->value;
+
+end:
+       return ret;
+}
+
+enum bt_value_status bt_value_bool_set(struct bt_value *bool_obj, bool val)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       struct bt_value_bool *typed_bool_obj = BT_VALUE_TO_BOOL(bool_obj);
+
+       if (!bool_obj || !bt_value_is_bool(bool_obj)) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       if (bool_obj->is_frozen) {
+               ret = BT_VALUE_STATUS_FROZEN;
+               goto end;
+       }
+
+       typed_bool_obj->value = val;
+
+end:
+       return ret;
+}
+
+enum bt_value_status bt_value_integer_get(const struct bt_value *integer_obj,
+       int64_t *val)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       struct bt_value_integer *typed_integer_obj =
+               BT_VALUE_TO_INTEGER(integer_obj);
+
+       if (!integer_obj || !bt_value_is_integer(integer_obj) || !val) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       *val = typed_integer_obj->value;
+
+end:
+       return ret;
+}
+
+enum bt_value_status bt_value_integer_set(struct bt_value *integer_obj,
+       int64_t val)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       struct bt_value_integer *typed_integer_obj =
+               BT_VALUE_TO_INTEGER(integer_obj);
+
+       if (!integer_obj || !bt_value_is_integer(integer_obj)) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       if (integer_obj->is_frozen) {
+               ret = BT_VALUE_STATUS_FROZEN;
+               goto end;
+       }
+
+       typed_integer_obj->value = val;
+
+end:
+       return ret;
+}
+
+enum bt_value_status bt_value_float_get(const struct bt_value *float_obj,
+       double *val)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       struct bt_value_float *typed_float_obj =
+               BT_VALUE_TO_FLOAT(float_obj);
+
+       if (!float_obj || !bt_value_is_float(float_obj) || !val) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       *val = typed_float_obj->value;
+
+end:
+       return ret;
+}
+
+enum bt_value_status bt_value_float_set(struct bt_value *float_obj,
+       double val)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       struct bt_value_float *typed_float_obj =
+               BT_VALUE_TO_FLOAT(float_obj);
+
+       if (!float_obj || !bt_value_is_float(float_obj)) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       if (float_obj->is_frozen) {
+               ret = BT_VALUE_STATUS_FROZEN;
+               goto end;
+       }
+
+       typed_float_obj->value = val;
+
+end:
+       return ret;
+}
+
+enum bt_value_status bt_value_string_get(const struct bt_value *string_obj,
+       const char **val)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       struct bt_value_string *typed_string_obj =
+               BT_VALUE_TO_STRING(string_obj);
+
+       if (!string_obj || !bt_value_is_string(string_obj) || !val) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       *val = typed_string_obj->gstr->str;
+
+end:
+       return ret;
+}
+
+enum bt_value_status bt_value_string_set(struct bt_value *string_obj,
+       const char *val)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       struct bt_value_string *typed_string_obj =
+               BT_VALUE_TO_STRING(string_obj);
+
+       if (!string_obj || !bt_value_is_string(string_obj) || !val) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       if (string_obj->is_frozen) {
+               ret = BT_VALUE_STATUS_FROZEN;
+               goto end;
+       }
+
+       g_string_assign(typed_string_obj->gstr, val);
+
+end:
+       return ret;
+}
+
+int bt_value_array_size(const struct bt_value *array_obj)
+{
+       int ret;
+       struct bt_value_array *typed_array_obj =
+               BT_VALUE_TO_ARRAY(array_obj);
+
+       if (!array_obj || !bt_value_is_array(array_obj)) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       ret = (int) typed_array_obj->garray->len;
+
+end:
+       return ret;
+}
+
+bool bt_value_array_is_empty(const struct bt_value *array_obj)
+{
+       return bt_value_array_size(array_obj) == 0;
+}
+
+struct bt_value *bt_value_array_get(const struct bt_value *array_obj,
+       size_t index)
+{
+       struct bt_value *ret;
+       struct bt_value_array *typed_array_obj =
+               BT_VALUE_TO_ARRAY(array_obj);
+
+       if (!array_obj || !bt_value_is_array(array_obj) ||
+                       index >= typed_array_obj->garray->len) {
+               ret = NULL;
+               goto end;
+       }
+
+       ret = g_ptr_array_index(typed_array_obj->garray, index);
+       bt_value_get(ret);
+
+end:
+       return ret;
+}
+
+enum bt_value_status bt_value_array_append(struct bt_value *array_obj,
+       struct bt_value *element_obj)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       struct bt_value_array *typed_array_obj =
+               BT_VALUE_TO_ARRAY(array_obj);
+
+       if (!array_obj || !bt_value_is_array(array_obj) || !element_obj) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       if (array_obj->is_frozen) {
+               ret = BT_VALUE_STATUS_FROZEN;
+               goto end;
+       }
+
+       g_ptr_array_add(typed_array_obj->garray, element_obj);
+       bt_value_get(element_obj);
+
+end:
+       return ret;
+}
+
+enum bt_value_status bt_value_array_append_bool(struct bt_value *array_obj,
+       bool val)
+{
+       enum bt_value_status ret;
+       struct bt_value *bool_obj = NULL;
+
+       bool_obj = bt_value_bool_create_init(val);
+       ret = bt_value_array_append(array_obj, bool_obj);
+       bt_value_put(bool_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_array_append_integer(
+       struct bt_value *array_obj, int64_t val)
+{
+       enum bt_value_status ret;
+       struct bt_value *integer_obj = NULL;
+
+       integer_obj = bt_value_integer_create_init(val);
+       ret = bt_value_array_append(array_obj, integer_obj);
+       bt_value_put(integer_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_array_append_float(struct bt_value *array_obj,
+       double val)
+{
+       enum bt_value_status ret;
+       struct bt_value *float_obj = NULL;
+
+       float_obj = bt_value_float_create_init(val);
+       ret = bt_value_array_append(array_obj, float_obj);
+       bt_value_put(float_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_array_append_string(struct bt_value *array_obj,
+       const char *val)
+{
+       enum bt_value_status ret;
+       struct bt_value *string_obj = NULL;
+
+       string_obj = bt_value_string_create_init(val);
+       ret = bt_value_array_append(array_obj, string_obj);
+       bt_value_put(string_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_array_append_array(struct bt_value *array_obj)
+{
+       enum bt_value_status ret;
+       struct bt_value *empty_array_obj = NULL;
+
+       empty_array_obj = bt_value_array_create();
+       ret = bt_value_array_append(array_obj, empty_array_obj);
+       bt_value_put(empty_array_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_array_append_map(struct bt_value *array_obj)
+{
+       enum bt_value_status ret;
+       struct bt_value *map_obj = NULL;
+
+       map_obj = bt_value_map_create();
+       ret = bt_value_array_append(array_obj, map_obj);
+       bt_value_put(map_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_array_set(struct bt_value *array_obj,
+       size_t index, struct bt_value *element_obj)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       struct bt_value_array *typed_array_obj =
+               BT_VALUE_TO_ARRAY(array_obj);
+
+       if (!array_obj || !bt_value_is_array(array_obj) || !element_obj ||
+                       index >= typed_array_obj->garray->len) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       if (array_obj->is_frozen) {
+               ret = BT_VALUE_STATUS_FROZEN;
+               goto end;
+       }
+
+       bt_value_put(g_ptr_array_index(typed_array_obj->garray, index));
+       g_ptr_array_index(typed_array_obj->garray, index) = element_obj;
+       bt_value_get(element_obj);
+
+end:
+       return ret;
+}
+
+int bt_value_map_size(const struct bt_value *map_obj)
+{
+       int ret;
+       struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
+
+       if (!map_obj || !bt_value_is_map(map_obj)) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       ret = (int) g_hash_table_size(typed_map_obj->ght);
+
+end:
+       return ret;
+}
+
+bool bt_value_map_is_empty(const struct bt_value *map_obj)
+{
+       return bt_value_map_size(map_obj) == 0;
+}
+
+struct bt_value *bt_value_map_get(const struct bt_value *map_obj,
+       const char *key)
+{
+       GQuark quark;
+       struct bt_value *ret;
+       struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
+
+       if (!map_obj || !bt_value_is_map(map_obj) || !key) {
+               ret = NULL;
+               goto end;
+       }
+
+       quark = g_quark_from_string(key);
+       ret = g_hash_table_lookup(typed_map_obj->ght, GUINT_TO_POINTER(quark));
+
+       if (ret) {
+               bt_value_get(ret);
+       }
+
+end:
+       return ret;
+}
+
+bool bt_value_map_has_key(const struct bt_value *map_obj, const char *key)
+{
+       bool ret;
+       GQuark quark;
+       struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
+
+       if (!map_obj || !bt_value_is_map(map_obj) || !key) {
+               ret = false;
+               goto end;
+       }
+
+       quark = g_quark_from_string(key);
+       ret = g_hash_table_contains(typed_map_obj->ght,
+               GUINT_TO_POINTER(quark));
+
+end:
+       return ret;
+}
+
+enum bt_value_status bt_value_map_insert(struct bt_value *map_obj,
+       const char *key, struct bt_value *element_obj)
+{
+       GQuark quark;
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
+
+       if (!map_obj || !bt_value_is_map(map_obj) || !key || !element_obj) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       if (map_obj->is_frozen) {
+               ret = BT_VALUE_STATUS_FROZEN;
+               goto end;
+       }
+
+       quark = g_quark_from_string(key);
+       g_hash_table_insert(typed_map_obj->ght,
+               GUINT_TO_POINTER(quark), element_obj);
+       bt_value_get(element_obj);
+
+end:
+       return ret;
+}
+
+enum bt_value_status bt_value_map_insert_bool(struct bt_value *map_obj,
+       const char *key, bool val)
+{
+       enum bt_value_status ret;
+       struct bt_value *bool_obj = NULL;
+
+       bool_obj = bt_value_bool_create_init(val);
+       ret = bt_value_map_insert(map_obj, key, bool_obj);
+       bt_value_put(bool_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_map_insert_integer(struct bt_value *map_obj,
+       const char *key, int64_t val)
+{
+       enum bt_value_status ret;
+       struct bt_value *integer_obj = NULL;
+
+       integer_obj = bt_value_integer_create_init(val);
+       ret = bt_value_map_insert(map_obj, key, integer_obj);
+       bt_value_put(integer_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_map_insert_float(struct bt_value *map_obj,
+       const char *key, double val)
+{
+       enum bt_value_status ret;
+       struct bt_value *float_obj = NULL;
+
+       float_obj = bt_value_float_create_init(val);
+       ret = bt_value_map_insert(map_obj, key, float_obj);
+       bt_value_put(float_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_map_insert_string(struct bt_value *map_obj,
+       const char *key, const char *val)
+{
+       enum bt_value_status ret;
+       struct bt_value *string_obj = NULL;
+
+       string_obj = bt_value_string_create_init(val);
+       ret = bt_value_map_insert(map_obj, key, string_obj);
+       bt_value_put(string_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_map_insert_array(struct bt_value *map_obj,
+       const char *key)
+{
+       enum bt_value_status ret;
+       struct bt_value *array_obj = NULL;
+
+       array_obj = bt_value_array_create();
+       ret = bt_value_map_insert(map_obj, key, array_obj);
+       bt_value_put(array_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_map_insert_map(struct bt_value *map_obj,
+       const char *key)
+{
+       enum bt_value_status ret;
+       struct bt_value *empty_map_obj = NULL;
+
+       empty_map_obj = bt_value_map_create();
+       ret = bt_value_map_insert(map_obj, key, empty_map_obj);
+       bt_value_put(empty_map_obj);
+
+       return ret;
+}
+
+enum bt_value_status bt_value_map_foreach(const struct bt_value *map_obj,
+       bt_value_map_foreach_cb cb, void *data)
+{
+       enum bt_value_status ret = BT_VALUE_STATUS_OK;
+       gpointer key, element_obj;
+       GHashTableIter iter;
+       struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj);
+
+       if (!map_obj || !bt_value_is_map(map_obj) || !cb) {
+               ret = BT_VALUE_STATUS_INVAL;
+               goto end;
+       }
+
+       g_hash_table_iter_init(&iter, typed_map_obj->ght);
+
+       while (g_hash_table_iter_next(&iter, &key, &element_obj)) {
+               const char *key_str = g_quark_to_string((unsigned long) key);
+
+               if (!cb(key_str, element_obj, data)) {
+                       ret = BT_VALUE_STATUS_CANCELLED;
+                       break;
+               }
+       }
+
+end:
+       return ret;
+}
+
+struct bt_value *bt_value_copy(const struct bt_value *object)
+{
+       struct bt_value *copy_obj = NULL;
+
+       if (!object) {
+               goto end;
+       }
+
+       copy_obj = copy_funcs[object->type](object);
+
+end:
+       return copy_obj;
+}
+
+bool bt_value_compare(const struct bt_value *object_a,
+       const struct bt_value *object_b)
+{
+       bool ret = false;
+
+       if (!object_a || !object_b) {
+               goto end;
+       }
+
+       if (object_a->type != object_b->type) {
+               goto end;
+       }
+
+       ret = compare_funcs[object_a->type](object_a, object_b);
+
+end:
+       return ret;
+}
index d11ac54531f3e6343004fb77a647cd69e969eb01..f5e836f6d2e36c0c27cfd4d389d0e46fbe34445a 100644 (file)
@@ -20,15 +20,15 @@ test_ctf_writer_LDADD = $(LIBTAP) \
        $(top_builddir)/lib/libbabeltrace.la \
        $(top_builddir)/formats/ctf/libbabeltrace-ctf.la
 
-test_bt_objects_LDADD = $(LIBTAP) \
+test_bt_values_LDADD = $(LIBTAP) \
        $(top_builddir)/lib/libbabeltrace.la
 
-noinst_PROGRAMS = test_seek test_bitfield test_ctf_writer test_bt_objects
+noinst_PROGRAMS = test_seek test_bitfield test_ctf_writer test_bt_values
 
 test_seek_SOURCES = test_seek.c
 test_bitfield_SOURCES = test_bitfield.c
 test_ctf_writer_SOURCES = test_ctf_writer.c
-test_bt_objects_SOURCES = test_bt_objects.c
+test_bt_values_SOURCES = test_bt_values.c
 
 SCRIPT_LIST = test_seek_big_trace \
        test_seek_empty_packet \
diff --git a/tests/lib/test_bt_objects.c b/tests/lib/test_bt_objects.c
deleted file mode 100644 (file)
index 9713136..0000000
+++ /dev/null
@@ -1,1167 +0,0 @@
-/*
- * test_bt_objects.c
- *
- * Babeltrace basic object system tests
- *
- * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
- * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; under version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#define _GNU_SOURCE
-#include <babeltrace/objects.h>
-#include <assert.h>
-#include <string.h>
-#include "tap/tap.h"
-
-static
-void test_null(void)
-{
-       ok(bt_object_null, "bt_object_null is not NULL");
-       ok(bt_object_is_null(bt_object_null),
-               "bt_object_null is a null object");
-       bt_object_get(bt_object_null);
-       pass("getting bt_object_null does not cause a crash");
-       bt_object_put(bt_object_null);
-       pass("putting bt_object_null does not cause a crash");
-
-       bt_object_get(NULL);
-       pass("getting NULL does not cause a crash");
-       bt_object_put(NULL);
-       pass("putting NULL does not cause a crash");
-
-       ok(bt_object_get_type(NULL) == BT_OBJECT_TYPE_UNKNOWN,
-               "bt_object_get_type(NULL) returns BT_OBJECT_TYPE_UNKNOWN");
-}
-
-static
-void test_bool(void)
-{
-       int ret;
-       bool value;
-       struct bt_object *obj;
-
-       obj = bt_object_bool_create();
-       ok(obj && bt_object_is_bool(obj),
-               "bt_object_bool_create() returns a boolean object");
-
-       value = true;
-       ret = bt_object_bool_get(obj, &value);
-       ok(!ret && !value, "default boolean object value is false");
-
-       ret = bt_object_bool_set(NULL, true);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_bool_set() fails with an object set to NULL");
-       ret = bt_object_bool_get(NULL, &value);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_bool_get() fails with an object set to NULL");
-       ret = bt_object_bool_get(obj, NULL);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_bool_get() fails with a return value set to NULL");
-
-       assert(!bt_object_bool_set(obj, false));
-       ret = bt_object_bool_set(obj, true);
-       ok(!ret, "bt_object_bool_set() succeeds");
-       ret = bt_object_bool_get(obj, &value);
-       ok(!ret && value, "bt_object_bool_set() works");
-
-       BT_OBJECT_PUT(obj);
-       pass("putting an existing boolean object does not cause a crash")
-
-       value = false;
-       obj = bt_object_bool_create_init(true);
-       ok(obj && bt_object_is_bool(obj),
-               "bt_object_bool_create_init() returns a boolean object");
-       ret = bt_object_bool_get(obj, &value);
-       ok(!ret && value,
-               "bt_object_bool_create_init() sets the appropriate initial value");
-
-       assert(!bt_object_freeze(obj));
-       ok(bt_object_bool_set(obj, false) == BT_OBJECT_STATUS_FROZEN,
-               "bt_object_bool_set() cannot be called on a frozen boolean object");
-       value = false;
-       ret = bt_object_bool_get(obj, &value);
-       ok(!ret && value,
-               "bt_object_bool_set() does not alter a frozen floating point number object");
-
-       BT_OBJECT_PUT(obj);
-}
-
-static
-void test_integer(void)
-{
-       int ret;
-       int64_t value;
-       struct bt_object *obj;
-
-       obj = bt_object_integer_create();
-       ok(obj && bt_object_is_integer(obj),
-               "bt_object_integer_create() returns an integer object");
-
-       ret = bt_object_integer_set(NULL, -12345);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_integer_set() fails with an object set to NULL");
-       ret = bt_object_integer_get(NULL, &value);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_integer_get() fails with an object set to NULL");
-       ret = bt_object_integer_get(obj, NULL);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_integer_get() fails with a return value set to NULL");
-
-       value = 1961;
-       ret = bt_object_integer_get(obj, &value);
-       ok(!ret && value == 0, "default integer object value is 0");
-
-       ret = bt_object_integer_set(obj, -98765);
-       ok(!ret, "bt_object_integer_set() succeeds");
-       ret = bt_object_integer_get(obj, &value);
-       ok(!ret && value == -98765, "bt_object_integer_set() works");
-
-       BT_OBJECT_PUT(obj);
-       pass("putting an existing integer object does not cause a crash")
-
-       obj = bt_object_integer_create_init(321456987);
-       ok(obj && bt_object_is_integer(obj),
-               "bt_object_integer_create_init() returns an integer object");
-       ret = bt_object_integer_get(obj, &value);
-       ok(!ret && value == 321456987,
-               "bt_object_integer_create_init() sets the appropriate initial value");
-
-       assert(!bt_object_freeze(obj));
-       ok(bt_object_integer_set(obj, 18276) == BT_OBJECT_STATUS_FROZEN,
-               "bt_object_integer_set() cannot be called on a frozen integer object");
-       value = 17;
-       ret = bt_object_integer_get(obj, &value);
-       ok(!ret && value == 321456987,
-               "bt_object_integer_set() does not alter a frozen integer object");
-
-       BT_OBJECT_PUT(obj);
-}
-
-static
-void test_float(void)
-{
-       int ret;
-       double value;
-       struct bt_object *obj;
-
-       obj = bt_object_float_create();
-       ok(obj && bt_object_is_float(obj),
-               "bt_object_float_create() returns a floating point number object");
-
-       ret = bt_object_float_set(NULL, 1.2345);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_float_set() fails with an object set to NULL");
-       ret = bt_object_float_get(NULL, &value);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_float_get() fails with an object set to NULL");
-       ret = bt_object_float_get(obj, NULL);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_float_get() fails with a return value set to NULL");
-
-       value = 17.34;
-       ret = bt_object_float_get(obj, &value);
-       ok(!ret && value == 0.,
-               "default floating point number object value is 0");
-
-       ret = bt_object_float_set(obj, -3.1416);
-       ok(!ret, "bt_object_float_set() succeeds");
-       ret = bt_object_float_get(obj, &value);
-       ok(!ret && value == -3.1416, "bt_object_float_set() works");
-
-       BT_OBJECT_PUT(obj);
-       pass("putting an existing floating point number object does not cause a crash")
-
-       obj = bt_object_float_create_init(33.1649758);
-       ok(obj && bt_object_is_float(obj),
-               "bt_object_float_create_init() returns a floating point number object");
-       ret = bt_object_float_get(obj, &value);
-       ok(!ret && value == 33.1649758,
-               "bt_object_float_create_init() sets the appropriate initial value");
-
-       assert(!bt_object_freeze(obj));
-       ok(bt_object_float_set(obj, 17.88) == BT_OBJECT_STATUS_FROZEN,
-               "bt_object_float_set() fails with a frozen floating point number object");
-       value = 1.2;
-       ret = bt_object_float_get(obj, &value);
-       ok(!ret && value == 33.1649758,
-               "bt_object_float_set() does not alter a frozen floating point number object");
-
-       BT_OBJECT_PUT(obj);
-}
-
-static
-void test_string(void)
-{
-       int ret;
-       const char *value;
-       struct bt_object *obj;
-
-       obj = bt_object_string_create();
-       ok(obj && bt_object_is_string(obj),
-               "bt_object_string_create() returns a string object");
-
-       ret = bt_object_string_set(NULL, "hoho");
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_string_set() fails with an object set to NULL");
-       ret = bt_object_string_set(obj, NULL);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_string_set() fails with a value set to NULL");
-       ret = bt_object_string_get(NULL, &value);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_string_get() fails with an object set to NULL");
-       ret = bt_object_string_get(obj, NULL);
-       ok(ret == BT_OBJECT_STATUS_INVAL,
-               "bt_object_string_get() fails with a return value set to NULL");
-
-       ret = bt_object_string_get(obj, &value);
-       ok(!ret && value && !strcmp(value, ""),
-               "default string object value is \"\"");
-
-       ret = bt_object_string_set(obj, "hello worldz");
-       ok(!ret, "bt_object_string_set() succeeds");
-       ret = bt_object_string_get(obj, &value);
-       ok(!ret && value && !strcmp(value, "hello worldz"),
-               "bt_object_string_get() works");
-
-       BT_OBJECT_PUT(obj);
-       pass("putting an existing string object does not cause a crash")
-
-       obj = bt_object_string_create_init(NULL);
-       ok(!obj, "bt_object_string_create_init() fails with an initial value set to NULL");
-       obj = bt_object_string_create_init("initial value");
-       ok(obj && bt_object_is_string(obj),
-               "bt_object_string_create_init() returns a string object");
-       ret = bt_object_string_get(obj, &value);
-       ok(!ret && value && !strcmp(value, "initial value"),
-               "bt_object_string_create_init() sets the appropriate initial value");
-
-       assert(!bt_object_freeze(obj));
-       ok(bt_object_string_set(obj, "new value") == BT_OBJECT_STATUS_FROZEN,
-               "bt_object_string_set() fails with a frozen string object");
-       value = "";
-       ret = bt_object_string_get(obj, &value);
-       ok(!ret && value && !strcmp(value, "initial value"),
-               "bt_object_string_set() does not alter a frozen string object");
-
-       BT_OBJECT_PUT(obj);
-}
-
-static
-void test_array(void)
-{
-       int ret;
-       bool bool_value;
-       int64_t int_value;
-       double float_value;
-       struct bt_object *obj;
-       const char *string_value;
-       struct bt_object *array_obj;
-
-       array_obj = bt_object_array_create();
-       ok(array_obj && bt_object_is_array(array_obj),
-               "bt_object_array_create() returns an array object");
-       ok(bt_object_array_is_empty(NULL) == false,
-               "bt_object_array_is_empty() returns false with an object set to NULL");
-       ok(bt_object_array_is_empty(array_obj),
-               "initial array object size is 0");
-       ok(bt_object_array_size(NULL) == BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_size() fails with an array object set to NULL");
-
-       ok(bt_object_array_append(NULL, bt_object_null)
-               == BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_append() fails with an array object set to NULL");
-       ok(bt_object_array_append(array_obj, NULL) == BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_append() fails with a value set to NULL");
-
-       obj = bt_object_integer_create_init(345);
-       ret = bt_object_array_append(array_obj, obj);
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_float_create_init(-17.45);
-       ret |= bt_object_array_append(array_obj, obj);
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_bool_create_init(true);
-       ret |= bt_object_array_append(array_obj, obj);
-       BT_OBJECT_PUT(obj);
-       ret |= bt_object_array_append(array_obj, bt_object_null);
-       ok(!ret, "bt_object_array_append() succeeds");
-       ok(bt_object_array_size(array_obj) == 4,
-               "appending an element to an array object increment its size");
-
-       obj = bt_object_array_get(array_obj, 4);
-       ok(!obj, "getting an array object's element at an index equal to its size fails");
-       obj = bt_object_array_get(array_obj, 5);
-       ok(!obj, "getting an array object's element at a larger index fails");
-
-       obj = bt_object_array_get(NULL, 2);
-       ok(!obj, "bt_object_array_get() fails with an array object set to NULL");
-
-       obj = bt_object_array_get(array_obj, 0);
-       ok(obj && bt_object_is_integer(obj),
-               "bt_object_array_get() returns an object with the appropriate type (integer)");
-       ret = bt_object_integer_get(obj, &int_value);
-       ok(!ret && int_value == 345,
-               "bt_object_array_get() returns an object with the appropriate value (integer)");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_array_get(array_obj, 1);
-       ok(obj && bt_object_is_float(obj),
-               "bt_object_array_get() returns an object with the appropriate type (floating point number)");
-       ret = bt_object_float_get(obj, &float_value);
-       ok(!ret && float_value == -17.45,
-               "bt_object_array_get() returns an object with the appropriate value (floating point number)");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_array_get(array_obj, 2);
-       ok(obj && bt_object_is_bool(obj),
-               "bt_object_array_get() returns an object with the appropriate type (boolean)");
-       ret = bt_object_bool_get(obj, &bool_value);
-       ok(!ret && bool_value,
-               "bt_object_array_get() returns an object with the appropriate value (boolean)");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_array_get(array_obj, 3);
-       ok(obj == bt_object_null,
-               "bt_object_array_get() returns an object with the appropriate type (null)");
-
-       ok(bt_object_array_set(NULL, 0, bt_object_null) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_set() fails with an array object set to NULL");
-       ok(bt_object_array_set(array_obj, 0, NULL) == BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_set() fails with an element object set to NULL");
-       ok(bt_object_array_set(array_obj, 4, bt_object_null) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_set() fails with an invalid index");
-       obj = bt_object_integer_create_init(1001);
-       assert(obj);
-       ok(!bt_object_array_set(array_obj, 2, obj),
-               "bt_object_array_set() succeeds");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_array_get(array_obj, 2);
-       ok(obj && bt_object_is_integer(obj),
-               "bt_object_array_set() inserts an object with the appropriate type");
-       ret = bt_object_integer_get(obj, &int_value);
-       assert(!ret);
-       ok(int_value == 1001,
-               "bt_object_array_set() inserts an object with the appropriate value");
-       BT_OBJECT_PUT(obj);
-
-       ret = bt_object_array_append_bool(array_obj, false);
-       ok(!ret, "bt_object_array_append_bool() succeeds");
-       ok(bt_object_array_append_bool(NULL, true) == BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_append_bool() fails with an array object set to NULL");
-       ret = bt_object_array_append_integer(array_obj, 98765);
-       ok(!ret, "bt_object_array_append_integer() succeeds");
-       ok(bt_object_array_append_integer(NULL, 18765) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_append_integer() fails with an array object set to NULL");
-       ret = bt_object_array_append_float(array_obj, 2.49578);
-       ok(!ret, "bt_object_array_append_float() succeeds");
-       ok(bt_object_array_append_float(NULL, 1.49578) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_append_float() fails with an array object set to NULL");
-       ret = bt_object_array_append_string(array_obj, "bt_object");
-       ok(!ret, "bt_object_array_append_string() succeeds");
-       ok(bt_object_array_append_string(NULL, "bt_obj") ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_append_string() fails with an array object set to NULL");
-       ret = bt_object_array_append_array(array_obj);
-       ok(!ret, "bt_object_array_append_array() succeeds");
-       ok(bt_object_array_append_array(NULL) == BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_append_array() fails with an array object set to NULL");
-       ret = bt_object_array_append_map(array_obj);
-       ok(!ret, "bt_object_array_append_map() succeeds");
-       ok(bt_object_array_append_map(NULL) == BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_append_map() fails with an array object set to NULL");
-
-       ok(bt_object_array_size(array_obj) == 10,
-               "the bt_object_array_append_*() functions increment the array object's size");
-       ok(!bt_object_array_is_empty(array_obj),
-               "map object is not empty");
-
-       obj = bt_object_array_get(array_obj, 4);
-       ok(obj && bt_object_is_bool(obj),
-               "bt_object_array_append_bool() appends a boolean object");
-       ret = bt_object_bool_get(obj, &bool_value);
-       ok(!ret && !bool_value,
-               "bt_object_array_append_bool() appends the appropriate value");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_array_get(array_obj, 5);
-       ok(obj && bt_object_is_integer(obj),
-               "bt_object_array_append_integer() appends an integer object");
-       ret = bt_object_integer_get(obj, &int_value);
-       ok(!ret && int_value == 98765,
-               "bt_object_array_append_integer() appends the appropriate value");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_array_get(array_obj, 6);
-       ok(obj && bt_object_is_float(obj),
-               "bt_object_array_append_float() appends a floating point number object");
-       ret = bt_object_float_get(obj, &float_value);
-       ok(!ret && float_value == 2.49578,
-               "bt_object_array_append_float() appends the appropriate value");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_array_get(array_obj, 7);
-       ok(obj && bt_object_is_string(obj),
-               "bt_object_array_append_string() appends a string object");
-       ret = bt_object_string_get(obj, &string_value);
-       ok(!ret && string_value && !strcmp(string_value, "bt_object"),
-               "bt_object_array_append_string() appends the appropriate value");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_array_get(array_obj, 8);
-       ok(obj && bt_object_is_array(obj),
-               "bt_object_array_append_array() appends an array object");
-       ok(bt_object_array_is_empty(obj),
-               "bt_object_array_append_array() an empty array object");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_array_get(array_obj, 9);
-       ok(obj && bt_object_is_map(obj),
-               "bt_object_array_append_map() appends a map object");
-       ok(bt_object_map_is_empty(obj),
-               "bt_object_array_append_map() an empty map object");
-       BT_OBJECT_PUT(obj);
-
-       assert(!bt_object_freeze(array_obj));
-       ok(bt_object_array_append(array_obj, bt_object_null) ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_array_append() fails with a frozen array object");
-       ok(bt_object_array_append_bool(array_obj, false) ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_array_append_bool() fails with a frozen array object");
-       ok(bt_object_array_append_integer(array_obj, 23) ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_array_append_integer() fails with a frozen array object");
-       ok(bt_object_array_append_float(array_obj, 2.34) ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_array_append_float() fails with a frozen array object");
-       ok(bt_object_array_append_string(array_obj, "yayayayaya") ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_array_append_string() fails with a frozen array object");
-       ok(bt_object_array_append_array(array_obj) ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_array_append_array() fails with a frozen array object");
-       ok(bt_object_array_append_map(array_obj) ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_array_append_map() fails with a frozen array object");
-       ok(bt_object_array_set(array_obj, 2, bt_object_null) ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_array_set() fails with a frozen array object");
-       ok(bt_object_array_size(array_obj) == 10,
-               "appending to a frozen array object does not change its size");
-
-       obj = bt_object_array_get(array_obj, 1);
-       assert(obj);
-       ok(bt_object_float_set(obj, 14.52) == BT_OBJECT_STATUS_FROZEN,
-               "freezing an array object also freezes its elements");
-       BT_OBJECT_PUT(obj);
-
-       BT_OBJECT_PUT(array_obj);
-       pass("putting an existing array object does not cause a crash")
-}
-
-static
-bool test_map_foreach_cb_count(const char *key, struct bt_object *object,
-       void *data)
-{
-       int *count = data;
-
-       if (*count == 3) {
-               return false;
-       }
-
-       (*count)++;
-
-       return true;
-}
-
-struct map_foreach_checklist {
-       bool bool1;
-       bool int1;
-       bool float1;
-       bool null1;
-       bool bool2;
-       bool int2;
-       bool float2;
-       bool string2;
-       bool array2;
-       bool map2;
-};
-
-static
-bool test_map_foreach_cb_check(const char *key, struct bt_object *object,
-       void *data)
-{
-       int ret;
-       struct map_foreach_checklist *checklist = data;
-
-       if (!strcmp(key, "bool")) {
-               if (checklist->bool1) {
-                       fail("test_map_foreach_cb_check(): duplicate key \"bool\"");
-               } else {
-                       bool val = false;
-
-                       ret = bt_object_bool_get(object, &val);
-                       ok(!ret, "test_map_foreach_cb_check(): success getting \"bool\" value");
-
-                       if (val) {
-                               pass("test_map_foreach_cb_check(): \"bool\" object has the right value");
-                               checklist->bool1 = true;
-                       } else {
-                               fail("test_map_foreach_cb_check(): \"bool\" object has the wrong value");
-                       }
-               }
-       } else if (!strcmp(key, "int")) {
-               if (checklist->int1) {
-                       fail("test_map_foreach_cb_check(): duplicate key \"int\"");
-               } else {
-                       int64_t val = 0;
-
-                       ret = bt_object_integer_get(object, &val);
-                       ok(!ret, "test_map_foreach_cb_check(): success getting \"int\" value");
-
-                       if (val == 19457) {
-                               pass("test_map_foreach_cb_check(): \"int\" object has the right value");
-                               checklist->int1 = true;
-                       } else {
-                               fail("test_map_foreach_cb_check(): \"int\" object has the wrong value");
-                       }
-               }
-       } else if (!strcmp(key, "float")) {
-               if (checklist->float1) {
-                       fail("test_map_foreach_cb_check(): duplicate key \"float\"");
-               } else {
-                       double val = 0;
-
-                       ret = bt_object_float_get(object, &val);
-                       ok(!ret, "test_map_foreach_cb_check(): success getting \"float\" value");
-
-                       if (val == 5.444) {
-                               pass("test_map_foreach_cb_check(): \"float\" object has the right value");
-                               checklist->float1 = true;
-                       } else {
-                               fail("test_map_foreach_cb_check(): \"float\" object has the wrong value");
-                       }
-               }
-       } else if (!strcmp(key, "null")) {
-               if (checklist->null1) {
-                       fail("test_map_foreach_cb_check(): duplicate key \"bool\"");
-               } else {
-                       ok(bt_object_is_null(object), "test_map_foreach_cb_check(): success getting \"null\" object");
-                       checklist->null1 = true;
-               }
-       } else if (!strcmp(key, "bool2")) {
-               if (checklist->bool2) {
-                       fail("test_map_foreach_cb_check(): duplicate key \"bool2\"");
-               } else {
-                       bool val = false;
-
-                       ret = bt_object_bool_get(object, &val);
-                       ok(!ret, "test_map_foreach_cb_check(): success getting \"bool2\" value");
-
-                       if (val) {
-                               pass("test_map_foreach_cb_check(): \"bool2\" object has the right value");
-                               checklist->bool2 = true;
-                       } else {
-                               fail("test_map_foreach_cb_check(): \"bool2\" object has the wrong value");
-                       }
-               }
-       } else if (!strcmp(key, "int2")) {
-               if (checklist->int2) {
-                       fail("test_map_foreach_cb_check(): duplicate key \"int2\"");
-               } else {
-                       int64_t val = 0;
-
-                       ret = bt_object_integer_get(object, &val);
-                       ok(!ret, "test_map_foreach_cb_check(): success getting \"int2\" value");
-
-                       if (val == 98765) {
-                               pass("test_map_foreach_cb_check(): \"int2\" object has the right value");
-                               checklist->int2 = true;
-                       } else {
-                               fail("test_map_foreach_cb_check(): \"int2\" object has the wrong value");
-                       }
-               }
-       } else if (!strcmp(key, "float2")) {
-               if (checklist->float2) {
-                       fail("test_map_foreach_cb_check(): duplicate key \"float2\"");
-               } else {
-                       double val = 0;
-
-                       ret = bt_object_float_get(object, &val);
-                       ok(!ret, "test_map_foreach_cb_check(): success getting \"float2\" value");
-
-                       if (val == -49.0001) {
-                               pass("test_map_foreach_cb_check(): \"float2\" object has the right value");
-                               checklist->float2 = true;
-                       } else {
-                               fail("test_map_foreach_cb_check(): \"float2\" object has the wrong value");
-                       }
-               }
-       } else if (!strcmp(key, "string2")) {
-               if (checklist->string2) {
-                       fail("test_map_foreach_cb_check(): duplicate key \"string2\"");
-               } else {
-                       const char *val;
-
-                       ret = bt_object_string_get(object, &val);
-                       ok(!ret, "test_map_foreach_cb_check(): success getting \"string2\" value");
-
-                       if (val && !strcmp(val, "bt_object")) {
-                               pass("test_map_foreach_cb_check(): \"string2\" object has the right value");
-                               checklist->string2 = true;
-                       } else {
-                               fail("test_map_foreach_cb_check(): \"string2\" object has the wrong value");
-                       }
-               }
-       } else if (!strcmp(key, "array2")) {
-               if (checklist->array2) {
-                       fail("test_map_foreach_cb_check(): duplicate key \"array2\"");
-               } else {
-                       ok(bt_object_is_array(object), "test_map_foreach_cb_check(): success getting \"array2\" object");
-                       ok(bt_object_array_is_empty(object),
-                               "test_map_foreach_cb_check(): \"array2\" object is empty");
-                       checklist->array2 = true;
-               }
-       } else if (!strcmp(key, "map2")) {
-               if (checklist->map2) {
-                       fail("test_map_foreach_cb_check(): duplicate key \"map2\"");
-               } else {
-                       ok(bt_object_is_map(object), "test_map_foreach_cb_check(): success getting \"map2\" object");
-                       ok(bt_object_map_is_empty(object),
-                               "test_map_foreach_cb_check(): \"map2\" object is empty");
-                       checklist->map2 = true;
-               }
-       } else {
-               fail("test_map_foreach_cb_check(): unknown map key \"%s\"", key);
-       }
-
-       return true;
-}
-
-static
-void test_map(void)
-{
-       int ret;
-       int count = 0;
-       bool bool_value;
-       int64_t int_value;
-       double float_value;
-       struct bt_object *obj;
-       struct bt_object *map_obj;
-       struct map_foreach_checklist checklist;
-
-       map_obj = bt_object_map_create();
-       ok(map_obj && bt_object_is_map(map_obj),
-               "bt_object_map_create() returns a map object");
-       ok(bt_object_map_size(map_obj) == 0,
-               "initial map object size is 0");
-       ok(bt_object_map_size(NULL) == BT_OBJECT_STATUS_INVAL,
-               "bt_object_map_size() fails with a map object set to NULL");
-
-       ok(bt_object_map_insert(NULL, "hello", bt_object_null) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_insert() fails with a map object set to NULL");
-       ok(bt_object_map_insert(map_obj, NULL, bt_object_null) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_insert() fails with a key set to NULL");
-       ok(bt_object_map_insert(map_obj, "yeah", NULL) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_array_insert() fails with an element object set to NULL");
-
-       obj = bt_object_integer_create_init(19457);
-       ret = bt_object_map_insert(map_obj, "int", obj);
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_float_create_init(5.444);
-       ret |= bt_object_map_insert(map_obj, "float", obj);
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_bool_create();
-       ret |= bt_object_map_insert(map_obj, "bool", obj);
-       BT_OBJECT_PUT(obj);
-       ret |= bt_object_map_insert(map_obj, "null", bt_object_null);
-       ok(!ret, "bt_object_map_insert() succeeds");
-       ok(bt_object_map_size(map_obj) == 4,
-               "inserting an element into a map object increment its size");
-
-       obj = bt_object_bool_create_init(true);
-       ret = bt_object_map_insert(map_obj, "bool", obj);
-       BT_OBJECT_PUT(obj);
-       ok(!ret, "bt_object_map_insert() accepts an existing key");
-
-       obj = bt_object_map_get(map_obj, NULL);
-       ok(!obj, "bt_object_map_get() fails with a key set to NULL");
-       obj = bt_object_map_get(NULL, "bool");
-       ok(!obj, "bt_object_map_get() fails with a map object set to NULL");
-
-       obj = bt_object_map_get(map_obj, "life");
-       ok(!obj, "bt_object_map_get() fails with an non existing key");
-       obj = bt_object_map_get(map_obj, "float");
-       ok(obj && bt_object_is_float(obj),
-               "bt_object_map_get() returns an object with the appropriate type (float)");
-       ret = bt_object_float_get(obj, &float_value);
-       ok(!ret && float_value == 5.444,
-               "bt_object_map_get() returns an object with the appropriate value (float)");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_map_get(map_obj, "int");
-       ok(obj && bt_object_is_integer(obj),
-               "bt_object_map_get() returns an object with the appropriate type (integer)");
-       ret = bt_object_integer_get(obj, &int_value);
-       ok(!ret && int_value == 19457,
-               "bt_object_map_get() returns an object with the appropriate value (integer)");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_map_get(map_obj, "null");
-       ok(obj && bt_object_is_null(obj),
-               "bt_object_map_get() returns an object with the appropriate type (null)");
-       obj = bt_object_map_get(map_obj, "bool");
-       ok(obj && bt_object_is_bool(obj),
-               "bt_object_map_get() returns an object with the appropriate type (boolean)");
-       ret = bt_object_bool_get(obj, &bool_value);
-       ok(!ret && bool_value,
-               "bt_object_map_get() returns an object with the appropriate value (boolean)");
-       BT_OBJECT_PUT(obj);
-
-       ret = bt_object_map_insert_bool(map_obj, "bool2", true);
-       ok(!ret, "bt_object_map_insert_bool() succeeds");
-       ok(bt_object_map_insert_bool(NULL, "bool2", false) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_map_insert_bool() fails with a map object set to NULL");
-       ret = bt_object_map_insert_integer(map_obj, "int2", 98765);
-       ok(!ret, "bt_object_map_insert_integer() succeeds");
-       ok(bt_object_map_insert_integer(NULL, "int2", 1001) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_map_insert_integer() fails with a map object set to NULL");
-       ret = bt_object_map_insert_float(map_obj, "float2", -49.0001);
-       ok(!ret, "bt_object_map_insert_float() succeeds");
-       ok(bt_object_map_insert_float(NULL, "float2", 495) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_map_insert_float() fails with a map object set to NULL");
-       ret = bt_object_map_insert_string(map_obj, "string2", "bt_object");
-       ok(!ret, "bt_object_map_insert_string() succeeds");
-       ok(bt_object_map_insert_string(NULL, "string2", "bt_obj") ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_map_insert_string() fails with a map object set to NULL");
-       ret = bt_object_map_insert_array(map_obj, "array2");
-       ok(!ret, "bt_object_map_insert_array() succeeds");
-       ok(bt_object_map_insert_array(NULL, "array2") == BT_OBJECT_STATUS_INVAL,
-               "bt_object_map_insert_array() fails with a map object set to NULL");
-       ret = bt_object_map_insert_map(map_obj, "map2");
-       ok(!ret, "bt_object_map_insert_map() succeeds");
-       ok(bt_object_map_insert_map(NULL, "map2") == BT_OBJECT_STATUS_INVAL,
-               "bt_object_map_insert_map() fails with a map object set to NULL");
-
-       ok(bt_object_map_size(map_obj) == 10,
-               "the bt_object_map_insert*() functions increment the map object's size");
-
-       ok(!bt_object_map_has_key(map_obj, "hello"),
-               "map object does not have key \"hello\"");
-       ok(bt_object_map_has_key(map_obj, "bool"),
-               "map object has key \"bool\"");
-       ok(bt_object_map_has_key(map_obj, "int"),
-               "map object has key \"int\"");
-       ok(bt_object_map_has_key(map_obj, "float"),
-               "map object has key \"float\"");
-       ok(bt_object_map_has_key(map_obj, "null"),
-               "map object has key \"null\"");
-       ok(bt_object_map_has_key(map_obj, "bool2"),
-               "map object has key \"bool2\"");
-       ok(bt_object_map_has_key(map_obj, "int2"),
-               "map object has key \"int2\"");
-       ok(bt_object_map_has_key(map_obj, "float2"),
-               "map object has key \"float2\"");
-       ok(bt_object_map_has_key(map_obj, "string2"),
-               "map object has key \"string2\"");
-       ok(bt_object_map_has_key(map_obj, "array2"),
-               "map object has key \"array2\"");
-       ok(bt_object_map_has_key(map_obj, "map2"),
-               "map object has key \"map2\"");
-
-       ok(bt_object_map_foreach(NULL, test_map_foreach_cb_count, &count) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_map_foreach() fails with a map object set to NULL");
-       ok(bt_object_map_foreach(map_obj, NULL, &count) ==
-               BT_OBJECT_STATUS_INVAL,
-               "bt_object_map_foreach() fails with a user function set to NULL");
-       ret = bt_object_map_foreach(map_obj, test_map_foreach_cb_count, &count);
-       ok(ret == BT_OBJECT_STATUS_CANCELLED && count == 3,
-               "bt_object_map_foreach() breaks the loop when the user function returns false");
-
-       memset(&checklist, 0, sizeof(checklist));
-       ret = bt_object_map_foreach(map_obj, test_map_foreach_cb_check,
-               &checklist);
-       ok(ret == BT_OBJECT_STATUS_OK,
-               "bt_object_map_foreach() succeeds with test_map_foreach_cb_check()");
-       ok(checklist.bool1 && checklist.int1 && checklist.float1 &&
-               checklist.null1 && checklist.bool2 && checklist.int2 &&
-               checklist.float2 && checklist.string2 &&
-               checklist.array2 && checklist.map2,
-               "bt_object_map_foreach() iterates over all the map object's elements");
-
-       assert(!bt_object_freeze(map_obj));
-       ok(bt_object_map_insert(map_obj, "allo", bt_object_null) ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_map_insert() fails with a frozen map object");
-       ok(bt_object_map_insert_bool(map_obj, "duh", false) ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_map_insert_bool() fails with a frozen array object");
-       ok(bt_object_map_insert_integer(map_obj, "duh", 23) ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_map_insert_integer() fails with a frozen array object");
-       ok(bt_object_map_insert_float(map_obj, "duh", 2.34) ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_map_insert_float() fails with a frozen array object");
-       ok(bt_object_map_insert_string(map_obj, "duh", "yayayayaya") ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_map_insert_string() fails with a frozen array object");
-       ok(bt_object_map_insert_array(map_obj, "duh") ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_map_insert_array() fails with a frozen array object");
-       ok(bt_object_map_insert_map(map_obj, "duh") ==
-               BT_OBJECT_STATUS_FROZEN,
-               "bt_object_map_insert_map() fails with a frozen array object");
-       ok(bt_object_map_size(map_obj) == 10,
-               "appending to a frozen map object does not change its size");
-
-       BT_OBJECT_PUT(map_obj);
-       pass("putting an existing map object does not cause a crash")
-}
-
-static
-void test_types(void)
-{
-       test_null();
-       test_bool();
-       test_integer();
-       test_float();
-       test_string();
-       test_array();
-       test_map();
-}
-
-static
-void test_compare_null(void)
-{
-       ok(!bt_object_compare(bt_object_null, NULL),
-               "cannot compare null object and NULL");
-       ok(!bt_object_compare(NULL, bt_object_null),
-               "cannot compare NULL and null object");
-       ok(bt_object_compare(bt_object_null, bt_object_null),
-               "null objects are equivalent");
-}
-
-static
-void test_compare_bool(void)
-{
-       struct bt_object *bool1 = bt_object_bool_create_init(false);
-       struct bt_object *bool2 = bt_object_bool_create_init(true);
-       struct bt_object *bool3 = bt_object_bool_create_init(false);
-
-       assert(bool1 && bool2 && bool3);
-       ok(!bt_object_compare(bt_object_null, bool1),
-               "cannot compare null object and bool object");
-       ok(!bt_object_compare(bool1, bool2),
-               "integer objects are not equivalent (false and true)");
-       ok(bt_object_compare(bool1, bool3),
-               "integer objects are equivalent (false and false)");
-
-       BT_OBJECT_PUT(bool1);
-       BT_OBJECT_PUT(bool2);
-       BT_OBJECT_PUT(bool3);
-}
-
-static
-void test_compare_integer(void)
-{
-       struct bt_object *int1 = bt_object_integer_create_init(10);
-       struct bt_object *int2 = bt_object_integer_create_init(-23);
-       struct bt_object *int3 = bt_object_integer_create_init(10);
-
-       assert(int1 && int2 && int3);
-       ok(!bt_object_compare(bt_object_null, int1),
-               "cannot compare null object and integer object");
-       ok(!bt_object_compare(int1, int2),
-               "integer objects are not equivalent (10 and -23)");
-       ok(bt_object_compare(int1, int3),
-               "integer objects are equivalent (10 and 10)");
-
-       BT_OBJECT_PUT(int1);
-       BT_OBJECT_PUT(int2);
-       BT_OBJECT_PUT(int3);
-}
-
-static
-void test_compare_float(void)
-{
-       struct bt_object *float1 = bt_object_float_create_init(17.38);
-       struct bt_object *float2 = bt_object_float_create_init(-14.23);
-       struct bt_object *float3 = bt_object_float_create_init(17.38);
-
-       assert(float1 && float2 && float3);
-
-       ok(!bt_object_compare(bt_object_null, float1),
-               "cannot compare null object and floating point number object");
-       ok(!bt_object_compare(float1, float2),
-               "floating point number objects are not equivalent (17.38 and -14.23)");
-       ok(bt_object_compare(float1, float3),
-               "floating point number objects are equivalent (17.38 and 17.38)");
-
-       BT_OBJECT_PUT(float1);
-       BT_OBJECT_PUT(float2);
-       BT_OBJECT_PUT(float3);
-}
-
-static
-void test_compare_string(void)
-{
-       struct bt_object *string1 = bt_object_string_create_init("hello");
-       struct bt_object *string2 = bt_object_string_create_init("bt_object");
-       struct bt_object *string3 = bt_object_string_create_init("hello");
-
-       assert(string1 && string2 && string3);
-
-       ok(!bt_object_compare(bt_object_null, string1),
-               "cannot compare null object and string object");
-       ok(!bt_object_compare(string1, string2),
-               "string objects are not equivalent (\"hello\" and \"bt_object\")");
-       ok(bt_object_compare(string1, string3),
-               "string objects are equivalent (\"hello\" and \"hello\")");
-
-       BT_OBJECT_PUT(string1);
-       BT_OBJECT_PUT(string2);
-       BT_OBJECT_PUT(string3);
-}
-
-static
-void test_compare_array(void)
-{
-       struct bt_object *array1 = bt_object_array_create();
-       struct bt_object *array2 = bt_object_array_create();
-       struct bt_object *array3 = bt_object_array_create();
-
-       assert(array1 && array2 && array3);
-
-       ok(bt_object_compare(array1, array2),
-               "empty array objects are equivalent");
-
-       assert(!bt_object_array_append_integer(array1, 23));
-       assert(!bt_object_array_append_float(array1, 14.2));
-       assert(!bt_object_array_append_bool(array1, false));
-       assert(!bt_object_array_append_float(array2, 14.2));
-       assert(!bt_object_array_append_integer(array2, 23));
-       assert(!bt_object_array_append_bool(array2, false));
-       assert(!bt_object_array_append_integer(array3, 23));
-       assert(!bt_object_array_append_float(array3, 14.2));
-       assert(!bt_object_array_append_bool(array3, false));
-       assert(bt_object_array_size(array1) == 3);
-       assert(bt_object_array_size(array2) == 3);
-       assert(bt_object_array_size(array3) == 3);
-
-       ok(!bt_object_compare(bt_object_null, array1),
-               "cannot compare null object and array object");
-       ok(!bt_object_compare(array1, array2),
-               "array objects are not equivalent ([23, 14.2, false] and [14.2, 23, false])");
-       ok(bt_object_compare(array1, array3),
-               "array objects are equivalent ([23, 14.2, false] and [23, 14.2, false])");
-
-       BT_OBJECT_PUT(array1);
-       BT_OBJECT_PUT(array2);
-       BT_OBJECT_PUT(array3);
-}
-
-static
-void test_compare_map(void)
-{
-       struct bt_object *map1 = bt_object_map_create();
-       struct bt_object *map2 = bt_object_map_create();
-       struct bt_object *map3 = bt_object_map_create();
-
-       assert(map1 && map2 && map3);
-
-       ok(bt_object_compare(map1, map2),
-               "empty map objects are equivalent");
-
-       assert(!bt_object_map_insert_integer(map1, "one", 23));
-       assert(!bt_object_map_insert_float(map1, "two", 14.2));
-       assert(!bt_object_map_insert_bool(map1, "three", false));
-       assert(!bt_object_map_insert_float(map2, "one", 14.2));
-       assert(!bt_object_map_insert_integer(map2, "two", 23));
-       assert(!bt_object_map_insert_bool(map2, "three", false));
-       assert(!bt_object_map_insert_bool(map3, "three", false));
-       assert(!bt_object_map_insert_integer(map3, "one", 23));
-       assert(!bt_object_map_insert_float(map3, "two", 14.2));
-       assert(bt_object_map_size(map1) == 3);
-       assert(bt_object_map_size(map2) == 3);
-       assert(bt_object_map_size(map3) == 3);
-
-       ok(!bt_object_compare(bt_object_null, map1),
-               "cannot compare null object and map object");
-       ok(!bt_object_compare(map1, map2),
-               "map objects are not equivalent");
-       ok(bt_object_compare(map1, map3),
-               "map objects are equivalent");
-
-       BT_OBJECT_PUT(map1);
-       BT_OBJECT_PUT(map2);
-       BT_OBJECT_PUT(map3);
-}
-
-static
-void test_compare(void)
-{
-       ok(!bt_object_compare(NULL, NULL), "cannot compare NULL and NULL");
-       test_compare_null();
-       test_compare_bool();
-       test_compare_integer();
-       test_compare_float();
-       test_compare_string();
-       test_compare_array();
-       test_compare_map();
-}
-
-static
-void test_copy(void)
-{
-       /*
-        * Here's the deal here. If we make sure that each object
-        * of our deep copy has a different address than its source,
-        * and that bt_object_compare() returns true for the top-level
-        * object, taking into account that we test the correctness of
-        * bt_object_compare() elsewhere, then the deep copy is a
-        * success.
-        */
-       struct bt_object *null_copy_obj;
-       struct bt_object *bool_obj, *bool_copy_obj;
-       struct bt_object *integer_obj, *integer_copy_obj;
-       struct bt_object *float_obj, *float_copy_obj;
-       struct bt_object *string_obj, *string_copy_obj;
-       struct bt_object *array_obj, *array_copy_obj;
-       struct bt_object *map_obj, *map_copy_obj;
-
-       bool_obj = bt_object_bool_create_init(true);
-       integer_obj = bt_object_integer_create_init(23);
-       float_obj = bt_object_float_create_init(-3.1416);
-       string_obj = bt_object_string_create_init("test");
-       array_obj = bt_object_array_create();
-       map_obj = bt_object_map_create();
-
-       assert(bool_obj && integer_obj && float_obj && string_obj &&
-               array_obj && map_obj);
-
-       assert(!bt_object_array_append(array_obj, bool_obj));
-       assert(!bt_object_array_append(array_obj, integer_obj));
-       assert(!bt_object_array_append(array_obj, float_obj));
-       assert(!bt_object_array_append(array_obj, bt_object_null));
-       assert(!bt_object_map_insert(map_obj, "array", array_obj));
-       assert(!bt_object_map_insert(map_obj, "string", string_obj));
-
-       map_copy_obj = bt_object_copy(NULL);
-       ok(!map_copy_obj,
-               "bt_object_copy() fails with a source object set to NULL");
-
-       map_copy_obj = bt_object_copy(map_obj);
-       ok(map_copy_obj,
-               "bt_object_copy() succeeds");
-
-       ok(map_obj != map_copy_obj,
-               "bt_object_copy() returns a different pointer (map)");
-       string_copy_obj = bt_object_map_get(map_copy_obj, "string");
-       ok(string_copy_obj != string_obj,
-               "bt_object_copy() returns a different pointer (string)");
-       array_copy_obj = bt_object_map_get(map_copy_obj, "array");
-       ok(array_copy_obj != array_obj,
-               "bt_object_copy() returns a different pointer (array)");
-       bool_copy_obj = bt_object_array_get(array_copy_obj, 0);
-       ok(bool_copy_obj != bool_obj,
-               "bt_object_copy() returns a different pointer (bool)");
-       integer_copy_obj = bt_object_array_get(array_copy_obj, 1);
-       ok(integer_copy_obj != integer_obj,
-               "bt_object_copy() returns a different pointer (integer)");
-       float_copy_obj = bt_object_array_get(array_copy_obj, 2);
-       ok(float_copy_obj != float_obj,
-               "bt_object_copy() returns a different pointer (float)");
-       null_copy_obj = bt_object_array_get(array_copy_obj, 3);
-       ok(null_copy_obj == bt_object_null,
-               "bt_object_copy() returns the same pointer (null)");
-
-       ok(bt_object_compare(map_obj, map_copy_obj),
-               "source and destination objects have the same content");
-
-       BT_OBJECT_PUT(bool_copy_obj);
-       BT_OBJECT_PUT(integer_copy_obj);
-       BT_OBJECT_PUT(float_copy_obj);
-       BT_OBJECT_PUT(string_copy_obj);
-       BT_OBJECT_PUT(array_copy_obj);
-       BT_OBJECT_PUT(map_copy_obj);
-       BT_OBJECT_PUT(bool_obj);
-       BT_OBJECT_PUT(integer_obj);
-       BT_OBJECT_PUT(float_obj);
-       BT_OBJECT_PUT(string_obj);
-       BT_OBJECT_PUT(array_obj);
-       BT_OBJECT_PUT(map_obj);
-}
-
-static
-void test_macros(void)
-{
-       struct bt_object *obj = bt_object_bool_create();
-       struct bt_object *src;
-       struct bt_object *dst;
-
-       assert(obj);
-       BT_OBJECT_PUT(obj);
-       ok(!obj, "BT_OBJECT_PUT() resets the variable to NULL");
-
-       obj = bt_object_bool_create();
-       assert(obj);
-       src = obj;
-       BT_OBJECT_MOVE(dst, src);
-       ok(!src, "BT_OBJECT_MOVE() resets the source variable to NULL");
-       ok(dst == obj, "BT_OBJECT_MOVE() moves the ownership");
-
-       BT_OBJECT_PUT(dst);
-}
-
-static
-void test_freeze(void)
-{
-       struct bt_object *obj;
-
-       ok(bt_object_freeze(NULL) == BT_OBJECT_STATUS_INVAL,
-               "bt_object_freeze() fails with an object set to NULL");
-       ok(!bt_object_freeze(bt_object_null),
-               "bt_object_freeze() succeeds with a null object");
-
-       ok(!bt_object_is_frozen(NULL), "NULL is not frozen");
-       ok(bt_object_is_frozen(bt_object_null),
-               "the null singleton is frozen");
-       obj = bt_object_integer_create();
-       assert(obj);
-       ok(!bt_object_is_frozen(obj),
-               "bt_object_is_frozen() returns false with a fresh object");
-       assert(!bt_object_freeze(obj));
-       ok(!bt_object_freeze(obj),
-               "bt_object_freeze() passes with a frozen object");
-       ok(bt_object_is_frozen(obj),
-               "bt_object_is_frozen() returns true with a frozen object");
-
-       BT_OBJECT_PUT(obj);
-}
-
-int main(void)
-{
-       plan_no_plan();
-
-       test_macros();
-       test_freeze();
-       test_types();
-       test_compare();
-       test_copy();
-
-       return 0;
-}
diff --git a/tests/lib/test_bt_values.c b/tests/lib/test_bt_values.c
new file mode 100644 (file)
index 0000000..4f56396
--- /dev/null
@@ -0,0 +1,1167 @@
+/*
+ * test_bt_values.c
+ *
+ * Babeltrace value value objects tests
+ *
+ * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define _GNU_SOURCE
+#include <babeltrace/values.h>
+#include <assert.h>
+#include <string.h>
+#include "tap/tap.h"
+
+static
+void test_null(void)
+{
+       ok(bt_value_null, "bt_value_null is not NULL");
+       ok(bt_value_is_null(bt_value_null),
+               "bt_value_null is a null value object");
+       bt_value_get(bt_value_null);
+       pass("getting bt_value_null does not cause a crash");
+       bt_value_put(bt_value_null);
+       pass("putting bt_value_null does not cause a crash");
+
+       bt_value_get(NULL);
+       pass("getting NULL does not cause a crash");
+       bt_value_put(NULL);
+       pass("putting NULL does not cause a crash");
+
+       ok(bt_value_get_type(NULL) == BT_VALUE_TYPE_UNKNOWN,
+               "bt_value_get_type(NULL) returns BT_VALUE_TYPE_UNKNOWN");
+}
+
+static
+void test_bool(void)
+{
+       int ret;
+       bool value;
+       struct bt_value *obj;
+
+       obj = bt_value_bool_create();
+       ok(obj && bt_value_is_bool(obj),
+               "bt_value_bool_create() returns a boolean value object");
+
+       value = true;
+       ret = bt_value_bool_get(obj, &value);
+       ok(!ret && !value, "default boolean value object value is false");
+
+       ret = bt_value_bool_set(NULL, true);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_bool_set() fails with an value object set to NULL");
+       ret = bt_value_bool_get(NULL, &value);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_bool_get() fails with an value object set to NULL");
+       ret = bt_value_bool_get(obj, NULL);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_bool_get() fails with a return value set to NULL");
+
+       assert(!bt_value_bool_set(obj, false));
+       ret = bt_value_bool_set(obj, true);
+       ok(!ret, "bt_value_bool_set() succeeds");
+       ret = bt_value_bool_get(obj, &value);
+       ok(!ret && value, "bt_value_bool_set() works");
+
+       BT_VALUE_PUT(obj);
+       pass("putting an existing boolean value object does not cause a crash")
+
+       value = false;
+       obj = bt_value_bool_create_init(true);
+       ok(obj && bt_value_is_bool(obj),
+               "bt_value_bool_create_init() returns a boolean value object");
+       ret = bt_value_bool_get(obj, &value);
+       ok(!ret && value,
+               "bt_value_bool_create_init() sets the appropriate initial value");
+
+       assert(!bt_value_freeze(obj));
+       ok(bt_value_bool_set(obj, false) == BT_VALUE_STATUS_FROZEN,
+               "bt_value_bool_set() cannot be called on a frozen boolean value object");
+       value = false;
+       ret = bt_value_bool_get(obj, &value);
+       ok(!ret && value,
+               "bt_value_bool_set() does not alter a frozen floating point number value object");
+
+       BT_VALUE_PUT(obj);
+}
+
+static
+void test_integer(void)
+{
+       int ret;
+       int64_t value;
+       struct bt_value *obj;
+
+       obj = bt_value_integer_create();
+       ok(obj && bt_value_is_integer(obj),
+               "bt_value_integer_create() returns an integer value object");
+
+       ret = bt_value_integer_set(NULL, -12345);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_integer_set() fails with an value object set to NULL");
+       ret = bt_value_integer_get(NULL, &value);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_integer_get() fails with an value object set to NULL");
+       ret = bt_value_integer_get(obj, NULL);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_integer_get() fails with a return value set to NULL");
+
+       value = 1961;
+       ret = bt_value_integer_get(obj, &value);
+       ok(!ret && value == 0, "default integer value object value is 0");
+
+       ret = bt_value_integer_set(obj, -98765);
+       ok(!ret, "bt_value_integer_set() succeeds");
+       ret = bt_value_integer_get(obj, &value);
+       ok(!ret && value == -98765, "bt_value_integer_set() works");
+
+       BT_VALUE_PUT(obj);
+       pass("putting an existing integer value object does not cause a crash")
+
+       obj = bt_value_integer_create_init(321456987);
+       ok(obj && bt_value_is_integer(obj),
+               "bt_value_integer_create_init() returns an integer value object");
+       ret = bt_value_integer_get(obj, &value);
+       ok(!ret && value == 321456987,
+               "bt_value_integer_create_init() sets the appropriate initial value");
+
+       assert(!bt_value_freeze(obj));
+       ok(bt_value_integer_set(obj, 18276) == BT_VALUE_STATUS_FROZEN,
+               "bt_value_integer_set() cannot be called on a frozen integer value object");
+       value = 17;
+       ret = bt_value_integer_get(obj, &value);
+       ok(!ret && value == 321456987,
+               "bt_value_integer_set() does not alter a frozen integer value object");
+
+       BT_VALUE_PUT(obj);
+}
+
+static
+void test_float(void)
+{
+       int ret;
+       double value;
+       struct bt_value *obj;
+
+       obj = bt_value_float_create();
+       ok(obj && bt_value_is_float(obj),
+               "bt_value_float_create() returns a floating point number value object");
+
+       ret = bt_value_float_set(NULL, 1.2345);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_float_set() fails with an value object set to NULL");
+       ret = bt_value_float_get(NULL, &value);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_float_get() fails with an value object set to NULL");
+       ret = bt_value_float_get(obj, NULL);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_float_get() fails with a return value set to NULL");
+
+       value = 17.34;
+       ret = bt_value_float_get(obj, &value);
+       ok(!ret && value == 0.,
+               "default floating point number value object value is 0");
+
+       ret = bt_value_float_set(obj, -3.1416);
+       ok(!ret, "bt_value_float_set() succeeds");
+       ret = bt_value_float_get(obj, &value);
+       ok(!ret && value == -3.1416, "bt_value_float_set() works");
+
+       BT_VALUE_PUT(obj);
+       pass("putting an existing floating point number value object does not cause a crash")
+
+       obj = bt_value_float_create_init(33.1649758);
+       ok(obj && bt_value_is_float(obj),
+               "bt_value_float_create_init() returns a floating point number value object");
+       ret = bt_value_float_get(obj, &value);
+       ok(!ret && value == 33.1649758,
+               "bt_value_float_create_init() sets the appropriate initial value");
+
+       assert(!bt_value_freeze(obj));
+       ok(bt_value_float_set(obj, 17.88) == BT_VALUE_STATUS_FROZEN,
+               "bt_value_float_set() fails with a frozen floating point number value object");
+       value = 1.2;
+       ret = bt_value_float_get(obj, &value);
+       ok(!ret && value == 33.1649758,
+               "bt_value_float_set() does not alter a frozen floating point number value object");
+
+       BT_VALUE_PUT(obj);
+}
+
+static
+void test_string(void)
+{
+       int ret;
+       const char *value;
+       struct bt_value *obj;
+
+       obj = bt_value_string_create();
+       ok(obj && bt_value_is_string(obj),
+               "bt_value_string_create() returns a string value object");
+
+       ret = bt_value_string_set(NULL, "hoho");
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_string_set() fails with an value object set to NULL");
+       ret = bt_value_string_set(obj, NULL);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_string_set() fails with a value set to NULL");
+       ret = bt_value_string_get(NULL, &value);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_string_get() fails with an value object set to NULL");
+       ret = bt_value_string_get(obj, NULL);
+       ok(ret == BT_VALUE_STATUS_INVAL,
+               "bt_value_string_get() fails with a return value set to NULL");
+
+       ret = bt_value_string_get(obj, &value);
+       ok(!ret && value && !strcmp(value, ""),
+               "default string value object value is \"\"");
+
+       ret = bt_value_string_set(obj, "hello worldz");
+       ok(!ret, "bt_value_string_set() succeeds");
+       ret = bt_value_string_get(obj, &value);
+       ok(!ret && value && !strcmp(value, "hello worldz"),
+               "bt_value_string_get() works");
+
+       BT_VALUE_PUT(obj);
+       pass("putting an existing string value object does not cause a crash")
+
+       obj = bt_value_string_create_init(NULL);
+       ok(!obj, "bt_value_string_create_init() fails with an initial value set to NULL");
+       obj = bt_value_string_create_init("initial value");
+       ok(obj && bt_value_is_string(obj),
+               "bt_value_string_create_init() returns a string value object");
+       ret = bt_value_string_get(obj, &value);
+       ok(!ret && value && !strcmp(value, "initial value"),
+               "bt_value_string_create_init() sets the appropriate initial value");
+
+       assert(!bt_value_freeze(obj));
+       ok(bt_value_string_set(obj, "new value") == BT_VALUE_STATUS_FROZEN,
+               "bt_value_string_set() fails with a frozen string value object");
+       value = "";
+       ret = bt_value_string_get(obj, &value);
+       ok(!ret && value && !strcmp(value, "initial value"),
+               "bt_value_string_set() does not alter a frozen string value object");
+
+       BT_VALUE_PUT(obj);
+}
+
+static
+void test_array(void)
+{
+       int ret;
+       bool bool_value;
+       int64_t int_value;
+       double float_value;
+       struct bt_value *obj;
+       const char *string_value;
+       struct bt_value *array_obj;
+
+       array_obj = bt_value_array_create();
+       ok(array_obj && bt_value_is_array(array_obj),
+               "bt_value_array_create() returns an array value object");
+       ok(bt_value_array_is_empty(NULL) == false,
+               "bt_value_array_is_empty() returns false with an value object set to NULL");
+       ok(bt_value_array_is_empty(array_obj),
+               "initial array value object size is 0");
+       ok(bt_value_array_size(NULL) == BT_VALUE_STATUS_INVAL,
+               "bt_value_array_size() fails with an array value object set to NULL");
+
+       ok(bt_value_array_append(NULL, bt_value_null)
+               == BT_VALUE_STATUS_INVAL,
+               "bt_value_array_append() fails with an array value object set to NULL");
+       ok(bt_value_array_append(array_obj, NULL) == BT_VALUE_STATUS_INVAL,
+               "bt_value_array_append() fails with a value set to NULL");
+
+       obj = bt_value_integer_create_init(345);
+       ret = bt_value_array_append(array_obj, obj);
+       BT_VALUE_PUT(obj);
+       obj = bt_value_float_create_init(-17.45);
+       ret |= bt_value_array_append(array_obj, obj);
+       BT_VALUE_PUT(obj);
+       obj = bt_value_bool_create_init(true);
+       ret |= bt_value_array_append(array_obj, obj);
+       BT_VALUE_PUT(obj);
+       ret |= bt_value_array_append(array_obj, bt_value_null);
+       ok(!ret, "bt_value_array_append() succeeds");
+       ok(bt_value_array_size(array_obj) == 4,
+               "appending an element to an array value object increment its size");
+
+       obj = bt_value_array_get(array_obj, 4);
+       ok(!obj, "getting an array value object's element at an index equal to its size fails");
+       obj = bt_value_array_get(array_obj, 5);
+       ok(!obj, "getting an array value object's element at a larger index fails");
+
+       obj = bt_value_array_get(NULL, 2);
+       ok(!obj, "bt_value_array_get() fails with an array value object set to NULL");
+
+       obj = bt_value_array_get(array_obj, 0);
+       ok(obj && bt_value_is_integer(obj),
+               "bt_value_array_get() returns an value object with the appropriate type (integer)");
+       ret = bt_value_integer_get(obj, &int_value);
+       ok(!ret && int_value == 345,
+               "bt_value_array_get() returns an value object with the appropriate value (integer)");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_array_get(array_obj, 1);
+       ok(obj && bt_value_is_float(obj),
+               "bt_value_array_get() returns an value object with the appropriate type (floating point number)");
+       ret = bt_value_float_get(obj, &float_value);
+       ok(!ret && float_value == -17.45,
+               "bt_value_array_get() returns an value object with the appropriate value (floating point number)");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_array_get(array_obj, 2);
+       ok(obj && bt_value_is_bool(obj),
+               "bt_value_array_get() returns an value object with the appropriate type (boolean)");
+       ret = bt_value_bool_get(obj, &bool_value);
+       ok(!ret && bool_value,
+               "bt_value_array_get() returns an value object with the appropriate value (boolean)");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_array_get(array_obj, 3);
+       ok(obj == bt_value_null,
+               "bt_value_array_get() returns an value object with the appropriate type (null)");
+
+       ok(bt_value_array_set(NULL, 0, bt_value_null) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_array_set() fails with an array value object set to NULL");
+       ok(bt_value_array_set(array_obj, 0, NULL) == BT_VALUE_STATUS_INVAL,
+               "bt_value_array_set() fails with an element value object set to NULL");
+       ok(bt_value_array_set(array_obj, 4, bt_value_null) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_array_set() fails with an invalid index");
+       obj = bt_value_integer_create_init(1001);
+       assert(obj);
+       ok(!bt_value_array_set(array_obj, 2, obj),
+               "bt_value_array_set() succeeds");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_array_get(array_obj, 2);
+       ok(obj && bt_value_is_integer(obj),
+               "bt_value_array_set() inserts an value object with the appropriate type");
+       ret = bt_value_integer_get(obj, &int_value);
+       assert(!ret);
+       ok(int_value == 1001,
+               "bt_value_array_set() inserts an value object with the appropriate value");
+       BT_VALUE_PUT(obj);
+
+       ret = bt_value_array_append_bool(array_obj, false);
+       ok(!ret, "bt_value_array_append_bool() succeeds");
+       ok(bt_value_array_append_bool(NULL, true) == BT_VALUE_STATUS_INVAL,
+               "bt_value_array_append_bool() fails with an array value object set to NULL");
+       ret = bt_value_array_append_integer(array_obj, 98765);
+       ok(!ret, "bt_value_array_append_integer() succeeds");
+       ok(bt_value_array_append_integer(NULL, 18765) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_array_append_integer() fails with an array value object set to NULL");
+       ret = bt_value_array_append_float(array_obj, 2.49578);
+       ok(!ret, "bt_value_array_append_float() succeeds");
+       ok(bt_value_array_append_float(NULL, 1.49578) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_array_append_float() fails with an array value object set to NULL");
+       ret = bt_value_array_append_string(array_obj, "bt_value");
+       ok(!ret, "bt_value_array_append_string() succeeds");
+       ok(bt_value_array_append_string(NULL, "bt_obj") ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_array_append_string() fails with an array value object set to NULL");
+       ret = bt_value_array_append_array(array_obj);
+       ok(!ret, "bt_value_array_append_array() succeeds");
+       ok(bt_value_array_append_array(NULL) == BT_VALUE_STATUS_INVAL,
+               "bt_value_array_append_array() fails with an array value object set to NULL");
+       ret = bt_value_array_append_map(array_obj);
+       ok(!ret, "bt_value_array_append_map() succeeds");
+       ok(bt_value_array_append_map(NULL) == BT_VALUE_STATUS_INVAL,
+               "bt_value_array_append_map() fails with an array value object set to NULL");
+
+       ok(bt_value_array_size(array_obj) == 10,
+               "the bt_value_array_append_*() functions increment the array value object's size");
+       ok(!bt_value_array_is_empty(array_obj),
+               "map value object is not empty");
+
+       obj = bt_value_array_get(array_obj, 4);
+       ok(obj && bt_value_is_bool(obj),
+               "bt_value_array_append_bool() appends a boolean value object");
+       ret = bt_value_bool_get(obj, &bool_value);
+       ok(!ret && !bool_value,
+               "bt_value_array_append_bool() appends the appropriate value");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_array_get(array_obj, 5);
+       ok(obj && bt_value_is_integer(obj),
+               "bt_value_array_append_integer() appends an integer value object");
+       ret = bt_value_integer_get(obj, &int_value);
+       ok(!ret && int_value == 98765,
+               "bt_value_array_append_integer() appends the appropriate value");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_array_get(array_obj, 6);
+       ok(obj && bt_value_is_float(obj),
+               "bt_value_array_append_float() appends a floating point number value object");
+       ret = bt_value_float_get(obj, &float_value);
+       ok(!ret && float_value == 2.49578,
+               "bt_value_array_append_float() appends the appropriate value");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_array_get(array_obj, 7);
+       ok(obj && bt_value_is_string(obj),
+               "bt_value_array_append_string() appends a string value object");
+       ret = bt_value_string_get(obj, &string_value);
+       ok(!ret && string_value && !strcmp(string_value, "bt_value"),
+               "bt_value_array_append_string() appends the appropriate value");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_array_get(array_obj, 8);
+       ok(obj && bt_value_is_array(obj),
+               "bt_value_array_append_array() appends an array value object");
+       ok(bt_value_array_is_empty(obj),
+               "bt_value_array_append_array() an empty array value object");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_array_get(array_obj, 9);
+       ok(obj && bt_value_is_map(obj),
+               "bt_value_array_append_map() appends a map value object");
+       ok(bt_value_map_is_empty(obj),
+               "bt_value_array_append_map() an empty map value object");
+       BT_VALUE_PUT(obj);
+
+       assert(!bt_value_freeze(array_obj));
+       ok(bt_value_array_append(array_obj, bt_value_null) ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_array_append() fails with a frozen array value object");
+       ok(bt_value_array_append_bool(array_obj, false) ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_array_append_bool() fails with a frozen array value object");
+       ok(bt_value_array_append_integer(array_obj, 23) ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_array_append_integer() fails with a frozen array value object");
+       ok(bt_value_array_append_float(array_obj, 2.34) ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_array_append_float() fails with a frozen array value object");
+       ok(bt_value_array_append_string(array_obj, "yayayayaya") ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_array_append_string() fails with a frozen array value object");
+       ok(bt_value_array_append_array(array_obj) ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_array_append_array() fails with a frozen array value object");
+       ok(bt_value_array_append_map(array_obj) ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_array_append_map() fails with a frozen array value object");
+       ok(bt_value_array_set(array_obj, 2, bt_value_null) ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_array_set() fails with a frozen array value object");
+       ok(bt_value_array_size(array_obj) == 10,
+               "appending to a frozen array value object does not change its size");
+
+       obj = bt_value_array_get(array_obj, 1);
+       assert(obj);
+       ok(bt_value_float_set(obj, 14.52) == BT_VALUE_STATUS_FROZEN,
+               "freezing an array value object also freezes its elements");
+       BT_VALUE_PUT(obj);
+
+       BT_VALUE_PUT(array_obj);
+       pass("putting an existing array value object does not cause a crash")
+}
+
+static
+bool test_map_foreach_cb_count(const char *key, struct bt_value *object,
+       void *data)
+{
+       int *count = data;
+
+       if (*count == 3) {
+               return false;
+       }
+
+       (*count)++;
+
+       return true;
+}
+
+struct map_foreach_checklist {
+       bool bool1;
+       bool int1;
+       bool float1;
+       bool null1;
+       bool bool2;
+       bool int2;
+       bool float2;
+       bool string2;
+       bool array2;
+       bool map2;
+};
+
+static
+bool test_map_foreach_cb_check(const char *key, struct bt_value *object,
+       void *data)
+{
+       int ret;
+       struct map_foreach_checklist *checklist = data;
+
+       if (!strcmp(key, "bool")) {
+               if (checklist->bool1) {
+                       fail("test_map_foreach_cb_check(): duplicate key \"bool\"");
+               } else {
+                       bool val = false;
+
+                       ret = bt_value_bool_get(object, &val);
+                       ok(!ret, "test_map_foreach_cb_check(): success getting \"bool\" value");
+
+                       if (val) {
+                               pass("test_map_foreach_cb_check(): \"bool\" value object has the right value");
+                               checklist->bool1 = true;
+                       } else {
+                               fail("test_map_foreach_cb_check(): \"bool\" value object has the wrong value");
+                       }
+               }
+       } else if (!strcmp(key, "int")) {
+               if (checklist->int1) {
+                       fail("test_map_foreach_cb_check(): duplicate key \"int\"");
+               } else {
+                       int64_t val = 0;
+
+                       ret = bt_value_integer_get(object, &val);
+                       ok(!ret, "test_map_foreach_cb_check(): success getting \"int\" value");
+
+                       if (val == 19457) {
+                               pass("test_map_foreach_cb_check(): \"int\" value object has the right value");
+                               checklist->int1 = true;
+                       } else {
+                               fail("test_map_foreach_cb_check(): \"int\" value object has the wrong value");
+                       }
+               }
+       } else if (!strcmp(key, "float")) {
+               if (checklist->float1) {
+                       fail("test_map_foreach_cb_check(): duplicate key \"float\"");
+               } else {
+                       double val = 0;
+
+                       ret = bt_value_float_get(object, &val);
+                       ok(!ret, "test_map_foreach_cb_check(): success getting \"float\" value");
+
+                       if (val == 5.444) {
+                               pass("test_map_foreach_cb_check(): \"float\" value object has the right value");
+                               checklist->float1 = true;
+                       } else {
+                               fail("test_map_foreach_cb_check(): \"float\" value object has the wrong value");
+                       }
+               }
+       } else if (!strcmp(key, "null")) {
+               if (checklist->null1) {
+                       fail("test_map_foreach_cb_check(): duplicate key \"bool\"");
+               } else {
+                       ok(bt_value_is_null(object), "test_map_foreach_cb_check(): success getting \"null\" value object");
+                       checklist->null1 = true;
+               }
+       } else if (!strcmp(key, "bool2")) {
+               if (checklist->bool2) {
+                       fail("test_map_foreach_cb_check(): duplicate key \"bool2\"");
+               } else {
+                       bool val = false;
+
+                       ret = bt_value_bool_get(object, &val);
+                       ok(!ret, "test_map_foreach_cb_check(): success getting \"bool2\" value");
+
+                       if (val) {
+                               pass("test_map_foreach_cb_check(): \"bool2\" value object has the right value");
+                               checklist->bool2 = true;
+                       } else {
+                               fail("test_map_foreach_cb_check(): \"bool2\" value object has the wrong value");
+                       }
+               }
+       } else if (!strcmp(key, "int2")) {
+               if (checklist->int2) {
+                       fail("test_map_foreach_cb_check(): duplicate key \"int2\"");
+               } else {
+                       int64_t val = 0;
+
+                       ret = bt_value_integer_get(object, &val);
+                       ok(!ret, "test_map_foreach_cb_check(): success getting \"int2\" value");
+
+                       if (val == 98765) {
+                               pass("test_map_foreach_cb_check(): \"int2\" value object has the right value");
+                               checklist->int2 = true;
+                       } else {
+                               fail("test_map_foreach_cb_check(): \"int2\" value object has the wrong value");
+                       }
+               }
+       } else if (!strcmp(key, "float2")) {
+               if (checklist->float2) {
+                       fail("test_map_foreach_cb_check(): duplicate key \"float2\"");
+               } else {
+                       double val = 0;
+
+                       ret = bt_value_float_get(object, &val);
+                       ok(!ret, "test_map_foreach_cb_check(): success getting \"float2\" value");
+
+                       if (val == -49.0001) {
+                               pass("test_map_foreach_cb_check(): \"float2\" value object has the right value");
+                               checklist->float2 = true;
+                       } else {
+                               fail("test_map_foreach_cb_check(): \"float2\" value object has the wrong value");
+                       }
+               }
+       } else if (!strcmp(key, "string2")) {
+               if (checklist->string2) {
+                       fail("test_map_foreach_cb_check(): duplicate key \"string2\"");
+               } else {
+                       const char *val;
+
+                       ret = bt_value_string_get(object, &val);
+                       ok(!ret, "test_map_foreach_cb_check(): success getting \"string2\" value");
+
+                       if (val && !strcmp(val, "bt_value")) {
+                               pass("test_map_foreach_cb_check(): \"string2\" value object has the right value");
+                               checklist->string2 = true;
+                       } else {
+                               fail("test_map_foreach_cb_check(): \"string2\" value object has the wrong value");
+                       }
+               }
+       } else if (!strcmp(key, "array2")) {
+               if (checklist->array2) {
+                       fail("test_map_foreach_cb_check(): duplicate key \"array2\"");
+               } else {
+                       ok(bt_value_is_array(object), "test_map_foreach_cb_check(): success getting \"array2\" value object");
+                       ok(bt_value_array_is_empty(object),
+                               "test_map_foreach_cb_check(): \"array2\" value object is empty");
+                       checklist->array2 = true;
+               }
+       } else if (!strcmp(key, "map2")) {
+               if (checklist->map2) {
+                       fail("test_map_foreach_cb_check(): duplicate key \"map2\"");
+               } else {
+                       ok(bt_value_is_map(object), "test_map_foreach_cb_check(): success getting \"map2\" value object");
+                       ok(bt_value_map_is_empty(object),
+                               "test_map_foreach_cb_check(): \"map2\" value object is empty");
+                       checklist->map2 = true;
+               }
+       } else {
+               fail("test_map_foreach_cb_check(): unknown map key \"%s\"", key);
+       }
+
+       return true;
+}
+
+static
+void test_map(void)
+{
+       int ret;
+       int count = 0;
+       bool bool_value;
+       int64_t int_value;
+       double float_value;
+       struct bt_value *obj;
+       struct bt_value *map_obj;
+       struct map_foreach_checklist checklist;
+
+       map_obj = bt_value_map_create();
+       ok(map_obj && bt_value_is_map(map_obj),
+               "bt_value_map_create() returns a map value object");
+       ok(bt_value_map_size(map_obj) == 0,
+               "initial map value object size is 0");
+       ok(bt_value_map_size(NULL) == BT_VALUE_STATUS_INVAL,
+               "bt_value_map_size() fails with a map value object set to NULL");
+
+       ok(bt_value_map_insert(NULL, "hello", bt_value_null) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_array_insert() fails with a map value object set to NULL");
+       ok(bt_value_map_insert(map_obj, NULL, bt_value_null) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_array_insert() fails with a key set to NULL");
+       ok(bt_value_map_insert(map_obj, "yeah", NULL) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_array_insert() fails with an element value object set to NULL");
+
+       obj = bt_value_integer_create_init(19457);
+       ret = bt_value_map_insert(map_obj, "int", obj);
+       BT_VALUE_PUT(obj);
+       obj = bt_value_float_create_init(5.444);
+       ret |= bt_value_map_insert(map_obj, "float", obj);
+       BT_VALUE_PUT(obj);
+       obj = bt_value_bool_create();
+       ret |= bt_value_map_insert(map_obj, "bool", obj);
+       BT_VALUE_PUT(obj);
+       ret |= bt_value_map_insert(map_obj, "null", bt_value_null);
+       ok(!ret, "bt_value_map_insert() succeeds");
+       ok(bt_value_map_size(map_obj) == 4,
+               "inserting an element into a map value object increment its size");
+
+       obj = bt_value_bool_create_init(true);
+       ret = bt_value_map_insert(map_obj, "bool", obj);
+       BT_VALUE_PUT(obj);
+       ok(!ret, "bt_value_map_insert() accepts an existing key");
+
+       obj = bt_value_map_get(map_obj, NULL);
+       ok(!obj, "bt_value_map_get() fails with a key set to NULL");
+       obj = bt_value_map_get(NULL, "bool");
+       ok(!obj, "bt_value_map_get() fails with a map value object set to NULL");
+
+       obj = bt_value_map_get(map_obj, "life");
+       ok(!obj, "bt_value_map_get() fails with an non existing key");
+       obj = bt_value_map_get(map_obj, "float");
+       ok(obj && bt_value_is_float(obj),
+               "bt_value_map_get() returns an value object with the appropriate type (float)");
+       ret = bt_value_float_get(obj, &float_value);
+       ok(!ret && float_value == 5.444,
+               "bt_value_map_get() returns an value object with the appropriate value (float)");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_map_get(map_obj, "int");
+       ok(obj && bt_value_is_integer(obj),
+               "bt_value_map_get() returns an value object with the appropriate type (integer)");
+       ret = bt_value_integer_get(obj, &int_value);
+       ok(!ret && int_value == 19457,
+               "bt_value_map_get() returns an value object with the appropriate value (integer)");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_map_get(map_obj, "null");
+       ok(obj && bt_value_is_null(obj),
+               "bt_value_map_get() returns an value object with the appropriate type (null)");
+       obj = bt_value_map_get(map_obj, "bool");
+       ok(obj && bt_value_is_bool(obj),
+               "bt_value_map_get() returns an value object with the appropriate type (boolean)");
+       ret = bt_value_bool_get(obj, &bool_value);
+       ok(!ret && bool_value,
+               "bt_value_map_get() returns an value object with the appropriate value (boolean)");
+       BT_VALUE_PUT(obj);
+
+       ret = bt_value_map_insert_bool(map_obj, "bool2", true);
+       ok(!ret, "bt_value_map_insert_bool() succeeds");
+       ok(bt_value_map_insert_bool(NULL, "bool2", false) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_map_insert_bool() fails with a map value object set to NULL");
+       ret = bt_value_map_insert_integer(map_obj, "int2", 98765);
+       ok(!ret, "bt_value_map_insert_integer() succeeds");
+       ok(bt_value_map_insert_integer(NULL, "int2", 1001) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_map_insert_integer() fails with a map value object set to NULL");
+       ret = bt_value_map_insert_float(map_obj, "float2", -49.0001);
+       ok(!ret, "bt_value_map_insert_float() succeeds");
+       ok(bt_value_map_insert_float(NULL, "float2", 495) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_map_insert_float() fails with a map value object set to NULL");
+       ret = bt_value_map_insert_string(map_obj, "string2", "bt_value");
+       ok(!ret, "bt_value_map_insert_string() succeeds");
+       ok(bt_value_map_insert_string(NULL, "string2", "bt_obj") ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_map_insert_string() fails with a map value object set to NULL");
+       ret = bt_value_map_insert_array(map_obj, "array2");
+       ok(!ret, "bt_value_map_insert_array() succeeds");
+       ok(bt_value_map_insert_array(NULL, "array2") == BT_VALUE_STATUS_INVAL,
+               "bt_value_map_insert_array() fails with a map value object set to NULL");
+       ret = bt_value_map_insert_map(map_obj, "map2");
+       ok(!ret, "bt_value_map_insert_map() succeeds");
+       ok(bt_value_map_insert_map(NULL, "map2") == BT_VALUE_STATUS_INVAL,
+               "bt_value_map_insert_map() fails with a map value object set to NULL");
+
+       ok(bt_value_map_size(map_obj) == 10,
+               "the bt_value_map_insert*() functions increment the map value object's size");
+
+       ok(!bt_value_map_has_key(map_obj, "hello"),
+               "map value object does not have key \"hello\"");
+       ok(bt_value_map_has_key(map_obj, "bool"),
+               "map value object has key \"bool\"");
+       ok(bt_value_map_has_key(map_obj, "int"),
+               "map value object has key \"int\"");
+       ok(bt_value_map_has_key(map_obj, "float"),
+               "map value object has key \"float\"");
+       ok(bt_value_map_has_key(map_obj, "null"),
+               "map value object has key \"null\"");
+       ok(bt_value_map_has_key(map_obj, "bool2"),
+               "map value object has key \"bool2\"");
+       ok(bt_value_map_has_key(map_obj, "int2"),
+               "map value object has key \"int2\"");
+       ok(bt_value_map_has_key(map_obj, "float2"),
+               "map value object has key \"float2\"");
+       ok(bt_value_map_has_key(map_obj, "string2"),
+               "map value object has key \"string2\"");
+       ok(bt_value_map_has_key(map_obj, "array2"),
+               "map value object has key \"array2\"");
+       ok(bt_value_map_has_key(map_obj, "map2"),
+               "map value object has key \"map2\"");
+
+       ok(bt_value_map_foreach(NULL, test_map_foreach_cb_count, &count) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_map_foreach() fails with a map value object set to NULL");
+       ok(bt_value_map_foreach(map_obj, NULL, &count) ==
+               BT_VALUE_STATUS_INVAL,
+               "bt_value_map_foreach() fails with a user function set to NULL");
+       ret = bt_value_map_foreach(map_obj, test_map_foreach_cb_count, &count);
+       ok(ret == BT_VALUE_STATUS_CANCELLED && count == 3,
+               "bt_value_map_foreach() breaks the loop when the user function returns false");
+
+       memset(&checklist, 0, sizeof(checklist));
+       ret = bt_value_map_foreach(map_obj, test_map_foreach_cb_check,
+               &checklist);
+       ok(ret == BT_VALUE_STATUS_OK,
+               "bt_value_map_foreach() succeeds with test_map_foreach_cb_check()");
+       ok(checklist.bool1 && checklist.int1 && checklist.float1 &&
+               checklist.null1 && checklist.bool2 && checklist.int2 &&
+               checklist.float2 && checklist.string2 &&
+               checklist.array2 && checklist.map2,
+               "bt_value_map_foreach() iterates over all the map value object's elements");
+
+       assert(!bt_value_freeze(map_obj));
+       ok(bt_value_map_insert(map_obj, "allo", bt_value_null) ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_map_insert() fails with a frozen map value object");
+       ok(bt_value_map_insert_bool(map_obj, "duh", false) ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_map_insert_bool() fails with a frozen array value object");
+       ok(bt_value_map_insert_integer(map_obj, "duh", 23) ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_map_insert_integer() fails with a frozen array value object");
+       ok(bt_value_map_insert_float(map_obj, "duh", 2.34) ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_map_insert_float() fails with a frozen array value object");
+       ok(bt_value_map_insert_string(map_obj, "duh", "yayayayaya") ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_map_insert_string() fails with a frozen array value object");
+       ok(bt_value_map_insert_array(map_obj, "duh") ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_map_insert_array() fails with a frozen array value object");
+       ok(bt_value_map_insert_map(map_obj, "duh") ==
+               BT_VALUE_STATUS_FROZEN,
+               "bt_value_map_insert_map() fails with a frozen array value object");
+       ok(bt_value_map_size(map_obj) == 10,
+               "appending to a frozen map value object does not change its size");
+
+       BT_VALUE_PUT(map_obj);
+       pass("putting an existing map value object does not cause a crash")
+}
+
+static
+void test_types(void)
+{
+       test_null();
+       test_bool();
+       test_integer();
+       test_float();
+       test_string();
+       test_array();
+       test_map();
+}
+
+static
+void test_compare_null(void)
+{
+       ok(!bt_value_compare(bt_value_null, NULL),
+               "cannot compare null value object and NULL");
+       ok(!bt_value_compare(NULL, bt_value_null),
+               "cannot compare NULL and null value object");
+       ok(bt_value_compare(bt_value_null, bt_value_null),
+               "null value objects are equivalent");
+}
+
+static
+void test_compare_bool(void)
+{
+       struct bt_value *bool1 = bt_value_bool_create_init(false);
+       struct bt_value *bool2 = bt_value_bool_create_init(true);
+       struct bt_value *bool3 = bt_value_bool_create_init(false);
+
+       assert(bool1 && bool2 && bool3);
+       ok(!bt_value_compare(bt_value_null, bool1),
+               "cannot compare null value object and bool value object");
+       ok(!bt_value_compare(bool1, bool2),
+               "integer value objects are not equivalent (false and true)");
+       ok(bt_value_compare(bool1, bool3),
+               "integer value objects are equivalent (false and false)");
+
+       BT_VALUE_PUT(bool1);
+       BT_VALUE_PUT(bool2);
+       BT_VALUE_PUT(bool3);
+}
+
+static
+void test_compare_integer(void)
+{
+       struct bt_value *int1 = bt_value_integer_create_init(10);
+       struct bt_value *int2 = bt_value_integer_create_init(-23);
+       struct bt_value *int3 = bt_value_integer_create_init(10);
+
+       assert(int1 && int2 && int3);
+       ok(!bt_value_compare(bt_value_null, int1),
+               "cannot compare null value object and integer value object");
+       ok(!bt_value_compare(int1, int2),
+               "integer value objects are not equivalent (10 and -23)");
+       ok(bt_value_compare(int1, int3),
+               "integer value objects are equivalent (10 and 10)");
+
+       BT_VALUE_PUT(int1);
+       BT_VALUE_PUT(int2);
+       BT_VALUE_PUT(int3);
+}
+
+static
+void test_compare_float(void)
+{
+       struct bt_value *float1 = bt_value_float_create_init(17.38);
+       struct bt_value *float2 = bt_value_float_create_init(-14.23);
+       struct bt_value *float3 = bt_value_float_create_init(17.38);
+
+       assert(float1 && float2 && float3);
+
+       ok(!bt_value_compare(bt_value_null, float1),
+               "cannot compare null value object and floating point number value object");
+       ok(!bt_value_compare(float1, float2),
+               "floating point number value objects are not equivalent (17.38 and -14.23)");
+       ok(bt_value_compare(float1, float3),
+               "floating point number value objects are equivalent (17.38 and 17.38)");
+
+       BT_VALUE_PUT(float1);
+       BT_VALUE_PUT(float2);
+       BT_VALUE_PUT(float3);
+}
+
+static
+void test_compare_string(void)
+{
+       struct bt_value *string1 = bt_value_string_create_init("hello");
+       struct bt_value *string2 = bt_value_string_create_init("bt_value");
+       struct bt_value *string3 = bt_value_string_create_init("hello");
+
+       assert(string1 && string2 && string3);
+
+       ok(!bt_value_compare(bt_value_null, string1),
+               "cannot compare null value object and string value object");
+       ok(!bt_value_compare(string1, string2),
+               "string value objects are not equivalent (\"hello\" and \"bt_value\")");
+       ok(bt_value_compare(string1, string3),
+               "string value objects are equivalent (\"hello\" and \"hello\")");
+
+       BT_VALUE_PUT(string1);
+       BT_VALUE_PUT(string2);
+       BT_VALUE_PUT(string3);
+}
+
+static
+void test_compare_array(void)
+{
+       struct bt_value *array1 = bt_value_array_create();
+       struct bt_value *array2 = bt_value_array_create();
+       struct bt_value *array3 = bt_value_array_create();
+
+       assert(array1 && array2 && array3);
+
+       ok(bt_value_compare(array1, array2),
+               "empty array value objects are equivalent");
+
+       assert(!bt_value_array_append_integer(array1, 23));
+       assert(!bt_value_array_append_float(array1, 14.2));
+       assert(!bt_value_array_append_bool(array1, false));
+       assert(!bt_value_array_append_float(array2, 14.2));
+       assert(!bt_value_array_append_integer(array2, 23));
+       assert(!bt_value_array_append_bool(array2, false));
+       assert(!bt_value_array_append_integer(array3, 23));
+       assert(!bt_value_array_append_float(array3, 14.2));
+       assert(!bt_value_array_append_bool(array3, false));
+       assert(bt_value_array_size(array1) == 3);
+       assert(bt_value_array_size(array2) == 3);
+       assert(bt_value_array_size(array3) == 3);
+
+       ok(!bt_value_compare(bt_value_null, array1),
+               "cannot compare null value object and array value object");
+       ok(!bt_value_compare(array1, array2),
+               "array value objects are not equivalent ([23, 14.2, false] and [14.2, 23, false])");
+       ok(bt_value_compare(array1, array3),
+               "array value objects are equivalent ([23, 14.2, false] and [23, 14.2, false])");
+
+       BT_VALUE_PUT(array1);
+       BT_VALUE_PUT(array2);
+       BT_VALUE_PUT(array3);
+}
+
+static
+void test_compare_map(void)
+{
+       struct bt_value *map1 = bt_value_map_create();
+       struct bt_value *map2 = bt_value_map_create();
+       struct bt_value *map3 = bt_value_map_create();
+
+       assert(map1 && map2 && map3);
+
+       ok(bt_value_compare(map1, map2),
+               "empty map value objects are equivalent");
+
+       assert(!bt_value_map_insert_integer(map1, "one", 23));
+       assert(!bt_value_map_insert_float(map1, "two", 14.2));
+       assert(!bt_value_map_insert_bool(map1, "three", false));
+       assert(!bt_value_map_insert_float(map2, "one", 14.2));
+       assert(!bt_value_map_insert_integer(map2, "two", 23));
+       assert(!bt_value_map_insert_bool(map2, "three", false));
+       assert(!bt_value_map_insert_bool(map3, "three", false));
+       assert(!bt_value_map_insert_integer(map3, "one", 23));
+       assert(!bt_value_map_insert_float(map3, "two", 14.2));
+       assert(bt_value_map_size(map1) == 3);
+       assert(bt_value_map_size(map2) == 3);
+       assert(bt_value_map_size(map3) == 3);
+
+       ok(!bt_value_compare(bt_value_null, map1),
+               "cannot compare null value object and map value object");
+       ok(!bt_value_compare(map1, map2),
+               "map value objects are not equivalent");
+       ok(bt_value_compare(map1, map3),
+               "map value objects are equivalent");
+
+       BT_VALUE_PUT(map1);
+       BT_VALUE_PUT(map2);
+       BT_VALUE_PUT(map3);
+}
+
+static
+void test_compare(void)
+{
+       ok(!bt_value_compare(NULL, NULL), "cannot compare NULL and NULL");
+       test_compare_null();
+       test_compare_bool();
+       test_compare_integer();
+       test_compare_float();
+       test_compare_string();
+       test_compare_array();
+       test_compare_map();
+}
+
+static
+void test_copy(void)
+{
+       /*
+        * Here's the deal here. If we make sure that each value object
+        * of our deep copy has a different address than its source,
+        * and that bt_value_compare() returns true for the top-level
+        * value object, taking into account that we test the correctness of
+        * bt_value_compare() elsewhere, then the deep copy is a
+        * success.
+        */
+       struct bt_value *null_copy_obj;
+       struct bt_value *bool_obj, *bool_copy_obj;
+       struct bt_value *integer_obj, *integer_copy_obj;
+       struct bt_value *float_obj, *float_copy_obj;
+       struct bt_value *string_obj, *string_copy_obj;
+       struct bt_value *array_obj, *array_copy_obj;
+       struct bt_value *map_obj, *map_copy_obj;
+
+       bool_obj = bt_value_bool_create_init(true);
+       integer_obj = bt_value_integer_create_init(23);
+       float_obj = bt_value_float_create_init(-3.1416);
+       string_obj = bt_value_string_create_init("test");
+       array_obj = bt_value_array_create();
+       map_obj = bt_value_map_create();
+
+       assert(bool_obj && integer_obj && float_obj && string_obj &&
+               array_obj && map_obj);
+
+       assert(!bt_value_array_append(array_obj, bool_obj));
+       assert(!bt_value_array_append(array_obj, integer_obj));
+       assert(!bt_value_array_append(array_obj, float_obj));
+       assert(!bt_value_array_append(array_obj, bt_value_null));
+       assert(!bt_value_map_insert(map_obj, "array", array_obj));
+       assert(!bt_value_map_insert(map_obj, "string", string_obj));
+
+       map_copy_obj = bt_value_copy(NULL);
+       ok(!map_copy_obj,
+               "bt_value_copy() fails with a source value object set to NULL");
+
+       map_copy_obj = bt_value_copy(map_obj);
+       ok(map_copy_obj,
+               "bt_value_copy() succeeds");
+
+       ok(map_obj != map_copy_obj,
+               "bt_value_copy() returns a different pointer (map)");
+       string_copy_obj = bt_value_map_get(map_copy_obj, "string");
+       ok(string_copy_obj != string_obj,
+               "bt_value_copy() returns a different pointer (string)");
+       array_copy_obj = bt_value_map_get(map_copy_obj, "array");
+       ok(array_copy_obj != array_obj,
+               "bt_value_copy() returns a different pointer (array)");
+       bool_copy_obj = bt_value_array_get(array_copy_obj, 0);
+       ok(bool_copy_obj != bool_obj,
+               "bt_value_copy() returns a different pointer (bool)");
+       integer_copy_obj = bt_value_array_get(array_copy_obj, 1);
+       ok(integer_copy_obj != integer_obj,
+               "bt_value_copy() returns a different pointer (integer)");
+       float_copy_obj = bt_value_array_get(array_copy_obj, 2);
+       ok(float_copy_obj != float_obj,
+               "bt_value_copy() returns a different pointer (float)");
+       null_copy_obj = bt_value_array_get(array_copy_obj, 3);
+       ok(null_copy_obj == bt_value_null,
+               "bt_value_copy() returns the same pointer (null)");
+
+       ok(bt_value_compare(map_obj, map_copy_obj),
+               "source and destination value objects have the same content");
+
+       BT_VALUE_PUT(bool_copy_obj);
+       BT_VALUE_PUT(integer_copy_obj);
+       BT_VALUE_PUT(float_copy_obj);
+       BT_VALUE_PUT(string_copy_obj);
+       BT_VALUE_PUT(array_copy_obj);
+       BT_VALUE_PUT(map_copy_obj);
+       BT_VALUE_PUT(bool_obj);
+       BT_VALUE_PUT(integer_obj);
+       BT_VALUE_PUT(float_obj);
+       BT_VALUE_PUT(string_obj);
+       BT_VALUE_PUT(array_obj);
+       BT_VALUE_PUT(map_obj);
+}
+
+static
+void test_macros(void)
+{
+       struct bt_value *obj = bt_value_bool_create();
+       struct bt_value *src;
+       struct bt_value *dst;
+
+       assert(obj);
+       BT_VALUE_PUT(obj);
+       ok(!obj, "BT_VALUE_PUT() resets the variable to NULL");
+
+       obj = bt_value_bool_create();
+       assert(obj);
+       src = obj;
+       BT_VALUE_MOVE(dst, src);
+       ok(!src, "BT_VALUE_MOVE() resets the source variable to NULL");
+       ok(dst == obj, "BT_VALUE_MOVE() moves the ownership");
+
+       BT_VALUE_PUT(dst);
+}
+
+static
+void test_freeze(void)
+{
+       struct bt_value *obj;
+
+       ok(bt_value_freeze(NULL) == BT_VALUE_STATUS_INVAL,
+               "bt_value_freeze() fails with an value object set to NULL");
+       ok(!bt_value_freeze(bt_value_null),
+               "bt_value_freeze() succeeds with a null value object");
+
+       ok(!bt_value_is_frozen(NULL), "NULL is not frozen");
+       ok(bt_value_is_frozen(bt_value_null),
+               "the null singleton is frozen");
+       obj = bt_value_integer_create();
+       assert(obj);
+       ok(!bt_value_is_frozen(obj),
+               "bt_value_is_frozen() returns false with a fresh value object");
+       assert(!bt_value_freeze(obj));
+       ok(!bt_value_freeze(obj),
+               "bt_value_freeze() passes with a frozen value object");
+       ok(bt_value_is_frozen(obj),
+               "bt_value_is_frozen() returns true with a frozen value object");
+
+       BT_VALUE_PUT(obj);
+}
+
+int main(void)
+{
+       plan_no_plan();
+
+       test_macros();
+       test_freeze();
+       test_types();
+       test_compare();
+       test_copy();
+
+       return 0;
+}
index 130baef245cfa966c8995f9b97509f633f6c63e6..db1eeab507bfbf06389bbff0fb3acdb2bff4c674 100644 (file)
@@ -29,7 +29,7 @@
 #include <babeltrace/ctf-ir/stream-class.h>
 #include <babeltrace/ctf-ir/ref.h>
 #include <babeltrace/ctf/events.h>
-#include <babeltrace/objects.h>
+#include <babeltrace/values.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -789,7 +789,7 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class,
        struct bt_ctf_stream_class *ret_stream_class;
        struct bt_ctf_event_class *ret_event_class;
        struct bt_ctf_field *packet_context, *packet_context_field;
-       struct bt_object *obj;
+       struct bt_value *obj;
 
        ok(bt_ctf_field_type_set_alignment(int_16_type, 0),
                "bt_ctf_field_type_set_alignment handles 0-alignment correctly");
@@ -953,17 +953,17 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class,
                "bt_ctf_event_class_get_id returns the correct value");
 
        /* Test event class attributes */
-       assert(obj = bt_object_integer_create_init(15));
+       assert(obj = bt_value_integer_create_init(15));
        ok(bt_ctf_event_class_set_attribute(NULL, "id", obj),
                "bt_ctf_event_class_set_attribute handles a NULL event class correctly");
        ok(bt_ctf_event_class_set_attribute(event_class, NULL, obj),
                "bt_ctf_event_class_set_attribute handles a NULL name correctly");
        ok(bt_ctf_event_class_set_attribute(event_class, "id", NULL),
                "bt_ctf_event_class_set_attribute handles a NULL value correctly");
-       assert(!bt_object_integer_set(obj, -3));
+       assert(!bt_value_integer_set(obj, -3));
        ok(bt_ctf_event_class_set_attribute(event_class, "id", obj),
                "bt_ctf_event_class_set_attribute fails with a negative \"id\" attribute");
-       assert(!bt_object_integer_set(obj, 11));
+       assert(!bt_value_integer_set(obj, 11));
        ret = bt_ctf_event_class_set_attribute(event_class, "id", obj);
        ok(!ret && bt_ctf_event_class_get_id(event_class) == 11,
                "bt_ctf_event_class_set_attribute succeeds in replacing the existing \"id\" attribute");
@@ -971,13 +971,13 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class,
        ret &= bt_ctf_event_class_set_attribute(event_class, "model.emf.uri", obj);
        ok(ret,
                "bt_ctf_event_class_set_attribute cannot set \"name\" or \"model.emf.uri\" to an integer value");
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
-       obj = bt_object_integer_create_init(5);
+       obj = bt_value_integer_create_init(5);
        assert(obj);
        ok(!bt_ctf_event_class_set_attribute(event_class, "loglevel", obj),
                "bt_ctf_event_class_set_attribute succeeds in setting the \"loglevel\" attribute");
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
        ok(!bt_ctf_event_class_get_attribute_value_by_name(NULL, "loglevel"),
                "bt_ctf_event_class_get_attribute_value_by_name handles a NULL event class correctly");
        ok(!bt_ctf_event_class_get_attribute_value_by_name(event_class, NULL),
@@ -987,12 +987,12 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class,
        obj = bt_ctf_event_class_get_attribute_value_by_name(event_class,
                "loglevel");
        int64_value = 0;
-       ret = bt_object_integer_get(obj, &int64_value);
+       ret = bt_value_integer_get(obj, &int64_value);
        ok(obj && !ret && int64_value == 5,
                "bt_ctf_event_class_get_attribute_value_by_name returns the correct value");
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
-       assert(obj = bt_object_string_create_init("nu name"));
+       assert(obj = bt_value_string_create_init("nu name"));
        assert(!bt_ctf_event_class_set_attribute(event_class, "name", obj));
        ret_string = bt_ctf_event_class_get_name(event_class);
        ok(!strcmp(ret_string, "nu name"),
@@ -1001,11 +1001,11 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class,
        ret &= bt_ctf_event_class_set_attribute(event_class, "loglevel", obj);
        ok(ret,
                "bt_ctf_event_class_set_attribute cannot set \"id\" or \"loglevel\" to a string value");
-       BT_OBJECT_PUT(obj);
-       obj = bt_object_string_create_init("http://kernel.org/");
+       BT_VALUE_PUT(obj);
+       obj = bt_value_string_create_init("http://kernel.org/");
        assert(obj);
        assert(!bt_ctf_event_class_set_attribute(event_class, "model.emf.uri", obj));
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        ok(bt_ctf_event_class_get_attribute_count(NULL),
                "bt_ctf_event_class_get_attribute_count handles a NULL event class");
@@ -1030,29 +1030,29 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class,
 
                if (!strcmp(ret_string, "id")) {
                        attrs_count.id++;
-                       ok(bt_object_is_integer(obj),
+                       ok(bt_value_is_integer(obj),
                                "bt_ctf_event_class_get_attribute_value returns the correct type (\"%s\")",
                                ret_string);
                } else if (!strcmp(ret_string, "name")) {
                        attrs_count.name++;
-                       ok(bt_object_is_string(obj),
+                       ok(bt_value_is_string(obj),
                                "bt_ctf_event_class_get_attribute_value returns the correct type (\"%s\")",
                                ret_string);
                } else if (!strcmp(ret_string, "loglevel")) {
                        attrs_count.loglevel++;
-                       ok(bt_object_is_integer(obj),
+                       ok(bt_value_is_integer(obj),
                                "bt_ctf_event_class_get_attribute_value returns the correct type (\"%s\")",
                                ret_string);
                } else if (!strcmp(ret_string, "model.emf.uri")) {
                        attrs_count.modelemfuri++;
-                       ok(bt_object_is_string(obj),
+                       ok(bt_value_is_string(obj),
                                "bt_ctf_event_class_get_attribute_value returns the correct type (\"%s\")",
                                ret_string);
                } else {
                        attrs_count.unknown++;
                }
 
-               BT_OBJECT_PUT(obj);
+               BT_VALUE_PUT(obj);
        }
 
        ok(attrs_count.unknown == 0, "event class has no unknown attributes");
@@ -2678,7 +2678,7 @@ int main(int argc, char **argv)
        struct bt_ctf_trace *trace;
        int ret;
        int64_t ret_int64_t;
-       struct bt_object *obj;
+       struct bt_value *obj;
 
        if (argc < 3) {
                printf("Usage: tests-ctf-writer path_to_ctf_parser_test path_to_babeltrace\n");
@@ -2726,7 +2726,7 @@ int main(int argc, char **argv)
                "bt_ctf_writer_add_environment_field error with NULL field value");
 
        /* Test bt_ctf_trace_set_environment_field with an integer object */
-       obj = bt_object_integer_create_init(23);
+       obj = bt_value_integer_create_init(23);
        assert(obj);
        ok(bt_ctf_trace_set_environment_field(NULL, "test_env_int_obj", obj),
                "bt_ctf_trace_set_environment_field handles a NULL trace correctly");
@@ -2736,14 +2736,14 @@ int main(int argc, char **argv)
                "bt_ctf_trace_set_environment_field handles a NULL value correctly");
        ok(!bt_ctf_trace_set_environment_field(trace, "test_env_int_obj", obj),
                "bt_ctf_trace_set_environment_field succeeds in adding an integer object");
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        /* Test bt_ctf_trace_set_environment_field with a string object */
-       obj = bt_object_string_create_init("the value");
+       obj = bt_value_string_create_init("the value");
        assert(obj);
        ok(!bt_ctf_trace_set_environment_field(trace, "test_env_str_obj", obj),
                "bt_ctf_trace_set_environment_field succeeds in adding a string object");
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        /* Test bt_ctf_trace_set_environment_field_integer */
        ok(bt_ctf_trace_set_environment_field_integer(NULL, "test_env_int",
@@ -2805,15 +2805,15 @@ int main(int argc, char **argv)
        ok(bt_ctf_trace_get_environment_field_value(trace, 5) == NULL,
                "bt_ctf_trace_get_environment_field_value handles an invalid index correctly (too large)");
        obj = bt_ctf_trace_get_environment_field_value(trace, 1);
-       ret = bt_object_integer_get(obj, &ret_int64_t);
+       ret = bt_value_integer_get(obj, &ret_int64_t);
        ok(!ret && ret_int64_t == 23,
                "bt_ctf_trace_get_environment_field_value succeeds in getting an integer value");
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
        obj = bt_ctf_trace_get_environment_field_value(trace, 2);
-       ret = bt_object_string_get(obj, &ret_string);
+       ret = bt_value_string_get(obj, &ret_string);
        ok(!ret && ret_string && !strcmp(ret_string, "the value"),
                "bt_ctf_trace_get_environment_field_value succeeds in getting a string value");
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        /* Test bt_ctf_trace_get_environment_field_value_by_name */
        ok(!bt_ctf_trace_get_environment_field_value_by_name(NULL,
@@ -2825,10 +2825,10 @@ int main(int argc, char **argv)
                "bt_ctf_trace_get_environment_field_value_by_name returns NULL or an unknown field name");
        obj = bt_ctf_trace_get_environment_field_value_by_name(trace,
                "test_env_str");
-       ret = bt_object_string_get(obj, &ret_string);
+       ret = bt_value_string_get(obj, &ret_string);
        ok(!ret && ret_string && !strcmp(ret_string, "oh yeah"),
                "bt_ctf_trace_get_environment_field_value_by_name succeeds in getting an existing field");
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        /* Test environment field replacement */
        ok(!bt_ctf_trace_set_environment_field_integer(trace, "test_env_int",
@@ -2837,10 +2837,10 @@ int main(int argc, char **argv)
        ok(bt_ctf_trace_get_environment_field_count(trace) == 5,
                "bt_ctf_trace_set_environment_field_integer with an existing key does not increase the environment size");
        obj = bt_ctf_trace_get_environment_field_value(trace, 3);
-       ret = bt_object_integer_get(obj, &ret_int64_t);
+       ret = bt_value_integer_get(obj, &ret_int64_t);
        ok(!ret && ret_int64_t == 654321,
                "bt_ctf_trace_get_environment_field_value successfully replaces an existing field");
-       BT_OBJECT_PUT(obj);
+       BT_VALUE_PUT(obj);
 
        if (uname(&name)) {
                perror("uname");
index 006f51b7e18a9fda3a9451e655830e014faa8c08..7d6ba4d437e55e9b4c8552350bbc1910c8dfde3e 100644 (file)
@@ -3,4 +3,4 @@ lib/test_bitfield
 lib/test_seek_empty_packet
 lib/test_seek_big_trace
 lib/test_ctf_writer_complete
-lib/test_bt_objects
+lib/test_bt_values
This page took 0.149355 seconds and 4 git commands to generate.