Welcome to little lamb

Code » limb » commit dd60535

Add siovec_gather0()/siovec_seek_gather0()

author Olivier Brunel
2023-03-17 15:20:59 UTC
committer Olivier Brunel
2023-03-19 07:58:08 UTC
parent 0b9da1c940a85648ca8c06f686008172cb583e63

Add siovec_gather0()/siovec_seek_gather0()

Same as their regular counterpart, but ensuring the data placed in dst
is NUL terminated.

doc/siovec.h.0.md +6 -0
doc/siovec_gather0.3.md +41 -0
doc/siovec_seek_gather.3.md +1 -1
include/limb/siovec.h +18 -12
meta/libs/limb +2 -0
src/siovec_gather0.c +19 -0
src/siovec_seek_gather0.c +16 -0

diff --git a/doc/siovec.h.0.md b/doc/siovec.h.0.md
index f1d3955..4b3e599 100644
--- a/doc/siovec.h.0.md
+++ b/doc/siovec.h.0.md
@@ -33,6 +33,9 @@ The following functions/macros are defined :
 : [siov_gather](3)
 :: Same as [siovec_gather](3) but with destination as first arguments
 
+: [siov_gather0](3)
+:: Same as [siovec_gather0](3)
+
 : [siov_scatter](3)
 :: Same as [siovec_scatter](3)
 
@@ -63,6 +66,9 @@ The following functions/macros are defined :
 : [siov_seek_bytein](3)
 :: Same a [siovec_seek_bytein](3)
 
+: [siovec_gather0](3)
+:: Same as [siovec_gather](3) but ensures the data gathered is NUL terminated
+
 : [siovec_seek_gather](3)
 :: Same as [siovec_gather](3) but from a given offset
 
diff --git a/doc/siovec_gather0.3.md b/doc/siovec_gather0.3.md
new file mode 100644
index 0000000..560d247
--- /dev/null
+++ b/doc/siovec_gather0.3.md
@@ -0,0 +1,41 @@
+% limb manual
+% siovec_gather0(3)
+
+# NAME
+
+siovec\_gather0, siovec\_seek\_gather0 - gather data from struct iovec into a
+byte array
+
+# SYNOPSIS
+
+    #include <limb/siovec.h>
+
+```pre hl
+size_t siovec_gather0(const struct iovec *<em>v</em>, unsigned int <em>n</em>, char *<em>dst</em>, size_t <em>max</em>)
+
+size_t siovec_seek_gather0(const struct iovec *<em>v</em>, unsigned int <em>n</em>, size_t <em>offset</em>,
+                           char *<em>dst</em>, size_t <em>max</em>)
+```
+
+# DESCRIPTION
+
+The `siovec_gather0`() function gathers data scattered across given array `v` of
+`n` *struct iovec* into the byte array pointer to by `s`, up to `max` bytes. It
+will ensure that the data placed into `s` are NUL-terminated, meaning that it
+/ends/ with a NUL byte (not checking whether there were in the middle of it).
+
+If a trailing NUL byte was already present, it does nothing more than
+`siovec_gather`(), else it will add one - possibly overwriting the last
+character gathered if `max` was reached.
+
+The `siovec_seek_gather0`() function is similar to [siovec_seek_gather](3) but
+will similarly ensure the data placed into `s` are NUL terminated.
+
+# RETURN VALUE
+
+These functions return the number of bytes copied into `s` (including the added
+terminating NUL byte, if any).
+
+# SEE ALSO
+
+[siovec_seek](3), [siovec_gather](3)
diff --git a/doc/siovec_seek_gather.3.md b/doc/siovec_seek_gather.3.md
index 066eb27..7d1edc8 100644
--- a/doc/siovec_seek_gather.3.md
+++ b/doc/siovec_seek_gather.3.md
@@ -29,4 +29,4 @@ bytes of data.
 
 # SEE ALSO
 
-[siovec_seek](3), [siovec_gather](3)
+[siovec_seek](3), [siovec_gather](3), [siovec_seek_gather0](3)
diff --git a/include/limb/siovec.h b/include/limb/siovec.h
index 5721a1a..932d726 100644
--- a/include/limb/siovec.h
+++ b/include/limb/siovec.h
@@ -6,8 +6,12 @@
 
 #include <skalibs/siovec.h>
 
+extern size_t siovec_gather0(const struct iovec *v, unsigned int n, char *dst, size_t max);
+
 extern size_t siovec_seek_gather(const struct iovec *v, unsigned int n, size_t offset,
                                  char *dst, size_t max);
+extern size_t siovec_seek_gather0(const struct iovec *v, unsigned int n, size_t offset,
+                                  char *dst, size_t max);
 extern size_t siovec_seek_bytechr(const struct iovec *v, unsigned int n, size_t offset,
                                   char c);
 extern size_t siovec_seek_bytein(const struct iovec *v, unsigned int n, size_t offset,
@@ -16,18 +20,20 @@ extern size_t siovec_seek_bytein(const struct iovec *v, unsigned int n, size_t o
 /* from skalibs */
 extern size_t siovec_search(const struct iovec *v, unsigned int n, const char *str, size_t len);
 
-#define siov_len(v,n)                   siovec_len(v, n)
-#define siov_gather(dst,max,v,n)        siovec_gather(v, n, dst, max)
-#define siov_scatter(v,n,sce,len)       siovec_scatter(v, n, sce, len)
-#define siov_deal(vdst,ndst,vsce,nsce)  siovec_deal(vdst, ndst, vsce, nsce)
-#define siov_seek(v,n,o)                siovec_seek(v, n, o)
-#define siov_trunc(v,n,l)               siovec_trunc(v, n, l)
-#define siov_bytechr(v,n,c)             siovec_bytechr(v, n, c)
-#define siov_bytein(v,n,s,l)            siovec_bytein(v, n, s, l)
-#define siov_search(v,n,s,l)            siovec_search(v, n, s, l)
+#define siov_len(v,n)                       siovec_len(v, n)
+#define siov_gather(dst,max,v,n)            siovec_gather(v, n, dst, max)
+#define siov_gather0(dst,max,v,n)           siovec_gather0(v, n, dst, max)
+#define siov_scatter(v,n,sce,len)           siovec_scatter(v, n, sce, len)
+#define siov_deal(vdst,ndst,vsce,nsce)      siovec_deal(vdst, ndst, vsce, nsce)
+#define siov_seek(v,n,o)                    siovec_seek(v, n, o)
+#define siov_trunc(v,n,l)                   siovec_trunc(v, n, l)
+#define siov_bytechr(v,n,c)                 siovec_bytechr(v, n, c)
+#define siov_bytein(v,n,s,l)                siovec_bytein(v, n, s, l)
+#define siov_search(v,n,s,l)                siovec_search(v, n, s, l)
 
-#define siov_seek_gather(dst,max,v,n,o) siovec_seek_gather(v, n, o, dst, max)
-#define siov_seek_bytechr(v,n,o,c)    siovec_seek_bytechr(v, n, o, c)
-#define siov_seek_bytein(v,n,o,s,l)     siovec_seek_bytein(v, n, o, s, l)
+#define siov_seek_gather(dst,max,v,n,o)     siovec_seek_gather(v, n, o, dst, max)
+#define siov_seek_gather0(dst,max,v,n,o)    siovec_seek_gather0(v, n, o, dst, max)
+#define siov_seek_bytechr(v,n,o,c)          siovec_seek_bytechr(v, n, o, c)
+#define siov_seek_bytein(v,n,o,s,l)         siovec_seek_bytein(v, n, o, s, l)
 
 #endif /* LIMB_SIOVEC_H */
diff --git a/meta/libs/limb b/meta/libs/limb
index 574549e..271cf9d 100644
--- a/meta/libs/limb
+++ b/meta/libs/limb
@@ -35,9 +35,11 @@ obj/uint64_unpack_trim.o
 obj/u64_fmt_generic.o
 obj/u640_fmt_generic.o
 # siovec.h
+obj/siovec_gather0.o
 obj/siovec_seek_bytechr.o
 obj/siovec_seek_bytein.o
 obj/siovec_seek_gather.o
+obj/siovec_seek_gather0.o
 # data-encoding (integers or blobs)
 obj/saencdata.o
 # content-based chunking
diff --git a/src/siovec_gather0.c b/src/siovec_gather0.c
new file mode 100644
index 0000000..4cccdc0
--- /dev/null
+++ b/src/siovec_gather0.c
@@ -0,0 +1,19 @@
+/* This file is part of limb                           https://lila.oss/limb
+ * Copyright (C) 2023 Olivier Brunel                          jjk@jjacky.com */
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include "limb/siovec.h"
+
+size_t
+siovec_gather0(const struct iovec *v, unsigned int n, char *s, size_t max)
+{
+    size_t w = siovec_gather(v, n, s, max);
+
+    if (s[w - 1]) {
+        if (w < max)
+            s[w++] = 0;
+        else
+            s[w] = 0;
+    }
+
+    return w;
+}
diff --git a/src/siovec_seek_gather0.c b/src/siovec_seek_gather0.c
new file mode 100644
index 0000000..69dc707
--- /dev/null
+++ b/src/siovec_seek_gather0.c
@@ -0,0 +1,16 @@
+/* This file is part of limb                           https://lila.oss/limb
+ * Copyright (C) 2023 Olivier Brunel                          jjk@jjacky.com */
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include "limb/siovec.h"
+
+size_t
+siovec_seek_gather0(const struct iovec *v, unsigned int n, size_t offset, char *s, size_t max)
+{
+    struct iovec vv[n];
+
+    for (unsigned int i = 0; i < n; ++i)
+        vv[i] = v[i];
+
+    siovec_seek(vv, n, offset);
+    return siovec_gather0(vv, n, s, max);
+}