static gboolean iter_get_fields (GVariant *variant, gulong attr_type, GckBuilder *builder) { GString *result; const gchar *key, *value; GVariantIter iter; g_assert (variant != NULL); g_assert (builder != NULL); g_return_val_if_fail (g_variant_type_is_array (g_variant_get_type (variant)), FALSE); result = g_string_new (""); g_variant_iter_init (&iter, variant); while (g_variant_iter_next (&iter, "{&s&s}", &key, &value)) { /* Key */ g_string_append (result, key); g_string_append_c (result, '\0'); /* Value */ g_string_append (result, value); g_string_append_c (result, '\0'); } gck_builder_add_data (builder, attr_type, (const guchar *)result->str, result->len); g_string_free (result, TRUE); return TRUE; }
gboolean variantIsValidForCCSType (GVariant *gsettingsValue, CCSSettingType settingType) { gboolean valid = FALSE; switch (settingType) { case TypeString: case TypeMatch: case TypeColor: case TypeKey: case TypeButton: case TypeEdge: valid = (g_variant_type_is_subtype_of (G_VARIANT_TYPE_STRING, g_variant_get_type (gsettingsValue))); break; case TypeInt: valid = (g_variant_type_is_subtype_of (G_VARIANT_TYPE_INT32, g_variant_get_type (gsettingsValue))); break; case TypeBool: case TypeBell: valid = (g_variant_type_is_subtype_of (G_VARIANT_TYPE_BOOLEAN, g_variant_get_type (gsettingsValue))); break; case TypeFloat: valid = (g_variant_type_is_subtype_of (G_VARIANT_TYPE_DOUBLE, g_variant_get_type (gsettingsValue))); break; case TypeList: valid = (g_variant_type_is_array (g_variant_get_type (gsettingsValue))); break; default: break; } return valid; }
static gboolean type_allows_choices (const GVariantType *type) { if (g_variant_type_is_array (type) || g_variant_type_is_maybe (type)) return type_allows_choices (g_variant_type_element (type)); return g_variant_type_equal (type, G_VARIANT_TYPE_STRING); }
void prop_set_from_gvariant(GVariant *v, prop_t *p) { const GVariantType *T = g_variant_get_type(v); if(g_variant_type_equal(T, G_VARIANT_TYPE_BOOLEAN)) { prop_set_int(p, g_variant_get_boolean(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_BYTE)) { prop_set_int(p, g_variant_get_byte(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_INT16)) { prop_set_int(p, g_variant_get_int16(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_UINT16)) { prop_set_int(p, g_variant_get_uint16(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_INT32)) { prop_set_int(p, g_variant_get_int32(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_UINT32)) { prop_set_int(p, g_variant_get_uint32(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_INT64)) { int64_t val = g_variant_get_int64(v); if(val <= INT_MAX) prop_set_int(p, val); else prop_set_float(p, val); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_UINT64)) { uint64_t val = g_variant_get_uint64(v); if(val <= INT_MAX) prop_set_int(p, val); else prop_set_float(p, val); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_STRING) || g_variant_type_equal(T, G_VARIANT_TYPE_OBJECT_PATH) || g_variant_type_equal(T, G_VARIANT_TYPE_SIGNATURE)) { const gchar *val = g_variant_get_string(v, NULL); prop_set_string(p, val); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_VARDICT)) { prop_void_childs(p); prop_set_from_vardict(v, p); } else if(g_variant_type_is_array(T)) { int num = g_variant_n_children(v); prop_destroy_childs(p); for(int i = 0; i < num; i++) { prop_set_from_gvariant(g_variant_get_child_value(v, i), prop_create(p, NULL)); } } else { fprintf(stderr, "%s(): can't deal with type %s\n", __FUNCTION__, g_variant_get_type_string(v)); } }
GVariant* js_to_dbus(JSContextRef ctx, const JSValueRef jsvalue, const GVariantType* sig, JSValueRef *exception) { if (g_variant_type_is_array(sig)) { GVariantBuilder builder; g_variant_builder_init(&builder, sig); JSPropertyNameArrayRef array = JSObjectCopyPropertyNames(ctx, (JSObjectRef)jsvalue); const GVariantType* child_sig = g_variant_type_element(sig); if (g_variant_type_is_dict_entry(child_sig)) { const GVariantType* key_sig = g_variant_type_first(child_sig); const GVariantType* value_sig = g_variant_type_next(key_sig); for (size_t i=0; i < JSPropertyNameArrayGetCount(array); i++) { if (filter_function_child(ctx, jsvalue, i)) continue; g_variant_builder_open(&builder, child_sig); JSValueRef key = JSValueMakeString(ctx, JSPropertyNameArrayGetNameAtIndex(array, i)); JSValueRef value = JSObjectGetPropertyAtIndex(ctx, (JSObjectRef)jsvalue, i, NULL); g_variant_builder_add_value(&builder, js_to_dbus(ctx, key, key_sig, exception)); g_variant_builder_add_value(&builder, js_to_dbus(ctx, value, value_sig, exception)); g_variant_builder_close(&builder); } return g_variant_builder_end(&builder); } else { GVariantBuilder builder; g_variant_builder_init(&builder, sig); JSPropertyNameArrayRef array = JSObjectCopyPropertyNames(ctx, (JSObjectRef)jsvalue); const GVariantType* child_sig = g_variant_type_element(sig); for (size_t i=0; i < JSPropertyNameArrayGetCount(array); i++) { if (filter_array_child(ctx, array, i)) continue; g_variant_builder_add_value(&builder, js_to_dbus(ctx, JSObjectGetPropertyAtIndex(ctx, (JSObjectRef)jsvalue, i, NULL), child_sig, exception)); } JSPropertyNameArrayRelease(array); return g_variant_builder_end(&builder); } } else if (g_variant_type_is_tuple(sig)) { GVariantBuilder builder; g_variant_builder_init(&builder, sig); JSPropertyNameArrayRef array = JSObjectCopyPropertyNames(ctx, (JSObjectRef)jsvalue); const GVariantType* current_sig = g_variant_type_first(sig); for (size_t i=0; i < JSPropertyNameArrayGetCount(array); i++) { if (filter_array_child(ctx, array, i)) continue; g_variant_builder_add_value(&builder, js_to_dbus(ctx, JSObjectGetPropertyAtIndex(ctx, (JSObjectRef)jsvalue, i, NULL), current_sig, exception)); current_sig = g_variant_type_next(current_sig); } JSPropertyNameArrayRelease(array); return g_variant_builder_end(&builder); } else { switch (g_variant_type_peek_string(sig)[0]) { case 'y': return g_variant_new_byte(JSValueToNumber(ctx, jsvalue, exception)); case 'n': return g_variant_new_int16(JSValueToNumber(ctx, jsvalue, exception)); case 'q': return g_variant_new_uint16(JSValueToNumber(ctx, jsvalue, exception)); case 'i': return g_variant_new_int32(JSValueToNumber(ctx, jsvalue, exception)); case 'u': return g_variant_new_uint32(JSValueToNumber(ctx, jsvalue, exception)); case 'x': return g_variant_new_int64(JSValueToNumber(ctx, jsvalue, exception)); case 't': return g_variant_new_uint64(JSValueToNumber(ctx, jsvalue, exception)); case 'd': return g_variant_new_double(JSValueToNumber(ctx, jsvalue, exception)); case 'h': return g_variant_new_handle(JSValueToNumber(ctx, jsvalue, exception)); case 'b': return g_variant_new_boolean(JSValueToBoolean(ctx, jsvalue)); case 's': { char* v = jsvalue_to_cstr(ctx, jsvalue); GVariant* r = g_variant_new_string(v); g_free(v); return r; } case 'v': { //TODO: /*g_variant_new_variant()*/ g_assert_not_reached(); } } } g_assert_not_reached(); }
/** * Convert a GVariant to a Scheme object. Returns NULL if there's a * problem. */ static Scheme_Object * g_variant_to_scheme_object (GVariant *gv) { const GVariantType *type; // The type of the GVariant const gchar *typestring; // A string that describes the type int i; // A counter variable int len; // Length of arrays and tuples Scheme_Object *lst = NULL; // A list that we build as a result Scheme_Object *sval = NULL; // One value Scheme_Object *result = NULL; // One result to return. // Special case: We'll treat NULL as void. if (gv == NULL) { return scheme_void; } // if (gv == NULL) // Get the type type = g_variant_get_type (gv); typestring = g_variant_get_type_string (gv); // ** Handle most of the basic types ** // Integer if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32)) { // We don't refer to any Scheme objects across allocating calls, // so no need for GC code. int i; i = g_variant_get_int32 (gv); result = scheme_make_integer (i); return result; } // if it's an integer // Double if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE)) { double d; d = g_variant_get_double (gv); result = scheme_make_double (d); return result; } // if it's a double // String if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING)) { // We don't refer to any Scheme objects across allocating calls, // so no need for GC code. const gchar *str; str = g_variant_get_string (gv, NULL); result = scheme_make_locale_string (str); return result; } // if it's a string // ** Handle some special cases ** // We treat arrays of bytes as bytestrings if (g_strcmp0 (typestring, "ay") == 0) { gsize size; guchar *data; data = (guchar *) g_variant_get_fixed_array (gv, &size, sizeof (guchar)); return scheme_make_sized_byte_string ((char *) data, size, 1); } // if it's an array of bytes // ** Handle the compound types ** // Tuple or Array if ( (g_variant_type_is_tuple (type)) || (g_variant_type_is_array (type)) ) { // Find out how many values to put into the list. len = g_variant_n_children (gv); // Here, we are referring to stuff across allocating calls, so we // need to be careful. MZ_GC_DECL_REG (2); MZ_GC_VAR_IN_REG (0, lst); MZ_GC_VAR_IN_REG (1, sval); MZ_GC_REG (); // Start with the empty list. lst = scheme_null; // Step through the items, right to left, adding them to the list. for (i = len-1; i >= 0; i--) { sval = g_variant_to_scheme_object (g_variant_get_child_value (gv, i)); lst = scheme_make_pair (sval, lst); } // for // Okay, we've made it through the list, now we can clean up. MZ_GC_UNREG (); if ((g_variant_type_is_array (type))) { //If type is array, convert to vector scheme_list_to_vector ((char*)lst); }//If array // And we're done. return lst; } // if it's a tuple or an array // Unknown. Give up. scheme_signal_error ("Unknown type %s", typestring); return scheme_void; } // g_variant_to_scheme_object
/** * Convert a GVariant to a Scheme object. Returns NULL if there's a * problem. */ static Scheme_Object * g_variant_to_scheme_object (GVariant *gv) { const GVariantType *type; // The type of the GVariant int i; // A counter variable int len; // Length of arrays and tuples Scheme_Object *lst = NULL; // A list that we build as a result Scheme_Object *sval = NULL; // One value Scheme_Object *result = NULL; // One result to return. // Special case: We'll treat NULL as void. if (gv == NULL) { return scheme_void; } // if (gv == NULL) // Get the type type = g_variant_get_type (gv); // ** Handle most of the basic types ** // Integer if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32)) { // We don't refer to any Scheme objects across allocating calls, // so no need for GC code. int i; i = g_variant_get_int32 (gv); result = scheme_make_integer (i); return result; } // if it's an integer // String if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING)) { // We don't refer to any Scheme objects across allocating calls, // so no need for GC code. const gchar *str; str = g_variant_get_string (gv, NULL); result = scheme_make_locale_string (str); return result; } // if it's a string // ** Handle the compound types ** // Tuple or Array if ( (g_variant_type_is_tuple (type)) || (g_variant_type_is_array (type)) ) { // Find out how many values to put into the list. len = g_variant_n_children (gv); // Here, we are referring to stuff across allocating calls, so we // need to be careful. MZ_GC_DECL_REG (2); MZ_GC_VAR_IN_REG (0, lst); MZ_GC_VAR_IN_REG (1, sval); MZ_GC_REG (); // Start with the empty list. lst = scheme_null; // Step through the items, right to left, adding them to the list. for (i = len-1; i >= 0; i--) { sval = g_variant_to_scheme_object (g_variant_get_child_value (gv, i)); lst = scheme_make_pair (sval, lst); } // for // Okay, we've made it through the list, now we can clean up. MZ_GC_UNREG (); // And we're done. return lst; } // if it's a tuple or an array // Unknown. Give up. return NULL; } // g_variant_to_scheme_object
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 * gconf_settings_backend_gconf_value_to_gvariant (GConfValue *gconf_value, const GVariantType *expected_type) { switch (gconf_value->type) { case GCONF_VALUE_STRING: case GCONF_VALUE_INT: case GCONF_VALUE_FLOAT: case GCONF_VALUE_BOOL: if (!gconf_settings_backend_simple_gconf_value_type_is_compatible (gconf_value->type, expected_type)) return NULL; return gconf_settings_backend_simple_gconf_value_type_to_gvariant (gconf_value, expected_type); case GCONF_VALUE_LIST: { GConfValueType list_type; const GVariantType *array_type; GSList *list; GPtrArray *array; GVariant *result; if (!g_variant_type_is_array (expected_type)) return NULL; list_type = gconf_value_get_list_type (gconf_value); array_type = g_variant_type_element (expected_type); if (!gconf_settings_backend_simple_gconf_value_type_is_compatible (list_type, array_type)) return NULL; array = g_ptr_array_new (); for (list = gconf_value_get_list (gconf_value); list != NULL; list = list->next) { GVariant *variant; variant = gconf_settings_backend_simple_gconf_value_type_to_gvariant (list->data, array_type); g_ptr_array_add (array, variant); } result = g_variant_new_array (array_type, (GVariant **) array->pdata, array->len); g_ptr_array_free (array, TRUE); return result; } break; case GCONF_VALUE_PAIR: { GConfValue *car; GConfValue *cdr; const GVariantType *first_type; const GVariantType *second_type; GVariant *tuple[2]; GVariant *result; if (!g_variant_type_is_tuple (expected_type) || g_variant_type_n_items (expected_type) != 2) return NULL; car = gconf_value_get_car (gconf_value); cdr = gconf_value_get_cdr (gconf_value); first_type = g_variant_type_first (expected_type); second_type = g_variant_type_next (first_type); if (!gconf_settings_backend_simple_gconf_value_type_is_compatible (car->type, first_type) || !gconf_settings_backend_simple_gconf_value_type_is_compatible (cdr->type, second_type)) return NULL; tuple[0] = gconf_settings_backend_simple_gconf_value_type_to_gvariant (car, first_type); tuple[1] = gconf_settings_backend_simple_gconf_value_type_to_gvariant (cdr, second_type); result = g_variant_new_tuple (tuple, 2); return result; } break; default: return NULL; } g_assert_not_reached (); return NULL; }
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; }