Files
rosetta/lib/libxpc/buffer.c

143 lines
2.3 KiB
C

#include <mango/status.h>
#include <string.h>
#include <xpc/buffer.h>
#include <xpc/msg.h>
kern_status_t xpc_buffer_read(
const xpc_buffer_t *buf,
size_t offset,
void *out,
size_t max,
size_t *nr_read)
{
if ((buf->buf_flags & (XPC_BUFFER_F_IN | XPC_BUFFER_F_REMOTE))
!= (XPC_BUFFER_F_IN | XPC_BUFFER_F_REMOTE)) {
return KERN_BAD_STATE;
}
if (offset >= buf->buf_len) {
if (nr_read) {
*nr_read = 0;
}
return KERN_OK;
}
size_t to_read = max;
if (offset + to_read > buf->buf_len) {
to_read = buf->buf_len - offset;
}
kern_status_t status = xpc_msg_read(
buf->buf_origin,
buf->buf_offset + offset,
out,
to_read,
nr_read);
if (status != KERN_OK) {
return status;
}
return KERN_OK;
}
kern_status_t xpc_buffer_write(
xpc_buffer_t *buf,
size_t offset,
const void *in,
size_t len,
size_t *nr_written)
{
if (!(buf->buf_flags & XPC_BUFFER_F_OUT)) {
return KERN_BAD_STATE;
}
if (offset >= buf->buf_max) {
if (nr_written) {
*nr_written = 0;
}
return KERN_OK;
}
size_t to_write = len;
if (offset + to_write > buf->buf_max) {
to_write = buf->buf_max - offset;
}
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
memcpy(buf->buf_ptr, in, to_write);
*nr_written = to_write;
return KERN_OK;
}
return xpc_msg_write(
buf->buf_origin,
buf->buf_offset + offset,
in,
to_write,
nr_written);
}
xpc_status_t xpc_buffer_readv(
const xpc_buffer_t *buf,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read)
{
if (!(buf->buf_flags & XPC_BUFFER_F_IN)) {
return KERN_BAD_STATE;
}
/* TODO limit to buffer bounds */
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
/* TODO */
return KERN_UNIMPLEMENTED;
}
return xpc_msg_readv(
buf->buf_origin,
buf->buf_offset + offset,
iov,
nr_iov,
nr_read);
}
xpc_status_t xpc_buffer_writev(
xpc_buffer_t *buf,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written)
{
if (!(buf->buf_flags & XPC_BUFFER_F_OUT)) {
return KERN_BAD_STATE;
}
/* TODO limit to buffer bounds */
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
/* TODO */
return KERN_UNIMPLEMENTED;
}
return xpc_msg_writev(
buf->buf_origin,
buf->buf_offset + offset,
iov,
nr_iov,
nr_written);
}
xpc_status_t xpc_buffer_length(const xpc_buffer_t *s)
{
return s->buf_len;
}
xpc_status_t xpc_buffer_capacity(const xpc_buffer_t *s)
{
return s->buf_max;
}