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; }
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; }
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; }
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; }
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; }
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; }
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; }
/* * 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)); }
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); }
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; }
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)); }