📄 gupnp-service-proxy.c
字号:
} else { g_warning ("Error collecting value: %s\n", collect_error); g_free (collect_error); /* we purposely leak the value here, it might not be * in a sane state if an error condition occoured */ } arg_name = va_arg (var_args, const char *); } /* Finish and send off */ finish_action_msg (ret, action); /* Save the current position in the va_list for send_action_valist() */ G_VA_COPY (ret->var_args, var_args); return ret;}/** * gupnp_service_proxy_begin_action_hash * @proxy: A #GUPnPServiceProxy * @action: An action * @callback: The callback to call when sending the action has succeeded * or failed * @user_data: User data for @callback * @hash: A #GHashTable of in parameter name and #GValue pairs * * See gupnp_service_proxy_begin_action(); this version takes a #GHashTable * for runtime generated parameter lists. * * Return value: A #GUPnPServiceProxyAction handle. This will * be freed when calling gupnp_service_proxy_cancel_action() or * gupnp_service_proxy_end_action_hash(). **/GUPnPServiceProxyAction *gupnp_service_proxy_begin_action_hash (GUPnPServiceProxy *proxy, const char *action, GUPnPServiceProxyActionCallback callback, gpointer user_data, GHashTable *hash){ GUPnPServiceProxyAction *ret; g_return_val_if_fail (GUPNP_IS_SERVICE_PROXY (proxy), NULL); g_return_val_if_fail (action, NULL); g_return_val_if_fail (callback, NULL); /* Create message */ ret = begin_action_msg (proxy, action, callback, user_data); if (ret->error) { callback (proxy, ret, user_data); return ret; } /* Arguments */ g_hash_table_foreach (hash, (GHFunc) write_in_parameter, ret->msg_str); /* Finish and send off */ finish_action_msg (ret, action); return ret;}/** * gupnp_service_proxy_end_action * @proxy: A #GUPnPServiceProxy * @action: A #GUPnPServiceProxyAction handle * @error: The location where to store any error, or %NULL * @Varargs: tuples of out parameter name, out paramater type, and out parameter * value location, terminated with %NULL. The out parameter values should be * freed after use * * Retrieves the result of @action. The out parameters in @Varargs will be * filled in, and if an error occurred, @error will be set. In case of * a UPnPError the error code will be the same in @error. * * Return value: %TRUE on success. **/gbooleangupnp_service_proxy_end_action (GUPnPServiceProxy *proxy, GUPnPServiceProxyAction *action, GError **error, ...){ va_list var_args; gboolean ret; va_start (var_args, error); ret = gupnp_service_proxy_end_action_valist (proxy, action, error, var_args); va_end (var_args); return ret;}/* Checks an action response for errors and returns the parsed * xmlDoc object. */static xmlDoc *check_action_response (GUPnPServiceProxy *proxy, GUPnPServiceProxyAction *action, xmlNode **params, GError **error){ xmlDoc *response; int code; /* Check for errors */ switch (action->msg->status_code) { case SOUP_STATUS_OK: case SOUP_STATUS_INTERNAL_SERVER_ERROR: break; default: set_server_error (error, action->msg); return NULL; } /* Parse response */ response = xmlParseMemory (action->msg->response_body->data, action->msg->response_body->length); if (!response) { if (action->msg->status_code == SOUP_STATUS_OK) { g_set_error (error, GUPNP_SERVER_ERROR, GUPNP_SERVER_ERROR_INVALID_RESPONSE, "Could not parse SOAP response"); } else { set_error_literal (error, GUPNP_SERVER_ERROR, GUPNP_SERVER_ERROR_INTERNAL_SERVER_ERROR, action->msg->reason_phrase); } return NULL; } /* Get parameter list */ *params = xml_util_get_element ((xmlNode *) response, "Envelope", NULL); if (*params != NULL) *params = xml_util_real_node ((*params)->children); if (*params != NULL) { if (strcmp ((const char *) (*params)->name, "Header") == 0) *params = xml_util_real_node ((*params)->next); if (*params != NULL) if (strcmp ((const char *) (*params)->name, "Body") != 0) *params = NULL; } if (*params != NULL) *params = xml_util_real_node ((*params)->children); if (*params == NULL) { g_set_error (error, GUPNP_SERVER_ERROR, GUPNP_SERVER_ERROR_INVALID_RESPONSE, "Invalid Envelope"); xmlFreeDoc (response); return NULL; } /* Check whether we have a Fault */ if (action->msg->status_code == SOUP_STATUS_INTERNAL_SERVER_ERROR) { xmlNode *param; char *desc; param = xml_util_get_element (*params, "detail", "UPnPError", NULL); if (!param) { g_set_error (error, GUPNP_SERVER_ERROR, GUPNP_SERVER_ERROR_INVALID_RESPONSE, "Invalid Fault"); xmlFreeDoc (response); return NULL; } /* Code */ code = xml_util_get_child_element_content_int (param, "errorCode"); if (code == -1) { g_set_error (error, GUPNP_SERVER_ERROR, GUPNP_SERVER_ERROR_INVALID_RESPONSE, "Invalid Fault"); xmlFreeDoc (response); return NULL; } /* Description */ desc = xml_util_get_child_element_content_glib (param, "errorDescription"); if (desc == NULL) desc = g_strdup (action->msg->reason_phrase); set_error_literal (error, GUPNP_CONTROL_ERROR, code, desc); g_free (desc); xmlFreeDoc (response); return NULL; } return response;}/* Reads a value into the parameter name and initialised GValue pair * from @response */static voidread_out_parameter (const char *arg_name, GValue *value, xmlNode *params){ xmlNode *param; /* Try to find a matching paramater in the response*/ param = xml_util_get_element (params, arg_name, NULL); if (!param) { g_warning ("Could not find variable \"%s\" in response", arg_name); return; } gvalue_util_set_value_from_xml_node (value, param);}/** * gupnp_service_proxy_end_action_valist * @proxy: A #GUPnPServiceProxy * @action: A #GUPnPServiceProxyAction handle * @error: The location where to store any error, or %NULL * @var_args: A va_list of tuples of out parameter name, out paramater type, * and out parameter value location. The out parameter values should be * freed after use * * See gupnp_service_proxy_end_action(); this version takes a va_list for * use by language bindings. * * Return value: %TRUE on success. **/gbooleangupnp_service_proxy_end_action_valist (GUPnPServiceProxy *proxy, GUPnPServiceProxyAction *action, GError **error, va_list var_args){ xmlDoc *response; xmlNode *params; const char *arg_name; g_return_val_if_fail (GUPNP_IS_SERVICE_PROXY (proxy), FALSE); g_return_val_if_fail (action, FALSE); /* Check for saved error from begin_action() */ if (action->error) { if (error) *error = action->error; else g_error_free (action->error); gupnp_service_proxy_action_free (action); return FALSE; } /* Check response for errors and do initial parsing */ response = check_action_response (proxy, action, ¶ms, error); if (response == NULL) { gupnp_service_proxy_action_free (action); return FALSE; } /* Arguments */ arg_name = va_arg (var_args, const char *); while (arg_name) { GType arg_type; GValue value = { 0, }; char *copy_error = NULL; arg_type = va_arg (var_args, GType); g_value_init (&value, arg_type); read_out_parameter (arg_name, &value, params); G_VALUE_LCOPY (&value, var_args, 0, ©_error); g_value_unset (&value); if (copy_error) { g_warning ("Error copying value: %s", copy_error); g_free (copy_error); } arg_name = va_arg (var_args, const char *); } /* Cleanup */ gupnp_service_proxy_action_free (action); xmlFreeDoc (response); return TRUE;}/** * gupnp_service_proxy_end_action_hash * @proxy: A #GUPnPServiceProxy * @action: A #GUPnPServiceProxyAction handle * @error: The location where to store any error, or %NULL * @hash: A #GHashTable of out parameter name and initialised #GValue pairs * * See gupnp_service_proxy_end_action(); this version takes a #GHashTable * for runtime generated parameter lists. * * Return value: %TRUE on success. **/gbooleangupnp_service_proxy_end_action_hash (GUPnPServiceProxy *proxy, GUPnPServiceProxyAction *action, GError **error, GHashTable *hash){ xmlDoc *response; xmlNode *params; g_return_val_if_fail (GUPNP_IS_SERVICE_PROXY (proxy), FALSE); g_return_val_if_fail (action, FALSE); /* Check for saved error from begin_action() */ if (action->error) { if (error) *error = action->error; else g_error_free (action->error); gupnp_service_proxy_action_free (action); return FALSE; } /* Check response for errors and do initial parsing */ response = check_action_response (proxy, action, ¶ms, error); if (response == NULL) { gupnp_service_proxy_action_free (action); return FALSE; } /* Read arguments */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -