author | Olivier Brunel
<jjk@jjacky.com> 2023-05-03 12:15:40 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-05-20 18:06:39 UTC |
parent | 426857f53ae2f6e6092a0fb9a525bc742514e9aa |
src/doc/buffer.h.0.md | +15 | -0 |
src/doc/buffer.h/buffer_patrim_put.3.md | +57 | -0 |
src/doc/buffer.h/buffer_puthdr.3.md | +48 | -0 |
src/doc/patrim.5.md | +7 | -0 |
src/liblimb/buffer.h/buffer_gethdr.c | +33 | -0 |
src/liblimb/buffer.h/buffer_patrim_get.c | +23 | -0 |
src/liblimb/buffer.h/buffer_patrim_put.c | +21 | -0 |
src/liblimb/buffer.h/buffer_patrim_putv.c | +23 | -0 |
src/liblimb/{fdpatrim.h/fdpatrim_initw.c => buffer.h/buffer_puthdr.c} | +5 | -11 |
src/liblimb/fdpatrim.h/fdpatrim_add.c | +0 | -22 |
src/liblimb/fdpatrim.h/fdpatrim_addv.c | +0 | -25 |
src/liblimb/fdpatrim.h/fdpatrim_get.c | +0 | -25 |
src/liblimb/fdpatrim.h/fdpatrim_initr.c | +0 | -30 |
src/liblimb/include/limb/buffer.h | +8 | -0 |
src/liblimb/include/limb/fdpatrim.h | +0 | -17 |
diff --git a/src/doc/buffer.h.0.md b/src/doc/buffer.h.0.md index 4cc0ee2..b185655 100644 --- a/src/doc/buffer.h.0.md +++ b/src/doc/buffer.h.0.md @@ -41,9 +41,21 @@ The following macros are defined : The following functions/macros are defined : +: [buffer_gethdr](3) +:: To read a file header of 32big big-endian magic & pack-trimmed version. + : [buffer_getuptoc](3) :: To read data from buffer up to a given character. +: [buffer_patrim_get](3) +:: To read [patrim](5)-encoded data. + +: [buffer_patrim_put](3) +:: To write given data in [patrim](5)-encoded format. + +: [buffer_patrim_putv](3) +:: Similar to [buffer_patrim_put](3) put using *struct iovec* for actual data. + : [buffer_putbase32](3) :: To write given data encoded in base32. @@ -60,6 +72,9 @@ The following functions/macros are defined : : [buffer_putescs](3) :: Similar but for a NUL-terminated string. +: [buffer_puthdr](3) +:: To write a file header of 32bit big-endian magic & pack-trimmed version. + : [buffer_puthex](3) :: To write given data as hexadecimal dump. diff --git a/src/doc/buffer.h/buffer_patrim_put.3.md b/src/doc/buffer.h/buffer_patrim_put.3.md new file mode 100644 index 0000000..5ca567b --- /dev/null +++ b/src/doc/buffer.h/buffer_patrim_put.3.md @@ -0,0 +1,57 @@ +% limb manual +% buffer_patrim_put(3) + +# NAME + +buffer\_patrim\_put, buffer\_patrim\_putv, buffer\_patrim\_get - write/read data +in PATRIM format + +# SYNOPSIS + + #include <limb/buffer.h> + +```pre hl +ssize_t buffer_patrim_put(buffer *<em>buf</em>, u64 <em>id</em>, u64 <em>u</em>, const char *<em>data</em>) +ssize_t buffer_patrim_putv(buffer *<em>buf</em>, u64 <em>id</em>, const struct iovec <em>v</em>[], unsigned int <em>n</em>) +int buffer_patrim_get(buffer *<em>buf</em>, u64 *<em>id</em>, u64 *<em>u</em>) +``` + +# DESCRIPTION + +The `buffer_patrim_put`() function writes into the buffer `buf` the data for the +given `id` and its associated value or length, `u`, encoded in [patrim](5) +format. + +So `u` must be either the value for an integer, or the length of the byte array +pointed by `data` for a blob. + +The `buffer_patrim_putv`() function is similar, but only works for `id` +representing a blob, whose data must be pointed by the array `v` of length `n`. + +The `buffer_patrim_get`() function reads [patrim](5)-encoded data from the +buffer `buf`, placing the ID in the value pointed by `id` and its associated +value or length, depending whether the ID represents an integer or a blob, in +the value pointed by `u`. + +In case of a blob, the actual content is not read, it is up to the caller to +get as many bytes from `buf` as the value placed into `u`. + +# RETURN VALUE + +The `buffer_patrim_put`() and `buffer_patrim_putv`() functions return the number +of bytes written on success. Otherwise they return -1 and set `errno` to +indicate the error. + +The `buffer_patrim_get`() function returns 1 on success, 0 on failure. + +# ERRORS + +The `buffer_patrim_put`() and `buffer_patrim_putv`() functions may fail and set +`errno` for any of the errors specified for [buffer_putv](3). + +The `buffer_patrim_get`() function may fail if : + +: *EPIPE* +:: Not enough data could be read from the buffer before reaching end-of-file. + +It may also fail for any of the error specified for [buffer_fill](3). diff --git a/src/doc/buffer.h/buffer_puthdr.3.md b/src/doc/buffer.h/buffer_puthdr.3.md new file mode 100644 index 0000000..6cd8f31 --- /dev/null +++ b/src/doc/buffer.h/buffer_puthdr.3.md @@ -0,0 +1,48 @@ +% limb manual +% buffer_puthdr(3) + +# NAME + +buffer\_puthdr, buffer\_gethdr - write/read file header + +# SYNOPSIS + + #include <limb/buffer.h> + +```pre hl +ssize_t buffer_puthdr(buffer *<em>buf</em>, u32 <em>magic</em>, u64 <em>ver</em>) +int buffer_gethdr(buffer *<em>buf</em>, u32 *<em>magic</em>, u64 *<em>ver</em>) +``` + +# DESCRIPTION + +The `buffer_puthdr`() function writes into the buffer `buf` the magic `magic` as +a 32bit unsigned integer in big-endian followed by the unsigned integer `ver` in +pack-trimmed form, as described in [u64_pack_trim](3). + +Such a combinaison is intended to be used as a file header, used notably for +files containing [patrim](5)-encoded data. + +The `buffer_get_hdr`() function reads such an header and places the 32bit magic +number as the value pointed by `magic`, and the version number as the value +pointer by `ver`. + +# RETURN VALUE + +The `buffer_puthdr`() function returns the number of bytes written into the +buffer on success. Otherwise, it returns -1. + +The `buffer_gethdr`() function returns 1 on success, and 0 on failure. + +# ERRORS + +The `buffer_puthdr`() function may fail and set `errno` for any of the errors +specified for [buffer_putv](3). + +The `buffer_gethdr`() function may fail if : + +: *EPIPE* +:: Not enough data could be read from the buffer before reaching end-of-file. + +It may also fail for any of the error specified for [buffer_get](3) or +[buffer_fill](3). diff --git a/src/doc/patrim.5.md b/src/doc/patrim.5.md index 8eac902..066c33c 100644 --- a/src/doc/patrim.5.md +++ b/src/doc/patrim.5.md @@ -28,6 +28,10 @@ The IDs are unsigned numbers to identify their associated value, with the least significant bit having a special meaning : if set, it represents a blob, otherwise an (unsigned) integer. +! HINT: +! Helpers functions are available, either directly (e.g. [patrim_put](3)) or +! when using a buffer (e.g. [buffer_patrim_put](3)). + That is all. # FILE FORMATS @@ -39,3 +43,6 @@ header as such : The magic number should have certain bits set to indicate it is PATRIM encoded, specifically : `(magic & 0xf0f0f000) = 0xa0e0f000` - A version number, pack-trimmed. + +Helpers functions [buffer_puthdr](3) and [buffer_gethdr](3) are available to +write and read such headers, respectively. diff --git a/src/liblimb/buffer.h/buffer_gethdr.c b/src/liblimb/buffer.h/buffer_gethdr.c new file mode 100644 index 0000000..a942b66 --- /dev/null +++ b/src/liblimb/buffer.h/buffer_gethdr.c @@ -0,0 +1,33 @@ +/* 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/siovec.h> +#include <limb/u32.h> +#include <limb/u64.h> + +int +buffer_gethdr(buffer *b, u32 *magic, u64 *ver) +{ + int r; + + /* magic number */ + r = buffer_get(b, (char *) magic, sizeof(*magic)); + if (r <= 0) return (!r) ? (errno = EPIPE, 0) : 0; + u32p_be(magic); + + struct iovec v[2]; + char buf[9]; + + /* peek into the buffer to unpack the version number */ + do { + buffer_rpeek(b, v); + r = u64_unpack_trim(ver, buf, siov_gather(buf, sizeof(buf), v, 2)); + } while (r < 0 && (r = buffer_fill(b)) > 0); + if (r <= 0) return (!r) ? (errno = EPIPE, 0) : 0; + /* we've only peeked into the buffer, actually consume read data */ + buffer_rseek(b, r); + + return 1; +} diff --git a/src/liblimb/buffer.h/buffer_patrim_get.c b/src/liblimb/buffer.h/buffer_patrim_get.c new file mode 100644 index 0000000..b977f93 --- /dev/null +++ b/src/liblimb/buffer.h/buffer_patrim_get.c @@ -0,0 +1,23 @@ +/* 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/patrim.h> + +int +buffer_patrim_get(buffer *b, u64 *id, u64 *u) +{ + struct iovec v[2]; + char buf[18]; + int r; + + do { + buffer_rpeek(b, v); + r = patrim_get(id, u, buf, siov_gather(buf, sizeof(buf), v, 2), 0); + } while (r < 0 && (r = buffer_fill(b)) > 0); + if (r <= 0) return (!r) ? (errno = EPIPE, 0) : 0; + + buffer_rseek(b, r); + return 1; +} diff --git a/src/liblimb/buffer.h/buffer_patrim_put.c b/src/liblimb/buffer.h/buffer_patrim_put.c new file mode 100644 index 0000000..0d4d2b7 --- /dev/null +++ b/src/liblimb/buffer.h/buffer_patrim_put.c @@ -0,0 +1,21 @@ +/* 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/buffer.h> +#include <limb/patrim.h> +#include <limb/siovec.h> + +ssize_t +buffer_patrim_put(buffer *b, u64 id, u64 u, const char *data) +{ + struct iovec v[2]; + char buf[18]; + + v[0].iov_base = buf; + v[0].iov_len = patrim_put(buf, sizeof(buf), 0, id, u); + + v[1].iov_base = (char *) data; + v[1].iov_len = (patrim_isblob(id)) ? u : 0; + + return buffer_putv(b, v, 2); +} diff --git a/src/liblimb/buffer.h/buffer_patrim_putv.c b/src/liblimb/buffer.h/buffer_patrim_putv.c new file mode 100644 index 0000000..7dae17d --- /dev/null +++ b/src/liblimb/buffer.h/buffer_patrim_putv.c @@ -0,0 +1,23 @@ +/* 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 <string.h> +#include <limb/buffer.h> +#include <limb/patrim.h> +#include <limb/siovec.h> + +ssize_t +buffer_patrim_putv(buffer *b, u64 id, const struct iovec v[], unsigned int n) +{ + if (!patrim_isblob(id)) return (errno = EINVAL, -1); + + char buf[18]; + struct iovec vv[1 + n]; + + vv[0].iov_base = buf; + vv[0].iov_len = patrim_put(buf, sizeof(buf), 0, id, siov_len(v, n)); + memcpy(vv + 1, v, sizeof(*v) * n); + + return buffer_putv(b, vv, 1 + n); +} diff --git a/src/liblimb/fdpatrim.h/fdpatrim_initw.c b/src/liblimb/buffer.h/buffer_puthdr.c similarity index 56% rename from src/liblimb/fdpatrim.h/fdpatrim_initw.c rename to src/liblimb/buffer.h/buffer_puthdr.c index 9155498..f69aa9b 100644 --- a/src/liblimb/fdpatrim.h/fdpatrim_initw.c +++ b/src/liblimb/buffer.h/buffer_puthdr.c @@ -1,28 +1,22 @@ /* 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 <skalibs/allreadwrite.h> -#include <limb/fdpatrim.h> -#include <limb/siovec.h> +#include <limb/buffer.h> #include <limb/u32.h> #include <limb/u64.h> -int -fdpatrim_initw(int fd, u32 magic, u64 ver) +ssize_t +buffer_puthdr(buffer *b, u32 magic, u64 ver) { char buf[9]; struct iovec v[2]; - if (magic & 0xf0f0f000 != 0xa0e0f000) - return (errno = EINVAL, -1); - u32p_be(&magic); v[0].iov_base = &magic; - v[0].iov_len = sizeof(u32); + v[0].iov_len = sizeof(magic); v[1].iov_base = buf; v[1].iov_len = u64_pack_trim(buf, sizeof(buf), ver); - return fd_writev(fd, v, 2) == (ssize_t) siov_len(v, 2); + return buffer_putv(b, v, 2); } diff --git a/src/liblimb/fdpatrim.h/fdpatrim_add.c b/src/liblimb/fdpatrim.h/fdpatrim_add.c deleted file mode 100644 index 6bde27f..0000000 --- a/src/liblimb/fdpatrim.h/fdpatrim_add.c +++ /dev/null @@ -1,22 +0,0 @@ -/* 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 <skalibs/allreadwrite.h> -#include <limb/fdpatrim.h> -#include <limb/patrim.h> - -int -fdpatrim_add(int fd, u64 id, u64 u, const char *data) -{ - char buf[18]; - int n; - - n = patrim_put(buf, sizeof(buf), 0, id, u); - if (fd_write(fd, buf, n) != n) - return 0; - - if (patrim_isblob(id) && fd_write(fd, data, (size_t) u) != (ssize_t) u) - return 0; - - return 1; -} diff --git a/src/liblimb/fdpatrim.h/fdpatrim_addv.c b/src/liblimb/fdpatrim.h/fdpatrim_addv.c deleted file mode 100644 index fab71f1..0000000 --- a/src/liblimb/fdpatrim.h/fdpatrim_addv.c +++ /dev/null @@ -1,25 +0,0 @@ -/* 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 <skalibs/allreadwrite.h> -#include <limb/fdpatrim.h> -#include <limb/patrim.h> -#include <limb/siovec.h> - -int -fdpatrim_addv(int fd, u64 id, const struct iovec v[], unsigned int n) -{ - char buf[18]; - u64 l; - int r; - - if (!patrim_isblob(id)) return (errno = EINVAL, 0); - - l = siov_len(v, n); - r = patrim_put(buf, sizeof(buf), 0, id, l); - if (fd_write(fd, buf, r) != r || fd_writev(fd, v, n) != (ssize_t) l) - return 0; - - return 1; -} diff --git a/src/liblimb/fdpatrim.h/fdpatrim_get.c b/src/liblimb/fdpatrim.h/fdpatrim_get.c deleted file mode 100644 index 7622dc4..0000000 --- a/src/liblimb/fdpatrim.h/fdpatrim_get.c +++ /dev/null @@ -1,25 +0,0 @@ -/* 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 <skalibs/allreadwrite.h> -#include <limb/fdpatrim.h> -#include <limb/u64.h> - -int -fdpatrim_get(int fd, u64 *id, u64 *u) -{ - char buf[9]; - int r = 0; - - for (;;) { - if (fd_read(fd, buf + r++, 1) != 1) - return 0; - if (u64_unpack_trim(id, buf, r) == r) { - if (id == u) break; - id = u; - r = 0; - } - } - - return 1; -} diff --git a/src/liblimb/fdpatrim.h/fdpatrim_initr.c b/src/liblimb/fdpatrim.h/fdpatrim_initr.c deleted file mode 100644 index aaac438..0000000 --- a/src/liblimb/fdpatrim.h/fdpatrim_initr.c +++ /dev/null @@ -1,30 +0,0 @@ -/* 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 <skalibs/allreadwrite.h> -#include <limb/fdpatrim.h> -#include <limb/u32.h> -#include <limb/u64.h> - -int -fdpatrim_initr(int fd, u32 *magic, u64 *ver) -{ - if (fd_read(fd, (char *) magic, sizeof(u32)) != sizeof(u32)) - return 0; - u32p_be(magic); - - if (*magic & 0xf0f0f000 != 0xa0e0f000) - return (errno = EINVAL, 0); - - char buf[9]; - int r = 0; - for (;;) { - if (fd_read(fd, buf + r++, 1) != 1) - return 0; - if (u64_unpack_trim(ver, buf, r) == r) - break; - } - - return 1; -} diff --git a/src/liblimb/include/limb/buffer.h b/src/liblimb/include/limb/buffer.h index 957d0f0..a6a3be6 100644 --- a/src/liblimb/include/limb/buffer.h +++ b/src/liblimb/include/limb/buffer.h @@ -6,6 +6,8 @@ #include <skalibs/buffer.h> #include <limb/hex.h> /* HEX_* */ +#include <limb/int.h> +#include <limb/siovec.h> /* special values usable as strings for buffer_putmsg() */ #define PUTMSG_FLUSH ((void *) 1) /* flush buffer */ @@ -49,9 +51,15 @@ 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) +extern ssize_t buffer_puthdr(buffer *b, u32 magic, u64 ver); +extern ssize_t buffer_patrim_put(buffer *b, u64 id, u64 u, const char *data); +extern ssize_t buffer_patrim_putv(buffer *b, u64 id, const struct iovec v[], unsigned int n); /* Reading */ extern int buffer_getuptoc(buffer *b, char *dst, size_t len, char c, size_t *got); +extern int buffer_gethdr(buffer *b, u32 *magic, u64 *ver); +extern int buffer_patrim_get(buffer *b, u64 *id, u64 *u); + #endif /* LIMB_BUFFER_H */ diff --git a/src/liblimb/include/limb/fdpatrim.h b/src/liblimb/include/limb/fdpatrim.h deleted file mode 100644 index 89fba54..0000000 --- a/src/liblimb/include/limb/fdpatrim.h +++ /dev/null @@ -1,17 +0,0 @@ -/* 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 */ -#ifndef LIMB_FDPATRIM_H -#define LIMB_FDPATRIM_H - -#include <limb/int.h> -#include <limb/siovec.h> - -extern int fdpatrim_initw(int fd, u32 magic, u64 ver); -extern int fdpatrim_add(int fd, u64 id, u64 u, const char *data); -extern int fdpatrim_addv(int fd, u64 id, const struct iovec v[], unsigned int n); - -extern int fdpatrim_initr(int fd, u32 *magic, u64 *ver); -extern int fdpatrim_get(int fd, u64 *id, u64 *u); - -#endif /* LIMB_FDPATRIM_H */