This is an automated email from the ASF dual-hosted git repository. astitcher pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/qpid-proton.git
commit 2ccfe74438ba283428a22a251e80bf25f6060457 Author: Andrew Stitcher <[email protected]> AuthorDate: Fri Mar 6 17:01:12 2026 -0500 PROTON-1442: [C++] Implement iterator for unsettled transfers This returns an iterator for all unsettled transfers on a link. Used to access transfers within a transaction or left unsettled after one has failed. This code was written with the assistance of Cursor. --- cpp/include/proton/delivery.hpp | 23 +++++++++++++++++++++++ cpp/include/proton/receiver.hpp | 9 +++++++-- cpp/include/proton/sender.hpp | 10 +++++++--- cpp/include/proton/session.hpp | 4 ++-- cpp/include/proton/tracker.hpp | 23 +++++++++++++++++++++++ cpp/src/delivery.cpp | 10 ++++++++++ cpp/src/link.cpp | 4 ---- cpp/src/receiver.cpp | 7 +++++++ cpp/src/sender.cpp | 5 +++++ cpp/src/tracker.cpp | 10 ++++++++++ cpp/src/transfer.cpp | 3 +-- 11 files changed, 95 insertions(+), 13 deletions(-) diff --git a/cpp/include/proton/delivery.hpp b/cpp/include/proton/delivery.hpp index 4c4ac030e..f60ea5438 100644 --- a/cpp/include/proton/delivery.hpp +++ b/cpp/include/proton/delivery.hpp @@ -23,6 +23,7 @@ */ #include "./binary.hpp" +#include "./endpoint.hpp" #include "./fwd.hpp" #include "./internal/export.hpp" #include "./internal/object.hpp" @@ -70,9 +71,31 @@ class delivery : public transfer { /// @cond INTERNAL friend class internal::factory<delivery>; + friend class receiver; /// @endcond }; +/// @cond INTERNAL + +/// An iterator of unsettled deliveries on a receiver. +class delivery_iterator : public internal::iter_base<delivery, delivery_iterator> { + delivery_iterator(delivery d) : + internal::iter_base<delivery, delivery_iterator>(d) {} + +public: + explicit delivery_iterator() : + internal::iter_base<delivery, delivery_iterator>(delivery()) {} + /// Advance to the next unsettled delivery. + PN_CPP_EXTERN delivery_iterator operator++(); + + friend class receiver; +}; + +/// A range of unsettled deliveries. +typedef internal::iter_range<delivery_iterator> delivery_range; + +/// @endcond + } // proton #endif // PROTON_DELIVERY_HPP diff --git a/cpp/include/proton/receiver.hpp b/cpp/include/proton/receiver.hpp index 353f1d269..8c58cadd1 100644 --- a/cpp/include/proton/receiver.hpp +++ b/cpp/include/proton/receiver.hpp @@ -22,6 +22,7 @@ * */ +#include "./delivery.hpp" #include "./fwd.hpp" #include "./internal/export.hpp" #include "./link.hpp" @@ -76,6 +77,10 @@ PN_CPP_CLASS_EXTERN receiver : public link { /// outstanding drained credit reaches zero. PN_CPP_EXTERN void drain(); + /// **Unsettled API** - Get a range of unsettled deliveries on this receiver. + /// Settled deliveries are not included. + PN_CPP_EXTERN delivery_range unsettled_deliveries() const; + /// @cond INTERNAL friend class internal::factory<receiver>; friend class receiver_iterator; @@ -86,13 +91,13 @@ PN_CPP_CLASS_EXTERN receiver : public link { /// An iterator of receivers. class receiver_iterator : public internal::iter_base<receiver, receiver_iterator> { - explicit receiver_iterator(receiver r, pn_session_t* s = 0) : + explicit receiver_iterator(receiver r, pn_session_t* s = nullptr) : internal::iter_base<receiver, receiver_iterator>(r), session_(s) {} public: /// Create an iterator of receivers. explicit receiver_iterator() : - internal::iter_base<receiver, receiver_iterator>(0), session_(0) {} + internal::iter_base<receiver, receiver_iterator>(nullptr), session_(nullptr) {} /// Advance to the next receiver. PN_CPP_EXTERN receiver_iterator operator++(); diff --git a/cpp/include/proton/sender.hpp b/cpp/include/proton/sender.hpp index 59fd74bd4..7118ad780 100644 --- a/cpp/include/proton/sender.hpp +++ b/cpp/include/proton/sender.hpp @@ -72,6 +72,10 @@ PN_CPP_CLASS_EXTERN sender : public link { /// @see receiver::drain PN_CPP_EXTERN void return_credit(); + /// **Unsettled API** - Get a range of unsettled trackers on this sender. + /// Settled trackers are not included. + PN_CPP_EXTERN tracker_range unsettled_trackers() const; + /// @cond INTERNAL friend class internal::factory<sender>; friend class sender_iterator; @@ -87,13 +91,13 @@ PN_CPP_CLASS_EXTERN sender : public link { /// An iterator of senders. class sender_iterator : public internal::iter_base<sender, sender_iterator> { - sender_iterator(sender snd, pn_session_t* s = 0) : + sender_iterator(sender snd, pn_session_t* s = nullptr) : internal::iter_base<sender, sender_iterator>(snd), session_(s) {} public: /// Create an iterator of senders. - sender_iterator() : - internal::iter_base<sender, sender_iterator>(0), session_(0) {} + explicit sender_iterator() : + internal::iter_base<sender, sender_iterator>(nullptr), session_(nullptr) {} /// Advance to the next sender. PN_CPP_EXTERN sender_iterator operator++(); diff --git a/cpp/include/proton/session.hpp b/cpp/include/proton/session.hpp index 60522c817..ea7d3bbc1 100644 --- a/cpp/include/proton/session.hpp +++ b/cpp/include/proton/session.hpp @@ -115,8 +115,8 @@ PN_CPP_CLASS_EXTERN session : public internal::object<pn_session_t>, public endp /// An iterator of sessions. class session_iterator : public internal::iter_base<session, session_iterator> { - public: - explicit session_iterator(session s = 0) : internal::iter_base<session, session_iterator>(s) {} + public: + explicit session_iterator(session s = nullptr) : internal::iter_base<session, session_iterator>(s) {} /// Advance to the next session. PN_CPP_EXTERN session_iterator operator++(); diff --git a/cpp/include/proton/tracker.hpp b/cpp/include/proton/tracker.hpp index 3d8ad0aab..0c5efef27 100644 --- a/cpp/include/proton/tracker.hpp +++ b/cpp/include/proton/tracker.hpp @@ -23,6 +23,7 @@ */ #include "./binary.hpp" +#include "./endpoint.hpp" #include "./internal/export.hpp" #include "./transfer.hpp" @@ -55,9 +56,31 @@ class tracker : public transfer { /// @cond INTERNAL friend class internal::factory<tracker>; + friend class sender; /// @endcond }; +/// @cond INTERNAL + +/// An iterator of unsettled trackers on a sender. +class tracker_iterator : public internal::iter_base<tracker, tracker_iterator> { + tracker_iterator(tracker t) : + internal::iter_base<tracker, tracker_iterator>(t) {} + +public: + explicit tracker_iterator() : + internal::iter_base<tracker, tracker_iterator>(tracker()) {} + /// Advance to the next unsettled tracker. + PN_CPP_EXTERN tracker_iterator operator++(); + + friend class sender; +}; + +/// A range of unsettled trackers. +typedef internal::iter_range<tracker_iterator> tracker_range; + +/// @endcond + } // proton #endif // PROTON_TRACKER_HPP diff --git a/cpp/src/delivery.cpp b/cpp/src/delivery.cpp index 9f03eaf73..654f50a36 100644 --- a/cpp/src/delivery.cpp +++ b/cpp/src/delivery.cpp @@ -26,6 +26,8 @@ #include "proton_bits.hpp" #include <proton/delivery.h> +#include <proton/disposition.h> +#include <proton/link.h> #include "types_internal.hpp" @@ -51,4 +53,12 @@ void delivery::reject() { settle_delivery(pn_object(), REJECTED); } void delivery::release() { settle_delivery(pn_object(), RELEASED); } void delivery::modify() { pn_disposition_set_failed(pn_delivery_local(pn_object()), true); settle_delivery(pn_object(), MODIFIED); } +delivery_iterator delivery_iterator::operator++() { + if (!!obj_) { + pn_delivery_t* next = pn_unsettled_next(unwrap(obj_)); + obj_ = make_wrapper<delivery>(next); + } + return *this; +} + } diff --git a/cpp/src/link.cpp b/cpp/src/link.cpp index c6f58f48d..6d28081ac 100644 --- a/cpp/src/link.cpp +++ b/cpp/src/link.cpp @@ -19,11 +19,8 @@ * */ -#include "proton_bits.hpp" - #include "proton/codec/map.hpp" #include "proton/link.hpp" -#include "proton/error.hpp" #include "proton/connection.hpp" #include <proton/connection.h> @@ -31,7 +28,6 @@ #include <proton/link.h> #include "contexts.hpp" -#include "msg.hpp" #include "proton_bits.hpp" namespace proton { diff --git a/cpp/src/receiver.cpp b/cpp/src/receiver.cpp index 9f3c77062..97cafa475 100644 --- a/cpp/src/receiver.cpp +++ b/cpp/src/receiver.cpp @@ -19,6 +19,7 @@ * */ #include "proton/receiver.hpp" +#include "proton/delivery.hpp" #include "proton/error.hpp" #include "proton/link.hpp" @@ -33,6 +34,7 @@ #include <proton/connection.h> #include <proton/session.h> #include <proton/link.h> +#include <proton/delivery.h> #include <proton/event.h> namespace proton { @@ -83,6 +85,11 @@ void receiver::drain() { } } +delivery_range receiver::unsettled_deliveries() const { + pn_delivery_t* d = pn_unsettled_head(pn_object()); + return delivery_range(delivery_iterator(make_wrapper<delivery>(d))); +} + receiver_iterator receiver_iterator::operator++() { if (!!obj_) { pn_link_t *lnk = pn_link_next(obj_.pn_object(), 0); diff --git a/cpp/src/sender.cpp b/cpp/src/sender.cpp index 942e755b0..8b3942bfe 100644 --- a/cpp/src/sender.cpp +++ b/cpp/src/sender.cpp @@ -87,6 +87,11 @@ tracker sender::send(const message &message, const binary &tag) { return track; } +tracker_range sender::unsettled_trackers() const { + pn_delivery_t* d = pn_unsettled_head(pn_object()); + return tracker_range(tracker_iterator(make_wrapper<tracker>(d))); +} + void sender::return_credit() { link_context &lctx = link_context::get(pn_object()); lctx.draining = false; diff --git a/cpp/src/tracker.cpp b/cpp/src/tracker.cpp index e703767ef..3f4db11aa 100644 --- a/cpp/src/tracker.cpp +++ b/cpp/src/tracker.cpp @@ -28,10 +28,20 @@ #include "proton/binary.hpp" #include <proton/delivery.h> +#include <proton/link.h> namespace proton { tracker::tracker(pn_delivery_t *d): transfer(make_wrapper(d)) {} sender tracker::sender() const { return make_wrapper<class sender>(pn_delivery_link(pn_object())); } binary tracker::tag() const { return bin(pn_delivery_tag(pn_object())); } + +tracker_iterator tracker_iterator::operator++() { + if (!!obj_) { + pn_delivery_t* next = pn_unsettled_next(unwrap(obj_)); + obj_ = make_wrapper<tracker>(next); + } + return *this; +} + } diff --git a/cpp/src/transfer.cpp b/cpp/src/transfer.cpp index 063254267..5fdf34ecd 100644 --- a/cpp/src/transfer.cpp +++ b/cpp/src/transfer.cpp @@ -19,10 +19,9 @@ * */ -#include "proton/delivery.hpp" +#include "proton/transfer.hpp" #include "proton/connection.hpp" -#include "proton/link.hpp" #include "proton/session.hpp" #include <proton/delivery.h> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
