static gboolean ibus_serializable_real_deserialize (IBusSerializable *object, IBusMessageIter *iter) { IBusMessageIter array_iter; gboolean retval; retval = ibus_message_iter_recurse (iter, IBUS_TYPE_ARRAY, &array_iter); g_return_val_if_fail (retval, FALSE); while (ibus_message_iter_get_arg_type (&array_iter) != G_TYPE_INVALID) { gchar *name; GValue *value; IBusMessageIter dict_entry; retval = ibus_message_iter_recurse (&array_iter, IBUS_TYPE_DICT_ENTRY, &dict_entry); g_return_val_if_fail (retval, FALSE); retval = ibus_message_iter_get (&dict_entry, G_TYPE_STRING, &name); g_return_val_if_fail (retval, FALSE); ibus_message_iter_next (&dict_entry); value = _g_value_deserialize (&dict_entry); g_return_val_if_fail (value != NULL, FALSE); ibus_serializable_set_attachment (object, name, value); ibus_message_iter_next (&array_iter); } ibus_message_iter_next (iter); return TRUE; }
static GValue * _g_value_deserialize (IBusMessageIter *iter) { IBusMessageIter variant_iter; gboolean retval; GValue *value = NULL; GType type; retval = ibus_message_iter_recurse (iter, IBUS_TYPE_VARIANT, &variant_iter); g_return_val_if_fail (retval, NULL); type = ibus_message_iter_get_arg_type (&variant_iter); if (type == IBUS_TYPE_STRUCT) { IBusSerializable *object; retval = ibus_message_iter_get (iter, IBUS_TYPE_SERIALIZABLE, &object); g_return_val_if_fail (retval, NULL); ibus_message_iter_next (iter); value = g_slice_new0 (GValue); g_value_init (value, G_OBJECT_TYPE (object)); g_value_take_object (value, object); return value; } typedef gchar *gstring; switch (type) { #define CASE_ENTRY(TYPE, _type) \ case G_TYPE_##TYPE: \ { \ g##_type v; \ ibus_message_iter_get_basic (&variant_iter, &v); \ ibus_message_iter_next (&variant_iter); \ value = g_slice_new0 (GValue); \ g_value_init (value, G_TYPE_##TYPE); \ g_value_set_##_type (value, v); \ ibus_message_iter_next (iter); \ return value; \ } CASE_ENTRY(CHAR, char); CASE_ENTRY(BOOLEAN, boolean); CASE_ENTRY(INT, int); CASE_ENTRY(UINT, uint); CASE_ENTRY(INT64, int64); CASE_ENTRY(UINT64, uint64); CASE_ENTRY(FLOAT, float); CASE_ENTRY(DOUBLE, double); CASE_ENTRY(STRING, string); } g_return_val_if_reached (NULL); }
IBusSerializable * ibus_serializable_deserialize (IBusMessageIter *iter) { g_return_val_if_fail (iter != NULL, NULL); gboolean retval; IBusMessageIter variant_iter; IBusMessageIter sub_iter; gchar *type_name; GType type; IBusSerializable *object; type = ibus_message_iter_get_arg_type (iter); if (type == IBUS_TYPE_VARIANT) { retval = ibus_message_iter_recurse (iter, IBUS_TYPE_VARIANT, &variant_iter); g_return_val_if_fail (retval, NULL); retval = ibus_message_iter_recurse (&variant_iter, IBUS_TYPE_STRUCT, &sub_iter); g_return_val_if_fail (retval, NULL); } else if (type == IBUS_TYPE_STRUCT) { retval = ibus_message_iter_recurse (iter, IBUS_TYPE_STRUCT, &sub_iter); g_return_val_if_fail (retval, NULL); } else g_return_val_if_reached (NULL); retval = ibus_message_iter_get (&sub_iter, G_TYPE_STRING, &type_name); g_return_val_if_fail (retval, NULL); ibus_message_iter_next (&sub_iter); type = g_type_from_name (type_name); g_return_val_if_fail (g_type_is_a (type, IBUS_TYPE_SERIALIZABLE), NULL); object = g_object_new (type, NULL); retval = IBUS_SERIALIZABLE_GET_CLASS (object)->deserialize (object, &sub_iter); if (retval) return object; g_object_unref (object); g_return_val_if_reached (NULL); }
static GList * ibus_bus_do_list_engines (IBusBus *bus, gboolean active_engines_only) { g_assert (IBUS_IS_BUS (bus)); IBusMessage *message, *reply; IBusError *error; gboolean retval; IBusBusPrivate *priv; IBusMessageIter iter, subiter; GList *engines; const gchar* member = active_engines_only ? "ListActiveEngines" : "ListEngines"; priv = IBUS_BUS_GET_PRIVATE (bus); message = ibus_message_new_method_call (IBUS_SERVICE_IBUS, IBUS_PATH_IBUS, IBUS_INTERFACE_IBUS, member); reply = ibus_connection_send_with_reply_and_block (priv->connection, message, -1, &error); ibus_message_unref (message); if (reply == NULL) { g_warning ("%s : %s", error->name, error->message); ibus_error_free (error); return NULL; } if ((error = ibus_error_new_from_message (reply)) != NULL) { g_warning ("%s : %s", error->name, error->message); ibus_error_free (error); ibus_message_unref (reply); return NULL; } retval = ibus_message_iter_init (reply, &iter); if (!retval) { error = ibus_error_new_from_printf (DBUS_ERROR_INVALID_ARGS, "Message does not have arguments!"); g_warning ("%s : %s", error->name, error->message); ibus_error_free (error); ibus_message_unref (reply); return NULL; } if (!ibus_message_iter_recurse (&iter, IBUS_TYPE_ARRAY, &subiter)) { ibus_message_unref (reply); return NULL; } engines = NULL; while (ibus_message_iter_get_arg_type (&subiter) != G_TYPE_INVALID) { IBusSerializable *object = NULL; if (!ibus_message_iter_get (&subiter, IBUS_TYPE_ENGINE_DESC, &object) || !object) { g_warning ("Unexpected type is returned from %s", member); continue; } engines = g_list_append (engines, object); ibus_message_iter_next (&subiter); }; ibus_message_unref (reply); return engines; }
gboolean ibus_message_iter_copy_data (IBusMessageIter *dst, IBusMessageIter *src) { GType type; gboolean retval; type = ibus_message_iter_get_arg_type (src); g_return_val_if_fail (type != G_TYPE_INVALID, FALSE); if (gtype_is_basic (type)) { gchar data[16]; ibus_message_iter_get_basic (src, data); retval = ibus_message_iter_append (dst, type, data); g_return_val_if_fail (retval, FALSE); return TRUE; } if (type == IBUS_TYPE_VARIANT) { IBusMessageIter subdst, subsrc; gchar *signature; retval = ibus_message_iter_recurse (src, IBUS_TYPE_VARIANT, &subsrc); g_return_val_if_fail (retval, FALSE); signature = dbus_message_iter_get_signature (&subsrc); g_return_val_if_fail (signature != NULL, FALSE); retval = ibus_message_iter_open_container (dst, IBUS_TYPE_VARIANT, signature, &subdst); dbus_free (signature); g_return_val_if_fail (retval, FALSE); retval = ibus_message_iter_copy_data (&subdst, &subsrc); g_return_val_if_fail (retval, FALSE); retval = ibus_message_iter_close_container (dst, &subdst); g_return_val_if_fail (retval, FALSE); return TRUE; } else if (type == IBUS_TYPE_ARRAY) { IBusMessageIter subdst, subsrc; gchar *signature; retval = ibus_message_iter_recurse (src, IBUS_TYPE_ARRAY, &subsrc); g_return_val_if_fail (retval, FALSE); signature = dbus_message_iter_get_signature (src); g_return_val_if_fail (signature != NULL, FALSE); retval = ibus_message_iter_open_container (dst, IBUS_TYPE_ARRAY, signature + 1, &subdst); dbus_free (signature); g_return_val_if_fail (retval, FALSE); while (ibus_message_iter_get_arg_type (&subsrc) != G_TYPE_INVALID) { retval = ibus_message_iter_copy_data (&subdst, &subsrc); g_return_val_if_fail (retval, FALSE); ibus_message_iter_next (&subsrc); } retval = ibus_message_iter_close_container (dst, &subdst); g_return_val_if_fail (retval, FALSE); return TRUE; } else if (type == IBUS_TYPE_STRUCT) { IBusMessageIter subdst, subsrc; retval = ibus_message_iter_recurse (src, IBUS_TYPE_STRUCT, &subsrc); g_return_val_if_fail (retval, FALSE); retval = ibus_message_iter_open_container (dst, IBUS_TYPE_STRUCT, NULL, &subdst); g_return_val_if_fail (retval, FALSE); while (ibus_message_iter_get_arg_type (&subsrc) != G_TYPE_INVALID) { retval = ibus_message_iter_copy_data (&subdst, &subsrc); ibus_message_iter_next (&subsrc); g_return_val_if_fail (retval, FALSE); } retval = ibus_message_iter_close_container (dst, &subdst); g_return_val_if_fail (retval, FALSE); return TRUE; } else if (type == IBUS_TYPE_DICT_ENTRY) { IBusMessageIter subdst, subsrc; retval = ibus_message_iter_recurse (src, IBUS_TYPE_DICT_ENTRY, &subsrc); g_return_val_if_fail (retval, FALSE); retval = ibus_message_iter_open_container (dst, IBUS_TYPE_DICT_ENTRY, NULL, &subdst); g_return_val_if_fail (retval, FALSE); /* copy key */ retval = ibus_message_iter_copy_data (&subdst, &subsrc); g_return_val_if_fail (retval, FALSE); ibus_message_iter_next (&subsrc); /* copy value */ retval = ibus_message_iter_copy_data (&subdst, &subsrc); g_return_val_if_fail (retval, FALSE); ibus_message_iter_next (&subsrc); retval = ibus_message_iter_close_container (dst, &subdst); g_return_val_if_fail (retval, FALSE); return TRUE; } return FALSE; }
gboolean ibus_message_get_args_valist (IBusMessage *message, IBusError **error, GType first_arg_type, va_list va_args) { g_assert (message != NULL); gboolean retval; IBusMessageIter iter; GType type; gpointer value; va_list backup_args; gint i; retval = ibus_message_iter_init (message, &iter); if (!retval) { if (error) { *error = ibus_error_new_from_printf (DBUS_ERROR_INVALID_ARGS, "Message does not have arguments!"); } return FALSE; } va_copy (backup_args, va_args); i = 0; type = first_arg_type; while (type != G_TYPE_INVALID) { value = va_arg (va_args, gpointer); retval = ibus_message_iter_get (&iter, type, value); if (!retval) goto _failed; ibus_message_iter_next (&iter); i ++; type = va_arg (va_args, GType); } va_end (backup_args); return TRUE; _failed: *error = ibus_error_new_from_printf (DBUS_ERROR_INVALID_ARGS, "The argument %d is not %s", i, g_type_name (type)); /* release resources */ type = first_arg_type; while (i > 0) { gpointer *value = va_arg (backup_args, gpointer *); if (g_type_is_a (type, G_TYPE_BOXED)) { g_boxed_free (type, *value); } else if (g_type_is_a (type, G_TYPE_OBJECT)) { g_object_unref (*value); } i --; type = va_arg (backup_args, GType); } va_end (backup_args); return FALSE; }