コード例 #1
0
ファイル: roster.c プロジェクト: cuckoohello/telepathy-fetion
    static void
fetion_contact_list_add_to_group_async (TpBaseContactList *contact_list,
        const gchar *group,
        TpHandleSet *contacts,
        GAsyncReadyCallback callback,
        gpointer user_data)
{
    FetionContactList *self = FETION_CONTACT_LIST (contact_list);
    FetionConnection *conn =
        FETION_CONNECTION (self->priv->conn);
    HybridAccount *account = conn->priv->account;
    HybridGroup *dest_group = hybrid_blist_find_group_by_name(account, group);
    if(dest_group == NULL)
        return ; // group must exist

    TpHandleSet *new_to_group = tp_handle_set_new (account->contact_repo);

    TpIntsetFastIter iter;
    TpHandle member;

    tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));

    while (tp_intset_fast_iter_next (&iter, &member))
    {
        HybridBuddy* buddy = hybrid_blist_find_buddy_by_handle(account,member);
        if (buddy == NULL)
            continue; // must existed
        HybridGroup *origin_group = buddy->parent;
        if (origin_group == dest_group)
            continue;

        if(!account->proto->info->im_ops->buddy_move(account,buddy,dest_group))
            continue;

        tp_handle_set_add (new_to_group, member);

    }


    if (!tp_handle_set_is_empty (new_to_group))
        tp_base_contact_list_groups_changed (contact_list, new_to_group, &group, 1,
                NULL, 0);

    tp_handle_set_destroy (new_to_group);
    tp_simple_async_report_success_in_idle ((GObject *) self, callback,
            user_data, fetion_contact_list_add_to_group_async);
}
static void _parse_and_forward_one(IdleParser *parser, gchar **tokens, IdleParserMessageCode code, const gchar *format) {
	IdleParserPrivate *priv = IDLE_PARSER_GET_PRIVATE(parser);
	GValueArray *args = g_value_array_new(3);
	GSList *link_ = priv->handlers[code];
	IdleParserHandlerResult result = IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED;
	gboolean success = TRUE;
	gchar **iter = tokens;
	/* We keep a ref to each unique handle in a message so that we can unref them after calling all handlers */
	TpHandleSet *contact_reffed = tp_handle_set_new(tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->conn), TP_HANDLE_TYPE_CONTACT));
	TpHandleSet *room_reffed = tp_handle_set_new(tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->conn), TP_HANDLE_TYPE_ROOM));

	IDLE_DEBUG("message code %u", code);

	while ((*format != '\0') && success && (*iter != NULL)) {
		GValue val = {0};

		if (*format == 'v') {
			format++;
			while (*iter != NULL) {
				if (!_parse_atom(parser, args, *format, iter[0], contact_reffed, room_reffed)) {
					success = FALSE;
					break;
				}

				iter += 2;
			}
		} else if ((*format == ':') || (*format == '.')) {
			/* Assume the happy case of the trailing parameter starting after the :
			 * in the trailing string as the RFC intended */
			const gchar *trailing = iter[1] + 1;

			/* Some IRC proxies *cough* bip *cough* omit the : in the trailing
			 * parameter if that parameter is just one word, to cope with that check
			 * if there are no more tokens after the current one and if so, accept a
			 * trailing string without the : prefix. */
			if (iter[0][0] != ':') {
				if (iter[2] == NULL) {
					trailing = iter[1];
				} else {
					success = FALSE;
					break;
				}
			}

			/*
			 * because of the way things are tokenized, if there is a
			 * space immediately after the the ':', the current token will only be
			 * ":", so we check that the trailing string is non-NULL rather than
			 * checking iter[0][1] (since iter[0] is a NULL-terminated token string
			 * whereas trailing is a pointer into the full message string
			 */
			if (trailing[0] == '\0') {
				success = FALSE;
				break;
			}

			g_value_init(&val, G_TYPE_STRING);
			g_value_set_string(&val, trailing);
			g_value_array_append(args, &val);
			g_value_unset(&val);

			IDLE_DEBUG("set string \"%s\"", trailing);
		} else {
			if (!_parse_atom(parser, args, *format, iter[0], contact_reffed, room_reffed)) {
				success = FALSE;
				break;
			}
		}

		format++;
		iter += 2;
	}

	if (!success && (*format != '.')) {
		IDLE_DEBUG("failed to parse \"%s\"", tokens[1]);

		goto cleanup;
	}

	if (*format && (*format != '.')) {
		IDLE_DEBUG("missing args in message \"%s\"", tokens[1]);

		goto cleanup;
	}

	IDLE_DEBUG("successfully parsed");

	while (link_) {
		MessageHandlerClosure *closure = link_->data;
		result = closure->handler(parser, code, args, closure->user_data);
		if (result == IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED) {
			link_ = link_->next;
		} else if (result == IDLE_PARSER_HANDLER_RESULT_HANDLED) {
			break;
		} else if (result == IDLE_PARSER_HANDLER_RESULT_NO_MORE_PLEASE) {
			GSList *tmp = link_->next;
			g_free(closure);
			priv->handlers[code] = g_slist_remove_link(priv->handlers[code], link_);
			link_ = tmp;
		} else {
			g_assert_not_reached();
		}
	}

cleanup:

	g_value_array_free(args);

	tp_handle_set_destroy(contact_reffed);
	tp_handle_set_destroy(room_reffed);
}