author | Olivier Brunel
<jjk@jjacky.com> 2023-04-14 21:35:39 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-05-20 18:06:36 UTC |
parent | 4b680215b4e47b757f83c05d2dca7b7c9e7e4260 |
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 */