author | Olivier Brunel
<jjk@jjacky.com> 2023-04-30 13:52:14 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-05-20 18:06:39 UTC |
parent | 8c6f6b94532cd641ae826d264e88476f256e1005 |
src/doc/patrim.5.md | +41 | -0 |
src/doc/patrim.h.0.md | +30 | -0 |
src/doc/patrim.h/patrim_put.3.md | +50 | -0 |
src/liblimb/include/limb/patrim.h | +16 | -0 |
src/liblimb/patrim.h/patrim_get.c | +20 | -0 |
src/liblimb/patrim.h/patrim_put.c | +20 | -0 |
diff --git a/src/doc/patrim.5.md b/src/doc/patrim.5.md new file mode 100644 index 0000000..8eac902 --- /dev/null +++ b/src/doc/patrim.5.md @@ -0,0 +1,41 @@ +% limb manual +% patrim(5) + +# NAME + +PATRIM - the pack-trimmed format + +# DESCRIPTION + +The PATRIM format is a simple format that allows to store data in binary form, +where every data is identified by an ID, that represents either an unsigned +integer or a blob/byte array. + +Data are stored very simply : first the ID, then either the value for an +integer, or the data length for a blob, in which case said data must immediately +follow. + +IDs and values/lengths are stored using the "pack trimmed" algorithm, as +described in [u64_pack_trim](3). Meaning the value is stored in little endian +mode, but only the low 7 bits are used for the value, the most significant bit +being a flag which, when set, indicates that another byte must be read and +processed. + +Any 64bit number can be written that way, packed into from 1 to 9 bytes, +depending on the actual value. + +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. + +That is all. + +# FILE FORMATS + +As a rule, any file whose content is encoded in PATRIM should first feature an +header as such : + +- A big-endian encoded 32bit magic number, to identify the specific file format. + The magic number should have certain bits set to indicate it is PATRIM + encoded, specifically : `(magic & 0xf0f0f000) = 0xa0e0f000` +- A version number, pack-trimmed. diff --git a/src/doc/patrim.h.0.md b/src/doc/patrim.h.0.md new file mode 100644 index 0000000..0e7bce8 --- /dev/null +++ b/src/doc/patrim.h.0.md @@ -0,0 +1,30 @@ +% limb manual +% patrim.h(0) + +# NAME + +patrim.h - encode/decode data in PATRIM format + +# SYNOPSIS + + #include <limb/patrim.h> + +# DESCRIPTION + +The header defines functions used to encode/decode data in [patrim](5) format. + +## Functions + +The following functions/macros are defined : + +: [patrim_isblob](3) +:: Returns whether the given ID is that of a blob or not. + +: [patrim_isint](3) +:: Returns whether the given ID is that of an integer or not. + +: [patrim_put](3) +:: To encode data in [patrim](5) format. + +: [patrim_get](3) +:: To decode data in [patrim](5) format. diff --git a/src/doc/patrim.h/patrim_put.3.md b/src/doc/patrim.h/patrim_put.3.md new file mode 100644 index 0000000..964a262 --- /dev/null +++ b/src/doc/patrim.h/patrim_put.3.md @@ -0,0 +1,50 @@ +% limb manual +% patrim_put(3) + +# NAME + +patrim\_put, patrim\_get, patrim\isblob, patrim\isint - encode/decode data in +PATRIM format + +# SYNOPSIS + + #include <limb/patrim.h> + +```pre hl +int patrim_put(char *<em>dst</em>, size_t <em>dlen</em>, size_t <em>offset</em>, u64 <em>id</em>, u64 <em>u</em>) +int patrim_get(u64 *<em>id</em>, u64 *<em>u</em>, const char *<em>data</em>, size_t <em>dlen</em>, size_t <em>offset</em>) + +int patrim_isblob(u64 <em>id</em>) +int patrim_isint(u64 <em>id</em>) +``` + +# DESCRIPTION + +The `patrim_put`() function will encode into the memory pointed by `dst` of +length `dlen`, starting at byte `offset`, the data for the given `id` and its +associated value or length, `u`. + +So `u` must be either the value if `id` represents an integer, or the length of +the blob if `id` represents a blob. The actual data/blob content should +obviously be added afterwards. + +The `patrim_get`() function will read the memory pointed by `data`, starting at +byte `offset` and not going past `dlen` bytes, decoding PATRIM-encoded data and +placing the ID in the memory pointed by `id` and either the value of data +length, depending whether the ID of that of an integer or a blob respectively, +into the memory pointed by `u`. + +The `patrim_isblob`() macro returns 1 if the `id` if that of a blob, zero +otherwise. + +The `patrim_isint`() macro returns 1 if the `id` if that of an integer, zero +otherwise. + +# RETURN VALUE + +On success the `patrim_put`() and `patrim_get`() functions return the number of +bytes written into `dst` or read from `data`, respectively. Otherwise - meaning +not enough bytes could be written or read - they return -1. + +The `patrim_isblob`() and `patrim_isint`() macros return 1 id `id` represents a +blob or an integer, respectively, otherwise they return 0. diff --git a/src/liblimb/include/limb/patrim.h b/src/liblimb/include/limb/patrim.h new file mode 100644 index 0000000..c13cc2a --- /dev/null +++ b/src/liblimb/include/limb/patrim.h @@ -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 */ +#ifndef LIMB_PATRIM_H +#define LIMB_PATRIM_H + +#include <sys/types.h> +#include <limb/int.h> + +#define patrim_isblob(id) (id & 1) +#define patrim_isint(id) !patrim_isblob(id) + +extern int patrim_put(char *dst, size_t dlen, size_t offset, u64 id, u64 u); +extern int patrim_get(u64 *id, u64 *u, const char *data, size_t dlen, size_t offset); + +#endif /* LIMB_PATRIM_H */ diff --git a/src/liblimb/patrim.h/patrim_get.c b/src/liblimb/patrim.h/patrim_get.c new file mode 100644 index 0000000..4cc1175 --- /dev/null +++ b/src/liblimb/patrim.h/patrim_get.c @@ -0,0 +1,20 @@ +/* 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/patrim.h> +#include <limb/u64.h> + +int +patrim_get(u64 *id, u64 *u, const char *data, size_t dlen, size_t offset) +{ + int r, n; + + if (offset >= dlen) return -1; + r = u64_unpack_trim(id, data + offset, dlen - offset); + if (r < 0) return -1; + + n = u64_unpack_trim(u, data + offset + r, dlen - offset - r); + if (n < 0) return -1; + + return r + n; +} diff --git a/src/liblimb/patrim.h/patrim_put.c b/src/liblimb/patrim.h/patrim_put.c new file mode 100644 index 0000000..d0f24e7 --- /dev/null +++ b/src/liblimb/patrim.h/patrim_put.c @@ -0,0 +1,20 @@ +/* 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/patrim.h> +#include <limb/u64.h> + +int +patrim_put(char *dst, size_t dlen, size_t offset, u64 id, u64 u) +{ + int r, n; + + if (offset >= dlen) return -1; + r = u64_pack_trim(dst + offset, dlen - offset, id); + if (r < 0) return -1; + + n = u64_pack_trim(dst + offset + r, dlen - offset - r, u); + if (n < 0) return -1; + + return r + n; +}