Welcome to little lamb

Code » limb » commit 1d59ee1

Add encdata() to encode data (integer or blob)

author Olivier Brunel
2023-02-17 09:51:06 UTC
committer Olivier Brunel
2023-02-20 09:02:20 UTC
parent b379f2b6d9729fd8a2f294174ec69caee27fa49f

Add encdata() to encode data (integer or blob)

The data is stored with the given ID whose mist-significant bit
indicates whether it is a blob/byte array or an integer (u64).

After the ID (little endian) is stored either the integer value or the
blob size using u64_pack_trim(), then the untouched blob if applicable.

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;
+}