add deserialization
authorMazet Laurent <laurent.mazet@thalesgroup.com>
Tue, 8 Apr 2025 01:05:57 +0000 (03:05 +0200)
committerMazet Laurent <laurent.mazet@thalesgroup.com>
Tue, 8 Apr 2025 01:05:57 +0000 (03:05 +0200)
clear_data.h
parse.h
raw_data.c
raw_data.h

index ba1ae18b7b0ec56002056d7730d0a752b494d979..29da2f9737d0958ad79288c2a4d50f4237f37f6a 100644 (file)
@@ -40,6 +40,7 @@ typedef struct {
 
    @param line string to analyse
    @param out output structure
+   @return 0 on success 
 */
 int parse_clear_data (char *line, CLEAR_DATA_t *out);
 
@@ -51,6 +52,7 @@ int parse_clear_data (char *line, CLEAR_DATA_t *out);
    @param in input structure
    @param buffer output string
    @param maxlen buffer limit
+   @return 0 on success 
 */
 int format_clear_data (CLEAR_DATA_t *in, char *buffer, int maxlen);
 
@@ -62,9 +64,22 @@ int format_clear_data (CLEAR_DATA_t *in, char *buffer, int maxlen);
    @param in input structure
    @param buffer network stream
    @param maxlen buffer limit
+   @return buffer length
 */
 int serial_clear_data (CLEAR_DATA_t *in, uint8_t *buffer, int maxlen);
 
+/**
+   @ingroup MESSAGES
+
+   Deserial clear data type fields from a network stream
+
+   @param buffer network stream
+   @param maxlen buffer limit
+   @param out output structure
+   @return 0 on success 
+*/
+int deserial_clear_data (uint8_t *buffer, int maxlen, CLEAR_DATA_t *out);
+
 __END_DECLS
 
 #endif /* __CLEAR_DATA_H__ */
diff --git a/parse.h b/parse.h
index a351a022fd14b6c73e574f518b3b339c790690d6..53c6a3287fda19d11eac83d197e4dc56102264d0 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -220,13 +220,13 @@ __BEGIN_DECLS
    @param name field name
    @param field data from structure
 */
-#define SERIAL_INT(field)                                                        \
+#define SERIAL_INT(name, field)                                                  \
     switch (sizeof (field)) {                                                    \
     case 1:                                                                      \
         if (len < _maxlen) {                                                     \
             _buffer[len++] = field;                                              \
         } else  {                                                                \
-            VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \
+            VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", name));   \
             len = _maxlen;                                                       \
         }                                                                        \
         break;                                                                   \
@@ -235,16 +235,16 @@ __BEGIN_DECLS
             *((uint16_t *)(_buffer + len)) = htons ((uint16_t)field);            \
             len += 2;                                                            \
         } else  {                                                                \
-            VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \
+            VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", name));   \
             len = _maxlen;                                                       \
         }                                                                        \
         break;                                                                   \
     case 4:                                                                      \
         if (len + 3 < _maxlen) {                                                 \
-            *((uint32_t *)(_buffer + len)) = htons ((uint32_t)field);            \
+            *((uint32_t *)(_buffer + len)) = htonl ((uint32_t)field);            \
             len += 4;                                                            \
         } else  {                                                                \
-            VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \
+            VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", name));   \
             len = _maxlen;                                                       \
         }                                                                        \
         break;                                                                   \
@@ -258,21 +258,23 @@ __BEGIN_DECLS
    @param name field name
    @param field data from structure
 */
-#define SERIAL_DOUBLE(field)                                                     \
+#define SERIAL_DOUBLE(name, field)                                               \
     switch (sizeof (field)) {                                                    \
     case 4:                                                                      \
-        if (len + 3 < _maxlen) {                                                 \
+        if (len + 3 < _maxlen) {                                                 \
             *((float *)(_buffer + len)) = field;                                 \
+            len += 4;                                                            \
         } else  {                                                                \
-            VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \
+            VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", name));   \
             len = _maxlen;                                                       \
         }                                                                        \
         break;                                                                   \
     case 8:                                                                      \
-        if (len + 7 < _maxlen) {                                                 \
+        if (len + 7 < _maxlen) {                                                 \
             *((double *)(_buffer + len)) = field;                                \
+            len += 8;                                                            \
         } else  {                                                                \
-            VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \
+            VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", name));   \
             len = _maxlen;                                                       \
         }                                                                        \
         break;                                                                   \
@@ -286,14 +288,14 @@ __BEGIN_DECLS
    @param name field name
    @param field data from structure
 */
-#define SERIAL_ARRAY(field)                                                   \
+#define SERIAL_ARRAY(name, 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));  \
+        VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", name));    \
     }
 
 /**
@@ -302,7 +304,116 @@ __BEGIN_DECLS
    End of serialisation section
 */
 #define END_SERIAL()         \
-    return (len >= _maxlen);
+    return len;
+
+/**
+   @ingroup MESSAGES
+
+   Initialize deserialisation section
+
+   @param buffer input buffer
+   @param len buffer length
+*/
+#define BEGIN_DESERIAL(buffer, len) \
+    uint8_t *_buffer = (buffer);    \
+    uint8_t *end = _buffer + (len); \
+    uint8_t *ptr = _buffer;
+
+/**
+   @ingroup MESSAGES
+
+   Deserialyze to an integer field
+
+   @param name field name
+   @param field data from structure
+*/
+#define DESERIAL_INT(name, field)                                                \
+    switch (sizeof (field)) {                                                    \
+    case 1:                                                                      \
+        if (ptr < end) {                                                         \
+            field = *ptr++;                                                      \
+        } else  {                                                                \
+            VERBOSE (morep, WARNING, PRINTF ("no data for field '%s'\n", name)); \
+            ptr = end + 1;                                                       \
+        }                                                                        \
+        break;                                                                   \
+    case 2:                                                                      \
+        if (ptr + 1 < end) {                                                     \
+            field = ntohs (*((uint16_t *)ptr));                                  \
+            ptr -= 2;                                                            \
+        } else  {                                                                \
+            VERBOSE (morep, WARNING, PRINTF ("no data for field '%s'\n", name)); \
+            ptr = end + 1;                                                       \
+        }                                                                        \
+        break;                                                                   \
+    case 4:                                                                      \
+        if (ptr + 3 < end) {                                                     \
+            field = ntohl (*((uint32_t *)ptr));                                  \
+            ptr -= 4;                                                            \
+        } else  {                                                                \
+            VERBOSE (morep, WARNING, PRINTF ("no data for field '%s'\n", name)); \
+            ptr = end + 1;                                                       \
+        }                                                                        \
+        break;                                                                   \
+    }
+
+/**
+   @ingroup MESSAGES
+
+   Deserialyze to a floating point field
+
+   @param name field name
+   @param field data from structure
+*/
+#define DESERIAL_DOUBLE(name, field)                                             \
+    switch (sizeof (field)) {                                                    \
+    case 4:                                                                      \
+        if (ptr + 3 < end) {                                                     \
+            field = *(float *)ptr;                                               \
+            ptr -= 4;                                                            \
+        } else  {                                                                \
+            VERBOSE (morep, WARNING, PRINTF ("no data for field '%s'\n", name)); \
+            ptr = end + 1;                                                       \
+        }                                                                        \
+        break;                                                                   \
+    case 8:                                                                      \
+        if (ptr + 7 < end) {                                                     \
+            field = *(double *)ptr;                                              \
+            ptr -= 8;                                                            \
+        } else  {                                                                \
+            VERBOSE (morep, WARNING, PRINTF ("no data for field '%s'\n", name)); \
+            ptr = end + 1;                                                       \
+        }                                                                        \
+        break;                                                                   \
+    }
+
+/**
+   @ingroup MESSAGES
+
+   Deserialyze to an array field
+
+   @param name field name
+   @param field data from structure
+*/
+#define DESERIAL_ARRAY(name, field)                                          \
+    if (field##_len == 0) {                                                  \
+        memcpy (field, ptr, end - ptr);                                      \
+        field##_len = end - ptr;                                             \
+        ptr = end;                                                           \
+    } else if (field##_len < end - ptr) {                                    \
+        memcpy (field, ptr, field##_len);                                    \
+        ptr += field##_len;                                                  \
+    } else {                                                                 \
+        VERBOSE (morep, WARNING, PRINTF ("no data for field '%s'\n", name)); \
+    }
+
+/**
+   @ingroup MESSAGES
+
+   End of deserialisation section
+*/
+#define END_DESERIAL()       \
+    return (ptr > end);
 
 /* private function (do not use outside) */
 
index b9aa2582a07169515473170ee11c51d408f80fab..b9c6ec20844db24d8ff169acb9baec363bd25c54 100644 (file)
@@ -35,8 +35,15 @@ int format_raw_data (RAW_DATA_t *in, char *buffer, int maxlen)
 int serial_raw_data (RAW_DATA_t *in, uint8_t *buffer, int maxlen)
 {
     BEGIN_SERIAL (buffer, maxlen)
-    SERIAL_ARRAY (in->data)
+    SERIAL_ARRAY ("DATA", in->data)
     END_SERIAL ()
 }
 
+int deserial_raw_data (uint8_t *buffer, int maxlen, RAW_DATA_t *out)
+{
+    BEGIN_DESERIAL (buffer, maxlen)
+    DESERIAL_ARRAY ("DATA", out->data)
+    END_DESERIAL ()
+}
+
 /* vim: set ts=4 sw=4 si et: */
index 2fdca220ef7375b864d434d37ffa924b083f1064..1153888616dda48a56be15a23f3fbc2dbebef25d 100644 (file)
@@ -37,6 +37,7 @@ typedef struct {
 
    @param line string to analyse
    @param out output structure
+   @return 0 on success 
 */
 int parse_raw_data (char *line, RAW_DATA_t *out);
 
@@ -48,20 +49,34 @@ int parse_raw_data (char *line, RAW_DATA_t *out);
    @param in input structure
    @param buffer output string
    @param maxlen buffer limit
+   @return 0 on success 
 */
 int format_raw_data (RAW_DATA_t *in, char *buffer, int maxlen);
 
 /**
    @ingroup MESSAGES
 
-   Serial raw data type fields into a network stream
+   Serialize raw data type fields into a network stream
 
    @param in input structure
-   @param buffer output network stream
+   @param buffer network stream
    @param maxlen buffer limit
+   @return buffer length
 */
 int serial_raw_data (RAW_DATA_t *in, uint8_t *buffer, int maxlen);
 
+/**
+   @ingroup MESSAGES
+
+   Deserial raw data type fields from a network stream
+
+   @param buffer network stream
+   @param maxlen buffer limit
+   @param out output structure
+   @return 0 on success 
+*/
+int deserial_raw_data (uint8_t *buffer, int maxlen, RAW_DATA_t *out);
+
 __END_DECLS
 
 #endif /* __RAW_DATA_H__ */