+// Copy data from the buffer without removing it.
+static ssize_t buffer_call(struct buffer *buf, utcp_recv_t cb, void *arg, size_t offset, size_t len) {
+ // Ensure we don't copy more than is actually stored in the buffer
+ if(offset >= buf->used) {
+ return 0;
+ }
+
+ if(buf->used - offset < len) {
+ len = buf->used - offset;
+ }
+
+ uint32_t realoffset = buf->offset + offset;
+
+ if(buf->size - buf->offset < offset) {
+ // The offset wrapped
+ realoffset -= buf->size;
+ }
+
+ if(buf->size - realoffset < len) {
+ // The data is wrapped
+ ssize_t rx1 = cb(arg, buf->data + realoffset, buf->size - realoffset);
+
+ if(rx1 < buf->size - realoffset) {
+ return rx1;
+ }
+
+ ssize_t rx2 = cb(arg, buf->data, len - (buf->size - realoffset));
+
+ if(rx2 < 0) {
+ return rx2;
+ } else {
+ return rx1 + rx2;
+ }
+ } else {
+ return cb(arg, buf->data + realoffset, len);
+ }
+}
+