Пример #1
0
/*
 * fill the mbuf in the msg with the content
 */
int msg_append_full(struct msg *msg, const uint8_t *pos, uint32_t n)
{
    struct mbuf *mbuf;
    uint32_t left, len;
    mbuf_base *mb = msg->mb;
    const uint8_t *start;

    start = pos;
    left = n;

    while (left > 0) {
        mbuf = listLastValue(msg->data);
        if (mbuf == NULL || mbuf_size(mbuf) == 0) {
            mbuf = mbuf_get(mb);
            if (mbuf == NULL) {
                log_error("ERROR: Mbuf get failed: out of memory");
                return RMT_ENOMEM;
            }
            listAddNodeTail(msg->data, mbuf);
        }

        len = MIN(left, mbuf_size(mbuf));
        mbuf_copy(mbuf, start, len);
        left -= len;
        start += len;
        msg->mlen += len;
    }
    
    return RMT_OK;
}
Пример #2
0
void 
mbuf_write_char(struct mbuf *mbuf, char ch) 
{
   ASSERT(mbuf_size(mbuf) >= 1);
   *mbuf->last = ch;
   mbuf->last += 1;
}
Пример #3
0
static rstatus_t
conn_recv_queue(struct conn *conn)
{
    struct mbuf *mbuf;
    size_t msize;         /* current mbuf size */
    ssize_t n;

    mbuf = STAILQ_LAST(&conn->recv_queue, mbuf, next);
    if (mbuf == NULL || mbuf_full(mbuf)) {
        mbuf = mbuf_get();
        if (mbuf == NULL) {
            return NC_ENOMEM;
        }
        mbuf_insert(&conn->recv_queue, mbuf);
    }

    msize = mbuf_size(mbuf);
    ASSERT(msize > 0);

    n = conn_recv_buf(conn, mbuf->last, msize);
    if (n < 0) {
        if (n == NC_EAGAIN) {
            return NC_OK;
        }
        return NC_ERROR;
    }

    ASSERT((mbuf->last + n) <= mbuf->end);
    mbuf->last += n;
    return NC_OK;
}
Пример #4
0
int
mbuf_steal_data(MBuf *mbuf, uint8 **data_p)
{
	int			len = mbuf_size(mbuf);

	mbuf->no_write = true;
	mbuf->own_data = false;

	*data_p = mbuf->data;

	mbuf->data = mbuf->data_end = mbuf->read_pos = mbuf->buf_end = NULL;

	return len;
}
Пример #5
0
/*
 * Copy n bytes from memory area pos to mbuf.
 *
 * The memory areas should not overlap and the mbuf should have
 * enough space for n bytes.
 */
void
mbuf_copy(struct mbuf *mbuf, uint8_t *pos, size_t n)
{
    if (n == 0) {
        return;
    }

    /* mbuf has space for n bytes */
    ASSERT(!mbuf_full(mbuf) && n <= mbuf_size(mbuf));

    /* no overlapping copy */
    ASSERT(pos < mbuf->start || pos >= mbuf->end);

    dn_memcpy(mbuf->last, pos, n);
    mbuf->last += n;
}
Пример #6
0
/*
 * append small(small than a mbuf) content into msg
 */
int
msg_append(struct msg *msg, uint8_t *pos, size_t n)
{
    struct mbuf *mbuf;

    ASSERT(n <= mbuf_data_size(msg->mb));

    mbuf = msg_ensure_mbuf(msg, n);
    if (mbuf == NULL) {
        return RMT_ENOMEM;
    }

    ASSERT(n <= mbuf_size(mbuf));

    mbuf_copy(mbuf, pos, n);
    msg->mlen += (uint32_t)n;
    return RMT_OK;
}
Пример #7
0
/*
 * prepend small(small than a mbuf) content into msg
 */
int
msg_prepend(struct msg *msg, uint8_t *pos, size_t n)
{
    mbuf_base *mb = msg->mb;
    struct mbuf *mbuf;

    mbuf = mbuf_get(mb);
    if (mbuf == NULL) {
        return RMT_ENOMEM;
    }

    ASSERT(n <= mbuf_size(mbuf));

    mbuf_copy(mbuf, pos, n);
    msg->mlen += (uint32_t)n;

    listAddNodeHead(msg->data, mbuf);

    return RMT_OK;
}
Пример #8
0
struct msg *
memcache_generate_error(struct msg *r, err_t err)
{
    struct mbuf *mbuf;
    int n;
    char *protstr = "SERVER_ERROR";
    char *errstr = err ? strerror(err) : "unknown";

    r->type = MSG_RSP_MC_SERVER_ERROR;

    mbuf = mbuf_get();
    if (mbuf == NULL) {
        return NULL;
    }
    mbuf_insert(&r->mhdr, mbuf);

    n = nc_scnprintf(mbuf->last, mbuf_size(mbuf), "%s %s"CRLF, protstr, errstr);
    mbuf->last += n;
    r->mlen = (uint32_t)n;

    return r;
}
Пример #9
0
struct mbuf *
msg_ensure_mbuf(struct msg *msg, size_t len)
{
    listNode *node;
    mbuf_base *mb = msg->mb;
    struct mbuf *mbuf;

    node = listLast(msg->data);
    
    if (node == NULL ||
        mbuf_size(listNodeValue(node)) < len) {
        mbuf = mbuf_get(mb);
        if (mbuf == NULL) {
            return NULL;
        }

        listAddNodeTail(msg->data, mbuf);
    } else {
        mbuf = listNodeValue(node);
    }

    return mbuf;
}
Пример #10
0
/*
 * prepend small(small than a mbuf) content into msg
 */
int
msg_prepend_format(struct msg *msg, const char *fmt, ...)
{
    mbuf_base *mb = msg->mb;
    struct mbuf *mbuf;
    int32_t n;
    va_list args;

    mbuf = mbuf_get(mb);
    if (mbuf == NULL) {
        return RMT_ENOMEM;
    }

    va_start(args, fmt);
    n = rmt_vscnprintf(mbuf->last, mbuf_size(mbuf), fmt, args);
    va_end(args);

    mbuf->last += n;
    msg->mlen += (uint32_t)n;

    listAddNodeHead(msg->data, mbuf);
    
    return RMT_OK;
}
Пример #11
0
/*
 * note: we should not call conn_add_out here.
 * because we may call append many times.
 */
rstatus_t
conn_sendq_append(struct conn *conn, char *pos, size_t n)
{
    struct mbuf *mbuf;
    size_t bytes = 0;
    size_t len;

    while (bytes < n) {
        mbuf = STAILQ_LAST(&conn->send_queue, mbuf, next);
        if ((mbuf == NULL) || mbuf_full(mbuf)) {
            mbuf = mbuf_get();
            if (mbuf == NULL) {
                return NC_ENOMEM;
            }
            mbuf_insert(&conn->send_queue, mbuf);
        }

        len = MIN(mbuf_size(mbuf), n - bytes);
        mbuf_copy(mbuf, (uint8_t *)pos + bytes, len);
        bytes += len;
    }

    return NC_OK;
}
Пример #12
0
void 
mbuf_write_string(struct mbuf *mbuf, struct string *s)
{
   ASSERT(s->len < mbuf_size(mbuf));
   mbuf_copy(mbuf, s->data, s->len);
}