From bb098be87ce8bdcfaa033cb3779f36b3c77bd9fd Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Sun, 24 Jan 2016 23:21:33 +0100 Subject: [PATCH] Create utility function _json_node_deep_copy() It truly duplicates a JsonNode, in contrast with json_node_copy(), which just increases reference counts. --- src/utils.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/utils.h | 2 ++ 2 files changed, 68 insertions(+) diff --git a/src/utils.c b/src/utils.c index c12e4bb..36299da 100644 --- a/src/utils.c +++ b/src/utils.c @@ -77,3 +77,69 @@ _g_enum_nick_to_value(GType enum_type, const gchar *nick, GError **error) return ret; } + +static void +deep_copy_object(JsonObject *object, + const gchar *member_name, + JsonNode *member_node, + JsonObject *new_obj) +{ + json_object_set_member(new_obj, + member_name, + _json_node_deep_copy((const JsonNode *)member_node)); +} + +static void +deep_copy_array(JsonArray *array, + guint idx, + JsonNode *element_node, + JsonArray *new_array) +{ + json_array_add_element(new_array, + _json_node_deep_copy((const JsonNode *)element_node)); +} + +JsonNode * +_json_node_deep_copy(const JsonNode *node) +{ + JsonNode *ret; + + if (node == NULL) { + return NULL; + } + + ret = json_node_new(JSON_NODE_TYPE((JsonNode *)node)); + + switch (JSON_NODE_TYPE((JsonNode *)node)) { + case JSON_NODE_OBJECT: + json_object_foreach_member(json_node_get_object((JsonNode *)node), + (JsonObjectForeach)deep_copy_object, + json_node_get_object(ret)); + + break; + + case JSON_NODE_ARRAY: + json_array_foreach_element(json_node_get_array((JsonNode *)node), + (JsonArrayForeach)deep_copy_array, + json_node_get_array(ret)); + + break; + + case JSON_NODE_VALUE: + { + GValue val = G_VALUE_INIT; + + json_node_get_value((JsonNode *)node, &val); + json_node_set_value(ret, &val); + + g_value_unset(&val); + + break; + } + + case JSON_NODE_NULL: + break; + } + + return ret; +} diff --git a/src/utils.h b/src/utils.h index ab85814..628834e 100644 --- a/src/utils.h +++ b/src/utils.h @@ -21,8 +21,10 @@ #include #include +#include gchar *_g_enum_to_string(GType enum_type, gint value, gboolean convert_dash); gint _g_enum_nick_to_value(GType enum_type, const gchar *nick, GError **error); +JsonNode *_json_node_deep_copy(const JsonNode *node); #endif /* __MATRIX_UTILS_H__ */