static void parse_not_supported (const GVariantType *type, GError **error) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "DBus type '%.*s' is unknown or not supported", (int)g_variant_type_get_string_length (type), g_variant_type_peek_string (type)); }
static void test_compare(CVariant *cv, GVariant *gv) { const GVariantType *gvt; GVariantIter gvi[C_VARIANT_MAX_VARG]; GVariant *gvig[C_VARIANT_MAX_VARG]; CVariantVarg varg; const char *s, *type; uint64_t val_64; uint32_t val_32; uint16_t val_16; uint8_t val_8; double val_f; size_t n, nest; GVariant *g; int r, c; type = c_variant_peek_type(cv, &n); gvt = g_variant_get_type(gv); assert(n == g_variant_type_get_string_length(gvt)); assert(!memcmp(type, g_variant_type_peek_string(gvt), n)); nest = 0; g = gv; for (c = c_variant_varg_init(&varg, type, n); c; c = c_variant_varg_next(&varg)) { if (c == -1) { r = c_variant_exit(cv, NULL); assert(r >= 0); assert(nest-- > 0); g_variant_unref(gvig[nest]); continue; } if (nest > 0) g = g_variant_iter_next_value(&gvi[nest - 1]); else g = g_variant_ref(gv); assert(g); switch (c) { case C_VARIANT_VARIANT: c_variant_enter(cv, "v"); type = c_variant_peek_type(cv, &n); c_variant_varg_push(&varg, type, n, -1); g_variant_iter_init(&gvi[nest], g); gvig[nest] = g_variant_ref(g); ++nest; break; case C_VARIANT_MAYBE: c_variant_enter(cv, "m"); n = c_variant_peek_count(cv); c_variant_varg_enter_bound(&varg, cv, n); g_variant_iter_init(&gvi[nest], g); gvig[nest] = g_variant_ref(g); ++nest; break; case C_VARIANT_ARRAY: c_variant_enter(cv, "a"); n = c_variant_peek_count(cv); c_variant_varg_enter_bound(&varg, cv, n); g_variant_iter_init(&gvi[nest], g); gvig[nest] = g_variant_ref(g); ++nest; break; case C_VARIANT_TUPLE_OPEN: c_variant_enter(cv, "("); c_variant_varg_enter_unbound(&varg, cv, ')'); g_variant_iter_init(&gvi[nest], g); gvig[nest] = g_variant_ref(g); ++nest; break; case C_VARIANT_PAIR_OPEN: c_variant_enter(cv, "{"); c_variant_varg_enter_unbound(&varg, cv, '}'); g_variant_iter_init(&gvi[nest], g); gvig[nest] = g_variant_ref(g); ++nest; break; case C_VARIANT_INT64: c_variant_read(cv, "x", &val_64); assert((int64_t)val_64 == g_variant_get_int64(g)); break; case C_VARIANT_UINT64: c_variant_read(cv, "t", &val_64); assert((uint64_t)val_64 == g_variant_get_uint64(g)); break; case C_VARIANT_DOUBLE: c_variant_read(cv, "d", &val_f); assert(!(val_f > g_variant_get_double(g)) && !(val_f < g_variant_get_double(g))); break; case C_VARIANT_INT32: c_variant_read(cv, "i", &val_32); assert((int32_t)val_32 == g_variant_get_int32(g)); break; case C_VARIANT_UINT32: c_variant_read(cv, "u", &val_32); assert((uint32_t)val_32 == g_variant_get_uint32(g)); break; case C_VARIANT_HANDLE: c_variant_read(cv, "h", &val_32); assert((int32_t)val_32 == g_variant_get_handle(g)); break; case C_VARIANT_INT16: c_variant_read(cv, "n", &val_16); assert((int16_t)val_16 == g_variant_get_int16(g)); break; case C_VARIANT_UINT16: c_variant_read(cv, "q", &val_16); assert((uint16_t)val_16 == g_variant_get_uint16(g)); break; case C_VARIANT_BOOL: c_variant_read(cv, "b", &val_8); assert((bool)val_8 == g_variant_get_boolean(g)); break; case C_VARIANT_BYTE: c_variant_read(cv, "y", &val_8); assert((guchar)val_8 == g_variant_get_byte(g)); break; case C_VARIANT_STRING: c_variant_read(cv, "s", &s); assert(!strcmp(s, g_variant_get_string(g, NULL))); break; case C_VARIANT_PATH: c_variant_read(cv, "o", &s); assert(!strcmp(s, g_variant_get_string(g, NULL))); break; case C_VARIANT_SIGNATURE: c_variant_read(cv, "g", &s); assert(!strcmp(s, g_variant_get_string(g, NULL))); break; default: assert(0); break; } r = c_variant_return_poison(cv); assert(r >= 0); g_variant_unref(g); } }
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; }