Beispiel #1
0
static inline void field_iterator_move_cursor(qd_iterator_t *iter, uint32_t length)
{
    // Only safe to call this help method if the cursor is parsing the data,
    // i.e. if iter is an address iterator, the cursor must be 'past' the
    // prefix
    assert(iter->state == STATE_IN_BODY);
    uint32_t count = (length > iter->view_pointer.remaining) ? iter->view_pointer.remaining : length;

    if (iter->view_pointer.buffer) {
        while (count) {
            uint32_t remaining = qd_buffer_cursor(iter->view_pointer.buffer) - iter->view_pointer.cursor;
            remaining = (remaining > count) ? count : remaining;
            iter->view_pointer.cursor += remaining;
            iter->view_pointer.remaining -= remaining;
            count -= remaining;
            if (iter->view_pointer.cursor == qd_buffer_cursor(iter->view_pointer.buffer)) {
                iter->view_pointer.buffer = iter->view_pointer.buffer->next;
                if (iter->view_pointer.buffer == 0) {
                    iter->view_pointer.remaining = 0;
                    iter->view_pointer.cursor = 0;
                    break;
                } else {
                    iter->view_pointer.cursor = qd_buffer_base(iter->view_pointer.buffer);
                }
            }
        }
    } else {    // string/binary data
        iter->view_pointer.cursor    += count;
        iter->view_pointer.remaining -= count;
    }
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
    }
}
Beispiel #6
0
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;
}