gatchat: break out the remove_if logic

And make unregister_group use the new function
This commit is contained in:
Denis Kenzior 2010-10-14 07:21:55 -05:00
parent 7fd86cf94f
commit fd113f7204
1 changed files with 64 additions and 46 deletions

View File

@ -63,6 +63,9 @@ struct at_notify_node {
GDestroyNotify notify;
};
typedef gboolean (*node_remove_func)(struct at_notify_node *node,
gpointer user_data);
struct at_notify {
GSList *nodes;
gboolean pdu;
@ -154,6 +157,57 @@ static gint at_command_compare_by_id(gconstpointer a, gconstpointer b)
return 0;
}
static gboolean at_chat_unregister_all(struct at_chat *chat,
node_remove_func func,
gpointer userdata)
{
GHashTableIter iter;
struct at_notify *notify;
struct at_notify_node *node;
gpointer key, value;
GSList *p;
GSList *c;
GSList *t;
if (chat->notify_list == NULL)
return FALSE;
g_hash_table_iter_init(&iter, chat->notify_list);
while (g_hash_table_iter_next(&iter, &key, &value)) {
notify = value;
p = NULL;
c = notify->nodes;
while (c) {
node = c->data;
if (func(node, userdata) != TRUE) {
p = c;
c = c->next;
continue;
}
if (p)
p->next = c->next;
else
notify->nodes = c->next;
at_notify_node_destroy(node, NULL);
t = c;
c = c->next;
g_slist_free_1(t);
}
if (notify->nodes == NULL)
g_hash_table_iter_remove(&iter);
}
return TRUE;
}
static struct at_command *at_command_create(guint gid, const char *cmd,
const char **prefix_list,
gboolean expect_pdu,
@ -1099,53 +1153,15 @@ static gboolean at_chat_unregister(struct at_chat *chat, guint group, guint id)
return FALSE;
}
static gboolean at_chat_unregister_group(struct at_chat *chat, guint group)
static gboolean node_compare_by_group(struct at_notify_node *node,
gpointer userdata)
{
GHashTableIter iter;
struct at_notify *notify;
struct at_notify_node *node;
gpointer key, value;
GSList *p;
GSList *c;
GSList *t;
guint group = GPOINTER_TO_UINT(userdata);
if (chat->notify_list == NULL)
return FALSE;
if (node->gid == group)
return TRUE;
g_hash_table_iter_init(&iter, chat->notify_list);
while (g_hash_table_iter_next(&iter, &key, &value)) {
notify = value;
p = NULL;
c = notify->nodes;
while (c) {
node = c->data;
if (node->gid != group) {
p = c;
c = c->next;
continue;
}
if (p)
p->next = c->next;
else
notify->nodes = c->next;
at_notify_node_destroy(node, NULL);
t = c;
c = c->next;
g_slist_free_1(t);
}
if (notify->nodes == NULL)
g_hash_table_iter_remove(&iter);
}
return TRUE;
return FALSE;
}
static struct at_chat *create_chat(GIOChannel *channel, GIOFlags flags,
@ -1310,7 +1326,7 @@ void g_at_chat_unref(GAtChat *chat)
return;
at_chat_cancel_group(chat->parent, chat->group);
at_chat_unregister_group(chat->parent, chat->group);
g_at_chat_unregister_all(chat);
at_chat_unref(chat->parent);
g_free(chat);
@ -1431,5 +1447,7 @@ gboolean g_at_chat_unregister_all(GAtChat *chat)
if (chat == NULL)
return FALSE;
return at_chat_unregister_group(chat->parent, chat->group);
return at_chat_unregister_all(chat->parent,
node_compare_by_group,
GUINT_TO_POINTER(chat->group));
}