author | Olivier Brunel
<jjk@jjacky.com> 2023-03-26 09:00:10 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-03-26 14:03:03 UTC |
parent | e244b3db58431d92655df4e4464950e1b7bcc54f |
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]); }