static GConfValue * gconf_settings_backend_gvariant_to_gconf_value (GVariant *value) { const GVariantType *type; GConfValue *gconf_value = NULL; type = g_variant_get_type (value); if (g_variant_type_is_basic (type) && !g_variant_type_equal (type, G_VARIANT_TYPE_BASIC)) gconf_value = gconf_settings_backend_simple_gvariant_to_gconf_value (value, type); else if (g_variant_type_is_array (type)) { const GVariantType *array_type; array_type = g_variant_type_element (type); if (g_variant_type_is_basic (array_type) && !g_variant_type_equal (array_type, G_VARIANT_TYPE_BASIC)) { GConfValueType value_type; int i; GSList *list = NULL; for (i = 0; i < g_variant_n_children (value); i++) { GConfValue *l; l = gconf_settings_backend_simple_gvariant_to_gconf_value (g_variant_get_child_value (value, i), array_type); list = g_slist_prepend (list, l); } list = g_slist_reverse (list); value_type = gconf_settings_backend_simple_gvariant_type_to_gconf_value_type (array_type); gconf_value = gconf_value_new (GCONF_VALUE_LIST); gconf_value_set_list_type (gconf_value, value_type); gconf_value_set_list (gconf_value, list); g_slist_foreach (list, (GFunc) gconf_value_free, NULL); g_slist_free (list); } } else if (g_variant_type_is_tuple (type) && g_variant_type_n_items (type) == 2) { const GVariantType *first_type; const GVariantType *second_type; first_type = g_variant_type_first (type); second_type = g_variant_type_next (first_type); if (g_variant_type_is_basic (first_type) && !g_variant_type_equal (first_type, G_VARIANT_TYPE_BASIC) && g_variant_type_is_basic (second_type) && !g_variant_type_equal (second_type, G_VARIANT_TYPE_BASIC)) { GConfValue *car; GConfValue *cdr; gconf_value = gconf_value_new (GCONF_VALUE_PAIR); car = gconf_settings_backend_simple_gvariant_to_gconf_value (g_variant_get_child_value (value, 0), first_type); cdr = gconf_settings_backend_simple_gvariant_to_gconf_value (g_variant_get_child_value (value, 1), second_type); if (car) gconf_value_set_car_nocopy (gconf_value, car); if (cdr) gconf_value_set_cdr_nocopy (gconf_value, cdr); if (car == NULL || cdr == NULL) { gconf_value_free (gconf_value); gconf_value = NULL; } } } return gconf_value; }
static GVariant * parse_json (JsonNode *node, const GVariantType *type, GError **error) { const GVariantType *element_type; const gchar *str; if (!g_variant_type_is_definite (type)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Indefinite type '%.*s' is not supported", (int)g_variant_type_get_string_length (type), g_variant_type_peek_string (type)); return NULL; } if (g_variant_type_is_basic (type)) { if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_BOOLEAN, error)) return g_variant_new_boolean (json_node_get_boolean (node)); } else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error)) return g_variant_new_byte (json_node_get_int (node)); } else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error)) return g_variant_new_int16 (json_node_get_int (node)); } else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error)) return g_variant_new_uint16 (json_node_get_int (node)); } else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error)) return g_variant_new_int32 (json_node_get_int (node)); } else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error)) return g_variant_new_uint32 (json_node_get_int (node)); } else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error)) return g_variant_new_int64 (json_node_get_int (node)); } else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error)) return g_variant_new_uint64 (json_node_get_int (node)); } else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, NULL)) return g_variant_new_double (json_node_get_int (node)); else if (check_type (node, JSON_NODE_VALUE, G_TYPE_DOUBLE, error)) return g_variant_new_double (json_node_get_double (node)); } else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error)) return g_variant_new_string (json_node_get_string (node)); } else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error)) { str = json_node_get_string (node); if (g_variant_is_object_path (str)) return g_variant_new_object_path (str); else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid object path '%s'", str); return NULL; } } } else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE)) { if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error)) { str = json_node_get_string (node); if (g_variant_is_signature (str)) return g_variant_new_signature (str); else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid signature '%s'", str); return NULL; } } } else { parse_not_supported (type, error); } } else if (g_variant_type_is_variant (type)) { return parse_json_variant (node, error); } else if (g_variant_type_is_array (type)) { element_type = g_variant_type_element (type); if (g_variant_type_is_dict_entry (element_type)) return parse_json_dictionary (node, element_type, error); else return parse_json_array (node, element_type, error); } else if (g_variant_type_is_tuple (type)) { return parse_json_tuple (node, g_variant_type_first (type), error); } else { parse_not_supported (type, error); } return NULL; }