예제 #1
0
void* ringbuf_memcpy_from(void* dst, ringbuf_t src, size_t count)
{
    size_t bytes_used = ringbuf_bytes_used(src);

    if (count > bytes_used) {
        return NULL;
    }

    const uint8_t* u8dst = dst;
    const uint8_t* bufend = ringbuf_end(src);
    size_t nwritten = 0;

    while (nwritten != count) {
        lwIP_ASSERT(bufend > src->tail);
        size_t n = LWIP_MIN(bufend - src->tail, count - nwritten);
        memcpy((uint8_t*)u8dst + nwritten, src->tail, n);
        src->tail += n;
        nwritten += n;

        if (src->tail == bufend) {
            src->tail = src->buf;
        }
    }

    lwIP_ASSERT(count + ringbuf_bytes_used(src) == bytes_used);
    return src->tail;
}
예제 #2
0
size_t ringbuf_memset(ringbuf_t dst, int c, size_t len)
{
    const uint8_t* bufend = ringbuf_end(dst);
    size_t nwritten = 0;
    size_t count = LWIP_MIN(len, ringbuf_buffer_size(dst));
    int overflow = count > ringbuf_bytes_free(dst);

    while (nwritten != count) {

        lwIP_ASSERT(bufend > dst->head);
        size_t n = LWIP_MIN(bufend - dst->head, count - nwritten);
        os_memset(dst->head, c, n);
        dst->head += n;
        nwritten += n;

        if (dst->head == bufend) {
            dst->head = dst->buf;
        }
    }

    if (overflow) {
        dst->tail = ringbuf_nextp(dst, dst->head);
        lwIP_ASSERT(ringbuf_is_full(dst));
    }

    return nwritten;
}
예제 #3
0
void* ringbuf_memcpy_into(ringbuf_t dst, const void* src, size_t count)
{
    const uint8_t* u8src = src;
    const uint8_t* bufend = ringbuf_end(dst);
    int overflow = count > ringbuf_bytes_free(dst);
    size_t nread = 0;

    while (nread != count) {
        lwIP_ASSERT(bufend > dst->head);
        size_t n = LWIP_MIN(bufend - dst->head, count - nread);
        memcpy(dst->head, u8src + nread, n);
        dst->head += n;
        nread += n;

        if (dst->head == bufend) {
            dst->head = dst->buf;
        }
    }

    if (overflow) {
        dst->tail = ringbuf_nextp(dst, dst->head);
        lwIP_ASSERT(ringbuf_is_full(dst));
    }

    return dst->head;
}
예제 #4
0
void *
ringbuf_memcpy_from(void *dst, ringbuf_t src, size_t count, bool destroy)
{
    size_t bytes_used = ringbuf_bytes_used(src);
    if (count > bytes_used)
        return 0;

    uint8_t *u8dst = dst;
    const uint8_t *bufend = ringbuf_end(src);
    uint8_t *tail = src->tail;
    size_t nwritten = 0;
    while (nwritten != count) {
        assert(bufend > src->tail);
        size_t n = MIN(bufend - src->tail, count - nwritten);
        memcpy(u8dst + nwritten, src->tail, n);
        src->tail += n;
        nwritten += n;

        /* wrap ? */
        if (src->tail == bufend)
            src->tail = src->buf;
    }

    if (!destroy)
    {
        src->tail = tail;
        assert(ringbuf_bytes_used(src) == bytes_used);
    }
    else
    {
        assert(count + ringbuf_bytes_used(src) == bytes_used);
    }
    return src->tail;
}
예제 #5
0
ssize_t
ringbuf_read(int fd, ringbuf_t rb, size_t count)
{
    const uint8_t *bufend = ringbuf_end(rb);
    size_t nfree = ringbuf_bytes_free(rb);

    /* don't write beyond the end of the buffer */
    assert(bufend > rb->head);
    count = MIN(bufend - rb->head, count);
    ssize_t n = read(fd, rb->head, count);
    if (n > 0) {
        assert(rb->head + n <= bufend);
        rb->head += n;

        /* wrap? */
        if (rb->head == bufend)
            rb->head = rb->buf;

        /* fix up the tail pointer if an overflow occurred */
        if (n > nfree) {
            rb->tail = ringbuf_nextp(rb, rb->head);
            assert(ringbuf_is_full(rb));
        }
    }

    return n;
}
예제 #6
0
void *
ringbuf_memcpy_into(ringbuf_t dst, const void *src, size_t count)
{
    const uint8_t *u8src = src;
    const uint8_t *bufend = ringbuf_end(dst);
    int overflow = count > ringbuf_bytes_free(dst);
    size_t nread = 0;

    while (nread != count) {
        /* don't copy beyond the end of the buffer */
        assert(bufend > dst->head);
        size_t n = MIN(bufend - dst->head, count - nread);
        memcpy(dst->head, u8src + nread, n);
        dst->head += n;
        nread += n;

        /* wrap? */
        if (dst->head == bufend)
            dst->head = dst->buf;
    }

    if (overflow) {
        dst->tail = ringbuf_nextp(dst, dst->head);
        assert(ringbuf_is_full(dst));
    }

    return dst->head;
}
예제 #7
0
size_t
ringbuf_memset(ringbuf_t dst, int c, size_t len)
{
    const uint8_t *bufend = ringbuf_end(dst);
    size_t nwritten = 0;
    size_t count = MIN(len, ringbuf_buffer_size(dst));
    int overflow = count > ringbuf_bytes_free(dst);

    while (nwritten != count) {

        /* don't copy beyond the end of the buffer */
        assert(bufend > dst->head);
        size_t n = MIN(bufend - dst->head, count - nwritten);
        memset(dst->head, c, n);
        dst->head += n;
        nwritten += n;

        /* wrap? */
        if (dst->head == bufend)
            dst->head = dst->buf;
    }

    if (overflow) {
        dst->tail = ringbuf_nextp(dst, dst->head);
        assert(ringbuf_is_full(dst));
    }

    return nwritten;
}
예제 #8
0
/*
 * Given a ring buffer rb and a pointer to a location within its
 * contiguous buffer, return the a pointer to the next logical
 * location in the ring buffer.
 */
static uint8_t *
ringbuf_nextp(ringbuf_t rb, const uint8_t *p)
{
    /*
     * The assert guarantees the expression (++p - rb->buf) is
     * non-negative; therefore, the modulus operation is safe and
     * portable.
     */
    assert((p >= rb->buf) && (p < ringbuf_end(rb)));
    return rb->buf + ((++p - rb->buf) % ringbuf_buffer_size(rb));
}
예제 #9
0
void *
ringbuf_copy(ringbuf_t dst, ringbuf_t src, size_t count)
{
    size_t src_bytes_used = ringbuf_bytes_used(src);
    if (count > src_bytes_used)
        return 0;
    int overflow = count > ringbuf_bytes_free(dst);

    const uint8_t *src_bufend = ringbuf_end(src);
    const uint8_t *dst_bufend = ringbuf_end(dst);
    size_t ncopied = 0;
    while (ncopied != count) {
        assert(src_bufend > src->tail);
        size_t nsrc = MIN(src_bufend - src->tail, count - ncopied);
        assert(dst_bufend > dst->head);
        size_t n = MIN(dst_bufend - dst->head, nsrc);
        memcpy(dst->head, src->tail, n);
        src->tail += n;
        dst->head += n;
        ncopied += n;

        /* wrap ? */
        if (src->tail == src_bufend)
            src->tail = src->buf;
        if (dst->head == dst_bufend)
            dst->head = dst->buf;
    }

    assert(count + ringbuf_bytes_used(src) == src_bytes_used);
    
    if (overflow) {
        dst->tail = ringbuf_nextp(dst, dst->head);
        assert(ringbuf_is_full(dst));
    }

    return dst->head;
}
size_t ringbuf_findchr(const struct ringbuf_t *rb, int c, size_t offset)
{
	const uint8_t *bufend = ringbuf_end(rb);
	size_t bytes_used = ringbuf_bytes_used(rb);
	if (offset >= bytes_used)
		return bytes_used;

	const uint8_t *start = rb ->buf + (((rb->tail - rb->buf) + offset) % ringbuf_buffer_size(rb));
	lwIP_ASSERT0(bufend > start);
	size_t n = LWIP_MIN(bufend - start, bytes_used - offset);
	const uint8_t *found = (const uint8_t *)memchr(start, c, n);
	if (found)
		return offset + (found - start);
	else
		return ringbuf_findchr(rb, c, offset + n);
}
예제 #11
0
ssize_t
ringbuf_write(int fd, ringbuf_t rb, size_t count)
{
    size_t bytes_used = ringbuf_bytes_used(rb);
    if (count > bytes_used)
        return 0;

    const uint8_t *bufend = ringbuf_end(rb);
    assert(bufend > rb->head);
    count = MIN(bufend - rb->tail, count);
    ssize_t n = write(fd, rb->tail, count);
    if (n > 0) {
        assert(rb->tail + n <= bufend);
        rb->tail += n;

        /* wrap? */
        if (rb->tail == bufend)
            rb->tail = rb->buf;

        assert(n + ringbuf_bytes_used(rb) == bytes_used);
    }

    return n;
}
예제 #12
0
static uint8_t* ringbuf_nextp(ringbuf_t rb, const uint8_t* p)
{
    lwIP_ASSERT((p >= rb->buf) && (p < ringbuf_end(rb)));
    return rb->buf + ((++p - rb->buf) % ringbuf_buffer_size(rb));
}