Skip to content

Commit

Permalink
PROTON-28xx: Add new APIs for different disposition types
Browse files Browse the repository at this point in the history
  • Loading branch information
astitcher committed Oct 22, 2024
1 parent 4e651bb commit 38599c9
Show file tree
Hide file tree
Showing 5 changed files with 323 additions and 25 deletions.
156 changes: 156 additions & 0 deletions c/include/proton/disposition.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,162 @@ PN_EXTERN void pn_disposition_set_undeliverable(pn_disposition_t *disposition, b
*/
PN_EXTERN pn_data_t *pn_disposition_annotations(pn_disposition_t *disposition);

/**
* There are different types of delivery status some of which hold their
* own different specific data and some of which hold no extra data
*/
typedef struct pn_received_disposition_t pn_received_disposition_t;
typedef struct pn_rejected_disposition_t pn_rejected_disposition_t;
typedef struct pn_modified_disposition_t pn_modified_disposition_t;
typedef struct pn_custom_disposition_t pn_custom_disposition_t;

/**
* Convert a delivery disposition to a custom disposition
*
* @param[in] disposition delivery disposition object
* @return a pointer to the equivalent custom disposition type
*/
PN_EXTERN pn_custom_disposition_t *pn_custom_disposition(pn_disposition_t *disposition);

/**
* Convert a delivery disposition to more specific disposition types
*
* @param[in] disposition delivery disposition object
* @return a pointer to the desired specific disposition type or NULL
* if the delivery is not that type
*/
PN_EXTERN pn_received_disposition_t *pn_received_disposition(pn_disposition_t *disposition);
PN_EXTERN pn_rejected_disposition_t *pn_rejected_disposition(pn_disposition_t *disposition);
PN_EXTERN pn_modified_disposition_t *pn_modified_disposition(pn_disposition_t *disposition);

/**
* Access the disposition as a raw pn_data_t.
*
* Dispositions are an extension point in the AMQP protocol. The
* disposition interface provides setters/getters for those
* dispositions that are predefined by the specification, however
* access to the raw disposition data is provided so that other
* dispositions can be used.
*
* The ::pn_data_t pointer returned by this operation is valid until
* the parent delivery is settled.
*
* @param[in] disposition a custom disposition object
* @return a pointer to the raw disposition data
*/
PN_EXTERN pn_data_t *pn_custom_disposition_data(pn_custom_disposition_t *disposition);

/**
* Get the type of a custom disposition.
*
* @param[in] disposition a custom disposition object
* @return the type of the disposition
*/
PN_EXTERN uint64_t pn_custom_disposition_get_type(pn_custom_disposition_t *disposition);

/**
* Set the type of a custom disposition.
*
* @param[in] disposition a custom disposition object
* @param[in] type the type of the disposition
*/
PN_EXTERN void pn_custom_disposition_set_type(pn_custom_disposition_t *disposition, uint64_t type);

/**
* Access the condition object associated with a rejected disposition.
*
* The ::pn_condition_t object retrieved by this operation may be
* modified prior to updating a delivery. When a delivery is updated,
* the condition described by the disposition is reported to the peer.
*
* The pointer returned by this operation is valid until the parent
* delivery is settled.
*
* @param[in] disposition a disposition object
* @return a pointer to the disposition condition
*/
PN_EXTERN pn_condition_t *pn_rejected_disposition_condition(pn_rejected_disposition_t *disposition);

/**
* Get the section number associated with a received disposition.
*
* @param[in] disposition a disposition object
* @return a section number
*/
PN_EXTERN uint32_t pn_received_disposition_get_section_number(pn_received_disposition_t *disposition);

/**
* Set the section number associated with a received disposition.
*
* @param[in] disposition a disposition object
* @param[in] section_number a section number
*/
PN_EXTERN void pn_received_disposition_set_section_number(pn_received_disposition_t *disposition, uint32_t section_number);

/**
* Get the section offset associated with a received disposition.
*
* @param[in] disposition a disposition object
* @return a section offset
*/
PN_EXTERN uint64_t pn_received_disposition_get_section_offset(pn_received_disposition_t *disposition);

/**
* Set the section offset associated with a received disposition.
*
* @param[in] disposition a disposition object
* @param[in] section_offset a section offset
*/
PN_EXTERN void pn_received_disposition_set_section_offset(pn_received_disposition_t *disposition, uint64_t section_offset);

/**
* Check if a modified disposition has the failed flag set.
*
* @param[in] disposition a disposition object
* @return true if the disposition has the failed flag set, false otherwise
*/
PN_EXTERN bool pn_modified_disposition_is_failed(pn_modified_disposition_t *disposition);

/**
* Set the failed flag on a modified disposition.
*
* @param[in] disposition a disposition object
* @param[in] failed the value of the failed flag
*/
PN_EXTERN void pn_modified_disposition_set_failed(pn_modified_disposition_t *disposition, bool failed);

/**
* Check if a modified disposition has the undeliverable flag set.
*
* @param[in] disposition a disposition object
* @return true if the disposition has the undeliverable flag set, false otherwise
*/
PN_EXTERN bool pn_modified_disposition_is_undeliverable(pn_modified_disposition_t *disposition);

/**
* Set the undeliverable flag on a modified disposition.
*
* @param[in] disposition a disposition object
* @param[in] undeliverable the value of the undeliverable flag
*/
PN_EXTERN void pn_modified_disposition_set_undeliverable(pn_modified_disposition_t *disposition, bool undeliverable);

/**
* Access the annotations associated with a modified disposition.
*
* The ::pn_data_t object retrieved by this operation may be modified
* prior to updating a delivery. When a delivery is updated, the
* annotations described by the ::pn_data_t are reported to the peer.
* The ::pn_data_t must be empty or contain a symbol keyed map.
*
* The pointer returned by this operation is valid until the parent
* delivery is settled.
*
* @param[in] disposition a disposition object
* @return the annotations associated with the disposition
*/
PN_EXTERN pn_data_t *pn_modified_disposition_annotations(pn_modified_disposition_t *disposition);

/**
* @}
*/
Expand Down
18 changes: 9 additions & 9 deletions c/src/core/engine-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,27 +343,27 @@ typedef enum pn_disposition_type_t {
PN_DISP_MODIFIED = PN_MODIFIED,
} pn_disposition_type_t;

typedef struct pn_received_disposition_t {
struct pn_received_disposition_t {
uint64_t section_offset;
uint32_t section_number;
} pn_received_disposition_t;
};

typedef struct pn_rejected_disposition_t {
struct pn_rejected_disposition_t {
pn_condition_t condition;
} pn_rejected_disposition_t;
};

typedef struct pn_modified_disposition_t {
struct pn_modified_disposition_t {
pn_data_t *annotations;
pn_bytes_t annotations_raw;
bool failed;
bool undeliverable;
} pn_modified_disposition_t;
};

typedef struct pn_custom_disposition_t {
struct pn_custom_disposition_t {
pn_data_t *data;
uint64_t type;
pn_bytes_t data_raw;
} pn_custom_disposition_t;
uint64_t type;
};

struct pn_disposition_t {
union {
Expand Down
106 changes: 106 additions & 0 deletions c/src/core/engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -1978,6 +1978,112 @@ pn_condition_t *pn_disposition_condition(pn_disposition_t *disposition)
return &disposition->u.s_rejected.condition;
}

pn_custom_disposition_t *pn_custom_disposition(pn_disposition_t *disposition)
{
pni_disposition_to_raw(disposition);
return &disposition->u.s_custom;
}

pn_received_disposition_t *pn_received_disposition(pn_disposition_t *disposition)
{
if (disposition->type==PN_DISP_EMPTY) disposition->type = PN_DISP_RECEIVED;
else if (disposition->type!=PN_DISP_RECEIVED) return NULL;
return &disposition->u.s_received;
}

pn_rejected_disposition_t *pn_rejected_disposition(pn_disposition_t *disposition)
{
if (disposition->type==PN_DISP_EMPTY) disposition->type = PN_DISP_REJECTED;
else if (disposition->type!=PN_DISP_REJECTED) return NULL;
return &disposition->u.s_rejected;
}

pn_modified_disposition_t *pn_modified_disposition(pn_disposition_t *disposition)
{
if (disposition->type==PN_DISP_EMPTY) disposition->type = PN_DISP_MODIFIED;
else if (disposition->type!=PN_DISP_MODIFIED) return NULL;
return &disposition->u.s_modified;
}

pn_data_t *pn_custom_disposition_data(pn_custom_disposition_t *disposition)
{
assert(disposition);
pni_switch_to_data(&disposition->data_raw, &disposition->data);
return disposition->data;
}

uint64_t pn_custom_disposition_get_type(pn_custom_disposition_t *disposition)
{
assert(disposition);
return disposition->type;
}

void pn_custom_disposition_set_type(pn_custom_disposition_t *disposition, uint64_t type)
{
assert(disposition);
disposition->type = type;
}

pn_condition_t *pn_rejected_disposition_condition(pn_rejected_disposition_t *disposition)
{
assert(disposition);
return &disposition->condition;
}

uint32_t pn_received_disposition_get_section_number(pn_received_disposition_t *disposition)
{
assert(disposition);
return disposition->section_number;
}

void pn_received_disposition_set_section_number(pn_received_disposition_t *disposition, uint32_t section_number)
{
assert(disposition);
disposition->section_number = section_number;
}

uint64_t pn_received_disposition_get_section_offset(pn_received_disposition_t *disposition)
{
assert(disposition);
return disposition->section_offset;
}

void pn_received_disposition_set_section_offset(pn_received_disposition_t *disposition, uint64_t section_offset)
{
assert(disposition);
disposition->section_offset = section_offset;
}

bool pn_modified_disposition_is_failed(pn_modified_disposition_t *disposition) {
assert(disposition);
return disposition->failed;
}

void pn_modified_disposition_set_failed(pn_modified_disposition_t *disposition, bool failed)
{
assert(disposition);
disposition->failed = failed;
}

bool pn_modified_disposition_is_undeliverable(pn_modified_disposition_t *disposition)
{
assert(disposition);
return disposition->undeliverable;
}

void pn_modified_disposition_set_undeliverable(pn_modified_disposition_t *disposition, bool undeliverable)
{
assert(disposition);
disposition->undeliverable = undeliverable;
}

pn_data_t *pn_modified_disposition_annotations(pn_modified_disposition_t *disposition)
{
assert(disposition);
pni_switch_to_data(&disposition->annotations_raw, &disposition->annotations);
return disposition->annotations;
}

pn_delivery_tag_t pn_delivery_tag(pn_delivery_t *delivery)
{
if (delivery) {
Expand Down
Loading

0 comments on commit 38599c9

Please sign in to comment.