static void gvariant_to_json_array_foreach (GVariant *variant_child, gpointer user_data) { JsonArray *array = user_data; JsonNode *json_child; json_child = json_gvariant_serialize (variant_child); json_array_add_element (array, json_child); }
static JsonNode * gvariant_dict_entry_to_json (GVariant *variant, gchar **member_name) { GVariant *member; GVariant *value; JsonNode *json_node; member = g_variant_get_child_value (variant, 0); *member_name = gvariant_simple_to_string (member); value = g_variant_get_child_value (variant, 1); json_node = json_gvariant_serialize (value); g_variant_unref (member); g_variant_unref (value); return json_node; }
static gboolean jsonify_variant (GVariant *variant, NPVariant *result) { gboolean ret; GVariant *real_value; JsonNode *root; JsonGenerator *generator; gsize json_length; gchar *json; gchar *buffer; ret = TRUE; /* DBus methods can return multiple values, * but we're only interested in the first. */ g_variant_get (variant, "(@*)", &real_value); root = json_gvariant_serialize (real_value); generator = json_generator_new (); json_generator_set_root (generator, root); json = json_generator_to_data (generator, &json_length); buffer = funcs.memalloc (json_length + 1); if (!buffer) { ret = FALSE; goto out; } strcpy (buffer, json); STRINGN_TO_NPVARIANT (buffer, json_length, *result); out: g_variant_unref (variant); g_variant_unref (real_value); json_node_free (root); g_free (json); return ret; }
/* Returns a new floating variant (essentially a fixed-up copy of @value) */ static GVariant * _my_replace (GVariant *value) { GVariant *ret; const gchar *dbus_type; if (g_variant_is_of_type (value, G_VARIANT_TYPE_VARDICT) && g_variant_lookup (value, "_dbus_type", "&s", &dbus_type)) { GVariant *passed_value; passed_value = g_variant_lookup_value (value, "value", NULL); if (passed_value != NULL) { JsonNode *serialized; GError *error; serialized = json_gvariant_serialize (passed_value); error = NULL; ret = json_gvariant_deserialize (serialized, dbus_type, &error); json_node_free (serialized); if (ret == NULL) { /* * HACK: Work around bug in JSON-glib, see: * https://bugzilla.gnome.org/show_bug.cgi?id=724319 */ if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_INVALID_DATA && g_variant_is_of_type (passed_value, G_VARIANT_TYPE_INT64) && g_strcmp0 (dbus_type, "d") == 0) { ret = g_variant_new_double (g_variant_get_int64 (passed_value)); g_clear_error (&error); } else { g_warning ("Error converting JSON to requested type %s: %s (%s, %d)", dbus_type, error->message, g_quark_to_string (error->domain), error->code); g_error_free (error); ret = g_variant_ref (value); } } } else { g_warning ("Malformed _dbus_type vardict"); ret = g_variant_ref (value); } } else if (g_variant_is_container (value)) { GVariantBuilder builder; GVariantIter iter; GVariant *child; g_variant_builder_init (&builder, g_variant_get_type (value)); g_variant_iter_init (&iter, value); while ((child = g_variant_iter_next_value (&iter)) != NULL) { g_variant_builder_add_value (&builder, _my_replace (child)); g_variant_unref (child); } ret = g_variant_builder_end (&builder); } else { ret = g_variant_ref (value); } return ret; }