diff options
| author | Will Thompson <will.thompson@collabora.co.uk> | 2010-03-24 02:09:21 (GMT) |
|---|---|---|
| committer | Will Thompson <will.thompson@collabora.co.uk> | 2010-03-24 13:38:20 (GMT) |
| commit | f6f96522cc9ff0e7541f6087f254e62900454fbf (patch) | |
| tree | 2158e8bb10ab0772f75cc69e718e062d79358bfe | |
| parent | ef53f61d5354999d0d934d4eacdc83d76fdde4ca (diff) | |
| download | wocky-f6f96522cc9ff0e7541f6087f254e62900454fbf.tar.gz wocky-f6f96522cc9ff0e7541f6087f254e62900454fbf.tar.xz | |
Add and use new variants of pubsub_distill_iq_reply
Often, you don't care at all about what the iq reply contains, only
whether it's a result or an error. wocky_pubsub_distill_void_iq_reply()
deals with that case more clearly than the caller passing three NULL
arguments to wocky_pubsub_distill_iq_reply().
Additionally, there exist cases where you're interested in the reply's
body if it's present, but the reply being empty is not an error.
wocky_pubsub_distill_ambivalent_iq_reply() handles this case.
They are all implemented in terms of a slightly enhanced version of the
former body of wocky_pubsub_distill_iq_reply().
| -rw-r--r-- | wocky/wocky-pubsub-helpers.c | 126 | ||||
| -rw-r--r-- | wocky/wocky-pubsub-helpers.h | 11 | ||||
| -rw-r--r-- | wocky/wocky-pubsub-node.c | 4 |
3 files changed, 127 insertions, 14 deletions
diff --git a/wocky/wocky-pubsub-helpers.c b/wocky/wocky-pubsub-helpers.c index 56fb1c4..650b022 100644 --- a/wocky/wocky-pubsub-helpers.c +++ b/wocky/wocky-pubsub-helpers.c @@ -112,6 +112,60 @@ get_pubsub_child_node (WockyXmppStanza *reply, return TRUE; } + +static gboolean +wocky_pubsub_distill_iq_reply_internal (GObject *source, + GAsyncResult *res, + const gchar *pubsub_ns, + const gchar *child_name, + gboolean body_optional, + WockyXmppNode **child_out, + GError **error) +{ + WockyXmppStanza *reply; + gboolean ret = FALSE; + + if (child_out != NULL) + *child_out = NULL; + + /* Superlative news out of the 00:04 to Cambridge: earlier today, an + * asynchronous method call announced its plans to bring a node to The + * People's Republic of Wocky. + */ + reply = wocky_porter_send_iq_finish (WOCKY_PORTER (source), res, error); + + if (reply == NULL) + return FALSE; + + if (!wocky_xmpp_stanza_extract_errors (reply, NULL, error, NULL, NULL)) + { + ret = TRUE; + + if (pubsub_ns != NULL) + { + /* A force of a thousand function calls will anchor the node to + * a resplendent out parameter modeled on the Dear Leader's hand. + */ + ret = get_pubsub_child_node (reply, pubsub_ns, child_name, child_out, + error); + + /* The People's Great and Harmonious Node Pointer of Peter + * Saint-Andre will conclude the most astonishing stanza breakdown + * ever witnessed by man. + */ + if (!ret && body_optional) + { + /* “The stanza is perfect. We have already succeeded.” */ + ret = TRUE; + g_clear_error (error); + } + } + } + + g_object_unref (reply); + return ret; +} + /** * wocky_pubsub_distill_iq_reply: * @source: a #WockyPorter instance @@ -141,18 +195,66 @@ wocky_pubsub_distill_iq_reply (GObject *source, WockyXmppNode **child_out, GError **error) { - WockyXmppStanza *reply = wocky_porter_send_iq_finish ( - WOCKY_PORTER (source), res, error); - gboolean ret = FALSE; - - if (reply == NULL) - return FALSE; + return wocky_pubsub_distill_iq_reply_internal (source, res, pubsub_ns, + child_name, FALSE, child_out, error); +} - if (!wocky_xmpp_stanza_extract_errors (reply, NULL, error, NULL, NULL) && - (pubsub_ns == NULL /* no child expected */ || - get_pubsub_child_node (reply, pubsub_ns, child_name, child_out, error))) - ret = TRUE; +/** + * wocky_pubsub_distill_void_iq_reply: + * @source: a #WockyPorter instance + * @res: a result passed to the callback for wocky_porter_send_iq_async() + * @error: location at which to store an error if the call to + * wocky_porter_send_iq_async() returned an error, or if the reply was + * an error + * + * Helper function to finish a wocky_porter_send_iq_async() operation where no + * pubsub child is expected in the resulting reply. + * + * Returns: %TRUE if the IQ was a success; %FALSE if + * sending the IQ failed or the reply had type='error', + * with @error set appropriately. + */ +gboolean +wocky_pubsub_distill_void_iq_reply (GObject *source, + GAsyncResult *res, + GError **error) +{ + return wocky_pubsub_distill_iq_reply_internal (source, res, NULL, NULL, TRUE, + NULL, error); +} - g_object_unref (reply); - return ret; +/** + * wocky_pubsub_distill_ambivalent_iq_reply: + * @source: a #WockyPorter instance + * @res: a result passed to the callback for wocky_porter_send_iq_async() + * @pubsub_ns: the namespace of the <pubsub/> node accepted in this reply (such + * WOCKY_XMPP_NS_PUBSUB) + * @child_name: the name of the child of <pubsub/> accepted in this reply (such + * as "subscriptions") + * @child_out: location at which to store a pointer to the node named + * @child_name, if is found, or to be set to %NULL if it is not + * found + * @error: location at which to store an error if the call to + * wocky_porter_send_iq_async() returned an error, or if the reply was + * an error + * + * Helper function to finish a wocky_porter_send_iq_async() operation + * and extract a particular pubsub child from the resulting reply, if it is + * present. This is like wocky_pubsub_distill_iq_reply(), but is ambivalent as + * to whether the <pubsub/> structure has to be included. + * + * Returns: %TRUE if the IQ was a success; %FALSE if + * sending the IQ failed or the reply had type='error', + * with @error set appropriately. + */ +gboolean +wocky_pubsub_distill_ambivalent_iq_reply (GObject *source, + GAsyncResult *res, + const gchar *pubsub_ns, + const gchar *child_name, + WockyXmppNode **child_out, + GError **error) +{ + return wocky_pubsub_distill_iq_reply_internal (source, res, pubsub_ns, + child_name, TRUE, child_out, error); } diff --git a/wocky/wocky-pubsub-helpers.h b/wocky/wocky-pubsub-helpers.h index f568221..65800e1 100644 --- a/wocky/wocky-pubsub-helpers.h +++ b/wocky/wocky-pubsub-helpers.h @@ -39,4 +39,15 @@ gboolean wocky_pubsub_distill_iq_reply (GObject *source, WockyXmppNode **child_out, GError **error); +gboolean wocky_pubsub_distill_ambivalent_iq_reply (GObject *source, + GAsyncResult *res, + const gchar *pubsub_ns, + const gchar *child_name, + WockyXmppNode **child_out, + GError **error); + +gboolean wocky_pubsub_distill_void_iq_reply (GObject *source, + GAsyncResult *res, + GError **error); + #endif /* WOCKY_PUBSUB_HELPERS_H */ diff --git a/wocky/wocky-pubsub-node.c b/wocky/wocky-pubsub-node.c index c2379e5..d9523fd 100644 --- a/wocky/wocky-pubsub-node.c +++ b/wocky/wocky-pubsub-node.c @@ -486,7 +486,7 @@ unsubscribe_cb (GObject *source, GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); GError *error = NULL; - if (!wocky_pubsub_distill_iq_reply (source, res, NULL, NULL, NULL, &error)) + if (!wocky_pubsub_distill_void_iq_reply (source, res, &error)) { g_simple_async_result_set_from_error (simple, error); g_clear_error (&error); @@ -554,7 +554,7 @@ delete_node_iq_cb (GObject *source, GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data); GError *error = NULL; - if (!wocky_pubsub_distill_iq_reply (source, res, NULL, NULL, NULL, &error)) + if (!wocky_pubsub_distill_void_iq_reply (source, res, &error)) { g_simple_async_result_set_from_error (result, error); g_clear_error (&error); |
