+// Copy data from the buffer without removing it.
+static ssize_t buffer_call(struct utcp_connection *c, struct buffer *buf, size_t offset, size_t len) {
+ if(!c->recv) {
+ return 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 = c->recv(c, buf->data + realoffset, buf->size - realoffset);
+
+ if(rx1 < buf->size - realoffset) {
+ return rx1;
+ }
+
+ // The channel might have been closed by the previous callback
+ if(!c->recv) {
+ return len;
+ }
+
+ ssize_t rx2 = c->recv(c, buf->data, len - (buf->size - realoffset));
+
+ if(rx2 < 0) {
+ return rx2;
+ } else {
+ return rx1 + rx2;
+ }
+ } else {
+ return c->recv(c, buf->data + realoffset, len);
+ }
+}
+