summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Thompson <will.thompson@collabora.co.uk>2012-03-28 14:09:58 +0100
committerWill Thompson <will.thompson@collabora.co.uk>2012-03-28 14:09:58 +0100
commit2776c23c3095ca4aaa356c6d9f0ee0c02b4c7edc (patch)
treef939ea4f34b1de3a211943ae74d20e6deeba2d9f
parentb5fe86f5fe8e2cfbc257fff29c1b087e3d2b4f74 (diff)
downloadtelepathy-glib-2776c23c3095ca4aaa356c6d9f0ee0c02b4c7edc.tar.gz
AutomaticClientFactory: add a channel type lookup table
This is a bit longer but it makes me feel smart.
-rw-r--r--telepathy-glib/automatic-client-factory.c165
1 files changed, 111 insertions, 54 deletions
diff --git a/telepathy-glib/automatic-client-factory.c b/telepathy-glib/automatic-client-factory.c
index ebab26529..0411ecaab 100644
--- a/telepathy-glib/automatic-client-factory.c
+++ b/telepathy-glib/automatic-client-factory.c
@@ -120,6 +120,93 @@ G_DEFINE_TYPE (TpAutomaticClientFactory, tp_automatic_client_factory,
#define chainup ((TpSimpleClientFactoryClass *) \
tp_automatic_client_factory_parent_class)
+typedef gboolean (*CheckPropertiesFunc) (
+ const gchar *object_path,
+ const GHashTable *properties);
+
+typedef TpChannel *(*NewFunc) (
+ TpSimpleClientFactory *client,
+ TpConnection *conn,
+ const gchar *object_path,
+ const GHashTable *properties,
+ GError **error);
+
+typedef struct {
+ const gchar *channel_type;
+ GType gtype;
+ CheckPropertiesFunc check_properties;
+ NewFunc new_func;
+ /* 0-terminated. All of a sudden, 3 is not such a scary number. */
+ GQuark features[3];
+} ChannelTypeMapping;
+
+static ChannelTypeMapping *channel_type_mapping = NULL;
+
+static gboolean
+check_for_messages (
+ const gchar *object_path,
+ const GHashTable *properties)
+{
+ /* Create a TpTextChannel only if the channel supports Messages */
+ const gchar * const * interfaces;
+
+ interfaces = tp_asv_get_strv (properties, TP_PROP_CHANNEL_INTERFACES);
+
+ if (!tp_strv_contains (interfaces, TP_IFACE_CHANNEL_INTERFACE_MESSAGES))
+ {
+ DEBUG ("channel %s doesn't implement Messages so we can't create "
+ "a TpTextChannel", object_path);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+static void
+build_channel_type_mapping (void)
+{
+ ChannelTypeMapping i_hate_c[] = {
+ { TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
+ TP_TYPE_STREAM_TUBE_CHANNEL,
+ NULL,
+ (NewFunc) _tp_stream_tube_channel_new_with_factory,
+ { 0 },
+ },
+ { TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
+ TP_TYPE_DBUS_TUBE_CHANNEL,
+ NULL,
+ (NewFunc) _tp_dbus_tube_channel_new_with_factory,
+ { 0 },
+ },
+ { TP_IFACE_CHANNEL_TYPE_TEXT,
+ TP_TYPE_TEXT_CHANNEL,
+ check_for_messages,
+ (NewFunc) _tp_text_channel_new_with_factory,
+ { TP_TEXT_CHANNEL_FEATURE_INCOMING_MESSAGES,
+ TP_TEXT_CHANNEL_FEATURE_SMS,
+ 0 },
+ },
+ { TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER,
+ TP_TYPE_FILE_TRANSFER_CHANNEL,
+ NULL,
+ (NewFunc) _tp_file_transfer_channel_new_with_factory,
+ { TP_FILE_TRANSFER_CHANNEL_FEATURE_CORE,
+ 0 },
+ },
+ { TP_IFACE_CHANNEL_TYPE_CALL,
+ TP_TYPE_CALL_CHANNEL,
+ NULL,
+ (NewFunc) _tp_call_channel_new_with_factory,
+ { TP_CALL_CHANNEL_FEATURE_CORE,
+ 0 },
+ },
+ { NULL }
+ };
+
+ g_return_if_fail (channel_type_mapping == NULL);
+
+ channel_type_mapping = g_memdup (i_hate_c, sizeof i_hate_c);
+}
+
static TpChannel *
create_channel_impl (TpSimpleClientFactory *self,
TpConnection *conn,
@@ -128,44 +215,20 @@ create_channel_impl (TpSimpleClientFactory *self,
GError **error)
{
const gchar *chan_type;
+ ChannelTypeMapping *m;
chan_type = tp_asv_get_string (properties, TP_PROP_CHANNEL_CHANNEL_TYPE);
- if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE))
- {
- return (TpChannel *) _tp_stream_tube_channel_new_with_factory (self, conn,
- object_path, properties, error);
- }
- else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE))
+ for (m = channel_type_mapping; m->channel_type != NULL; m++)
{
- return (TpChannel *) _tp_dbus_tube_channel_new_with_factory (self, conn,
- object_path, properties, error);
- }
- else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_TEXT))
- {
- const gchar * const * interfaces;
-
- interfaces = tp_asv_get_strv (properties, TP_PROP_CHANNEL_INTERFACES);
+ if (tp_strdiff (chan_type, m->channel_type))
+ continue;
- /* Create a TpTextChannel only if the channel supports Messages */
- if (tp_strv_contains (interfaces, TP_IFACE_CHANNEL_INTERFACE_MESSAGES))
- {
- return (TpChannel *) _tp_text_channel_new_with_factory (self, conn,
- object_path, properties, error);
- }
+ if (m->check_properties != NULL &&
+ !m->check_properties (object_path, properties))
+ break;
- DEBUG ("channel %s doesn't implement Messages so we can't create "
- "a TpTextChannel", object_path);
- }
- else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER))
- {
- return (TpChannel *) _tp_file_transfer_channel_new_with_factory (self,
- conn, object_path, properties, error);
- }
- else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_CALL))
- {
- return (TpChannel *) _tp_call_channel_new_with_factory (self,
- conn, object_path, properties, error);
+ return m->new_func (self, conn, object_path, properties, error);
}
/* Chainup on parent implementation as fallback */
@@ -177,34 +240,26 @@ dup_channel_features_impl (TpSimpleClientFactory *self,
TpChannel *channel)
{
GArray *features;
- GQuark feature;
+ GQuark standard_features[] = {
+ TP_CHANNEL_FEATURE_GROUP,
+ TP_CHANNEL_FEATURE_PASSWORD,
+ };
+ ChannelTypeMapping *m;
/* Chainup to get desired features for all channel types */
features = chainup->dup_channel_features (self, channel);
- feature = TP_CHANNEL_FEATURE_GROUP;
- g_array_append_val (features, feature);
-
- feature = TP_CHANNEL_FEATURE_PASSWORD;
- g_array_append_val (features, feature);
+ g_array_append_vals (features, standard_features, G_N_ELEMENTS (standard_features));
- if (TP_IS_TEXT_CHANNEL (channel))
- {
- feature = TP_TEXT_CHANNEL_FEATURE_INCOMING_MESSAGES;
- g_array_append_val (features, feature);
-
- feature = TP_TEXT_CHANNEL_FEATURE_SMS;
- g_array_append_val (features, feature);
- }
- else if (TP_IS_FILE_TRANSFER_CHANNEL (channel))
+ for (m = channel_type_mapping; m->channel_type != NULL; m++)
{
- feature = TP_FILE_TRANSFER_CHANNEL_FEATURE_CORE;
- g_array_append_val (features, feature);
- }
- else if (TP_IS_CALL_CHANNEL (channel))
- {
- feature = TP_CALL_CHANNEL_FEATURE_CORE;
- g_array_append_val (features, feature);
+ if (G_TYPE_CHECK_INSTANCE_TYPE (channel, m->gtype))
+ {
+ guint j;
+ for (j = 0; m->features[j] != 0; j++)
+ g_array_append_val (features, m->features[j]);
+ break;
+ }
}
return features;
@@ -222,6 +277,8 @@ tp_automatic_client_factory_class_init (TpAutomaticClientFactoryClass *cls)
simple_class->create_channel = create_channel_impl;
simple_class->dup_channel_features = dup_channel_features_impl;
+
+ build_channel_type_mapping ();
}
/**