From dbbdf3f6644ee61a74e364727a630117eb6e20cf Mon Sep 17 00:00:00 2001
From: Kaspar Schleiser <kaspar@schleiser.de>
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 <kaspar@schleiser.de>
+ *
+ * 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 <kaspar@schleiser.de>
+ */
+
+#ifndef IOLIST_H
+#define IOLIST_H
+
+#include <unistd.h>
+
+#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 <kaspar@schleiser.de>
+ *
+ * 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 <kaspar@schleiser.de>
+ * @}
+ */
+
+#include <sys/uio.h>
+
+#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;
+}
-- 
GitLab