unsigned int qd_buffer_list_clone(qd_buffer_list_t *dst, const qd_buffer_list_t *src) { uint32_t len = 0; DEQ_INIT(*dst); qd_buffer_t *buf = DEQ_HEAD(*src); while (buf) { size_t to_copy = qd_buffer_size(buf); unsigned char *src = qd_buffer_base(buf); len += to_copy; while (to_copy) { qd_buffer_t *newbuf = qd_buffer(); size_t count = qd_buffer_capacity(newbuf); // default buffer capacity may have changed, // so don't assume it will fit: if (count > to_copy) count = to_copy; memcpy(qd_buffer_cursor(newbuf), src, count); qd_buffer_insert(newbuf, count); DEQ_INSERT_TAIL(*dst, newbuf); src += count; to_copy -= count; } buf = DEQ_NEXT(buf); } return len; }
qdr_field_t *qdr_field_from_iter(qd_iterator_t *iter) { if (!iter) return 0; qdr_field_t *field = new_qdr_field_t(); qd_buffer_t *buf; int remaining; int length; ZERO(field); qd_iterator_reset(iter); remaining = qd_iterator_remaining(iter); length = remaining; while (remaining) { buf = qd_buffer(); size_t cap = qd_buffer_capacity(buf); int copied = qd_iterator_ncopy(iter, qd_buffer_cursor(buf), cap); qd_buffer_insert(buf, copied); DEQ_INSERT_TAIL(field->buffers, buf); remaining = qd_iterator_remaining(iter); } field->iterator = qd_iterator_buffer(DEQ_HEAD(field->buffers), 0, length, ITER_VIEW_ALL); return field; }
qdr_field_t *qdr_field(const char *text) { size_t length = text ? strlen(text) : 0; size_t ilength = length; if (length == 0) return 0; qdr_field_t *field = new_qdr_field_t(); qd_buffer_t *buf; ZERO(field); while (length > 0) { buf = qd_buffer(); size_t cap = qd_buffer_capacity(buf); size_t copy = length > cap ? cap : length; memcpy(qd_buffer_cursor(buf), text, copy); qd_buffer_insert(buf, copy); length -= copy; text += copy; DEQ_INSERT_TAIL(field->buffers, buf); } field->iterator = qd_iterator_buffer(DEQ_HEAD(field->buffers), 0, ilength, ITER_VIEW_ALL); return field; }
static void build_buffer_chain(qd_buffer_list_t *chain, const char *text, int segment_size) { int len = strlen(text); while (len) { int count = (segment_size > len) ? len : segment_size; qd_buffer_t *buf = qd_buffer(); count = (qd_buffer_capacity(buf) < count) ? qd_buffer_capacity(buf) : count; memcpy(qd_buffer_cursor(buf), text, count); qd_buffer_insert(buf, count); DEQ_INSERT_TAIL(*chain, buf); len -= count; text += count; } }
qd_message_t *qd_message_receive(pn_delivery_t *delivery) { pn_link_t *link = pn_delivery_link(delivery); ssize_t rc; qd_buffer_t *buf; qd_message_pvt_t *msg = (qd_message_pvt_t*) pn_delivery_get_context(delivery); // // If there is no message associated with the delivery, this is the first time // we've received anything on this delivery. Allocate a message descriptor and // link it and the delivery together. // if (!msg) { msg = (qd_message_pvt_t*) qd_message(); pn_delivery_set_context(delivery, (void*) msg); } // // Get a reference to the tail buffer on the message. This is the buffer into which // we will store incoming message data. If there is no buffer in the message, allocate // an empty one and add it to the message. // buf = DEQ_TAIL(msg->content->buffers); if (!buf) { buf = qd_buffer(); DEQ_INSERT_TAIL(msg->content->buffers, buf); } while (1) { // // Try to receive enough data to fill the remaining space in the tail buffer. // rc = pn_link_recv(link, (char*) qd_buffer_cursor(buf), qd_buffer_capacity(buf)); // // If we receive PN_EOS, we have come to the end of the message. // if (rc == PN_EOS) { // // If the last buffer in the list is empty, remove it and free it. This // will only happen if the size of the message content is an exact multiple // of the buffer size. // if (qd_buffer_size(buf) == 0) { DEQ_REMOVE_TAIL(msg->content->buffers); qd_buffer_free(buf); } pn_delivery_set_context(delivery, 0); char repr[qd_message_repr_len()]; qd_log(log_source, QD_LOG_TRACE, "Received %s on link %s", qd_message_repr((qd_message_t*)msg, repr, sizeof(repr)), pn_link_name(link)); return (qd_message_t*) msg; } if (rc > 0) { // // We have received a positive number of bytes for the message. Advance // the cursor in the buffer. // qd_buffer_insert(buf, rc); // // If the buffer is full, allocate a new empty buffer and append it to the // tail of the message's list. // if (qd_buffer_capacity(buf) == 0) { buf = qd_buffer(); DEQ_INSERT_TAIL(msg->content->buffers, buf); } } else // // We received zero bytes, and no PN_EOS. This means that we've received // all of the data available up to this point, but it does not constitute // the entire message. We'll be back later to finish it up. // break; } return 0; }