From: Laurent Mazet Date: Mon, 7 Apr 2025 21:56:39 +0000 (+0200) Subject: add serialisation macros X-Git-Tag: v1.0~65 X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=3d7d8f544ff681dbe094fddc0eec69b2e9bc1999;p=morep.git add serialisation macros --- diff --git a/clear_data.c b/clear_data.c index 148a057..f5840bc 100644 --- a/clear_data.c +++ b/clear_data.c @@ -21,19 +21,28 @@ int parse_clear_data (char *line, CLEAR_DATA_t *out) { BEGIN_PARSE (line) - PARSE ("CHANNEL", out->channel_id) - PARSE ("BYPASS", out->bypass) - PARSEA ("DATA", out->data) + PARSE_INT ("CHANNEL", out->channel_id) + PARSE_INT ("BYPASS", out->bypass) + PARSE_ARRAY ("DATA", out->data) END_PARSE () } int format_clear_data (CLEAR_DATA_t *in, char *buffer, int maxlen) { BEGIN_FORMAT (buffer, maxlen); - FORMAT ("CHANNEL", out->channel_id) - FORMAT ("BYPASS", out->bypass) - FORMATA ("DATA", out->data) + FORMAT_INT ("CHANNEL", out->channel_id) + FORMAT_INT ("BYPASS", out->bypass) + FORMAT_ARRAY ("DATA", out->data) END_FORMAT () } +int serial_clear_data (CLEAR_DATA_t *in, uint8_t *buffer, int maxlen) +{ + BEGIN_SERIAL (buffer, maxlen); + SERIAL_INT (out->channel_id) + SERIAL_INT (out->bypass) + SERIAL_ARRAY (out->data) + END_SERIAL () +} + /* vim: set ts=4 sw=4 si et: */ diff --git a/clear_data.h b/clear_data.h index 795e9ec..ba1ae18 100644 --- a/clear_data.h +++ b/clear_data.h @@ -54,6 +54,17 @@ int parse_clear_data (char *line, CLEAR_DATA_t *out); */ int format_clear_data (CLEAR_DATA_t *in, char *buffer, int maxlen); +/** + @ingroup MESSAGES + + Serial clear data type fields into a network stream + + @param in input structure + @param buffer network stream + @param maxlen buffer limit +*/ +int serial_clear_data (CLEAR_DATA_t *in, uint8_t *buffer, int maxlen); + __END_DECLS #endif /* __CLEAR_DATA_H__ */ diff --git a/makefile b/makefile index a15e108..02cc6b1 100644 --- a/makefile +++ b/makefile @@ -13,7 +13,8 @@ OFLAGS = -O4 -Os #OFLAGS += -malign-double CFLAGS += -W -Wall -Wextra -g #CFLAGS += -std=c99 -D_XOPEN_SOURCE=500 -CFLAGS += -std=c11 -D_XOPEN_SOURCE=500 +#CFLAGS += -std=c11 -D_XOPEN_SOURCE=500 +CFLAGS += -D_XOPEN_SOURCE=500 CFLAGS += $(OFLAGS) $(INCLUDES) $(OPTIONS) LDFLAGS += -g $(LDOPTS) $(OPTIONS) diff --git a/parse.h b/parse.h index e01570c..a351a02 100644 --- a/parse.h +++ b/parse.h @@ -15,6 +15,7 @@ #ifndef __PARSE_H__ #define __PARSE_H__ +#include #include #include #include @@ -85,25 +86,37 @@ __BEGIN_DECLS /** @ingroup MESSAGES - Parsing macro + Parsing macro for integer field @param name field name @param buf preallocated storage */ -#define PARSE(name, buf) \ - else if (strcmp (var, name) == 0) { \ - _Generic ((buf), \ - uint8_t: buf = parse_int (val), \ - int8_t: buf = parse_int (val), \ - uint16_t: buf = parse_int (val), \ - int16_t: buf = parse_int (val), \ - uint32_t: buf = parse_int (val), \ - int32_t: buf = parse_int (val), \ - float: buf = parse_double (val), \ - double: buf = parse_double (val)); \ +#define PARSE_INT(name, buf) \ + else if (strcmp (var, name) == 0) { \ + buf = parse_int (val); \ + } +/** + @ingroup MESSAGES + + Parsing macro for floating point field + + @param name field name + @param buf preallocated storage +*/ +#define PARSE_DOUBLE(name, buf) \ + else if (strcmp (var, name) == 0) { \ + buf = parse_double (val); \ } -#define PARSEA(name, buf) \ +/** + @ingroup MESSAGES + + Parsing macro for array field + + @param name field name + @param buf preallocated storage +*/ +#define PARSE_ARRAY(name, buf) \ else if (strcmp (var, name) == 0) { \ buf##_len = parse_array (val, buf, sizeof (buf)); \ } @@ -139,26 +152,40 @@ __BEGIN_DECLS /** @ingroup MESSAGES - Format a field + Format an integer field + + @param name field name + @param field data from structure +*/ +#define FORMAT_INT(name, field) \ + len += snprintf (_buffer, _maxlen - len, "%d", field); \ + if (len == _maxlen) { \ + VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \ + } + +/** + @ingroup MESSAGES + + Format a floating point field @param name field name @param field data from structure */ -#define FORMAT(name, field) \ - _Generic (field, \ - uint8_t: len += snprintf (_buffer, _maxlen - len, "%d", field), \ - int8_t: len += snprintf (_buffer, _maxlen - len, "%d", field), \ - uint16_t: len += snprintf (_buffer, _maxlen - len, "%d", field), \ - int16_t: len += snprintf (_buffer, _maxlen - len, "%d", field), \ - uint32_t: len += snprintf (_buffer, _maxlen - len, "%d", field), \ - int32_t: len += snprintf (_buffer, _maxlen - len, "%d", field), \ - float: len += snprintf (_buffer, _maxlen - len, "%g", field), \ - double: len += snprintf (_buffer, _maxlen - len, "%g", field)); \ +#define FORMAT_DOUBLE(name, field) \ + len += snprintf (_buffer, _maxlen - len, "%g", field); \ if (len == _maxlen) { \ VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \ } -#define FORMATA(name, field) \ +/** + @ingroup MESSAGES + + Format an array field + + @param name field name + @param field data from structure +*/ +#define FORMAT_ARRAY(name, field) \ len += snprint_array (_buffer, _maxlen - len, field, field##_len); \ if (len == _maxlen) { \ VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \ @@ -172,6 +199,111 @@ __BEGIN_DECLS #define END_FORMAT() \ return (len >= _maxlen); +/** + @ingroup MESSAGES + + Initialize serialisation section + + @param buffer output buffer + @maxlen buffer limit +*/ +#define BEGIN_SERIAL(buffer, maxlen) \ + uint8_t *_buffer = (buffer); \ + int _maxlen = (maxlen); \ + int len = 0; + +/** + @ingroup MESSAGES + + Serialyze an integer field + + @param name field name + @param field data from structure +*/ +#define SERIAL_INT(field) \ + switch (sizeof (field)) { \ + case 1: \ + if (len < _maxlen) { \ + _buffer[len++] = field; \ + } else { \ + VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \ + len = _maxlen; \ + } \ + break; \ + case 2: \ + if (len + 1 < _maxlen) { \ + *((uint16_t *)(_buffer + len)) = htons ((uint16_t)field); \ + len += 2; \ + } else { \ + VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \ + len = _maxlen; \ + } \ + break; \ + case 4: \ + if (len + 3 < _maxlen) { \ + *((uint32_t *)(_buffer + len)) = htons ((uint32_t)field); \ + len += 4; \ + } else { \ + VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \ + len = _maxlen; \ + } \ + break; \ + } + +/** + @ingroup MESSAGES + + Serialyze a floating point field + + @param name field name + @param field data from structure +*/ +#define SERIAL_DOUBLE(field) \ + switch (sizeof (field)) { \ + case 4: \ + if (len + 3 < _maxlen) {  \ + *((float *)(_buffer + len)) = field; \ + } else { \ + VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \ + len = _maxlen; \ + } \ + break; \ + case 8: \ + if (len + 7 < _maxlen) {  \ + *((double *)(_buffer + len)) = field; \ + } else { \ + VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \ + len = _maxlen; \ + } \ + break; \ + } + +/** + @ingroup MESSAGES + + Serialyze an array field + + @param name field name + @param field data from structure +*/ +#define SERIAL_ARRAY(field) \ + { \ + int _l = (field##_len < _maxlen - len) ? field##_len : _maxlen - len; \ + memcpy (_buffer + len, field, _l); \ + len += _l; \ + } \ + if (len == _maxlen) { \ + VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \ + } + +/** + @ingroup MESSAGES + + End of serialisation section +*/ +#define END_SERIAL() \ + return (len >= _maxlen); + /* private function (do not use outside) */ int parse_int (char *val); diff --git a/payload.c b/payload.c index 4a6d690..88ad718 100644 --- a/payload.c +++ b/payload.c @@ -21,17 +21,25 @@ int parse_payload (char *line, PAYLOAD_t *out) { BEGIN_PARSE (line) - PARSE ("MSG", out->msgtype) - PARSEA ("PAYLOAD", out->data) + PARSE_INT ("MSG", out->msgtype) + PARSE_ARRAY ("PAYLOAD", out->data) END_PARSE () } int format_payload (PAYLOAD_t *in, char *buffer, int maxlen) { BEGIN_FORMAT (buffer, maxlen) - FORMAT ("MSG", in->msgtype) - FORMATA ("PAYLOAD", in->data) + FORMAT_INT ("MSG", in->msgtype) + FORMAT_ARRAY ("PAYLOAD", in->data) END_FORMAT () } +int serial_payload (PAYLOAD_t *in, uint8_t *buffer, int maxlen) +{ + BEGIN_SERIAL (buffer, maxlen) + SERIAL_INT (in->msgtype) + SERIAL_ARRAY (in->data) + END_SERIAL () +} + /* vim: set ts=4 sw=4 si et: */ diff --git a/payload.h b/payload.h index b53a329..f21cecd 100644 --- a/payload.h +++ b/payload.h @@ -52,6 +52,17 @@ int parse_payload (char *line, PAYLOAD_t *out); */ int format_payload (PAYLOAD_t *in, char *buffer, int maxlen); +/** + @ingroup MESSAGES + + Serialize payload into a network stream + + @param in input structure + @param buffer network stream + @param maxlen buffer limit +*/ +int serial_payload (PAYLOAD_t *in, uint8_t *buffer, int maxlen); + __END_DECLS #endif /* __PAYLOAD_H__ */ diff --git a/raw_data.c b/raw_data.c index 00cc787..b9aa258 100644 --- a/raw_data.c +++ b/raw_data.c @@ -21,16 +21,22 @@ int parse_raw_data (char *line, RAW_DATA_t *out) { BEGIN_PARSE (line) - PARSEA ("DATA", out->data) - PARSEA ("PAYLOAD", out->data) + PARSE_ARRAY ("DATA", out->data) END_PARSE () } int format_raw_data (RAW_DATA_t *in, char *buffer, int maxlen) { BEGIN_FORMAT (buffer, maxlen) - FORMATA ("DATA", in->data) + FORMAT_ARRAY ("DATA", in->data) END_FORMAT () } +int serial_raw_data (RAW_DATA_t *in, uint8_t *buffer, int maxlen) +{ + BEGIN_SERIAL (buffer, maxlen) + SERIAL_ARRAY (in->data) + END_SERIAL () +} + /* vim: set ts=4 sw=4 si et: */ diff --git a/raw_data.h b/raw_data.h index e4dc476..2fdca22 100644 --- a/raw_data.h +++ b/raw_data.h @@ -51,6 +51,17 @@ int parse_raw_data (char *line, RAW_DATA_t *out); */ int format_raw_data (RAW_DATA_t *in, char *buffer, int maxlen); +/** + @ingroup MESSAGES + + Serial raw data type fields into a network stream + + @param in input structure + @param buffer output network stream + @param maxlen buffer limit +*/ +int serial_raw_data (RAW_DATA_t *in, uint8_t *buffer, int maxlen); + __END_DECLS #endif /* __RAW_DATA_H__ */