From 501ca7e34d24a375aff5bf25bc0c8bf94acd7239 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 2 May 2022 22:48:21 +0200 Subject: [PATCH] sys/iolist: introduce iolist_to_buffer() --- sys/include/iolist.h | 12 ++++++++++++ sys/iolist/iolist.c | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/sys/include/iolist.h b/sys/include/iolist.h index ff6c27f23d..a5617b4e1f 100644 --- a/sys/include/iolist.h +++ b/sys/include/iolist.h @@ -82,6 +82,18 @@ struct iovec; */ size_t iolist_to_iovec(const iolist_t *iolist, struct iovec *iov, unsigned *count); +/** + * @brief Copies the bytes of the iolist to a buffer + * + * @param[in] iolist iolist to read from + * @param[out] dst Destination buffer + * @param[in] len Size of the destination buffer + * + * @returns iolist_size(iolist) on success + * -ENOBUFS if the buffer is too small + */ +ssize_t iolist_to_buffer(const iolist_t *iolist, void *dst, size_t len); + #ifdef __cplusplus } #endif diff --git a/sys/iolist/iolist.c b/sys/iolist/iolist.c index b10e4e982c..cbc9b32b7b 100644 --- a/sys/iolist/iolist.c +++ b/sys/iolist/iolist.c @@ -18,6 +18,9 @@ * @} */ +#include +#include +#include #include #include "iolist.h" @@ -60,3 +63,20 @@ size_t iolist_to_iovec(const iolist_t *iolist, struct iovec *iov, unsigned *coun return bytes; } + +ssize_t iolist_to_buffer(const iolist_t *iolist, void *buf, size_t len) +{ + char *dst = buf; + + while (iolist) { + if (iolist->iol_len > len) { + return -ENOBUFS; + } + memcpy(dst, iolist->iol_base, iolist->iol_len); + len -= iolist->iol_len; + dst += iolist->iol_len; + iolist = iolist->iol_next; + } + + return (uintptr_t)dst - (uintptr_t)buf; +}