#ifndef PROTON_DELIVERY_H #define PROTON_DELIVERY_H 1 /* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** * @file * * @copybrief delivery * * @addtogroup delivery * @{ */ /** * An AMQP delivery tag. */ typedef pn_bytes_t pn_delivery_tag_t; /** * Construct a delivery tag. * * @param[in] bytes a pointer to the beginning of the tag * @param[in] size the size of the tag * @return the delivery tag */ PN_EXTERN pn_delivery_tag_t pn_dtag(const char *bytes, size_t size); /** * Create a delivery on a link. * * Every delivery object within a link must be supplied with a unique * tag. Links maintain a sequence of delivery object in the order that * they are created. * * @param[in] link a link object * @param[in] tag the delivery tag * @return a newly created delivery, or NULL if there was an error */ PN_EXTERN pn_delivery_t *pn_delivery(pn_link_t *link, pn_delivery_tag_t tag); /** * Get the application context that is associated with a delivery object. * * The application context for a delivery may be set using * ::pn_delivery_set_context. * * @param[in] delivery the delivery whose context is to be returned. * @return the application context for the delivery object */ PN_EXTERN void *pn_delivery_get_context(pn_delivery_t *delivery); /** * Set a new application context for a delivery object. * * The application context for a delivery object may be retrieved using * ::pn_delivery_get_context. * * @param[in] delivery the delivery object * @param[in] context the application context */ PN_EXTERN void pn_delivery_set_context(pn_delivery_t *delivery, void *context); /** * Get the attachments that are associated with a delivery object. * * @param[in] delivery the delivery whose attachments are to be returned. * @return the attachments for the delivery object */ PN_EXTERN pn_record_t *pn_delivery_attachments(pn_delivery_t *delivery); /** * Get the tag for a delivery object. * * @param[in] delivery a delivery object * @return the delivery tag */ PN_EXTERN pn_delivery_tag_t pn_delivery_tag(pn_delivery_t *delivery); /** * Get the parent link for a delivery object. * * @param[in] delivery a delivery object * @return the parent link */ PN_EXTERN pn_link_t *pn_delivery_link(pn_delivery_t *delivery); /** * Get the local disposition for a delivery. * * The pointer returned by this object is valid until the delivery is * settled. * * @param[in] delivery a delivery object * @return a pointer to the local disposition */ PN_EXTERN pn_disposition_t *pn_delivery_local(pn_delivery_t *delivery); /** * Get the local disposition state for a delivery. * * @param[in] delivery a delivery object * @return the local disposition state */ PN_EXTERN uint64_t pn_delivery_local_state(pn_delivery_t *delivery); /** * Get the remote disposition for a delivery. * * The pointer returned by this object is valid until the delivery is * settled. * * @param[in] delivery a delivery object * @return a pointer to the remote disposition */ PN_EXTERN pn_disposition_t *pn_delivery_remote(pn_delivery_t *delivery); /** * Get the remote disposition state for a delivery. * * @param[in] delivery a delivery object * @return the remote disposition state */ PN_EXTERN uint64_t pn_delivery_remote_state(pn_delivery_t *delivery); /** * Check if a delivery is remotely settled. * * @param[in] delivery a delivery object * @return true if the delivery is settled at the remote endpoint, false otherwise */ PN_EXTERN bool pn_delivery_settled(pn_delivery_t *delivery); /** * Get the amount of pending message data for a delivery. * * @param[in] delivery a delivery object * @return the amount of pending message data in bytes */ PN_EXTERN size_t pn_delivery_pending(pn_delivery_t *delivery); /** * Check if a delivery only has partial message data. * * The receiver can expect more ::PN_DELIVERY events for this delivery containing * the remainder of this message. * * @param[in] delivery a delivery object * @return true if the delivery only contains part of a message, false otherwise */ PN_EXTERN bool pn_delivery_partial(pn_delivery_t *delivery); /** * Check if a received delivery has been aborted. * * An aborted delivery means the sender cannot complete this message and the * receiver should discard any data already received. The link remains open for * future messages. * * You must still call pn_delivery_settle() to free local resources. An aborted * delivery consumes a credit, use pn_link_flow() to issue new credit as for a * successful delivery. * * Calling pn_link_recv() when the current delivery is aborted returns * ::PN_ABORTED. * * @see pn_delivery_abort() * @param[in] delivery a delivery object * @return true if the delivery has been aborted, false otherwise */ PN_EXTERN bool pn_delivery_aborted(pn_delivery_t *delivery); /** * Check if a delivery is writable. * * A delivery is considered writable if it is the current delivery on * an outgoing link, and the link has positive credit. * * @param[in] delivery a delivery object * @return true if the delivery is writable, false otherwise */ PN_EXTERN bool pn_delivery_writable(pn_delivery_t *delivery); /** * Check if a delivery is readable. * * A delivery is considered readable if it is the current delivery on * an incoming link. * * @param[in] delivery a delivery object * @return true if the delivery is readable, false otherwise */ PN_EXTERN bool pn_delivery_readable(pn_delivery_t *delivery); /** * Check if a delivery is updated. * * A delivery is considered updated whenever the peer communicates a * new disposition for the delivery. Once a delivery becomes updated, * it will remain so until ::pn_delivery_clear is called. * * @param[in] delivery a delivery object * @return true if the delivery is updated, false otherwise */ PN_EXTERN bool pn_delivery_updated(pn_delivery_t *delivery); /** * Update the disposition of a delivery. * * When update is invoked the updated disposition of the delivery will * be communicated to the peer. * * @param[in] delivery a delivery object * @param[in] state the updated delivery state */ PN_EXTERN void pn_delivery_update(pn_delivery_t *delivery, uint64_t state); /** * Clear the updated flag for a delivery. * * See ::pn_delivery_updated. * * @param[in] delivery a delivery object */ PN_EXTERN void pn_delivery_clear(pn_delivery_t *delivery); /** * Return true if delivery is the current delivery for its link. * * @param[in] delivery a delivery object * @return true if delivery is the current delivery for its link. */ PN_EXTERN bool pn_delivery_current(pn_delivery_t *delivery); /** * Abort a delivery being sent. * * Aborting means the sender cannot complete this message. It will not send any * more data, and data sent so far should be discarded by the receiver. The * link remains open for future messages. * * If some data has already been sent on the network, an AMQP "aborted" frame * will be sent to inform the peer. If no data has yet been sent, the delivery * will simply be forgotten. * * The delivery will be freed, and cannot be used after the call. * * @see pn_delivery_aborted() * * @param[in] delivery a delivery object */ PN_EXTERN void pn_delivery_abort(pn_delivery_t *delivery); /** * Settle a delivery. * * A settled delivery can never be used again. * * @note If pn_delivery_current(delivery) is true before the call then * pn_link_advance(pn_delivery_link(deliver)) is called automatically. * * @param[in] delivery a delivery object */ PN_EXTERN void pn_delivery_settle(pn_delivery_t *delivery); /** * Utility function for printing details of a delivery. * * @param[in] delivery a delivery object */ PN_EXTERN void pn_delivery_dump(pn_delivery_t *delivery); /** * Check if a delivery is buffered. * * A delivery that is buffered has not yet been written to the wire. * * Note that returning false does not imply that a delivery was * definitely written to the wire. If false is returned, it is not * known whether the delivery was actually written to the wire or not. * * @param[in] delivery a delivery object * @return true if the delivery is buffered */ PN_EXTERN bool pn_delivery_buffered(pn_delivery_t *delivery); /** * Extracts the first delivery on the connection that has pending * operations. * * Retrieves the first delivery on the Connection that has pending * operations. A readable delivery indicates message data is waiting * to be read. A writable delivery indicates that message data may be * sent. An updated delivery indicates that the delivery's disposition * has changed. A delivery will never be both readable and writable, * but it may be both readable and updated or both writable and * updated. * * @param[in] connection the connection * @return the first delivery object that needs to be serviced, else * NULL if none */ PN_DEPRECATED("Use the PN_DELIVERY event to track deliveries with pending operations") PN_EXTERN pn_delivery_t *pn_work_head(pn_connection_t *connection); /** * Get the next delivery on the connection that needs has pending * operations. * * @param[in] delivery the previous delivery retrieved from * either pn_work_head or pn_work_next * @return the next delivery that has pending operations, else * NULL if none */ PN_DEPRECATED("Use the PN_DELIVERY event to track deliveries with pending operations") PN_EXTERN pn_delivery_t *pn_work_next(pn_delivery_t *delivery); /** * @} */ #ifdef __cplusplus } #endif #endif /* delivery.h */