From dbbdf3f6644ee61a74e364727a630117eb6e20cf Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Thu, 11 Jan 2018 23:47:22 +0100 Subject: [PATCH] sys: introduce iolist --- sys/include/iolist.h | 87 ++++++++++++++++++++++++++++++++++++++++++++ sys/iolist/Makefile | 1 + sys/iolist/iolist.c | 61 +++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 sys/include/iolist.h create mode 100644 sys/iolist/Makefile create mode 100644 sys/iolist/iolist.c diff --git a/sys/include/iolist.h b/sys/include/iolist.h new file mode 100644 index 0000000000..e5d8d753e7 --- /dev/null +++ b/sys/include/iolist.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2018 Kaspar Schleiser + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup sys_util_iolist iolist scatter / gather IO + * @ingroup sys_util + * @brief Provides linked-list scatter / gather IO + * + * @{ + * + * @file + * @brief iolist scatter / gather IO + * + * @author Kaspar Schleiser + */ + +#ifndef IOLIST_H +#define IOLIST_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief iolist forward declaration */ +typedef struct iolist iolist_t; + +/** + * @brief iolist structure definition + */ +struct iolist { + iolist_t *iol_next; /**< ptr to next list entry */ + void *iol_base; /**< ptr to this list entries data */ + size_t iol_len; /**< size of data pointet to by ptr */ +}; + +/** + * @brief Count number of entries in an iolist_t + * + * @param[in] iolist iolist to count + * + * @returns number of entries (zero for NULL parameter) + */ +unsigned iolist_count(const iolist_t *iolist); + +/** + * @brief Sum up number of bytes in iolist + * + * This function returns the summed ip lenght values of all entries in @p + * iolist. + * + * @param[in] iolist iolist to sum up + * + * @returns summed up number of bytes or zero if @p iolist == NULL + */ +size_t iolist_size(const iolist_t *iolist); + +/** @brief struct iovec anonymous declaration */ +struct iovec; + +/** + * @brief Create struct iovec from iolist + * + * This function fills an array of struct iovecs with the contents of @p + * iolist. It will write the number of used array entries into @p count. + * + * The caller *must* ensure that @p iov p points to an array of size >= count! + * + * @param[in] iolist iolist to read from + * @param[out] iov ptr to array of struct iovec that will be filled + * @param[out] count number of elements in @p iolist + * + * @returns iolist_size(iolist) + */ +size_t iolist_to_iovec(const iolist_t *iolist, struct iovec *iov, unsigned *count); + +#ifdef __cplusplus +} +#endif +#endif /* IOLIST_H */ +/** @} */ diff --git a/sys/iolist/Makefile b/sys/iolist/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/sys/iolist/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/sys/iolist/iolist.c b/sys/iolist/iolist.c new file mode 100644 index 0000000000..b64f0139e2 --- /dev/null +++ b/sys/iolist/iolist.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2018 Kaspar Schleiser + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup sys_util + * @{ + * + * @file + * @brief iolist scatter / gather IO + * + * @author Kaspar Schleiser + * @} + */ + +#include + +#include "iolist.h" + +unsigned iolist_count(const iolist_t *iolist) +{ + unsigned count = 0; + while (iolist) { + count++; + iolist = iolist->iol_next; + } + return count; +} + +size_t iolist_size(const iolist_t *iolist) +{ + size_t result = 0; + while (iolist) { + result += iolist->iol_len; + iolist = iolist->iol_next; + } + return result; +} + +size_t iolist_to_iovec(const iolist_t *iolist, struct iovec *iov, unsigned *count) +{ + size_t bytes = 0; + unsigned _count = 0; + + while (iolist) { + iov->iov_base = iolist->iol_base; + iov->iov_len = iolist->iol_len; + bytes += iov->iov_len; + _count++; + iolist = iolist->iol_next; + iov++; + } + + *count = _count; + + return bytes; +}