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:
@@ -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);
|
||||
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);
|
||||
size_t ring_buffer_peek(struct ring_buffer *buffer, size_t offset, void *data,
|
||||
size_t length);
|
||||
size_t ring_buffer_peek(struct ring_buffer *buffer, size_t offset, void *data, 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);
|
||||
size_t ring_buffer_move(struct ring_buffer *to, ssize_t length, struct ring_buffer *from);
|
||||
|
||||
|
||||
@@ -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 -
|
||||
|
||||
|
||||
@@ -241,30 +282,15 @@ size_t
|
||||
ring_buffer_peek(struct ring_buffer* buffer, size_t offset, void* data,
|
||||
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)
|
||||
length = available - offset;
|
||||
|
||||
if ((offset += buffer->first) >= (size_t)buffer->size)
|
||||
offset -= buffer->size;
|
||||
|
||||
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;
|
||||
ssize_t
|
||||
ring_buffer_user_peek(struct ring_buffer* buffer, size_t offset, void* data,
|
||||
ssize_t length)
|
||||
{
|
||||
return buffer_peek(buffer, offset, data, length, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user