author | Olivier Brunel
<jjk@jjacky.com> 2023-02-17 09:51:06 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-02-20 09:02:20 UTC |
parent | b379f2b6d9729fd8a2f294174ec69caee27fa49f |
doc/encdata.3.md | +40 | -0 |
include/limb/encdata.h | +9 | -0 |
meta/libs/limb | +2 | -0 |
src/encdata.c | +29 | -0 |
diff --git a/doc/encdata.3.md b/doc/encdata.3.md new file mode 100644 index 0000000..0f0886a --- /dev/null +++ b/doc/encdata.3.md @@ -0,0 +1,40 @@ +% limb manual +% encdata(3) + +# NAME + +encdata - encode data (integer (u64) or blob (byte array)) into stralloc + +# SYNOPSIS + + #include <limb/encdata.h> + +```pre hl +int encdata(const u16 <em>id</em>, const void *<em>val</em>, const size_t <em>size</em>, + stralloc *<em>sa</em>) +``` + +# DESCRIPTION + +The `encdata`() function will encode the specified `val` into the given stralloc +`sa` as a byte array that can be stored e.g. in a file. + +First the given `id` is stored in little endian. Its most significant bit +determines what kind of data is pointed to by `val` : + +- If set, `val` must point to a blob/byte array of length `size` that will be + stored as-is. +- If unset, `val` must point to an u64 + +## Encoding details + +When encoding a blob/byte array, first its `size` will be stored using +[`u64_pack_trim`](3) then the blob stored as-is. + +When encoding an integer (u64), it will be stored via [`u64_pack_trim`](3) + + +# RETURN VALUE + +`encdata`() return 1 on success and 0 on failure, i.e. failure to allocate +memory within the given `sa` diff --git a/include/limb/encdata.h b/include/limb/encdata.h new file mode 100644 index 0000000..0d7ffba --- /dev/null +++ b/include/limb/encdata.h @@ -0,0 +1,9 @@ +#ifndef LIMB_ENCDATA_h +#define LIMB_ENCDATA_h + +#include <skalibs/stralloc.h> +#include "limb/int.h" + +extern int encdata(const u16 id, const void *val, const size_t size, stralloc *sa); + +#endif /* LIMB_ENCDATA_h */ diff --git a/meta/libs/limb b/meta/libs/limb index 71f9d43..af6f2cc 100644 --- a/meta/libs/limb +++ b/meta/libs/limb @@ -10,6 +10,8 @@ obj/msb64.o # {,un}pack u64 obj/uint64_pack_trim.o obj/uint64_unpack_trim.o +# data-encoding (integers or blobs) +obj/encdata.o # content-based chunking obj/nextsplit_ae.o obj/nextsplit_buz.o diff --git a/src/encdata.c b/src/encdata.c new file mode 100644 index 0000000..c8d8282 --- /dev/null +++ b/src/encdata.c @@ -0,0 +1,29 @@ +#include "limb/encdata.h" +#include "limb/u16.h" +#include "limb/u64.h" + +int +encdata(const u16 id, const void *val, const size_t size, stralloc *sa) +{ + int is_blob = id & 0x8000; + int salen = sa->len; + + /* 2 bytes for id, then we might need up to 9 bytes to store our integer */ + if (!stralloc_readyplus(sa, 2 + 9)) + return 0; + u16_pack(id, sa->s + sa->len); + sa->len += 2; + + if (is_blob) { + sa->len += u64_pack_trim((u64) size, (u8 *) sa->s + sa->len); + if (!stralloc_catb(sa, * (char **) val, size)) + goto err; + } else { + sa->len += u64_pack_trim(* (u64 *) val, (u8 *) sa->s + sa->len); + } + + return 1; +err: + sa->len = salen; + return 0; +}