Added ring_buffer_user_peek() similar to ring_buffer_peek()

Change-Id: Ife183989e0c031f648feb6a4b03f1a3ffc15503c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9858
Reviewed-by: waddlesplash <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
Jérôme Duval
2025-11-13 14:11:35 +00:00
parent 22f4b0e5f8
commit 5e0c933df0
2 changed files with 50 additions and 24 deletions
+2 -2
View File
@@ -41,8 +41,8 @@ size_t ring_buffer_read(struct ring_buffer *buffer, uint8 *data, ssize_t length)
size_t ring_buffer_write(struct ring_buffer *buffer, const uint8 *data, ssize_t length); size_t ring_buffer_write(struct ring_buffer *buffer, const uint8 *data, ssize_t length);
ssize_t ring_buffer_user_read(struct ring_buffer *buffer, uint8 *data, ssize_t length); ssize_t ring_buffer_user_read(struct ring_buffer *buffer, uint8 *data, ssize_t length);
ssize_t ring_buffer_user_write(struct ring_buffer *buffer, const uint8 *data, ssize_t length); ssize_t ring_buffer_user_write(struct ring_buffer *buffer, const uint8 *data, ssize_t length);
size_t ring_buffer_peek(struct ring_buffer *buffer, size_t offset, void *data, size_t ring_buffer_peek(struct ring_buffer *buffer, size_t offset, void *data, size_t length);
size_t length); ssize_t ring_buffer_user_peek(struct ring_buffer *buffer, size_t offset, void *data, ssize_t length);
int32 ring_buffer_get_vecs(struct ring_buffer *buffer, struct iovec *vecs); int32 ring_buffer_get_vecs(struct ring_buffer *buffer, struct iovec *vecs);
size_t ring_buffer_move(struct ring_buffer *to, ssize_t length, struct ring_buffer *from); size_t ring_buffer_move(struct ring_buffer *to, ssize_t length, struct ring_buffer *from);
+48 -22
View File
@@ -120,6 +120,47 @@ write_to_buffer(struct ring_buffer *buffer, const uint8 *data, ssize_t length,
} }
static ssize_t
buffer_peek(struct ring_buffer* buffer, size_t offset, void* data,
ssize_t length, bool user)
{
size_t available = buffer->in;
if (offset >= available || length == 0)
return 0;
if (offset + length > available)
length = available - offset;
if ((offset += buffer->first) >= (size_t)buffer->size)
offset -= buffer->size;
if (offset + length <= (size_t)buffer->size) {
// simple copy
if (user) {
if (user_memcpy(data, buffer->buffer + offset, length) < B_OK)
return B_BAD_ADDRESS;
} else
memcpy(data, buffer->buffer + offset, length);
} else {
// need to copy both ends
size_t upper = buffer->size - offset;
size_t lower = length - upper;
if (user) {
if (user_memcpy(data, buffer->buffer + offset, upper) < B_OK
|| user_memcpy((uint8*)data + upper, buffer->buffer, lower) < B_OK)
return B_BAD_ADDRESS;
} else {
memcpy(data, buffer->buffer + offset, upper);
memcpy((uint8*)data + upper, buffer->buffer, lower);
}
}
return length;
}
// #pragma mark - // #pragma mark -
@@ -241,30 +282,15 @@ size_t
ring_buffer_peek(struct ring_buffer* buffer, size_t offset, void* data, ring_buffer_peek(struct ring_buffer* buffer, size_t offset, void* data,
size_t length) size_t length)
{ {
size_t available = buffer->in; return buffer_peek(buffer, offset, data, length, false);
}
if (offset >= available || length == 0)
return 0;
if (offset + length > available) ssize_t
length = available - offset; ring_buffer_user_peek(struct ring_buffer* buffer, size_t offset, void* data,
ssize_t length)
if ((offset += buffer->first) >= (size_t)buffer->size) {
offset -= buffer->size; return buffer_peek(buffer, offset, data, length, true);
if (offset + length <= (size_t)buffer->size) {
// simple copy
memcpy(data, buffer->buffer + offset, length);
} else {
// need to copy both ends
size_t upper = buffer->size - offset;
size_t lower = length - upper;
memcpy(data, buffer->buffer + offset, upper);
memcpy((uint8*)data + upper, buffer->buffer, lower);
}
return length;
} }