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: */
#ifndef __PARSE_H__
#define __PARSE_H__
+#include <arpa/inet.h>
#include <stdint.h>
#include <string.h>
#include <sys/cdefs.h>
/**
@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)); \
}
/**
@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)); \
#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);