[Telepathy-commits] [telepathy-mission-control/master] Dispatcher: .client file parsing: fill the new channel filter structure (GPtrArray of GHashTable)
Alban Crequy
alban.crequy at collabora.co.uk
Wed Nov 19 11:53:25 PST 2008
---
src/mcd-dispatcher.c | 225 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 156 insertions(+), 69 deletions(-)
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index 4363c99..ffba560 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -98,17 +98,6 @@ typedef struct _McdDispatcherArgs
GPtrArray *channel_handler_caps;
} McdDispatcherArgs;
-#define MCD_CLIENT_FILTER_CHANNEL_TYPE 0x1
-#define MCD_CLIENT_FILTER_HANDLE_TYPE 0x2
-#define MCD_CLIENT_FILTER_REQUESTED 0x4
-typedef struct _McdClientFilter
-{
- guint field_mask;
- GQuark channel_type;
- TpHandleType handle_type;
- guint requested : 1;
-} McdClientFilter;
-
typedef enum
{
MCD_CLIENT_APPROVER = 0x1,
@@ -122,10 +111,16 @@ typedef struct _McdClient
gchar *name;
McdClientInterface interfaces;
guint bypass_approver : 1;
- /* each element is a McdClientFilter */
+
+ /* Channel filters
+ * A channel filter is a GHashTable of
+ * - key: gchar *property_name
+ * - value: one of the allowed types on the ObserverChannelFilter spec
+ */
GList *approver_filters;
GList *handler_filters;
GList *observer_filters;
+
/* from the HandlerChannelFilter property */
GValue *caps;
} McdClient;
@@ -272,12 +267,6 @@ mcd_dispatcher_context_handler_done (McdDispatcherContext *context)
}
static void
-mcd_client_filter_free (McdClientFilter *filter)
-{
- g_slice_free (McdClientFilter, filter);
-}
-
-static void
mcd_client_free (McdClient *client)
{
if (client->proxy)
@@ -288,11 +277,11 @@ mcd_client_free (McdClient *client)
g_value_unset (client->caps);
g_list_foreach (client->approver_filters,
- (GFunc)mcd_client_filter_free, NULL);
+ (GFunc)g_hash_table_destroy, NULL);
g_list_foreach (client->handler_filters,
- (GFunc)mcd_client_filter_free, NULL);
+ (GFunc)g_hash_table_destroy, NULL);
g_list_foreach (client->observer_filters,
- (GFunc)mcd_client_filter_free, NULL);
+ (GFunc)g_hash_table_destroy, NULL);
}
static void
@@ -883,38 +872,104 @@ start_old_channel_handler (McdDispatcherContext *context)
static gboolean
match_filters (McdChannel *channel, GList *filters)
{
+ GHashTable *channel_properties =
+ _mcd_channel_get_immutable_properties (channel);
gboolean matched = FALSE;
GList *list;
for (list = filters; list != NULL; list = list->next)
{
- McdClientFilter *filter = list->data;
+ GHashTable *filter = list->data;
+ GHashTableIter filter_iter;
+ gboolean filter_matched = TRUE;
+ gchar *property_name;
+ GValue *filter_value;
- if (filter->field_mask & MCD_CLIENT_FILTER_CHANNEL_TYPE)
+ g_hash_table_iter_init (&filter_iter, filter);
+ while (g_hash_table_iter_next (&filter_iter,
+ (gpointer *) &property_name,
+ (gpointer *) &filter_value))
{
- g_debug ("channel type: %u, filter %u",
- mcd_channel_get_channel_type_quark (channel),
- filter->channel_type);
- if (mcd_channel_get_channel_type_quark (channel) !=
- filter->channel_type)
- continue;
- }
+ GValue *channel_value;
- if (filter->field_mask & MCD_CLIENT_FILTER_REQUESTED)
- {
- /* TODO */
- }
+ channel_value = g_hash_table_lookup (channel_properties,
+ property_name);
+ if (channel_value == NULL)
+ {
+ /* the channel does not even have this property */
+ filter_matched = FALSE;
+ break;
+ }
+
+ g_assert (G_IS_VALUE (filter_value));
+ g_assert (G_IS_VALUE (channel_value));
+
+ /* string */
+ if (G_VALUE_TYPE (filter_value) == G_TYPE_STRING)
+ {
+ if (G_VALUE_TYPE (channel_value) != G_TYPE_STRING)
+ {
+ /* the channel has this property, but the wrong type */
+ filter_matched = FALSE;
+ break;
+ }
+
+ if (strcmp (g_value_get_string (filter_value),
+ g_value_get_string (channel_value)) != 0)
+ {
+ /* the content does not match */
+ filter_matched = FALSE;
+ break;
+ }
+ }
+
+ /* boolean */
+ if (G_VALUE_TYPE (filter_value) == G_TYPE_BOOLEAN)
+ {
+ if (G_VALUE_TYPE (channel_value) != G_TYPE_BOOLEAN)
+ {
+ /* the channel has this property, but the wrong type */
+ filter_matched = FALSE;
+ break;
+ }
+
+ if (g_value_get_boolean (filter_value) !=
+ g_value_get_boolean (channel_value))
+ {
+ /* the content does not match */
+ filter_matched = FALSE;
+ break;
+ }
+ }
+
+ /* integers */
+ if (g_value_type_compatible (G_VALUE_TYPE (filter_value),
+ G_TYPE_UINT64))
+ {
+ if (g_value_type_compatible (G_VALUE_TYPE (channel_value),
+ G_TYPE_UINT64))
+ {
+ /* the channel has this property, but the wrong type */
+ filter_matched = FALSE;
+ break;
+ }
+
+ if (g_value_get_uint64 (filter_value) !=
+ g_value_get_uint64 (channel_value))
+ {
+ /* the content does not match */
+ filter_matched = FALSE;
+ break;
+ }
+ }
- if (filter->field_mask & MCD_CLIENT_FILTER_HANDLE_TYPE)
- {
- g_debug ("handle type: %u, filter %u",
- mcd_channel_get_handle_type (channel),
- filter->handle_type);
- if (mcd_channel_get_handle_type (channel) != filter->handle_type)
- continue;
}
- matched = TRUE;
- break;
+
+ if (filter_matched)
+ {
+ matched = TRUE;
+ break;
+ }
}
return matched;
@@ -1748,49 +1803,81 @@ mcd_dispatcher_send (McdDispatcher * dispatcher, McdChannel *channel)
return TRUE;
}
-static McdClientFilter *
+static GHashTable *
parse_client_filter (GKeyFile *file, const gchar *group)
{
- McdClientFilter *filter;
+ GHashTable *filter;
gchar **keys;
gsize len = 0;
guint i;
- filter = g_slice_new0 (McdClientFilter);
+ filter = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify) g_value_unset);
keys = g_key_file_get_keys (file, group, &len, NULL);
for (i = 0; i < len; i++)
{
const gchar *key;
+ const gchar *space;
+ gchar *file_property;
+ gchar file_property_type;
key = keys[i];
- if (strcmp (key, TP_IFACE_CHANNEL ".Type s") == 0)
- {
- gchar *string;
+ space = g_strrstr (key, " ");
- string = g_key_file_get_string (file, group, key, NULL);
- filter->channel_type = g_quark_from_string (string);
- g_free (string);
-
- filter->field_mask |= MCD_CLIENT_FILTER_CHANNEL_TYPE;
- }
- else if (strcmp (key, TP_IFACE_CHANNEL ".TargetHandleType u") == 0)
- {
- filter->handle_type =
- (guint) g_key_file_get_integer (file, group, key, NULL);
- filter->field_mask |= MCD_CLIENT_FILTER_HANDLE_TYPE;
- }
- else if (strcmp (key, TP_IFACE_CHANNEL ".Requested b") == 0)
- {
- filter->requested =
- g_key_file_get_boolean (file, group, key, NULL);
- filter->field_mask |= MCD_CLIENT_FILTER_REQUESTED;
- }
- else
+ if (space == NULL || space + 1 == '\0' || space + 2 != '\0' )
{
g_warning ("Invalid key %s in client file", key);
continue;
}
+ file_property_type = space[1];
+ file_property = g_strndup (key, space - key);
+
+ switch (file_property_type)
+ {
+ case 'y': case 'n': case 'q': case 'i': case 'u':
+ case 'x': case 't':
+ /* cannot use g_key_file_get_integer because we need to
+ * support 64 bits */
+ break;
+
+ case 'b':
+ {
+ GValue *value = tp_g_value_slice_new (G_TYPE_BOOLEAN);
+ gboolean b = g_key_file_get_boolean (file, group, key,
+ NULL);
+ g_value_set_boolean (value, b);
+ g_hash_table_insert (filter, file_property, value);
+ break;
+ }
+
+ case 's':
+ {
+ GValue *value = tp_g_value_slice_new (G_TYPE_STRING);
+ gchar *str = g_key_file_get_string (file, group, key,
+ NULL);
+
+ g_value_set_string (value, str);
+ g_hash_table_insert (filter, file_property, value);
+ break;
+ }
+
+ case 'o':
+ {
+ GValue *value = tp_g_value_slice_new
+ (DBUS_TYPE_G_OBJECT_PATH);
+ gchar *str = g_key_file_get_string (file, group, key,
+ NULL);
+
+ g_value_set_boxed (value, str);
+ g_hash_table_insert (filter, file_property, value);
+ break;
+ }
+
+ default:
+ g_warning ("Invalid key %s in client file", key);
+ continue;
+ }
}
g_strfreev (keys);
--
1.5.6.5
More information about the Telepathy-commits
mailing list