Welcome to little lamb

Code » limb » commit 338c9a1

buffer.h: Add buffer_getuptoc() to read up to a given byte

author Olivier Brunel
2023-04-14 21:35:39 UTC
committer Olivier Brunel
2023-05-20 18:06:36 UTC
parent 4b680215b4e47b757f83c05d2dca7b7c9e7e4260

buffer.h: Add buffer_getuptoc() to read up to a given byte

Intended to e.g. read user input (up tp \n) from (buffered) stdin.

src/doc/buffer.h.0.md +3 -0
src/doc/buffer.h/buffer_getuptoc.3.md +57 -0
src/liblimb/buffer.h/buffer_getuptoc.c +36 -0
src/liblimb/include/limb/buffer.h +7 -0

diff --git a/src/doc/buffer.h.0.md b/src/doc/buffer.h.0.md
index 4f58672..7b94fdf 100644
--- a/src/doc/buffer.h.0.md
+++ b/src/doc/buffer.h.0.md
@@ -78,6 +78,9 @@ The following macros are defined :
 
 The following functions/macros are defined :
 
+: [buffer_getuptoc](3)
+:: To read data from buffer up to a given character.
+
 : [buffer_putbase32](3)
 :: To write given data encoded in base32.
 
diff --git a/src/doc/buffer.h/buffer_getuptoc.3.md b/src/doc/buffer.h/buffer_getuptoc.3.md
new file mode 100644
index 0000000..f92a293
--- /dev/null
+++ b/src/doc/buffer.h/buffer_getuptoc.3.md
@@ -0,0 +1,57 @@
+% limb manual
+% buffer_getuptoc(3)
+
+# NAME
+
+buffer\_getuptoc - read data from buffer up to a given character
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+int buffer_getuptoc(buffer *<em>buf</em>, char *<em>dst</em>, size_t <em>len</em>, char <em>c</em>, size_t *<em>got</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_getuptoc`() function will read data from the buffer `buf` (filling
+it if needed) and put the data into memory area pointed to by `dst` up to `len`
+bytes, stopping as soon as byte `c` is read.
+
+That is, the buffer will have only been read up to a byte whose value is `c`.
+Meaning in case of success, the last byte read from the buffer will be the last
+byte put into `dst`, i.e. byte `c`.
+
+The value pointed to by `got` must indicate how much data has already been
+filled into `dst` prior (i.e. it will usually be 0), and will be updated as
+needed.
+
+In other words, data will be written into `dst` starting at the offset pointed
+to by `got`.
+
+! HINT:
+! This function can be useful to read user input from *stdin* up to a new line
+! (`\n`).
+
+# RETURN VALUE
+
+The `buffer_getuptoc`() function returns 1 on success. Otherwise it returns 0
+and sets `errno` to indicate the error.
+
+# ERRORS
+
+The `buffer_getuptoc`() function may fail if :
+
+: *EINVAL*
+:: The value pointed to by `got` is larger than `len`
+
+: *ENOBUFS*
+:: There is no more space in `dst` (i.e. the value pointed to by `got` has
+:: reached `len`).
+
+: *EPIPE*
+:: End of file has been reached hence the buffer couldn't be filled (anymore).
+
+It can also fail and set `errno` for any of the errors specified for
+[buffer_fill](3).
diff --git a/src/liblimb/buffer.h/buffer_getuptoc.c b/src/liblimb/buffer.h/buffer_getuptoc.c
new file mode 100644
index 0000000..f5c49c0
--- /dev/null
+++ b/src/liblimb/buffer.h/buffer_getuptoc.c
@@ -0,0 +1,36 @@
+/* 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 <errno.h>
+#include <limb/buffer.h>
+#include <limb/bytestr.h>
+
+int
+buffer_getuptoc(buffer *b, char *dst, size_t len, char c, size_t *got)
+{
+    if (*got > len) return (errno = EINVAL, 0);
+    dst += *got;
+    len -= *got;
+
+    for (;;) {
+        size_t n = buffer_getnofill(b, dst, len);
+        if (n) {
+            size_t e = byte_chr(dst, n, c);
+            if (e++ < n) {
+                *got += e;
+                buffer_unget(b, n - e);
+                return 1;
+            }
+            *got += n;
+            if (*got >= len)
+                return (errno = ENOBUFS, 0);
+            dst += n;
+            len -= n;
+        }
+        ssize_t r = buffer_fill(b);
+        if (r <= 0) {
+            if (!r) errno = EPIPE;
+            return 0;
+        }
+    }
+}
diff --git a/src/liblimb/include/limb/buffer.h b/src/liblimb/include/limb/buffer.h
index 1112c77..eee3eb9 100644
--- a/src/liblimb/include/limb/buffer.h
+++ b/src/liblimb/include/limb/buffer.h
@@ -24,6 +24,8 @@
 #define ESC                 PUTMSG_ESC
 #define HEX(d,l)            PUTMSG_HEX(d,l)
 
+/* Writing */
+
 extern void buffer_putmsg(buffer *b, const char * const *as, unsigned int n);
 extern size_t buffer_putescall(buffer *b, const char *s, size_t len, size_t *pos);
 extern ssize_t buffer_putesc(buffer *b, const char *s, size_t len);
@@ -35,4 +37,9 @@ extern ssize_t buffer_putbase(buffer *b, const char *data, size_t dlen, base_fmt
 #define buffer_putbase32(b,d,l,p)   buffer_putbase(b, d, l, base32, 40, 64, p)
 #define buffer_putbase64(b,d,l,p)   buffer_putbase(b, d, l, base64, 42, 56, p)
 
+
+/* Reading */
+
+extern int buffer_getuptoc(buffer *b, char *dst, size_t len, char c, size_t *got);
+
 #endif /* LIMB_BUFFER_H */