#ifndef UCT_IOV_INL_
#define UCT_IOV_INL_
#include <uct/api/uct.h>
#include <ucs/sys/math.h>
#include <ucs/debug/assert.h>
#include <ucs/sys/iovec.h>
#include <ucs/sys/iovec.inl>
static UCS_F_ALWAYS_INLINE
size_t uct_iov_get_length(const uct_iov_t *iov)
{
return iov->count * iov->length;
}
static UCS_F_ALWAYS_INLINE
void *uct_iov_get_buffer(const uct_iov_t *iov)
{
return iov->buffer;
}
static UCS_F_ALWAYS_INLINE
size_t uct_iov_total_length(const uct_iov_t *iov, size_t iov_cnt)
{
return ucs_iov_total_length(iov, iov_cnt, uct_iov_get_length);
}
static UCS_F_ALWAYS_INLINE
size_t uct_iov_iter_flat_offset(const uct_iov_t *iov, size_t iov_cnt,
const ucs_iov_iter_t *iov_iter)
{
return ucs_iov_iter_flat_offset(iov, iov_cnt, iov_iter,
uct_iov_get_length);
}
static UCS_F_ALWAYS_INLINE
size_t uct_iov_to_iovec(struct iovec *io_vec, size_t *io_vec_cnt_p,
const uct_iov_t *uct_iov, size_t uct_iov_cnt,
size_t max_length, ucs_iov_iter_t *uct_iov_iter_p)
{
return ucs_iov_converter(io_vec, io_vec_cnt_p,
ucs_iovec_set_buffer, ucs_iovec_set_length,
uct_iov, uct_iov_cnt,
uct_iov_get_buffer, uct_iov_get_length,
max_length, uct_iov_iter_p);
}
static UCS_F_ALWAYS_INLINE
size_t uct_iov_to_buffer(const uct_iov_t *iov, size_t iovcnt,
ucs_iov_iter_t *iov_iter, void *buf, size_t copy_limit)
{
size_t offset = iov_iter->buffer_offset;
size_t copied = 0;
size_t limit_reached = 0;
size_t to_copy;
for (; iov_iter->iov_index < iovcnt; ++iov_iter->iov_index) {
to_copy = iov[iov_iter->iov_index].length - offset;
if (copied + to_copy > copy_limit) {
to_copy = copy_limit - copied;
limit_reached = 1;
}
memcpy(UCS_PTR_BYTE_OFFSET(buf, copied),
UCS_PTR_BYTE_OFFSET(iov[iov_iter->iov_index].buffer, offset),
to_copy);
copied += to_copy;
if (limit_reached) {
offset += to_copy;
break;
}
offset = 0;
}
iov_iter->buffer_offset = offset;
return copied;
}
#endif