void _cockpit_assert_json_eq_msg (const char *domain, const char *file, int line, const char *func, JsonObject *object, const gchar *expect) { GError *error = NULL; JsonNode *node; JsonNode *exnode; gchar *escaped; gchar *msg; node = json_node_init_object (json_node_alloc (), object); exnode = cockpit_json_parse (expect, -1, &error); if (error) g_assertion_message_error (domain, file, line, func, "error", error, 0, 0); g_assert (exnode); if (!cockpit_json_equal (exnode, node)) { escaped = cockpit_json_write (node, NULL); msg = g_strdup_printf ("%s != %s", escaped, expect); g_assertion_message (domain, file, line, func, msg); g_free (escaped); g_free (msg); } json_node_free (node); json_node_free (exnode); }
static GVariant * parse_json_dictionary (JsonNode *node, const GVariantType *entry_type, GError **error) { const GVariantType *key_type; const GVariantType *value_type; GVariant *result = NULL; GPtrArray *children; JsonObject *object; JsonNode *key_node; GList *members = NULL; gboolean is_string; GVariant *value; GVariant *key; GVariant *child; GList *l; children = g_ptr_array_new (); if (!check_type (node, JSON_NODE_OBJECT, 0, error)) goto out; object = json_node_get_object (node); key_type = g_variant_type_key (entry_type); value_type = g_variant_type_value (entry_type); is_string = (g_variant_type_equal (key_type, G_VARIANT_TYPE_STRING) || g_variant_type_equal (key_type, G_VARIANT_TYPE_OBJECT_PATH) || g_variant_type_equal (key_type, G_VARIANT_TYPE_SIGNATURE)); members = json_object_get_members (object); for (l = members; l != NULL; l = g_list_next (l)) { if (is_string) { key_node = json_node_init_string (json_node_alloc (), l->data); } else { key_node = cockpit_json_parse (l->data, -1, NULL); if (key_node == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Unexpected key '%s' in JSON object", (gchar *)l->data); goto out; } } key = parse_json (key_node, key_type, error); json_node_free (key_node); if (!key) goto out; value = parse_json (json_object_get_member (object, l->data), value_type, error); if (!value) { g_variant_unref (key); goto out; } child = g_variant_new_dict_entry (key, value); g_ptr_array_add (children, child); } result = g_variant_new_array (entry_type, (GVariant *const *)children->pdata, children->len); children->len = 0; out: g_list_free (members); g_ptr_array_foreach (children, (GFunc)g_variant_unref, NULL); g_ptr_array_free (children, TRUE); return result; }