Welcome to little lamb

Code » limb » commit d780c0d

Add buffer_puthex() and PUTMSG_HEX() macro

author Olivier Brunel
2023-03-26 09:00:10 UTC
committer Olivier Brunel
2023-03-26 14:03:03 UTC
parent e244b3db58431d92655df4e4464950e1b7bcc54f

Add buffer_puthex() and PUTMSG_HEX() macro

Easy way to write a byet array as hexadecimal dump into a buffer.

Which can also be done inside a "message" via buffer_putmsg(3) and macro
HEX(data,dlen), making it available in all the output.h macros.

doc/buffer.h.0.md +15 -0
doc/buffer_puthex.3.md +30 -0
doc/buffer_putmsg.3.md +13 -0
doc/out.3.md +8 -0
include/limb/buffer.h +4 -0
meta/bins/mkrabintables +1 -0
meta/libs/limb +1 -0
src/buffer_puthex.c +27 -0
src/buffer_putmsg.c +3 -0

diff --git a/doc/buffer.h.0.md b/doc/buffer.h.0.md
index fac22b9..7261513 100644
--- a/doc/buffer.h.0.md
+++ b/doc/buffer.h.0.md
@@ -24,6 +24,12 @@ The following constants are defined :
 : *PUTMSG_ESC*, *ESC*
 :: Can be used as special string given to [buffer_putmsg](3) to toggle escaping
 
+: *PUTMSG_HEX_NEXT*
+:: Can be used as special string given to [buffer_putmsg](3) to indicate that
+:: the next element is a pointer to a byte array (i.e. may include NULs) whose
+:: length is specified as the following element, to be treated as an unsigned
+:: integer. The byte array's content should be written into the buffer as
+:: hexadecimal.
 
 : *PUTMSG_LFF*
 :: Can be used as special string given to [buffer_putmsg](3) to add a new line
@@ -54,6 +60,12 @@ The following macros are defined :
 :: Same as *PUTMSG_ASUINT(`n`)* but with a signed integer (following
 :: *PUTMSG_INT_NEXT*)
 
+: *PUTMSG_HEX(`data`,`dlen`)*, *HEX(`data`,`dlen`)*
+:: Shorthand to easily add a blob/byte array whose content shall be written out
+:: in hexadecimal form into a message. This is intended for use in a
+:: coma-separated, as it expands to:
+:: `PUTMSG_HEX_NEXT, data, PUTMSG_ASUINT(dlen)`
+
 : *PUTMSG_UINT(`n`)*
 :: Shorthand to easily add an unsigned number into a message. This is intended
 :: for use in a coma-separated list, as it expands to:
@@ -76,5 +88,8 @@ The following functions are defined :
 : [buffer_putescs](3)
 :: Similar but for a NUL-terminated string.
 
+: [buffer_puthex](3)
+:: To write given data as hexadecimal dump.
+
 : [buffer_putmsg](3)
 :: To write a message, given as an array of NUL-terminated strings
diff --git a/doc/buffer_puthex.3.md b/doc/buffer_puthex.3.md
new file mode 100644
index 0000000..e54c177
--- /dev/null
+++ b/doc/buffer_puthex.3.md
@@ -0,0 +1,30 @@
+% limb manual
+% buffer_puthex(3)
+
+# NAME
+
+buffer\_puthex - write byte array content as hexadecimal dump into buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+ssize_t buffer_puthex(buffer *<em>buf</em>, const void *<em>data</em>, size_t <em>dlen</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_puthex`() function will write the content of byte array pointed to
+by `data` of length `dlen` into the buffer `buf` as an hexadecimal dump, i.e.
+every byte's value will be written out in 2-character hexadecimal form.
+
+# RETURN VALUE
+
+The `buffer_puthex`() function returns the number of bytes written into `b`
+on success. Otherwise, it returns -1 and sets `errno` to indicate the error.
+
+# ERRORS
+
+The `buffer_puthex`() function may fail and set `errno` for any of the errors
+specified for [buffer_put](3).
diff --git a/doc/buffer_putmsg.3.md b/doc/buffer_putmsg.3.md
index e12c578..febe7ca 100644
--- a/doc/buffer_putmsg.3.md
+++ b/doc/buffer_putmsg.3.md
@@ -40,6 +40,13 @@ into the buffer.
 When *PUTMSG_INT_NEXT* was given as one of the strings, it does the same as
 *PUTMSG_UINT_NEXT* only treating the next element as a signed integer.
 
+When *PUTMSG_HEX_NEXT* was given as one of the strings, it acts as an indicator
+that the next element in `strings` in a byte-array whose length in to be
+obtained from the following element, treated as an unsigned integer (instead of
+a pointer to a string).
+The content of the byte array shall be written into the buffer as an hexadecimal
+dump, as described on [buffer_puthex](3).
+
 ! INFO:
 ! A few macros are available, in order to simply things:
 ! : *PUTMSG_ASUINT(`n`)*, *PUTMSG_ASINT(`n`)*
@@ -50,6 +57,12 @@ When *PUTMSG_INT_NEXT* was given as one of the strings, it does the same as
 ! :: Shorthand to easily add an unsigned or signed number, respectively, into a
 ! :: message. This is intended for use in a coma-separated list, as it expands
 ! :: to, e.g: `PUTMSG_UINT_NEXT, PUTMSG_ASUINT(n)`
+!
+! : *PUTMSG_HEX(`data`,`dlen`)*, *HEX(`data`,`dlen`)*
+! :: Shorthand to easily add a blob/byte array whose content shall be written
+! :: out :: in hexadecimal form into a message. This is intended for use in a
+! :: coma-separated, as it expands to:
+! :: `PUTMSG_HEX_NEXT, data, PUTMSG_ASUINT(dlen)`
 
 # ESCAPING
 
diff --git a/doc/out.3.md b/doc/out.3.md
index c456a12..15da8c6 100644
--- a/doc/out.3.md
+++ b/doc/out.3.md
@@ -93,6 +93,14 @@ the buffer into decimal form, through the use of macros :
 
 Refer to [buffer_putmsg](3) for more.
 
+## Hexadecimal dump
+
+It is possible to specify a byte-array whose content shall be written out as
+hexadecimal dump, through the use of macro *PUTMSG_HEX* (or simply *HEX*),
+taking two arguments : a pointer to the byte array, and its length.
+
+For more, refer to [buffer_putmsg](3).
+
 # SEE ALSO
 
 [out_putmsg](3), [buffer_putmsg](3)
diff --git a/include/limb/buffer.h b/include/limb/buffer.h
index c529e15..4cf6e2f 100644
--- a/include/limb/buffer.h
+++ b/include/limb/buffer.h
@@ -12,18 +12,22 @@
 #define PUTMSG_ESC          ((void *) 3)    /* toggle escaping */
 #define PUTMSG_UINT_NEXT    ((void *) 4)    /* next string is an uint */
 #define PUTMSG_INT_NEXT     ((void *) 5)    /* next string is an int */
+#define PUTMSG_HEX_NEXT     ((void *) 6)    /* next strings are data, dlen */
 
 #define PUTMSG_ASUINT(n)    ((const char *) (uintptr_t) (n))
 #define PUTMSG_ASINT(n)     ((const char *) ( intptr_t) (n))
 
 #define PUTMSG_UINT(n)      PUTMSG_UINT_NEXT, PUTMSG_ASUINT(n)
 #define PUTMSG_INT(n)       PUTMSG_INT_NEXT,  PUTMSG_ASINT(n)
+#define PUTMSG_HEX(d,l)     PUTMSG_HEX_NEXT, d, PUTMSG_ASUINT(l)
 
 #define ESC                 PUTMSG_ESC
+#define HEX(d,l)            PUTMSG_HEX(d,l)
 
 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);
 extern ssize_t buffer_putescs(buffer *b, const char *s);
+extern ssize_t buffer_puthex(buffer *b, const void *data, size_t dlen);
 
 #endif /* LIMB_BUFFER_H */
diff --git a/meta/bins/mkrabintables b/meta/bins/mkrabintables
index 51b249e..f5311b7 100644
--- a/meta/bins/mkrabintables
+++ b/meta/bins/mkrabintables
@@ -3,6 +3,7 @@ obj/msb64.o
 obj/buffer_putescall.o
 obj/buffer_putesc.o
 obj/buffer_putescs.o
+obj/buffer_puthex.o
 obj/u64_fmt_generic.o
 obj/buffer_putmsg.o
 obj/obuffer_putmsg.o
diff --git a/meta/libs/limb b/meta/libs/limb
index 8948676..12a5ae3 100644
--- a/meta/libs/limb
+++ b/meta/libs/limb
@@ -29,6 +29,7 @@ obj/buffer_putescall.o
 obj/buffer_putesc.o
 obj/buffer_putescs.o
 obj/buffer_putmsg.o
+obj/buffer_puthex.o
 # obuffer.h
 obj/obuffer_put.o
 obj/obuffer_putmsg.o
diff --git a/src/buffer_puthex.c b/src/buffer_puthex.c
new file mode 100644
index 0000000..71c6697
--- /dev/null
+++ b/src/buffer_puthex.c
@@ -0,0 +1,27 @@
+/* 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/fmtscan.h>
+#include "limb/buffer.h"
+
+ssize_t
+buffer_puthex(buffer *b, const void *data_, size_t dlen)
+{
+    const unsigned char *data = data_;
+    ssize_t w = 0;
+    char buf[2];
+
+    for (int i = 0; i < dlen; ++i) {
+        ssize_t l;
+
+        buf[0] = fmtscan_asc(data[i] >> 4);
+        buf[1] = fmtscan_asc(data[i] & 0xf);
+
+        l = buffer_put(b, buf, 2);
+        if (l < 0)
+            return -1;
+        w += l;
+    }
+
+    return w;
+}
diff --git a/src/buffer_putmsg.c b/src/buffer_putmsg.c
index dc6ca2e..b8c4623 100644
--- a/src/buffer_putmsg.c
+++ b/src/buffer_putmsg.c
@@ -32,6 +32,9 @@ buffer_putmsg(buffer *b, const char * const *as, unsigned int n)
 
             buf[u64_fmt(buf, u)] = 0;
             buffer_puts(b, buf_);
+        } else if (as[i] == PUTMSG_HEX_NEXT && i + 2 < n) {
+            buffer_puthex(b, as[i + 1], (uintptr_t) as[i + 2]);
+            i += 2;
         } else if (as[i] && as[i][0]) {
             puts(b, as[i]);
         }