http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/ruby/spec/qpid/proton/messenger_spec.rb ---------------------------------------------------------------------- diff --git a/proton-c/bindings/ruby/spec/qpid/proton/messenger_spec.rb b/proton-c/bindings/ruby/spec/qpid/proton/messenger_spec.rb index 80716bb..86050ed 100644 --- a/proton-c/bindings/ruby/spec/qpid/proton/messenger_spec.rb +++ b/proton-c/bindings/ruby/spec/qpid/proton/messenger_spec.rb @@ -212,6 +212,16 @@ module Qpid @messenger.incoming_window.should eq(window) end + it "can be put into passive mode" do + @messenger.passive = true + @messenger.passive?.should be_true + end + + it "can be taken out of passive mode" do + @messenger.passive = false + @messenger.passive?.should_not be_true + end + describe "once started" do before (:each) do
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/codec.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/codec.h b/proton-c/include/proton/codec.h index b54f7a5..af268fa 100644 --- a/proton-c/include/proton/codec.h +++ b/proton-c/include/proton/codec.h @@ -26,12 +26,7 @@ #include <proton/object.h> #include <proton/types.h> #include <proton/error.h> -#ifndef __cplusplus -#include <stdbool.h> -#include <stdint.h> -#else #include <proton/type_compat.h> -#endif #include <stdarg.h> #ifdef __cplusplus http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/condition.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/condition.h b/proton-c/include/proton/condition.h index ab985f0..6fe0333 100644 --- a/proton-c/include/proton/condition.h +++ b/proton-c/include/proton/condition.h @@ -24,9 +24,7 @@ #include <proton/import_export.h> #include <proton/codec.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <stddef.h> #include <sys/types.h> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/connection.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/connection.h b/proton-c/include/proton/connection.h index 22c0652..104f78f 100644 --- a/proton-c/include/proton/connection.h +++ b/proton-c/include/proton/connection.h @@ -23,9 +23,7 @@ */ #include <proton/import_export.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <stddef.h> #include <sys/types.h> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/container.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/container.h b/proton-c/include/proton/container.h index b0d57e3..a1de525 100644 --- a/proton-c/include/proton/container.h +++ b/proton-c/include/proton/container.h @@ -23,9 +23,7 @@ */ #include <proton/import_export.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <stddef.h> #include <sys/types.h> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/delivery.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/delivery.h b/proton-c/include/proton/delivery.h index 016fc44..527eaed 100644 --- a/proton-c/include/proton/delivery.h +++ b/proton-c/include/proton/delivery.h @@ -24,9 +24,7 @@ #include <proton/import_export.h> #include <proton/disposition.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <stddef.h> #include <sys/types.h> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/disposition.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/disposition.h b/proton-c/include/proton/disposition.h index f4fcec1..2ee7068 100644 --- a/proton-c/include/proton/disposition.h +++ b/proton-c/include/proton/disposition.h @@ -23,9 +23,7 @@ */ #include <proton/import_export.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <stddef.h> #include <sys/types.h> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/event.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/event.h b/proton-c/include/proton/event.h index 9ddbc05..fdb2803 100644 --- a/proton-c/include/proton/event.h +++ b/proton-c/include/proton/event.h @@ -23,9 +23,7 @@ */ #include <proton/import_export.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <stddef.h> #include <sys/types.h> @@ -79,6 +77,15 @@ extern "C" { typedef struct pn_event_t pn_event_t; /** + * Related events are grouped into categories + */ +typedef enum { + PN_EVENT_CATEGORY_NONE = 0, + PN_EVENT_CATEGORY_PROTOCOL = 0x00010000, + PN_EVENT_CATEGORY_COUNT = 2 +} pn_event_category_t; + +/** * An event type. */ typedef enum { @@ -92,37 +99,40 @@ typedef enum { * this type point to the relevant connection as well as its * associated transport. */ - PN_CONNECTION_STATE = 1, + PN_CONNECTION_REMOTE_STATE = PN_EVENT_CATEGORY_PROTOCOL+1, + PN_CONNECTION_LOCAL_STATE = PN_EVENT_CATEGORY_PROTOCOL+2, /** * The endpoint state flags for a session have changed. Events of * this type point to the relevant session as well as its associated * connection and transport. */ - PN_SESSION_STATE = 2, + PN_SESSION_REMOTE_STATE = PN_EVENT_CATEGORY_PROTOCOL+3, + PN_SESSION_LOCAL_STATE = PN_EVENT_CATEGORY_PROTOCOL+4, /** * The endpoint state flags for a link have changed. Events of this * type point to the relevant link as well as its associated * session, connection, and transport. */ - PN_LINK_STATE = 4, + PN_LINK_REMOTE_STATE = PN_EVENT_CATEGORY_PROTOCOL+5, + PN_LINK_LOCAL_STATE = PN_EVENT_CATEGORY_PROTOCOL+6, /** * The flow control state for a link has changed. Events of this * type point to the relevant link along with its associated * session, connection, and transport. */ - PN_LINK_FLOW = 8, + PN_LINK_FLOW = PN_EVENT_CATEGORY_PROTOCOL+7, /** * A delivery has been created or updated. Events of this type point * to the relevant delivery as well as its associated link, session, * connection, and transport. */ - PN_DELIVERY = 16, + PN_DELIVERY = PN_EVENT_CATEGORY_PROTOCOL+8, /** * The transport has new data to read and/or write. Events of this * type point to the relevant transport as well as its associated * connection. */ - PN_TRANSPORT = 32 + PN_TRANSPORT = PN_EVENT_CATEGORY_PROTOCOL+9 } pn_event_type_t; /** @@ -180,6 +190,14 @@ PN_EXTERN bool pn_collector_pop(pn_collector_t *collector); PN_EXTERN pn_event_type_t pn_event_type(pn_event_t *event); /** + * Get the category an event belongs to. + * + * @param[in] event an event object + * @return the category the event belongs to + */ +PN_EXTERN pn_event_category_t pn_event_category(pn_event_t *event); + +/** * Get the connection associated with an event. * * @param[in] event an event object http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/framing.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/framing.h b/proton-c/include/proton/framing.h index 0e69995..9650979 100644 --- a/proton-c/include/proton/framing.h +++ b/proton-c/include/proton/framing.h @@ -23,11 +23,7 @@ */ #include <proton/import_export.h> -#ifndef __cplusplus -#include <stdint.h> -#else #include <proton/type_compat.h> -#endif #include <sys/types.h> #ifdef __cplusplus http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/io.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/io.h b/proton-c/include/proton/io.h index dc8ee77..fffc09a 100644 --- a/proton-c/include/proton/io.h +++ b/proton-c/include/proton/io.h @@ -26,9 +26,6 @@ #include <proton/error.h> #include <sys/types.h> #include <proton/type_compat.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif #ifdef __cplusplus extern "C" { http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/link.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/link.h b/proton-c/include/proton/link.h index 1fb73a9..8c5f82c 100644 --- a/proton-c/include/proton/link.h +++ b/proton-c/include/proton/link.h @@ -23,9 +23,7 @@ */ #include <proton/import_export.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <stddef.h> #include <sys/types.h> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/message.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/message.h b/proton-c/include/proton/message.h index c6bfd5d..2857731 100644 --- a/proton-c/include/proton/message.h +++ b/proton-c/include/proton/message.h @@ -27,9 +27,7 @@ #include <proton/codec.h> #include <proton/error.h> #include <sys/types.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #ifdef __cplusplus extern "C" { @@ -42,107 +40,777 @@ extern "C" { * @{ */ +/** + * An AMQP Message object. + * + * An AMQP Message object is a mutable holder of message content that + * may be used to generate and encode or decode and access AMQP + * formatted message data. + */ typedef struct pn_message_t pn_message_t; +/** + * Encoding format for message content. + */ typedef enum { - PN_DATA, - PN_TEXT, - PN_AMQP, - PN_JSON + PN_DATA, /**< Raw binary data. Not all messages can be encoded this way.*/ + PN_TEXT, /**< Raw text. Not all messages can be encoded this way.*/ + PN_AMQP, /**< AMQP formatted data. All messages can be encoded this way.*/ + PN_JSON /**< JSON formatted data. Not all messages can be encoded with full fidelity way.*/ } pn_format_t; +/** + * Default priority for messages. + */ #define PN_DEFAULT_PRIORITY (4) +/** + * Construct a new ::pn_message_t. + * + * Every message that is constructed must be freed using + * ::pn_message_free(). + * + * @return pointer to a new ::pn_message_t + */ PN_EXTERN pn_message_t * pn_message(void); + +/** + * Free a previously constructed ::pn_message_t. + * + * @param[in] msg pointer to a ::pn_message_t or NULL + */ PN_EXTERN void pn_message_free(pn_message_t *msg); +/** + * Clears the content of a ::pn_message_t. + * + * When pn_message_clear returns, the supplied ::pn_message_t will be + * emptied of all content and effectively returned to the same state + * as if it was just created. + * + * @param[in] msg pointer to the ::pn_message_t to be cleared + */ PN_EXTERN void pn_message_clear(pn_message_t *msg); + +/** + * Access the error code of a message. + * + * Every operation on a message that can result in an error will set + * the message's error code in case of error. The pn_message_errno() + * call will access the error code of the most recent failed + * operation. + * + * @param[in] msg a message + * @return the message's error code + */ PN_EXTERN int pn_message_errno(pn_message_t *msg); + +/** + * Access the error information for a message. + * + * Every operation on a message that can result in an error will + * update the error information held by its error descriptor should + * that operation fail. The pn_message_error() call will access the + * error information of the most recent failed operation. The pointer + * returned by this call is valid until the message is freed. + * + * @param[in] msg a message + * @return the message's error descriptor + */ PN_EXTERN pn_error_t *pn_message_error(pn_message_t *msg); +/** + * Get the inferred flag for a message. + * + * The inferred flag for a message indicates how the message content + * is encoded into AMQP sections. If inferred is true then binary and + * list values in the body of the message will be encoded as AMQP DATA + * and AMQP SEQUENCE sections, respectively. If inferred is false, + * then all values in the body of the message will be encoded as AMQP + * VALUE sections regardless of their type. Use + * ::pn_message_set_inferred to set the value. + * + * @param[in] msg a message object + * @return the value of the inferred flag for the message + */ PN_EXTERN bool pn_message_is_inferred(pn_message_t *msg); + +/** + * Set the inferred flag for a message. + * + * See ::pn_message_is_inferred() for a description of what the + * inferred flag is. + * + * @param[in] msg a message object + * @param[in] inferred the new value of the inferred flag + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_inferred(pn_message_t *msg, bool inferred); // standard message headers and properties + +/** + * Get the durable flag for a message. + * + * The durable flag indicates that any parties taking responsibility + * for the message must durably store the content. + * + * @param[in] msg a message object + * @return the value of the durable flag + */ PN_EXTERN bool pn_message_is_durable (pn_message_t *msg); + +/** + * Set the durable flag for a message. + * + * See ::pn_message_is_durable() for a description of the durable + * flag. + * + * @param[in] msg a message object + * @param[in] durable the new value of the durable flag + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_durable (pn_message_t *msg, bool durable); +/** + * Get the priority for a message. + * + * The priority of a message impacts ordering guarantees. Within a + * given ordered context, higher priority messages may jump ahead of + * lower priority messages. + * + * @param[in] msg a message object + * @return the message priority + */ PN_EXTERN uint8_t pn_message_get_priority (pn_message_t *msg); + +/** + * Set the priority for a message. + * + * See ::pn_message_get_priority() for details on message priority. + * + * @param[in] msg a message object + * @param[in] priority the new priority for the message + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_priority (pn_message_t *msg, uint8_t priority); +/** + * Get the ttl for a message. + * + * The ttl for a message determines how long a message is considered + * live. When a message is held for retransmit, the ttl is + * decremented. Once the ttl reaches zero, the message is considered + * dead. Once a message is considered dead it may be dropped. Use + * ::pn_message_set_ttl() to set the ttl for a message. + * + * @param[in] msg a message object + * @return the ttl in milliseconds + */ PN_EXTERN pn_millis_t pn_message_get_ttl (pn_message_t *msg); + +/** + * Set the ttl for a message. + * + * See ::pn_message_get_ttl() for a detailed description of message ttl. + * + * @param[in] msg a message object + * @param[in] ttl the new value for the message ttl + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_ttl (pn_message_t *msg, pn_millis_t ttl); +/** + * Get the first acquirer flag for a message. + * + * When set to true, the first acquirer flag for a message indicates + * that the recipient of the message is the first recipient to acquire + * the message, i.e. there have been no failed delivery attempts to + * other acquirers. Note that this does not mean the message has not + * been delivered to, but not acquired, by other recipients. + * + * @param[in] msg a message object + * @return the first acquirer flag for the message + */ PN_EXTERN bool pn_message_is_first_acquirer (pn_message_t *msg); + +/** + * Set the first acquirer flag for a message. + * + * See ::pn_message_is_first_acquirer() for details on the first + * acquirer flag. + * + * @param[in] msg a message object + * @param[in] first the new value for the first acquirer flag + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_first_acquirer (pn_message_t *msg, bool first); +/** + * Get the delivery count for a message. + * + * The delivery count field tracks how many attempts have been made to + * delivery a message. Use ::pn_message_set_delivery_count() to set + * the delivery count for a message. + * + * @param[in] msg a message object + * @return the delivery count for the message + */ PN_EXTERN uint32_t pn_message_get_delivery_count (pn_message_t *msg); + +/** + * Set the delivery count for a message. + * + * See ::pn_message_get_delivery_count() for details on what the + * delivery count means. + * + * @param[in] msg a message object + * @param[in] count the new delivery count + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_delivery_count (pn_message_t *msg, uint32_t count); +/** + * Get/set the id for a message. + * + * The message id provides a globally unique identifier for a message. + * A message id can be an a string, an unsigned long, a uuid or a + * binary value. This operation returns a pointer to a ::pn_data_t + * that can be used to access and/or modify the value of the message + * id. The pointer is valid until the message is freed. See + * ::pn_data_t for details on how to get/set the value. + * + * @param[in] msg a message object + * @return pointer to a ::pn_data_t holding the id + */ PN_EXTERN pn_data_t * pn_message_id (pn_message_t *msg); + +/** + * Get the id for a message. + * + * The message id provides a globally unique identifier for a message. + * A message id can be an a string, an unsigned long, a uuid or a + * binary value. This operation returns the value of the id using the + * ::pn_atom_t descriminated union. See ::pn_atom_t for details on how + * to access the value. + * + * @param[in] msg a message object + * @return the message id + */ PN_EXTERN pn_atom_t pn_message_get_id (pn_message_t *msg); + +/** + * Set the id for a message. + * + * See ::pn_message_get_id() for more details on the meaning of the + * message id. Note that only string, unsigned long, uuid, or binary + * values are permitted. + * + * @param[in] msg a message object + * @param[in] id the new value of the message id + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_id (pn_message_t *msg, pn_atom_t id); +/** + * Get the user id for a message. + * + * The pointer referenced by the ::pn_bytes_t struct will be valid + * until any one of the following operations occur: + * + * - ::pn_message_free() + * - ::pn_message_clear() + * - ::pn_message_set_user_id() + * + * @param[in] msg a message object + * @return a pn_bytes_t referencing the message's user_id + */ PN_EXTERN pn_bytes_t pn_message_get_user_id (pn_message_t *msg); + +/** + * Set the user id for a message. + * + * This operation copies the bytes referenced by the provided + * ::pn_bytes_t struct. + * + * @param[in] msg a message object + * @param[in] user_id the new user_id for the message + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_user_id (pn_message_t *msg, pn_bytes_t user_id); +/** + * Get the address for a message. + * + * This operation will return NULL if no address has been set or if + * the address has been set to NULL. The pointer returned by this + * operation is valid until any one of the following operations occur: + * + * - ::pn_message_free() + * - ::pn_message_clear() + * - ::pn_message_set_address() + * + * @param[in] msg a message object + * @return a pointer to the address of the message (or NULL) + */ PN_EXTERN const char * pn_message_get_address (pn_message_t *msg); + +/** + * Set the address for a message. + * + * The supplied address pointer must either be NULL or reference a NUL + * terminated string. When the pointer is NULL, the address of the + * message is set to NULL. When the pointer is non NULL, the contents + * are copied into the message. + * + * @param[in] msg a message object + * @param[in] address a pointer to the new address (or NULL) + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_address (pn_message_t *msg, const char *address); +/** + * Get the subject for a message. + * + * This operation will return NULL if no subject has been set or if + * the subject has been set to NULL. The pointer returned by this + * operation is valid until any one of the following operations occur: + * + * - ::pn_message_free() + * - ::pn_message_clear() + * - ::pn_message_set_subject() + * + * @param[in] msg a message object + * @return a pointer to the subject of the message (or NULL) + */ PN_EXTERN const char * pn_message_get_subject (pn_message_t *msg); + +/** + * Set the subject for a message. + * + * The supplied subject pointer must either be NULL or reference a NUL + * terminated string. When the pointer is NULL, the subject is set to + * NULL. When the pointer is non NULL, the contents are copied into + * the message. + * + * @param[in] msg a message object + * @param[in] subject a pointer to the new subject (or NULL) + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_subject (pn_message_t *msg, const char *subject); +/** + * Get the reply_to for a message. + * + * This operation will return NULL if no reply_to has been set or if + * the reply_to has been set to NULL. The pointer returned by this + * operation is valid until any one of the following operations occur: + * + * - ::pn_message_free() + * - ::pn_message_clear() + * - ::pn_message_set_reply_to() + * + * @param[in] msg a message object + * @return a pointer to the reply_to of the message (or NULL) + */ PN_EXTERN const char * pn_message_get_reply_to (pn_message_t *msg); + +/** + * Set the reply_to for a message. + * + * The supplied reply_to pointer must either be NULL or reference a NUL + * terminated string. When the pointer is NULL, the reply_to is set to + * NULL. When the pointer is non NULL, the contents are copied into + * the message. + * + * @param[in] msg a message object + * @param[in] reply_to a pointer to the new reply_to (or NULL) + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_reply_to (pn_message_t *msg, const char *reply_to); +/** + * Get/set the correlation id for a message. + * + * A correlation id can be an a string, an unsigned long, a uuid or a + * binary value. This operation returns a pointer to a ::pn_data_t + * that can be used to access and/or modify the value of the + * correlation id. The pointer is valid until the message is freed. + * See ::pn_data_t for details on how to get/set the value. + * + * @param[in] msg a message object + * @return pointer to a ::pn_data_t holding the correlation id + */ PN_EXTERN pn_data_t * pn_message_correlation_id (pn_message_t *msg); + +/** + * Get the correlation id for a message. + * + * A correlation id can be an a string, an unsigned long, a uuid or a + * binary value. This operation returns the value of the id using the + * ::pn_atom_t descriminated union. See ::pn_atom_t for details on how + * to access the value. + * + * @param[in] msg a message object + * @return the message id + */ PN_EXTERN pn_atom_t pn_message_get_correlation_id (pn_message_t *msg); -PN_EXTERN int pn_message_set_correlation_id (pn_message_t *msg, pn_atom_t atom); +/** + * Set the correlation id for a message. + * + * See ::pn_message_get_correlation_id() for more details on the + * meaning of the correlation id. Note that only string, unsigned + * long, uuid, or binary values are permitted. + * + * @param[in] msg a message object + * @param[in] id the new value of the message id + * @return zero on success or an error code on failure + */ +PN_EXTERN int pn_message_set_correlation_id (pn_message_t *msg, pn_atom_t id); + +/** + * Get the content_type for a message. + * + * This operation will return NULL if no content_type has been set or if + * the content_type has been set to NULL. The pointer returned by this + * operation is valid until any one of the following operations occur: + * + * - ::pn_message_free() + * - ::pn_message_clear() + * - ::pn_message_set_content_type() + * + * @param[in] msg a message object + * @return a pointer to the content_type of the message (or NULL) + */ PN_EXTERN const char * pn_message_get_content_type (pn_message_t *msg); + +/** + * Set the content_type for a message. + * + * The supplied content_type pointer must either be NULL or reference a NUL + * terminated string. When the pointer is NULL, the content_type is set to + * NULL. When the pointer is non NULL, the contents are copied into + * the message. + * + * @param[in] msg a message object + * @param[in] type a pointer to the new content_type (or NULL) + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_content_type (pn_message_t *msg, const char *type); +/** + * Get the content_encoding for a message. + * + * This operation will return NULL if no content_encoding has been set or if + * the content_encoding has been set to NULL. The pointer returned by this + * operation is valid until any one of the following operations occur: + * + * - ::pn_message_free() + * - ::pn_message_clear() + * - ::pn_message_set_content_encoding() + * + * @param[in] msg a message object + * @return a pointer to the content_encoding of the message (or NULL) + */ PN_EXTERN const char * pn_message_get_content_encoding (pn_message_t *msg); + +/** + * Set the content_encoding for a message. + * + * The supplied content_encoding pointer must either be NULL or reference a NUL + * terminated string. When the pointer is NULL, the content_encoding is set to + * NULL. When the pointer is non NULL, the contents are copied into + * the message. + * + * @param[in] msg a message object + * @param[in] encoding a pointer to the new content_encoding (or NULL) + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_content_encoding (pn_message_t *msg, const char *encoding); +/** + * Get the expiry time for a message. + * + * A zero value for the expiry time indicates that the message will + * never expire. This is the default value. + * + * @param[in] msg a message object + * @return the expiry time for the message + */ PN_EXTERN pn_timestamp_t pn_message_get_expiry_time (pn_message_t *msg); + +/** + * Set the expiry time for a message. + * + * See ::pn_message_get_expiry_time() for more details. + * + * @param[in] msg a message object + * @param[in] time the new expiry time for the message + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_expiry_time (pn_message_t *msg, pn_timestamp_t time); +/** + * Get the creation time for a message. + * + * A zero value for the creation time indicates that the creation time + * has not been set. This is the default value. + * + * @param[in] msg a message object + * @return the creation time for the message + */ PN_EXTERN pn_timestamp_t pn_message_get_creation_time (pn_message_t *msg); + +/** + * Set the creation time for a message. + * + * See ::pn_message_get_creation_time() for more details. + * + * @param[in] msg a message object + * @param[in] time the new creation time for the message + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_creation_time (pn_message_t *msg, pn_timestamp_t time); +/** + * Get the group_id for a message. + * + * This operation will return NULL if no group_id has been set or if + * the group_id has been set to NULL. The pointer returned by this + * operation is valid until any one of the following operations occur: + * + * - ::pn_message_free() + * - ::pn_message_clear() + * - ::pn_message_set_group_id() + * + * @param[in] msg a message object + * @return a pointer to the group_id of the message (or NULL) + */ PN_EXTERN const char * pn_message_get_group_id (pn_message_t *msg); + +/** + * Set the group_id for a message. + * + * The supplied group_id pointer must either be NULL or reference a NUL + * terminated string. When the pointer is NULL, the group_id is set to + * NULL. When the pointer is non NULL, the contents are copied into + * the message. + * + * @param[in] msg a message object + * @param[in] group_id a pointer to the new group_id (or NULL) + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_group_id (pn_message_t *msg, const char *group_id); +/** + * Get the group sequence for a message. + * + * The group sequence of a message identifies the relative ordering of + * messages within a group. The default value for the group sequence + * of a message is zero. + * + * @param[in] msg a message object + * @return the group sequence for the message + */ PN_EXTERN pn_sequence_t pn_message_get_group_sequence (pn_message_t *msg); + +/** + * Set the group sequence for a message. + * + * See ::pn_message_get_group_sequence() for details on what the group + * sequence means. + * + * @param[in] msg a message object + * @param[in] n the new group sequence for the message + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_group_sequence (pn_message_t *msg, pn_sequence_t n); +/** + * Get the reply_to_group_id for a message. + * + * This operation will return NULL if no reply_to_group_id has been set or if + * the reply_to_group_id has been set to NULL. The pointer returned by this + * operation is valid until any one of the following operations occur: + * + * - ::pn_message_free() + * - ::pn_message_clear() + * - ::pn_message_set_reply_to_group_id() + * + * @param[in] msg a message object + * @return a pointer to the reply_to_group_id of the message (or NULL) + */ PN_EXTERN const char * pn_message_get_reply_to_group_id (pn_message_t *msg); + +/** + * Set the reply_to_group_id for a message. + * + * The supplied reply_to_group_id pointer must either be NULL or reference a NUL + * terminated string. When the pointer is NULL, the reply_to_group_id is set to + * NULL. When the pointer is non NULL, the contents are copied into + * the message. + * + * @param[in] msg a message object + * @param[in] reply_to_group_id a pointer to the new reply_to_group_id (or NULL) + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_set_reply_to_group_id (pn_message_t *msg, const char *reply_to_group_id); +/** + * @deprecated + */ PN_EXTERN pn_format_t pn_message_get_format(pn_message_t *message); + +/** + * @deprecated + */ PN_EXTERN int pn_message_set_format(pn_message_t *message, pn_format_t format); +/** + * @deprecated Use ::pn_message_body() instead. + */ PN_EXTERN int pn_message_load(pn_message_t *message, const char *data, size_t size); + +/** + * @deprecated Use ::pn_message_body() instead. + */ PN_EXTERN int pn_message_load_data(pn_message_t *message, const char *data, size_t size); + +/** + * @deprecated Use ::pn_message_body() instead. + */ PN_EXTERN int pn_message_load_text(pn_message_t *message, const char *data, size_t size); + +/** + * @deprecated Use ::pn_message_body() instead. + */ PN_EXTERN int pn_message_load_amqp(pn_message_t *message, const char *data, size_t size); + +/** + * @deprecated Use ::pn_message_body() instead. + */ PN_EXTERN int pn_message_load_json(pn_message_t *message, const char *data, size_t size); +/** + * @deprecated Use ::pn_message_body() instead. + */ PN_EXTERN int pn_message_save(pn_message_t *message, char *data, size_t *size); + +/** + * @deprecated Use ::pn_message_body() instead. + */ PN_EXTERN int pn_message_save_data(pn_message_t *message, char *data, size_t *size); + +/** + * @deprecated Use ::pn_message_body() instead. + */ PN_EXTERN int pn_message_save_text(pn_message_t *message, char *data, size_t *size); + +/** + * @deprecated Use ::pn_message_body() instead. + */ PN_EXTERN int pn_message_save_amqp(pn_message_t *message, char *data, size_t *size); + +/** + * @deprecated Use ::pn_message_body() instead. + */ PN_EXTERN int pn_message_save_json(pn_message_t *message, char *data, size_t *size); +/** + * Get/set the delivery instructions for a message. + * + * This operation returns a pointer to a ::pn_data_t representing the + * content of the delivery instructions section of a message. The + * pointer is valid until the message is freed and may be used to both + * access and modify the content of the delivery instructions section + * of a message. + * + * The ::pn_data_t must either be empty or consist of a symbol keyed + * map in order to be considered valid delivery instructions. + * + * @param[in] msg a message object + * @return a pointer to the delivery instructions + */ PN_EXTERN pn_data_t *pn_message_instructions(pn_message_t *msg); + +/** + * Get/set the annotations for a message. + * + * This operation returns a pointer to a ::pn_data_t representing the + * content of the annotations section of a message. The pointer is + * valid until the message is freed and may be used to both access and + * modify the content of the annotations section of a message. + * + * The ::pn_data_t must either be empty or consist of a symbol keyed + * map in order to be considered valid message annotations. + * + * @param[in] msg a message object + * @return a pointer to the message annotations + */ PN_EXTERN pn_data_t *pn_message_annotations(pn_message_t *msg); + +/** + * Get/set the properties for a message. + * + * This operation returns a pointer to a ::pn_data_t representing the + * content of the properties section of a message. The pointer is + * valid until the message is freed and may be used to both access and + * modify the content of the properties section of a message. + * + * The ::pn_data_t must either be empty or consist of a string keyed + * map in order to be considered valid message properties. + * + * @param[in] msg a message object + * @return a pointer to the message properties + */ PN_EXTERN pn_data_t *pn_message_properties(pn_message_t *msg); + +/** + * Get/set the body of a message. + * + * This operation returns a pointer to a ::pn_data_t representing the + * body of a message. The pointer is valid until the message is freed + * and may be used to both access and modify the content of the + * message body. + * + * @param[in] msg a message object + * @return a pointer to the message body + */ PN_EXTERN pn_data_t *pn_message_body(pn_message_t *msg); +/** + * Decode/load message content from AMQP formatted binary data. + * + * Upon invoking this operation, any existing message content will be + * cleared and replaced with the content from the provided binary + * data. + * + * @param[in] msg a message object + * @param[in] bytes the start of the encoded AMQP data + * @param[in] size the size of the encoded AMQP data + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_decode(pn_message_t *msg, const char *bytes, size_t size); + +/** + * Encode/save message content as AMQP formatted binary data. + * + * If the buffer space provided is insufficient to store the content + * held in the message, the operation will fail and return a + * ::PN_OVERFLOW error code. + * + * @param[in] msg a message object + * @param[in] bytes the start of empty buffer space + * @param[in] size the amount of empty buffer space + * @param[out] size the amount of data written + * @return zero on success or an error code on failure + */ PN_EXTERN int pn_message_encode(pn_message_t *msg, char *bytes, size_t *size); +/** + * @deprecated + */ PN_EXTERN ssize_t pn_message_data(char *dst, size_t available, const char *src, size_t size); /** @} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/object.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/object.h b/proton-c/include/proton/object.h index 94d82d0..dc4983a 100644 --- a/proton-c/include/proton/object.h +++ b/proton-c/include/proton/object.h @@ -24,12 +24,7 @@ #include <proton/types.h> #include <stdarg.h> -#ifndef __cplusplus -#include <stdbool.h> -#include <stdint.h> -#else #include <proton/type_compat.h> -#endif #include <stddef.h> #include <proton/import_export.h> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/sasl.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/sasl.h b/proton-c/include/proton/sasl.h index 7a4cc2d..0cd9141 100644 --- a/proton-c/include/proton/sasl.h +++ b/proton-c/include/proton/sasl.h @@ -24,9 +24,7 @@ #include <proton/import_export.h> #include <sys/types.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <proton/engine.h> #ifdef __cplusplus http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/selectable.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/selectable.h b/proton-c/include/proton/selectable.h index 078999f..7d048c4 100644 --- a/proton-c/include/proton/selectable.h +++ b/proton-c/include/proton/selectable.h @@ -25,9 +25,7 @@ #include <proton/import_export.h> #include <proton/object.h> #include <proton/io.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #ifdef __cplusplus extern "C" { http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/selector.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/selector.h b/proton-c/include/proton/selector.h index 541caf0..37370d4 100644 --- a/proton-c/include/proton/selector.h +++ b/proton-c/include/proton/selector.h @@ -24,9 +24,7 @@ #include <proton/import_export.h> #include <proton/selectable.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #ifdef __cplusplus extern "C" { http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/session.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/session.h b/proton-c/include/proton/session.h index 711e14e..678b141 100644 --- a/proton-c/include/proton/session.h +++ b/proton-c/include/proton/session.h @@ -23,9 +23,7 @@ */ #include <proton/import_export.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <stddef.h> #include <sys/types.h> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/ssl.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/ssl.h b/proton-c/include/proton/ssl.h index 40fec95..cf5061d 100644 --- a/proton-c/include/proton/ssl.h +++ b/proton-c/include/proton/ssl.h @@ -24,9 +24,7 @@ #include <proton/import_export.h> #include <sys/types.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <proton/engine.h> #ifdef __cplusplus http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/terminus.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/terminus.h b/proton-c/include/proton/terminus.h index af7af8f..9c9096b 100644 --- a/proton-c/include/proton/terminus.h +++ b/proton-c/include/proton/terminus.h @@ -23,9 +23,7 @@ */ #include <proton/import_export.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <stddef.h> #include <sys/types.h> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/transport.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/transport.h b/proton-c/include/proton/transport.h index ab81e09..1fa24c8 100644 --- a/proton-c/include/proton/transport.h +++ b/proton-c/include/proton/transport.h @@ -23,9 +23,7 @@ */ #include <proton/import_export.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif +#include <proton/type_compat.h> #include <stddef.h> #include <sys/types.h> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/type_compat.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/type_compat.h b/proton-c/include/proton/type_compat.h index 6b5b958..9501d9a 100644 --- a/proton-c/include/proton/type_compat.h +++ b/proton-c/include/proton/type_compat.h @@ -22,6 +22,22 @@ * */ +// Get Boolean +#if !defined(__cplusplus) && !defined(__bool_true_false_are_defined) +# if __STDC_VERSION__ >= 199901L || __GNUC__ >= 3 || _MSC_VER >=1800 +# include <stdbool.h> +# else +// Need to get bool/true/false manually +# if _MSC_VER +# define bool char +# define false 0 +# define true 1 +# define __bool_true_false_are_defined +# else +# error "No definitions for bool/true/false" +# endif +# endif +#endif /* * Handle special cases for stdint.h and the definition for ssize_t. * Third party libraries (e.g. Boost) may provide competing solutions. @@ -34,70 +50,70 @@ // Honor positive overrides #if defined(PN_DEFINE_STDINT) -#define PNI_DEFINE_STDINT +# define PNI_DEFINE_STDINT #endif #if defined(PN_INCLUDE_STDINT) -#define PNI_INCLUDE_STDINT) +# define PNI_INCLUDE_STDINT) #endif #if defined(PN_DEFINE_SSIZE_T) -#define PNI_DEFINE_SSIZE_T +# define PNI_DEFINE_SSIZE_T #endif // Determinine default action #ifndef _MSC_VER // Not Windows and not using Visual Studio -#ifndef PNI_INCLUDE_STDINT -#define PNI_INCLUDE_STDINT -#endif +# ifndef PNI_INCLUDE_STDINT +# define PNI_INCLUDE_STDINT +# endif #else // all versions of Visual Studio -#ifndef PNI_DEFINE_SSIZE_T -// ssie_t def is needed, unless third party definition interferes, e.g. python/swig -#ifndef Py_CONFIG_H -#define PNI_DEFINE_SSIZE_T -#endif -#endif +# ifndef PNI_DEFINE_SSIZE_T +// ssize_t def is needed, unless third party definition interferes, e.g. python/swig +# ifndef Py_CONFIG_H +# define PNI_DEFINE_SSIZE_T +# endif +# endif -#if (_MSC_VER < 1600) +# if (_MSC_VER < 1600) // VS 2008 and earlier -#ifndef PNI_DEFINE_STDINT -#define PNI_DEFINE_STDINT -#endif -#else +# ifndef PNI_DEFINE_STDINT +# define PNI_DEFINE_STDINT +# endif +# else // VS 2010 and newer -#ifndef PNI_INCLUDE_STDINT -#define PNI_INCLUDE_STDINT -#endif +# ifndef PNI_INCLUDE_STDINT +# define PNI_INCLUDE_STDINT +# endif -#endif // (_MSC_VER < 1600) +# endif // (_MSC_VER < 1600) #endif //_MSC_VER // Honor negative overrides #ifdef PN_NODEFINE_SSIZE_T -#undef PNI_DEFINE_SSIZE_T +# undef PNI_DEFINE_SSIZE_T #endif #ifdef PN_NODEFINE_STDINT -#undef PNI_DEFINE_STDINT +# undef PNI_DEFINE_STDINT #endif #ifdef PN_NOINCLUDE_STDINT -#undef PNI_INCLUDE_STDINT +# undef PNI_INCLUDE_STDINT #endif #ifdef PNI_INCLUDE_STDINT -#include <stdint.h> +# include <stdint.h> #endif #ifdef PNI_DEFINE_SSIZE_T -#ifdef _MSC_VER -#include <BaseTsd.h> +# ifdef _MSC_VER +# include <BaseTsd.h> typedef SSIZE_T ssize_t; -#else -#error ssize_t definition not kown -#endif +# else +# error ssize_t definition not kown +# endif #endif // PNI_DEFINE_SSIZE_T #ifdef PNI_DEFINE_STDINT -#ifdef _MSC_VER +# ifdef _MSC_VER typedef signed __int8 int8_t; typedef signed __int16 int16_t; @@ -109,9 +125,9 @@ typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; -#else // _MSC_VER -#error stdint.h definitions not kown -#endif +# else // _MSC_VER +# error stdint.h definitions not kown +# endif #endif // PNI_DEFINE_SSIZE_T #endif /* type_compat.h */ http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/include/proton/types.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/types.h b/proton-c/include/proton/types.h index f06bc2a..4182f25 100644 --- a/proton-c/include/proton/types.h +++ b/proton-c/include/proton/types.h @@ -24,11 +24,7 @@ #include <proton/import_export.h> #include <sys/types.h> -#ifndef __cplusplus -#include <stdint.h> -#else #include <proton/type_compat.h> -#endif /** * @file @@ -152,6 +148,85 @@ typedef struct pn_link_t pn_link_t; * associated with an AMQP Delivery. Every delivery exists within the * context of a ::pn_link_t object. * + * The AMQP model for settlement is based on the lifecycle of a + * delivery at an endpoint. At each end of a link, a delivery is + * created, it exists for some period of time, and finally it is + * forgotten, aka settled. Note that because this lifecycle happens + * independently at both the sender and the receiver, there are + * actually four events of interest in the combined lifecycle of a + * given delivery: + * + * - created at sender + * - created at receiver + * - settled at sender + * - settled at receiver + * + * Because the sender and receiver are operating concurrently, these + * events can occur in a variety of different orders, and the order of + * these events impacts the types of failures that may occur when + * transferring a delivery. Eliminating scenarios where the receiver + * creates the delivery first, we have the following possible + * sequences of interest: + * + * Sender presettles (aka at-most-once): + * ------------------------------------- + * + * 1. created at sender + * 2. settled at sender + * 3. created at receiver + * 4. settled at receiver + * + * In this configuration the sender settles (i.e. forgets about) the + * delivery before it even reaches the receiver, and if anything + * should happen to the delivery in-flight, there is no way to + * recover, hence the "at most once" semantics. + * + * Receiver settles first (aka at-least-once): + * ------------------------------------------- + * + * 1. created at sender + * 2. created at receiver + * 3. settled at receiver + * 4. settled at sender + * + * In this configuration the receiver settles the delivery first, and + * the sender settles once it sees the receiver has settled. Should + * anything happen to the delivery in-flight, the sender can resend, + * however the receiver may have already forgotten the delivery and so + * it could interpret the resend as a new delivery, hence the "at + * least once" semantics. + * + * Receiver settles second (aka exactly-once): + * ------------------------------------------- + * + * 1. created at sender + * 2. created at receiver + * 3. settled at sender + * 4. settled at receiver + * + * In this configuration the receiver settles only once it has seen + * that the sender has settled. This provides the sender the option to + * retransmit, and the receiver has the option to recognize (and + * discard) duplicates, allowing for exactly once semantics. + * + * Note that in the last scenario the sender needs some way to know + * when it is safe to settle. This is where delivery state comes in. + * In addition to these lifecycle related events surrounding + * deliveries there is also the notion of a delivery state that can + * change over the lifetime of a delivery, e.g. it might start out as + * nothing, transition to ::PN_RECEIVED and then transition to + * ::PN_ACCEPTED. In the first two scenarios the delivery state isn't + * required, however in final scenario the sender would typically + * trigger settlement based on seeing the delivery state transition to + * a terminal state like ::PN_ACCEPTED or ::PN_REJECTED. + * + * In practice settlement is controlled by application policy, so + * there may well be more options here, e.g. a sender might not settle + * strictly based on what has happened at the receiver, it might also + * choose to impose some time limit and settle after that period has + * expired, or it could simply have a sliding window of the last N + * deliveries and settle the oldest whenever a new one comes along. + * * @ingroup delivery */ typedef struct pn_delivery_t pn_delivery_t; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/ProtonConfig.cmake.in ---------------------------------------------------------------------- diff --git a/proton-c/src/ProtonConfig.cmake.in b/proton-c/src/ProtonConfig.cmake.in new file mode 100644 index 0000000..fce1a3a --- /dev/null +++ b/proton-c/src/ProtonConfig.cmake.in @@ -0,0 +1,30 @@ +# +# 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. +# + +# Name: Proton +# Description: Qpid Proton C library +# Version: @PN_VERSION@ +# URL: http://qpid.apache.org/proton/ + +set (Proton_VERSION @PN_VERSION@) + +set (Proton_INCLUDE_DIRS @INCLUDEDIR@) +set (Proton_LIBRARIES optimized @LIBDIR@/@PROTONLIB@ debug @LIBDIR@/@PROTONLIBDEBUG@) + +set (Proton_FOUND True) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/ProtonConfigVersion.cmake.in ---------------------------------------------------------------------- diff --git a/proton-c/src/ProtonConfigVersion.cmake.in b/proton-c/src/ProtonConfigVersion.cmake.in new file mode 100644 index 0000000..d40f5c3 --- /dev/null +++ b/proton-c/src/ProtonConfigVersion.cmake.in @@ -0,0 +1,30 @@ +# This is a basic version file for the Config-mode of find_package(). +# It is used by write_basic_package_version_file() as input file for configure_file() +# to create a version-file which can be installed along a config.cmake file. +# +# The created file sets PACKAGE_VERSION_EXACT if the current version string and +# the requested version string are exactly the same and it sets +# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version. + +set(PACKAGE_VERSION "@PN_VERSION@") + +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" ) + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() + +# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: +if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "") + return() +endif() + +# check that the installed version has the same 32/64bit-ness as the one which is currently searching: +if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@") + math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8") + set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") + set(PACKAGE_VERSION_UNSUITABLE TRUE) +endif() http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/engine/engine.c ---------------------------------------------------------------------- diff --git a/proton-c/src/engine/engine.c b/proton-c/src/engine/engine.c index fda523f..718974a 100644 --- a/proton-c/src/engine/engine.c +++ b/proton-c/src/engine/engine.c @@ -33,6 +33,7 @@ #include "../platform.h" #include "../platform_fmt.h" #include "../transport/transport.h" +#include "../engine/event.h" // endpoints @@ -51,18 +52,61 @@ pn_connection_t *pn_ep_get_connection(pn_endpoint_t *endpoint) return NULL; } +/* map the endpoint type to its local event type */ +static const pn_event_type_t endpoint_event_map[] = { + PN_CONNECTION_LOCAL_STATE, /* CONNECTION */ + PN_SESSION_LOCAL_STATE, /* SESSION */ + PN_LINK_LOCAL_STATE, /* SENDER */ + PN_LINK_LOCAL_STATE}; /* RECEIVER */ + +/* setup the event given the endpoint that generated the event */ +static void endpoint_init_event(pn_event_t *event, + pn_endpoint_t *endpoint) +{ + switch (endpoint->type) { + case CONNECTION: { + pn_connection_t *conn = (pn_connection_t *) endpoint; + pn_event_init_connection(event, conn); + } + break; + case SESSION: { + pn_session_t *ssn = (pn_session_t *) endpoint; + pn_event_init_session(event, ssn); + } + break; + case SENDER: + case RECEIVER: { + pn_link_t *link = (pn_link_t*) endpoint; + pn_event_init_link(event, link); + } + break; + } +} + static void pn_endpoint_open(pn_endpoint_t *endpoint) { // TODO: do we care about the current state? PN_SET_LOCAL(endpoint->state, PN_LOCAL_ACTIVE); - pn_modified(pn_ep_get_connection(endpoint), endpoint, true); + pn_connection_t *conn = pn_ep_get_connection(endpoint); + pn_event_t *event = pn_collector_put(conn->collector, + endpoint_event_map[endpoint->type]); + if (event) { + endpoint_init_event(event, endpoint); + } + pn_modified(conn, endpoint, true); } -void pn_endpoint_close(pn_endpoint_t *endpoint) +static void pn_endpoint_close(pn_endpoint_t *endpoint) { // TODO: do we care about the current state? PN_SET_LOCAL(endpoint->state, PN_LOCAL_CLOSED); - pn_modified(pn_ep_get_connection(endpoint), endpoint, true); + pn_connection_t *conn = pn_ep_get_connection(endpoint); + pn_event_t *event = pn_collector_put(conn->collector, + endpoint_event_map[endpoint->type]); + if (event) { + endpoint_init_event(event, endpoint); + } + pn_modified(conn, endpoint, true); } void pn_connection_reset(pn_connection_t *connection) @@ -74,12 +118,14 @@ void pn_connection_reset(pn_connection_t *connection) void pn_connection_open(pn_connection_t *connection) { - if (connection) pn_endpoint_open((pn_endpoint_t *) connection); + assert(connection); + pn_endpoint_open(&connection->endpoint); } void pn_connection_close(pn_connection_t *connection) { - if (connection) pn_endpoint_close((pn_endpoint_t *) connection); + assert(connection); + pn_endpoint_close(&connection->endpoint); } void pn_endpoint_tini(pn_endpoint_t *endpoint); @@ -185,12 +231,14 @@ pn_connection_t *pn_session_connection(pn_session_t *session) void pn_session_open(pn_session_t *session) { - if (session) pn_endpoint_open((pn_endpoint_t *) session); + assert(session); + pn_endpoint_open(&session->endpoint); } void pn_session_close(pn_session_t *session) { - if (session) pn_endpoint_close((pn_endpoint_t *) session); + assert(session); + pn_endpoint_close(&session->endpoint); } void pn_session_free(pn_session_t *session) @@ -234,12 +282,14 @@ void pn_remove_link(pn_session_t *ssn, pn_link_t *link) void pn_link_open(pn_link_t *link) { - if (link) pn_endpoint_open((pn_endpoint_t *) link); + assert(link); + pn_endpoint_open(&link->endpoint); } void pn_link_close(pn_link_t *link) { - if (link) pn_endpoint_close((pn_endpoint_t *) link); + assert(link); + pn_endpoint_close(&link->endpoint); } void pn_terminus_free(pn_terminus_t *terminus) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/engine/event.c ---------------------------------------------------------------------- diff --git a/proton-c/src/engine/event.c b/proton-c/src/engine/event.c index 5ea612d..9a3f220 100644 --- a/proton-c/src/engine/event.c +++ b/proton-c/src/engine/event.c @@ -242,6 +242,11 @@ pn_event_type_t pn_event_type(pn_event_t *event) return event->type; } +pn_event_category_t pn_event_category(pn_event_t *event) +{ + return (pn_event_category_t)(event->type & 0xFFFF0000); +} + pn_connection_t *pn_event_connection(pn_event_t *event) { return event->connection; @@ -272,12 +277,18 @@ const char *pn_event_type_name(pn_event_type_t type) switch (type) { case PN_EVENT_NONE: return "PN_EVENT_NONE"; - case PN_CONNECTION_STATE: - return "PN_CONNECTION_STATE"; - case PN_SESSION_STATE: - return "PN_SESSION_STATE"; - case PN_LINK_STATE: - return "PN_LINK_STATE"; + case PN_CONNECTION_REMOTE_STATE: + return "PN_CONNECTION_REMOTE_STATE"; + case PN_CONNECTION_LOCAL_STATE: + return "PN_CONNECTION_LOCAL_STATE"; + case PN_SESSION_REMOTE_STATE: + return "PN_SESSION_REMOTE_STATE"; + case PN_SESSION_LOCAL_STATE: + return "PN_SESSION_LOCAL_STATE"; + case PN_LINK_REMOTE_STATE: + return "PN_LINK_REMOTE_STATE"; + case PN_LINK_LOCAL_STATE: + return "PN_LINK_LOCAL_STATE"; case PN_LINK_FLOW: return "PN_LINK_FLOW"; case PN_DELIVERY: http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/libqpid-proton.cmake.in ---------------------------------------------------------------------- diff --git a/proton-c/src/libqpid-proton.cmake.in b/proton-c/src/libqpid-proton.cmake.in deleted file mode 100644 index b99646a..0000000 --- a/proton-c/src/libqpid-proton.cmake.in +++ /dev/null @@ -1,29 +0,0 @@ -# -# 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. -# - -# Name: Proton -# Description: Qpid Proton C library -# Version: @PN_VERSION@ -# URL: http://qpid.apache.org/proton/ - -set (PROTON_FOUND "True") -set (PROTON_VERSION @PN_VERSION@) -set (PROTON_INCLUDE_DIRS "@INCLUDEDIR@") -set (PROTON_LIBRARY_DIRS "@PREFIX@/bin") -set (PROTON_LIBRARIES "qpid-proton") http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/messenger/messenger.c ---------------------------------------------------------------------- diff --git a/proton-c/src/messenger/messenger.c b/proton-c/src/messenger/messenger.c index 81853d7..d2cd10c 100644 --- a/proton-c/src/messenger/messenger.c +++ b/proton-c/src/messenger/messenger.c @@ -373,7 +373,7 @@ static pn_listener_ctx_t *pn_listener_ctx(pn_messenger_t *messenger, return NULL; } - pn_listener_ctx_t *ctx = (pn_listener_ctx_t *) malloc(sizeof(pn_listener_ctx_t)); + pn_listener_ctx_t *ctx = (pn_listener_ctx_t *) pn_new(sizeof(pn_listener_ctx_t), NULL); ctx->messenger = messenger; ctx->domain = pn_ssl_domain(PN_SSL_MODE_SERVER); if (messenger->certificate) { @@ -384,7 +384,7 @@ static pn_listener_ctx_t *pn_listener_ctx(pn_messenger_t *messenger, if (err) { pn_error_format(messenger->error, PN_ERR, "invalid credentials"); pn_ssl_domain_free(ctx->domain); - free(ctx); + pn_free(ctx); pn_close(messenger->io, socket); return NULL; } @@ -423,7 +423,7 @@ static void pn_listener_ctx_free(pn_messenger_t *messenger, pn_listener_ctx_t *c free(ctx->host); free(ctx->port); pn_ssl_domain_free(ctx->domain); - free(ctx); + pn_free(ctx); } static pn_connection_ctx_t *pn_connection_ctx(pn_messenger_t *messenger, @@ -1217,13 +1217,16 @@ int pn_messenger_process_events(pn_messenger_t *messenger) while ((event = pn_collector_peek(messenger->collector))) { processed++; switch (pn_event_type(event)) { - case PN_CONNECTION_STATE: + case PN_CONNECTION_REMOTE_STATE: + case PN_CONNECTION_LOCAL_STATE: pn_messenger_process_connection(messenger, event); break; - case PN_SESSION_STATE: + case PN_SESSION_REMOTE_STATE: + case PN_SESSION_LOCAL_STATE: pn_messenger_process_session(messenger, event); break; - case PN_LINK_STATE: + case PN_LINK_REMOTE_STATE: + case PN_LINK_LOCAL_STATE: pn_messenger_process_link(messenger, event); break; case PN_LINK_FLOW: http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/object/object.c ---------------------------------------------------------------------- diff --git a/proton-c/src/object/object.c b/proton-c/src/object/object.c index 4c2f7d6..dd5fd17 100644 --- a/proton-c/src/object/object.c +++ b/proton-c/src/object/object.c @@ -484,17 +484,21 @@ size_t pn_map_size(pn_map_t *map) return map->size; } +static float pni_map_load(pn_map_t *map) +{ + return ((float) map->size) / ((float) map->addressable); +} + static bool pni_map_ensure(pn_map_t *map, size_t capacity) { - float load = map->size / map->addressable; + float load = pni_map_load(map); if (capacity <= map->capacity && load < map->load_factor) { return false; } size_t oldcap = map->capacity; - while (map->capacity < capacity || - (map->size / map->addressable) > map->load_factor) { + while (map->capacity < capacity || pni_map_load(map) > map->load_factor) { map->capacity *= 2; map->addressable = (size_t) (0.86 * map->capacity); } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/platform.h ---------------------------------------------------------------------- diff --git a/proton-c/src/platform.h b/proton-c/src/platform.h index a9ae580..6b63e2e 100644 --- a/proton-c/src/platform.h +++ b/proton-c/src/platform.h @@ -82,16 +82,12 @@ int64_t pn_i_atoll(const char* num); #define vsnprintf pn_i_vsnprintf int pn_i_snprintf(char *buf, size_t count, const char *fmt, ...); int pn_i_vsnprintf(char *buf, size_t count, const char *fmt, va_list ap); +#endif -/** Windows va_copy - * - * Provide function/macro definition - */ +#if defined _MSC_VER || defined _OPENVMS #define va_copy(d,s) ((d) = (s)) #endif - - #ifdef __cplusplus } #endif http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/platform_fmt.h ---------------------------------------------------------------------- diff --git a/proton-c/src/platform_fmt.h b/proton-c/src/platform_fmt.h index 8e62b56..17f95f3 100644 --- a/proton-c/src/platform_fmt.h +++ b/proton-c/src/platform_fmt.h @@ -37,6 +37,25 @@ #define PN_ZI "zi" #define PN_ZU "zu" +#ifdef _OPENVMS + +#undef PN_ZI +#undef PN_ZU +#define PN_ZI "i" +#define PN_ZU "u" +#define PRIu64 "llu" +#define PRIu8 "u" +#define PRIu16 "u" +#define PRIu32 "u" +#define PRIu64 "llu" + +#define PRIi8 "i" +#define PRIi16 "i" +#define PRIi32 "i" +#define PRIi64 "lli" + +#endif /* _OPENVMS */ + #else #ifdef _MSC_VER http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/posix/io.c ---------------------------------------------------------------------- diff --git a/proton-c/src/posix/io.c b/proton-c/src/posix/io.c index cac7baf..11379ff 100644 --- a/proton-c/src/posix/io.c +++ b/proton-c/src/posix/io.c @@ -119,7 +119,7 @@ static void pn_configure_sock(pn_io_t *io, pn_socket_t sock) { } } -static inline int pn_create_socket(void); +static inline int pn_create_socket(int af); pn_socket_t pn_listen(pn_io_t *io, const char *host, const char *port) { @@ -130,7 +130,7 @@ pn_socket_t pn_listen(pn_io_t *io, const char *host, const char *port) return PN_INVALID_SOCKET; } - pn_socket_t sock = pn_create_socket(); + pn_socket_t sock = pn_create_socket(addr->ai_family); if (sock == PN_INVALID_SOCKET) { pn_i_error_from_errno(io->error, "pn_create_socket"); return PN_INVALID_SOCKET; @@ -170,7 +170,7 @@ pn_socket_t pn_connect(pn_io_t *io, const char *host, const char *port) return PN_INVALID_SOCKET; } - pn_socket_t sock = pn_create_socket(); + pn_socket_t sock = pn_create_socket(addr->ai_family); if (sock == PN_INVALID_SOCKET) { pn_i_error_from_errno(io->error, "pn_create_socket"); return PN_INVALID_SOCKET; @@ -195,7 +195,7 @@ pn_socket_t pn_connect(pn_io_t *io, const char *host, const char *port) pn_socket_t pn_accept(pn_io_t *io, pn_socket_t socket, char *name, size_t size) { struct sockaddr_in addr = {0}; - addr.sin_family = AF_INET; + addr.sin_family = AF_UNSPEC; socklen_t addrlen = sizeof(addr); pn_socket_t sock = accept(socket, (struct sockaddr *) &addr, &addrlen); if (sock == PN_INVALID_SOCKET) { @@ -224,18 +224,18 @@ ssize_t pn_send(pn_io_t *io, pn_socket_t socket, const void *buf, size_t len) { return count; } -static inline int pn_create_socket(void) { - return socket(AF_INET, SOCK_STREAM, getprotobyname("tcp")->p_proto); +static inline int pn_create_socket(int af) { + return socket(af, SOCK_STREAM, getprotobyname("tcp")->p_proto); } #elif defined(SO_NOSIGPIPE) ssize_t pn_send(pn_io_t *io, pn_socket_t socket, const void *buf, size_t size) { - ssize_t count = return send(socket, buf, len, 0); + ssize_t count = send(socket, buf, size, 0); io->wouldblock = count < 0 && (errno == EAGAIN || errno == EWOULDBLOCK); return count; } -static inline int pn_create_socket(void) { - int sock = socket(AF_INET, SOCK_STREAM, getprotobyname("tcp")->p_proto); +static inline int pn_create_socket(int af) { + int sock = socket(af, SOCK_STREAM, getprotobyname("tcp")->p_proto); if (sock == -1) return sock; int optval = 1; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/proton.c ---------------------------------------------------------------------- diff --git a/proton-c/src/proton.c b/proton-c/src/proton.c index 35c81f0..9cd44ef 100644 --- a/proton-c/src/proton.c +++ b/proton-c/src/proton.c @@ -41,12 +41,23 @@ #include "platform_fmt.h" #include "protocol.h" +void error_exit(const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); +} + + typedef struct { char *buf; size_t capacity; } heap_buffer; heap_buffer client_msg, client_data, server_data, server_iresp; + void free_heap_buffers(void) { free(client_msg.buf); free(client_data.buf); @@ -309,7 +320,7 @@ void client_callback(pn_connector_t *ctor) ctx->init = true; char container[1024]; - if (gethostname(container, 1024)) pn_fatal("hostname lookup failed"); + if (gethostname(container, 1024)) error_exit("hostname lookup failed"); pn_connection_set_container(connection, container); pn_connection_set_hostname(connection, ctx->hostname); @@ -418,7 +429,7 @@ int main(int argc, char **argv) { switch (opt) { case 'c': - if (url) pn_fatal("multiple connect urls not allowed\n"); + if (url) error_exit("multiple connect urls not allowed\n"); url = optarg; break; case 'a': @@ -462,7 +473,7 @@ int main(int argc, char **argv) printf(" -h Print this help.\n"); exit(EXIT_SUCCESS); default: /* '?' */ - pn_fatal("Usage: %s -h\n", argv[0]); + error_exit("Usage: %s -h\n", argv[0]); } } @@ -484,7 +495,7 @@ int main(int argc, char **argv) ctx.hostname = host; ctx.address = address; pn_connector_t *ctor = pn_connector(drv, host, port, &ctx); - if (!ctor) pn_fatal("connector failed\n"); + if (!ctor) error_exit("connector failed\n"); pn_connector_set_connection(ctor, pn_connection()); while (!ctx.done) { pn_driver_wait(drv, -1); @@ -502,7 +513,7 @@ int main(int argc, char **argv) } } else { struct server_context ctx = {0, quiet, size}; - if (!pn_listener(drv, host, port, &ctx)) pn_fatal("listener failed\n"); + if (!pn_listener(drv, host, port, &ctx)) error_exit("listener failed\n"); while (true) { pn_driver_wait(drv, -1); pn_listener_t *l; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/ssl/openssl.c ---------------------------------------------------------------------- diff --git a/proton-c/src/ssl/openssl.c b/proton-c/src/ssl/openssl.c index 12205a8..5815845 100644 --- a/proton-c/src/ssl/openssl.c +++ b/proton-c/src/ssl/openssl.c @@ -877,13 +877,13 @@ static ssize_t process_input_ssl( pn_io_layer_t *io_layer, const char *input_dat // write incoming data to app layer if (!ssl->app_input_closed) { - char *data = ssl->inbuf; if (ssl->in_count > 0 || ssl->ssl_closed) { /* if ssl_closed, send 0 count */ pn_io_layer_t *io_next = ssl->io_layer->next; - ssize_t consumed = io_next->process_input( io_next, data, ssl->in_count); + ssize_t consumed = io_next->process_input( io_next, ssl->inbuf, ssl->in_count); if (consumed > 0) { ssl->in_count -= consumed; - data += consumed; + if (ssl->in_count) + memmove( ssl->inbuf, ssl->inbuf + consumed, ssl->in_count ); work_pending = true; _log( ssl, "Application consumed %d bytes from peer\n", (int) consumed ); } else if (consumed < 0) { @@ -906,7 +906,7 @@ static ssize_t process_input_ssl( pn_io_layer_t *io_layer, const char *input_dat // no max frame limit - grow it. char *newbuf = (char *)malloc( max_frame ); if (newbuf) { - ssl->in_size *= max_frame; + ssl->in_size = max_frame; memmove( newbuf, ssl->inbuf, ssl->in_count ); free( ssl->inbuf ); ssl->inbuf = newbuf; @@ -923,8 +923,6 @@ static ssize_t process_input_ssl( pn_io_layer_t *io_layer, const char *input_dat } } } - if (ssl->in_count > 0 && data != ssl->inbuf) - memmove( ssl->inbuf, data, ssl->in_count ); } } while (work_pending); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/tests/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/proton-c/src/tests/CMakeLists.txt b/proton-c/src/tests/CMakeLists.txt index 2292e78..5825b77 100644 --- a/proton-c/src/tests/CMakeLists.txt +++ b/proton-c/src/tests/CMakeLists.txt @@ -19,10 +19,10 @@ add_definitions(${COMPILE_WARNING_FLAGS} ${COMPILE_PLATFORM_FLAGS}) -if (ENABLE_VALGRIND AND VALGRIND) - set(memcheck-cmd ${VALGRIND} --error-exitcode=1 --quiet +if (ENABLE_VALGRIND AND VALGRIND_EXE) + set(memcheck-cmd ${VALGRIND_EXE} --error-exitcode=1 --quiet --leak-check=full --trace-children=yes) -endif (ENABLE_VALGRIND AND VALGRIND) +endif () macro (pn_add_c_test test file) add_executable (${test} ${file}) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/tests/parse-url.c ---------------------------------------------------------------------- diff --git a/proton-c/src/tests/parse-url.c b/proton-c/src/tests/parse-url.c index 1481590..4489ab2 100644 --- a/proton-c/src/tests/parse-url.c +++ b/proton-c/src/tests/parse-url.c @@ -20,11 +20,7 @@ */ #include <stdarg.h> -#ifndef __cplusplus -#include <stdbool.h> -#else #include <proton/type_compat.h> -#endif #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -74,6 +70,19 @@ int main(int argc, char **argv) assert(test_url_parse("user:1243^&^:pw@host:423", 0, "user", "1243^&^:pw", "host", "423", 0)); assert(test_url_parse("user:1243^&^:pw@host:423/Foo.bar:90087", 0, "user", "1243^&^:pw", "host", "423", "Foo.bar:90087")); assert(test_url_parse("user:1243^&^:pw@host:423/Foo.bar:90087@somewhere", 0, "user", "1243^&^:pw", "host", "423", "Foo.bar:90087@somewhere")); + assert(test_url_parse("[::1]", 0, 0, 0, "::1", 0, 0)); + assert(test_url_parse("[::1]:amqp", 0, 0, 0, "::1", "amqp", 0)); + assert(test_url_parse("user@[::1]", 0, "user", 0, "::1", 0, 0)); + assert(test_url_parse("user@[::1]:amqp", 0, "user", 0, "::1", "amqp", 0)); + assert(test_url_parse("user:1243^&^:pw@[::1]:amqp", 0, "user", "1243^&^:pw", "::1", "amqp", 0)); + assert(test_url_parse("user:1243^&^:pw@[::1]:amqp/Foo.bar:90087", 0, "user", "1243^&^:pw", "::1", "amqp", "Foo.bar:90087")); + assert(test_url_parse("user:1243^&^:pw@[::1:amqp/Foo.bar:90087", 0, "user", "1243^&^:pw", "[", ":1:amqp", "Foo.bar:90087")); + assert(test_url_parse("user:1243^&^:pw@::1]:amqp/Foo.bar:90087", 0, "user", "1243^&^:pw", "", ":1]:amqp", "Foo.bar:90087")); + assert(test_url_parse("amqp://user@[::1]", "amqp", "user", 0, "::1", 0, 0)); + assert(test_url_parse("amqp://user@[::1]:amqp", "amqp", "user", 0, "::1", "amqp", 0)); + assert(test_url_parse("amqp://user@[1234:52:0:1260:f2de:f1ff:fe59:8f87]:amqp", "amqp", "user", 0, "1234:52:0:1260:f2de:f1ff:fe59:8f87", "amqp", 0)); + assert(test_url_parse("amqp://user:1243^&^:pw@[::1]:amqp", "amqp", "user", "1243^&^:pw", "::1", "amqp", 0)); + assert(test_url_parse("amqp://user:1243^&^:pw@[::1]:amqp/Foo.bar:90087", "amqp", "user", "1243^&^:pw", "::1", "amqp", "Foo.bar:90087")); assert(test_url_parse("amqp://host", "amqp", 0, 0, "host", 0, 0)); assert(test_url_parse("amqp://user@host", "amqp", "user", 0, "host", 0, 0)); assert(test_url_parse("amqp://user@host/path:%", "amqp", "user", 0, "host", 0, "path:%")); @@ -82,5 +91,10 @@ int main(int argc, char **argv) assert(test_url_parse("amqp://bigbird@host/queue@host", "amqp", "bigbird", 0, "host", 0, "queue@host")); assert(test_url_parse("amqp://host/queue@host", "amqp", 0, 0, "host", 0, "queue@host")); assert(test_url_parse("amqp://host:9765/queue@host", "amqp", 0, 0, "host", "9765", "queue@host")); + assert(test_url_parse("user:pass%2fword@host", 0, "user", "pass/word", "host", 0, 0)); + assert(test_url_parse("user:pass%2Fword@host", 0, "user", "pass/word", "host", 0, 0)); + assert(test_url_parse("us%2fer:password@host", 0, "us/er", "password", "host", 0, 0)); + assert(test_url_parse("us%2Fer:password@host", 0, "us/er", "password", "host", 0, 0)); + assert(test_url_parse("user:pass%2fword%@host", 0, "user", "pass/word%", "host", 0, 0)); return 0; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/transport/transport.c ---------------------------------------------------------------------- diff --git a/proton-c/src/transport/transport.c b/proton-c/src/transport/transport.c index e0bef84..e5b4a31 100644 --- a/proton-c/src/transport/transport.c +++ b/proton-c/src/transport/transport.c @@ -284,7 +284,8 @@ int pn_transport_bind(pn_transport_t *transport, pn_connection_t *connection) pn_incref(connection); if (transport->open_rcvd) { PN_SET_REMOTE(connection->endpoint.state, PN_REMOTE_ACTIVE); - pn_event_t *event = pn_collector_put(connection->collector, PN_CONNECTION_STATE); + pn_event_t *event = pn_collector_put(connection->collector, + PN_CONNECTION_REMOTE_STATE); if (event) { pn_event_init_connection(event, connection); } @@ -474,7 +475,8 @@ int pn_do_open(pn_dispatcher_t *disp) if (conn) { PN_SET_REMOTE(conn->endpoint.state, PN_REMOTE_ACTIVE); - pn_event_t *event = pn_collector_put(conn->collector, PN_CONNECTION_STATE); + pn_event_t *event = pn_collector_put(conn->collector, + PN_CONNECTION_REMOTE_STATE); if (event) { pn_event_init_connection(event, conn); } @@ -507,7 +509,8 @@ int pn_do_begin(pn_dispatcher_t *disp) pn_map_channel(transport, disp->channel, ssn); PN_SET_REMOTE(ssn->endpoint.state, PN_REMOTE_ACTIVE); - pn_event_t *event = pn_collector_put(transport->connection->collector, PN_SESSION_STATE); + pn_event_t *event = pn_collector_put(transport->connection->collector, + PN_SESSION_REMOTE_STATE); if (event) { pn_event_init_session(event, ssn); } @@ -681,7 +684,8 @@ int pn_do_attach(pn_dispatcher_t *disp) link->state.delivery_count = idc; } - pn_event_t *event = pn_collector_put(transport->connection->collector, PN_LINK_STATE); + pn_event_t *event = pn_collector_put(transport->connection->collector, + PN_LINK_REMOTE_STATE); if (event) { pn_event_init_link(event, link); } @@ -951,7 +955,8 @@ int pn_do_detach(pn_dispatcher_t *disp) if (closed) { PN_SET_REMOTE(link->endpoint.state, PN_REMOTE_CLOSED); - pn_event_t *event = pn_collector_put(transport->connection->collector, PN_LINK_STATE); + pn_event_t *event = pn_collector_put(transport->connection->collector, + PN_LINK_REMOTE_STATE); if (event) { pn_event_init_link(event, link); } @@ -970,7 +975,8 @@ int pn_do_end(pn_dispatcher_t *disp) int err = pn_scan_error(disp->args, &ssn->endpoint.remote_condition, SCAN_ERROR_DEFAULT); if (err) return err; PN_SET_REMOTE(ssn->endpoint.state, PN_REMOTE_CLOSED); - pn_event_t *event = pn_collector_put(transport->connection->collector, PN_SESSION_STATE); + pn_event_t *event = pn_collector_put(transport->connection->collector, + PN_SESSION_REMOTE_STATE); if (event) { pn_event_init_session(event, ssn); } @@ -986,7 +992,8 @@ int pn_do_close(pn_dispatcher_t *disp) if (err) return err; transport->close_rcvd = true; PN_SET_REMOTE(conn->endpoint.state, PN_REMOTE_CLOSED); - pn_event_t *event = pn_collector_put(transport->connection->collector, PN_CONNECTION_STATE); + pn_event_t *event = pn_collector_put(transport->connection->collector, + PN_CONNECTION_REMOTE_STATE); if (event) { pn_event_init_connection(event, conn); } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/src/util.c ---------------------------------------------------------------------- diff --git a/proton-c/src/util.c b/proton-c/src/util.c index 6ac7b51..e6b9af0 100644 --- a/proton-c/src/util.c +++ b/proton-c/src/util.c @@ -23,12 +23,7 @@ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> -#ifndef __cplusplus -#include <stdint.h> -#include <stdbool.h> -#else #include <proton/type_compat.h> -#endif #include <ctype.h> #include <string.h> #include <proton/error.h> @@ -106,6 +101,42 @@ void pn_print_data(const char *bytes, size_t size) pn_fprint_data(stdout, bytes, size); } +void pni_urldecode(const char *src, char *dst) +{ + const char *in = src; + char *out = dst; + while (*in != '\0') + { + if ('%' == *in) + { + if ((in[1] != '\0') && (in[2] != '\0')) + { + char esc[3]; + esc[0] = in[1]; + esc[1] = in[2]; + esc[2] = '\0'; + unsigned long d = strtoul(esc, NULL, 16); + *out = (char)d; + in += 3; + out++; + } + else + { + *out = *in; + in++; + out++; + } + } + else + { + *out = *in; + in++; + out++; + } + } + *out = '\0'; +} + // Parse URL syntax: // [ <scheme> :// ] [ <user> [ : <password> ] @ ] <host> [ : <port> ] [ / <path> ] // <user>, <password>, <host>, <port> cannot contain any of '@', ':', '/' @@ -141,13 +172,24 @@ void pni_parse_url(char *url, char **scheme, char **user, char **pass, char **ho } *host = url; + char *open = (*url == '[') ? url : 0; + if (open) { + char *close = strchr(open, ']'); + if (close) { + *host = open + 1; + *close = '\0'; + url = close + 1; + } + } - char *colon = strchr(*host, ':'); + char *colon = strchr(url, ':'); if (colon) { *colon = '\0'; *port = colon + 1; } + if (*user) pni_urldecode(*user, *user); + if (*pass) pni_urldecode(*pass, *pass); } void pn_vfatal(const char *fmt, va_list ap) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-j/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/proton-j/CMakeLists.txt b/proton-j/CMakeLists.txt index 5e70457..d614196 100644 --- a/proton-j/CMakeLists.txt +++ b/proton-j/CMakeLists.txt @@ -17,8 +17,12 @@ # under the License. # +include(UseJava) +include(ProtonUseJava) set(CMAKE_JAVA_TARGET_VERSION ${PN_VERSION}) file(GLOB_RECURSE SOURCES_ABS "src/main/java/*.java") add_jar(proton-j ${SOURCES_ABS}) rebuild_jar(proton-j proton-j-${PN_VERSION}.jar) +set (JAVA_INSTALL_DIR ${SHARE_INSTALL_DIR}/java CACHE PATH "Installation directory for all JARs except those using JNI") +mark_as_advanced (JAVA_INSTALL_DIR) install_jar(proton-j ${JAVA_INSTALL_DIR}) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-j/src/main/java/org/apache/qpid/proton/engine/Event.java ---------------------------------------------------------------------- diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/Event.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/Event.java index a995926..14c0dc7 100644 --- a/proton-j/src/main/java/org/apache/qpid/proton/engine/Event.java +++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/Event.java @@ -28,16 +28,38 @@ package org.apache.qpid.proton.engine; public interface Event { + public enum Category { + PROTOCOL; + } public enum Type { - CONNECTION_STATE, - SESSION_STATE, - LINK_STATE, - LINK_FLOW, - DELIVERY, - TRANSPORT + CONNECTION_REMOTE_STATE(Category.PROTOCOL, 1), + CONNECTION_LOCAL_STATE(Category.PROTOCOL, 2), + SESSION_REMOTE_STATE(Category.PROTOCOL, 3), + SESSION_LOCAL_STATE(Category.PROTOCOL, 4), + LINK_REMOTE_STATE(Category.PROTOCOL, 5), + LINK_LOCAL_STATE(Category.PROTOCOL, 6), + LINK_FLOW(Category.PROTOCOL, 7), + DELIVERY(Category.PROTOCOL, 8), + TRANSPORT(Category.PROTOCOL, 9); + + private int _opcode; + private Category _category; + + private Type(Category c, int o) + { + this._category = c; + this._opcode = o; + } + + public Category getCategory() + { + return this._category; + } } + Category getCategory(); + Type getType(); Connection getConnection(); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ConnectionImpl.java ---------------------------------------------------------------------- diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ConnectionImpl.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ConnectionImpl.java index 7401e5b..6a27103 100644 --- a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ConnectionImpl.java +++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ConnectionImpl.java @@ -31,7 +31,7 @@ import org.apache.qpid.proton.amqp.transport.Open; public class ConnectionImpl extends EndpointImpl implements ProtonJConnection { - public static final int MAX_CHANNELS = 255; + public static final int MAX_CHANNELS = 65535; private List<SessionImpl> _sessions = new ArrayList<SessionImpl>(); private EndpointImpl _transportTail; @@ -201,7 +201,7 @@ public class ConnectionImpl extends EndpointImpl implements ProtonJConnection setRemoteDesiredCapabilities(open.getDesiredCapabilities()); setRemoteOfferedCapabilities(open.getOfferedCapabilities()); setRemoteProperties(open.getProperties()); - EventImpl ev = put(Event.Type.CONNECTION_STATE); + EventImpl ev = put(Event.Type.CONNECTION_REMOTE_STATE); if (ev != null) { ev.init(this); } @@ -582,4 +582,12 @@ public class ConnectionImpl extends EndpointImpl implements ProtonJConnection } } + @Override + protected void localStateChanged() + { + EventImpl ev = put(Event.Type.CONNECTION_LOCAL_STATE); + if (ev != null) { + ev.init(this); + } + } } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/EndpointImpl.java ---------------------------------------------------------------------- diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/EndpointImpl.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/EndpointImpl.java index 0d52e8f..72ae1a6 100644 --- a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/EndpointImpl.java +++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/EndpointImpl.java @@ -37,6 +37,8 @@ public abstract class EndpointImpl implements ProtonJEndpoint private EndpointImpl _transportPrev; private Object _context; + protected abstract void localStateChanged(); + public void open() { switch(_localState) @@ -47,6 +49,7 @@ public abstract class EndpointImpl implements ProtonJEndpoint // TODO case UNINITIALIZED: _localState = EndpointState.ACTIVE; + localStateChanged(); } modified(); } @@ -62,6 +65,7 @@ public abstract class EndpointImpl implements ProtonJEndpoint // TODO case ACTIVE: _localState = EndpointState.CLOSED; + localStateChanged(); } modified(); } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/EventImpl.java ---------------------------------------------------------------------- diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/EventImpl.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/EventImpl.java index 2049cf8..7d57909 100644 --- a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/EventImpl.java +++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/EventImpl.java @@ -47,6 +47,11 @@ class EventImpl implements Event this.type = type; } + public Category getCategory() + { + return type.getCategory(); + } + public Type getType() { return type; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/FrameParser.java ---------------------------------------------------------------------- diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/FrameParser.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/FrameParser.java index 58ae67b..a83f888 100644 --- a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/FrameParser.java +++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/FrameParser.java @@ -338,7 +338,7 @@ class FrameParser implements TransportInput // type int type = in.get() & 0xFF; - int channel = in.getShort() & 0xFF; + int channel = in.getShort() & 0xFFFF; if(type != 0) { http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/LinkImpl.java ---------------------------------------------------------------------- diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/LinkImpl.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/LinkImpl.java index 0159c41..dda2171 100644 --- a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/LinkImpl.java +++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/LinkImpl.java @@ -27,6 +27,7 @@ import org.apache.qpid.proton.engine.EndpointState; import org.apache.qpid.proton.engine.Link; import org.apache.qpid.proton.amqp.transport.Source; import org.apache.qpid.proton.amqp.transport.Target; +import org.apache.qpid.proton.engine.Event; public abstract class LinkImpl extends EndpointImpl implements Link { @@ -373,4 +374,12 @@ public abstract class LinkImpl extends EndpointImpl implements Link return _head; } + @Override + protected void localStateChanged() + { + EventImpl ev = getConnectionImpl().put(Event.Type.LINK_LOCAL_STATE); + if (ev != null) { + ev.init(this); + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
