|
@@ -13,16 +13,13 @@
|
|
|
/* Enable support for dynamically allocated fields */
|
|
/* Enable support for dynamically allocated fields */
|
|
|
/* #define PB_ENABLE_MALLOC 1 */
|
|
/* #define PB_ENABLE_MALLOC 1 */
|
|
|
|
|
|
|
|
-/* Define this if your CPU architecture is big endian, i.e. it
|
|
|
|
|
- * stores the most-significant byte first. */
|
|
|
|
|
-/* #define __BIG_ENDIAN__ 1 */
|
|
|
|
|
|
|
+/* Define this if your CPU / compiler combination does not support
|
|
|
|
|
+ * unaligned memory access to packed structures. */
|
|
|
|
|
+/* #define PB_NO_PACKED_STRUCTS 1 */
|
|
|
|
|
|
|
|
/* Increase the number of required fields that are tracked.
|
|
/* Increase the number of required fields that are tracked.
|
|
|
* A compiler warning will tell if you need this. */
|
|
* A compiler warning will tell if you need this. */
|
|
|
-#define PB_MAX_REQUIRED_FIELDS 256
|
|
|
|
|
-
|
|
|
|
|
-/* Add support for tag numbers > 255 and fields larger than 255 bytes. */
|
|
|
|
|
-#define PB_FIELD_16BIT 1
|
|
|
|
|
|
|
+/* #define PB_MAX_REQUIRED_FIELDS 256 */
|
|
|
|
|
|
|
|
/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */
|
|
/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */
|
|
|
/* #define PB_FIELD_32BIT 1 */
|
|
/* #define PB_FIELD_32BIT 1 */
|
|
@@ -37,6 +34,11 @@
|
|
|
* This was the default until nanopb-0.2.1. */
|
|
* This was the default until nanopb-0.2.1. */
|
|
|
/* #define PB_OLD_CALLBACK_STYLE */
|
|
/* #define PB_OLD_CALLBACK_STYLE */
|
|
|
|
|
|
|
|
|
|
+/* Set the fieldinfo width for all messages using automatic width
|
|
|
|
|
+ * selection. Valid values are 2, 4 and 8. Usually even if you need
|
|
|
|
|
+ * to change the width manually for some reason, it is preferrable
|
|
|
|
|
+ * to do so through the descriptorsize option in .options file. */
|
|
|
|
|
+/* #define PB_FIELDINFO_WIDTH 4 */
|
|
|
|
|
|
|
|
/******************************************************************
|
|
/******************************************************************
|
|
|
* You usually don't need to change anything below this line. *
|
|
* You usually don't need to change anything below this line. *
|
|
@@ -46,12 +48,12 @@
|
|
|
|
|
|
|
|
/* Version of the nanopb library. Just in case you want to check it in
|
|
/* Version of the nanopb library. Just in case you want to check it in
|
|
|
* your own program. */
|
|
* your own program. */
|
|
|
-#define NANOPB_VERSION nanopb-0.3.1
|
|
|
|
|
|
|
+#define NANOPB_VERSION nanopb-0.4.0-dev
|
|
|
|
|
|
|
|
/* Include all the system headers needed by nanopb. You will need the
|
|
/* Include all the system headers needed by nanopb. You will need the
|
|
|
* definitions of the following:
|
|
* definitions of the following:
|
|
|
* - strlen, memcpy, memset functions
|
|
* - strlen, memcpy, memset functions
|
|
|
- * - [u]int8_t, [u]int16_t, [u]int32_t, [u]int64_t
|
|
|
|
|
|
|
+ * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t
|
|
|
* - size_t
|
|
* - size_t
|
|
|
* - bool
|
|
* - bool
|
|
|
*
|
|
*
|
|
@@ -66,16 +68,26 @@
|
|
|
#include <stddef.h>
|
|
#include <stddef.h>
|
|
|
#include <stdbool.h>
|
|
#include <stdbool.h>
|
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
|
|
+#include <limits.h>
|
|
|
|
|
|
|
|
#ifdef PB_ENABLE_MALLOC
|
|
#ifdef PB_ENABLE_MALLOC
|
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
|
#endif
|
|
#endif
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
+#ifdef __cplusplus
|
|
|
|
|
+extern "C" {
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
/* Macro for defining packed structures (compiler dependent).
|
|
/* Macro for defining packed structures (compiler dependent).
|
|
|
* This just reduces memory requirements, but is not required.
|
|
* This just reduces memory requirements, but is not required.
|
|
|
*/
|
|
*/
|
|
|
-#if defined(__GNUC__) || defined(__clang__)
|
|
|
|
|
|
|
+#if defined(PB_NO_PACKED_STRUCTS)
|
|
|
|
|
+ /* Disable struct packing */
|
|
|
|
|
+# define PB_PACKED_STRUCT_START
|
|
|
|
|
+# define PB_PACKED_STRUCT_END
|
|
|
|
|
+# define pb_packed
|
|
|
|
|
+#elif defined(__GNUC__) || defined(__clang__)
|
|
|
/* For GCC and clang */
|
|
/* For GCC and clang */
|
|
|
# define PB_PACKED_STRUCT_START
|
|
# define PB_PACKED_STRUCT_START
|
|
|
# define PB_PACKED_STRUCT_END
|
|
# define PB_PACKED_STRUCT_END
|
|
@@ -112,13 +124,20 @@
|
|
|
* in the place where the PB_STATIC_ASSERT macro was called.
|
|
* in the place where the PB_STATIC_ASSERT macro was called.
|
|
|
*/
|
|
*/
|
|
|
#ifndef PB_NO_STATIC_ASSERT
|
|
#ifndef PB_NO_STATIC_ASSERT
|
|
|
-#ifndef PB_STATIC_ASSERT
|
|
|
|
|
-#define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1];
|
|
|
|
|
-#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER)
|
|
|
|
|
-#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##LINE##COUNTER
|
|
|
|
|
-#endif
|
|
|
|
|
|
|
+# ifndef PB_STATIC_ASSERT
|
|
|
|
|
+# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
|
|
|
|
+ /* C11 standard _Static_assert mechanism */
|
|
|
|
|
+# define PB_STATIC_ASSERT(COND,MSG) _Static_assert(COND,#MSG);
|
|
|
|
|
+# else
|
|
|
|
|
+ /* Classic negative-size-array static assert mechanism */
|
|
|
|
|
+# define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1];
|
|
|
|
|
+# define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER)
|
|
|
|
|
+# define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##_##LINE##_##COUNTER
|
|
|
|
|
+# endif
|
|
|
|
|
+# endif
|
|
|
#else
|
|
#else
|
|
|
-#define PB_STATIC_ASSERT(COND,MSG)
|
|
|
|
|
|
|
+ /* Static asserts disabled by PB_NO_STATIC_ASSERT */
|
|
|
|
|
+# define PB_STATIC_ASSERT(COND,MSG)
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
/* Number of required fields to keep track of. */
|
|
/* Number of required fields to keep track of. */
|
|
@@ -135,7 +154,7 @@
|
|
|
* Most-significant 4 bits specify repeated/required/packed etc.
|
|
* Most-significant 4 bits specify repeated/required/packed etc.
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
-typedef uint8_t pb_type_t;
|
|
|
|
|
|
|
+typedef uint_least8_t pb_type_t;
|
|
|
|
|
|
|
|
/**** Field data types ****/
|
|
/**** Field data types ****/
|
|
|
|
|
|
|
@@ -165,15 +184,24 @@ typedef uint8_t pb_type_t;
|
|
|
* The field contains a pointer to pb_extension_t */
|
|
* The field contains a pointer to pb_extension_t */
|
|
|
#define PB_LTYPE_EXTENSION 0x08
|
|
#define PB_LTYPE_EXTENSION 0x08
|
|
|
|
|
|
|
|
|
|
+/* Byte array with inline, pre-allocated byffer.
|
|
|
|
|
+ * data_size is the length of the inline, allocated buffer.
|
|
|
|
|
+ * This differs from PB_LTYPE_BYTES by defining the element as
|
|
|
|
|
+ * pb_byte_t[data_size] rather than pb_bytes_array_t. */
|
|
|
|
|
+#define PB_LTYPE_FIXED_LENGTH_BYTES 0x09
|
|
|
|
|
+
|
|
|
/* Number of declared LTYPES */
|
|
/* Number of declared LTYPES */
|
|
|
-#define PB_LTYPES_COUNT 9
|
|
|
|
|
|
|
+#define PB_LTYPES_COUNT 0x0A
|
|
|
#define PB_LTYPE_MASK 0x0F
|
|
#define PB_LTYPE_MASK 0x0F
|
|
|
|
|
|
|
|
/**** Field repetition rules ****/
|
|
/**** Field repetition rules ****/
|
|
|
|
|
|
|
|
#define PB_HTYPE_REQUIRED 0x00
|
|
#define PB_HTYPE_REQUIRED 0x00
|
|
|
#define PB_HTYPE_OPTIONAL 0x10
|
|
#define PB_HTYPE_OPTIONAL 0x10
|
|
|
|
|
+#define PB_HTYPE_SINGULAR 0x10
|
|
|
#define PB_HTYPE_REPEATED 0x20
|
|
#define PB_HTYPE_REPEATED 0x20
|
|
|
|
|
+#define PB_HTYPE_FIXARRAY 0x20
|
|
|
|
|
+#define PB_HTYPE_ONEOF 0x30
|
|
|
#define PB_HTYPE_MASK 0x30
|
|
#define PB_HTYPE_MASK 0x30
|
|
|
|
|
|
|
|
/**** Field allocation types ****/
|
|
/**** Field allocation types ****/
|
|
@@ -191,69 +219,86 @@ typedef uint8_t pb_type_t;
|
|
|
* and array counts.
|
|
* and array counts.
|
|
|
*/
|
|
*/
|
|
|
#if defined(PB_FIELD_32BIT)
|
|
#if defined(PB_FIELD_32BIT)
|
|
|
-#define PB_SIZE_MAX ((uint32_t)-1)
|
|
|
|
|
typedef uint32_t pb_size_t;
|
|
typedef uint32_t pb_size_t;
|
|
|
typedef int32_t pb_ssize_t;
|
|
typedef int32_t pb_ssize_t;
|
|
|
-#elif defined(PB_FIELD_16BIT)
|
|
|
|
|
-#define PB_SIZE_MAX ((uint16_t)-1)
|
|
|
|
|
- typedef uint16_t pb_size_t;
|
|
|
|
|
- typedef int16_t pb_ssize_t;
|
|
|
|
|
#else
|
|
#else
|
|
|
-#define PB_SIZE_MAX ((uint8_t)-1)
|
|
|
|
|
- typedef uint8_t pb_size_t;
|
|
|
|
|
- typedef int8_t pb_ssize_t;
|
|
|
|
|
|
|
+ typedef uint_least16_t pb_size_t;
|
|
|
|
|
+ typedef int_least16_t pb_ssize_t;
|
|
|
#endif
|
|
#endif
|
|
|
|
|
+#define PB_SIZE_MAX ((pb_size_t)-1)
|
|
|
|
|
+
|
|
|
|
|
+/* Data type for storing encoded data and other byte streams.
|
|
|
|
|
+ * This typedef exists to support platforms where uint8_t does not exist.
|
|
|
|
|
+ * You can regard it as equivalent on uint8_t on other platforms.
|
|
|
|
|
+ */
|
|
|
|
|
+typedef uint_least8_t pb_byte_t;
|
|
|
|
|
+
|
|
|
|
|
+/* Forward declaration of struct types */
|
|
|
|
|
+typedef struct pb_istream_s pb_istream_t;
|
|
|
|
|
+typedef struct pb_ostream_s pb_ostream_t;
|
|
|
|
|
+typedef struct pb_field_iter_s pb_field_iter_t;
|
|
|
|
|
|
|
|
/* This structure is used in auto-generated constants
|
|
/* This structure is used in auto-generated constants
|
|
|
* to specify struct fields.
|
|
* to specify struct fields.
|
|
|
- * You can change field sizes if you need structures
|
|
|
|
|
- * larger than 256 bytes or field tags larger than 256.
|
|
|
|
|
- * The compiler should complain if your .proto has such
|
|
|
|
|
- * structures. Fix that by defining PB_FIELD_16BIT or
|
|
|
|
|
- * PB_FIELD_32BIT.
|
|
|
|
|
*/
|
|
*/
|
|
|
PB_PACKED_STRUCT_START
|
|
PB_PACKED_STRUCT_START
|
|
|
-typedef struct pb_field_s pb_field_t;
|
|
|
|
|
-struct pb_field_s {
|
|
|
|
|
- pb_size_t tag;
|
|
|
|
|
- pb_type_t type;
|
|
|
|
|
- pb_size_t data_offset; /* Offset of field data, relative to previous field. */
|
|
|
|
|
- pb_ssize_t size_offset; /* Offset of array size or has-boolean, relative to data */
|
|
|
|
|
- pb_size_t data_size; /* Data size in bytes for a single item */
|
|
|
|
|
- pb_size_t array_size; /* Maximum number of entries in array */
|
|
|
|
|
-
|
|
|
|
|
- /* Field definitions for submessage
|
|
|
|
|
- * OR default value for all other non-array, non-callback types
|
|
|
|
|
- * If null, then field will zeroed. */
|
|
|
|
|
- const void *ptr;
|
|
|
|
|
|
|
+typedef struct pb_msgdesc_s pb_msgdesc_t;
|
|
|
|
|
+struct pb_msgdesc_s {
|
|
|
|
|
+ pb_size_t field_count;
|
|
|
|
|
+ const uint32_t *field_info;
|
|
|
|
|
+ const pb_msgdesc_t **submsg_info;
|
|
|
|
|
+ const pb_byte_t *default_value;
|
|
|
|
|
+
|
|
|
|
|
+ bool (*field_callback)(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field);
|
|
|
} pb_packed;
|
|
} pb_packed;
|
|
|
PB_PACKED_STRUCT_END
|
|
PB_PACKED_STRUCT_END
|
|
|
|
|
|
|
|
|
|
+/* Iterator for message descriptor */
|
|
|
|
|
+struct pb_field_iter_s {
|
|
|
|
|
+ const pb_msgdesc_t *descriptor; /* Pointer to message descriptor constant */
|
|
|
|
|
+ void *message; /* Pointer to start of the structure */
|
|
|
|
|
+
|
|
|
|
|
+ pb_size_t index; /* Index of the field */
|
|
|
|
|
+ pb_size_t field_info_index; /* Index to descriptor->field_info array */
|
|
|
|
|
+ pb_size_t required_field_index; /* Index that counts only the required fields */
|
|
|
|
|
+ pb_size_t submessage_index; /* Index that counts only submessages */
|
|
|
|
|
+
|
|
|
|
|
+ pb_size_t tag; /* Tag of current field */
|
|
|
|
|
+ pb_size_t data_size; /* sizeof() of a single item */
|
|
|
|
|
+ pb_size_t array_size; /* Number of array entries */
|
|
|
|
|
+ pb_type_t type; /* Type of current field */
|
|
|
|
|
+
|
|
|
|
|
+ void *pField; /* Pointer to current field in struct */
|
|
|
|
|
+ void *pData; /* Pointer to current data contents. Different than pField for arrays and pointers. */
|
|
|
|
|
+ void *pSize; /* Pointer to count/has field */
|
|
|
|
|
+
|
|
|
|
|
+ const pb_msgdesc_t *submsg_desc; /* For submessage fields, pointer to field descriptor for the submessage. */
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/* For compatibility with legacy code */
|
|
|
|
|
+typedef pb_field_iter_t pb_field_t;
|
|
|
|
|
+
|
|
|
/* Make sure that the standard integer types are of the expected sizes.
|
|
/* Make sure that the standard integer types are of the expected sizes.
|
|
|
- * All kinds of things may break otherwise.. atleast all fixed* types.
|
|
|
|
|
|
|
+ * Otherwise fixed32/fixed64 fields can break.
|
|
|
*
|
|
*
|
|
|
* If you get errors here, it probably means that your stdint.h is not
|
|
* If you get errors here, it probably means that your stdint.h is not
|
|
|
* correct for your platform.
|
|
* correct for your platform.
|
|
|
*/
|
|
*/
|
|
|
-PB_STATIC_ASSERT(sizeof(int8_t) == 1, INT8_T_WRONG_SIZE)
|
|
|
|
|
-PB_STATIC_ASSERT(sizeof(uint8_t) == 1, UINT8_T_WRONG_SIZE)
|
|
|
|
|
-PB_STATIC_ASSERT(sizeof(int16_t) == 2, INT16_T_WRONG_SIZE)
|
|
|
|
|
-PB_STATIC_ASSERT(sizeof(uint16_t) == 2, UINT16_T_WRONG_SIZE)
|
|
|
|
|
-PB_STATIC_ASSERT(sizeof(int32_t) == 4, INT32_T_WRONG_SIZE)
|
|
|
|
|
-PB_STATIC_ASSERT(sizeof(uint32_t) == 4, UINT32_T_WRONG_SIZE)
|
|
|
|
|
-PB_STATIC_ASSERT(sizeof(int64_t) == 8, INT64_T_WRONG_SIZE)
|
|
|
|
|
-PB_STATIC_ASSERT(sizeof(uint64_t) == 8, UINT64_T_WRONG_SIZE)
|
|
|
|
|
|
|
+#ifndef PB_WITHOUT_64BIT
|
|
|
|
|
+PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE)
|
|
|
|
|
+PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE)
|
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
/* This structure is used for 'bytes' arrays.
|
|
/* This structure is used for 'bytes' arrays.
|
|
|
* It has the number of bytes in the beginning, and after that an array.
|
|
* It has the number of bytes in the beginning, and after that an array.
|
|
|
* Note that actual structs used will have a different length of bytes array.
|
|
* Note that actual structs used will have a different length of bytes array.
|
|
|
*/
|
|
*/
|
|
|
-#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; uint8_t bytes[n]; }
|
|
|
|
|
|
|
+#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; }
|
|
|
#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes))
|
|
#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes))
|
|
|
|
|
|
|
|
struct pb_bytes_array_s {
|
|
struct pb_bytes_array_s {
|
|
|
pb_size_t size;
|
|
pb_size_t size;
|
|
|
- uint8_t bytes[1];
|
|
|
|
|
|
|
+ pb_byte_t bytes[1];
|
|
|
};
|
|
};
|
|
|
typedef struct pb_bytes_array_s pb_bytes_array_t;
|
|
typedef struct pb_bytes_array_s pb_bytes_array_t;
|
|
|
|
|
|
|
@@ -275,8 +320,6 @@ typedef struct pb_bytes_array_s pb_bytes_array_t;
|
|
|
*
|
|
*
|
|
|
* The callback can be null if you want to skip a field.
|
|
* The callback can be null if you want to skip a field.
|
|
|
*/
|
|
*/
|
|
|
-typedef struct pb_istream_s pb_istream_t;
|
|
|
|
|
-typedef struct pb_ostream_s pb_ostream_t;
|
|
|
|
|
typedef struct pb_callback_s pb_callback_t;
|
|
typedef struct pb_callback_s pb_callback_t;
|
|
|
struct pb_callback_s {
|
|
struct pb_callback_s {
|
|
|
#ifdef PB_OLD_CALLBACK_STYLE
|
|
#ifdef PB_OLD_CALLBACK_STYLE
|
|
@@ -297,6 +340,8 @@ struct pb_callback_s {
|
|
|
void *arg;
|
|
void *arg;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+extern bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field);
|
|
|
|
|
+
|
|
|
/* Wire types. Library user needs these only in encoder callbacks. */
|
|
/* Wire types. Library user needs these only in encoder callbacks. */
|
|
|
typedef enum {
|
|
typedef enum {
|
|
|
PB_WT_VARINT = 0,
|
|
PB_WT_VARINT = 0,
|
|
@@ -366,7 +411,7 @@ struct pb_extension_s {
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
/* This is used to inform about need to regenerate .pb.h/.pb.c files. */
|
|
/* This is used to inform about need to regenerate .pb.h/.pb.c files. */
|
|
|
-#define PB_PROTO_HEADER_VERSION 30
|
|
|
|
|
|
|
+#define PB_PROTO_HEADER_VERSION 40
|
|
|
|
|
|
|
|
/* These macros are used to declare pb_field_t's in the constant array. */
|
|
/* These macros are used to declare pb_field_t's in the constant array. */
|
|
|
/* Size of a structure member, in bytes. */
|
|
/* Size of a structure member, in bytes. */
|
|
@@ -375,144 +420,361 @@ struct pb_extension_s {
|
|
|
#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0]))
|
|
#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0]))
|
|
|
/* Delta from start of one member to the start of another member. */
|
|
/* Delta from start of one member to the start of another member. */
|
|
|
#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2))
|
|
#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2))
|
|
|
-/* Marks the end of the field list */
|
|
|
|
|
-#define PB_LAST_FIELD {0,(pb_type_t) 0,0,0,0,0,0}
|
|
|
|
|
-
|
|
|
|
|
-/* Macros for filling in the data_offset field */
|
|
|
|
|
-/* data_offset for first field in a message */
|
|
|
|
|
-#define PB_DATAOFFSET_FIRST(st, m1, m2) (offsetof(st, m1))
|
|
|
|
|
-/* data_offset for subsequent fields */
|
|
|
|
|
-#define PB_DATAOFFSET_OTHER(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2))
|
|
|
|
|
-/* Choose first/other based on m1 == m2 (deprecated, remains for backwards compatibility) */
|
|
|
|
|
-#define PB_DATAOFFSET_CHOOSE(st, m1, m2) (int)(offsetof(st, m1) == offsetof(st, m2) \
|
|
|
|
|
- ? PB_DATAOFFSET_FIRST(st, m1, m2) \
|
|
|
|
|
- : PB_DATAOFFSET_OTHER(st, m1, m2))
|
|
|
|
|
-
|
|
|
|
|
-/* Required fields are the simplest. They just have delta (padding) from
|
|
|
|
|
- * previous field end, and the size of the field. Pointer is used for
|
|
|
|
|
- * submessages and default values.
|
|
|
|
|
|
|
+
|
|
|
|
|
+/* Force expansion of macro value */
|
|
|
|
|
+#define PB_EXPAND(x) x
|
|
|
|
|
+
|
|
|
|
|
+/* Binding of a message field set into a specific structure */
|
|
|
|
|
+#define PB_BIND(msgname, structname, width) \
|
|
|
|
|
+ const uint32_t structname ## _field_info[] = \
|
|
|
|
|
+ { \
|
|
|
|
|
+ msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ ## width, structname) \
|
|
|
|
|
+ 0 \
|
|
|
|
|
+ }; \
|
|
|
|
|
+ const pb_msgdesc_t* structname ## _submsg_info[] = \
|
|
|
|
|
+ { \
|
|
|
|
|
+ msgname ## _FIELDLIST(PB_GEN_SUBMSG_INFO, structname) \
|
|
|
|
|
+ NULL \
|
|
|
|
|
+ }; \
|
|
|
|
|
+ const pb_msgdesc_t structname ## _msg = \
|
|
|
|
|
+ { \
|
|
|
|
|
+ 0 msgname ## _FIELDLIST(PB_GEN_FIELD_COUNT, structname), \
|
|
|
|
|
+ structname ## _field_info, \
|
|
|
|
|
+ structname ## _submsg_info, \
|
|
|
|
|
+ msgname ## _DEFAULT, \
|
|
|
|
|
+ msgname ## _CALLBACK, \
|
|
|
|
|
+ }; \
|
|
|
|
|
+ msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ASSERT_ ## width, structname)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) +1
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_1(structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO(1, structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_2(structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO(2, structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_4(structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO(4, structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_8(structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO(8, structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_AUTO(structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO_AUTO2(PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype), structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_AUTO2(width, structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO(width, structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO(width, structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_FIELDINFO_ ## width(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \
|
|
|
|
|
+ PB_DATA_OFFSET_ ## atype(htype, structname, fieldname), \
|
|
|
|
|
+ PB_DATA_SIZE_ ## atype(htype, structname, fieldname), \
|
|
|
|
|
+ PB_SIZE_OFFSET_ ## atype(htype, structname, fieldname), \
|
|
|
|
|
+ PB_ARRAY_SIZE_ ## atype(htype, structname, fieldname))
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_ASSERT_1(structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO_ASSERT(1, structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_ASSERT_2(structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO_ASSERT(2, structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_ASSERT_4(structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO_ASSERT(4, structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_ASSERT_8(structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO_ASSERT(8, structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_ASSERT_AUTO(structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO_ASSERT_AUTO2(PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype), structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_ASSERT_AUTO2(width, structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_GEN_FIELD_INFO_ASSERT(width, structname, atype, htype, ltype, fieldname, tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_FIELD_INFO_ASSERT(width, structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_FIELDINFO_ASSERT_ ## width(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \
|
|
|
|
|
+ PB_DATA_OFFSET_ ## atype(htype, structname, fieldname), \
|
|
|
|
|
+ PB_DATA_SIZE_ ## atype(htype, structname, fieldname), \
|
|
|
|
|
+ PB_SIZE_OFFSET_ ## atype(htype, structname, fieldname), \
|
|
|
|
|
+ PB_ARRAY_SIZE_ ## atype(htype, structname, fieldname))
|
|
|
|
|
+
|
|
|
|
|
+#define PB_DATA_OFFSET_STATIC(htype, structname, fieldname) PB_DATA_OFFSET_ ## htype(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_OFFSET_POINTER(htype, structname, fieldname) PB_DATA_OFFSET_ ## htype(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_OFFSET_CALLBACK(htype, structname, fieldname) PB_DATA_OFFSET_ ## htype(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_OFFSET_REQUIRED(structname, fieldname) offsetof(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_OFFSET_SINGULAR(structname, fieldname) offsetof(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_OFFSET_ONEOF(structname, fieldname) offsetof(structname, PB_ONEOF_NAME(FULL, fieldname))
|
|
|
|
|
+#define PB_DATA_OFFSET_OPTIONAL(structname, fieldname) offsetof(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_OFFSET_REPEATED(structname, fieldname) offsetof(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_OFFSET_FIXARRAY(structname, fieldname) offsetof(structname, fieldname)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_SIZE_OFFSET_STATIC(htype, structname, fieldname) PB_SIZE_OFFSET_ ## htype(structname, fieldname)
|
|
|
|
|
+#define PB_SIZE_OFFSET_POINTER(htype, structname, fieldname) PB_SIZE_OFFSET_PTR_ ## htype(structname, fieldname)
|
|
|
|
|
+#define PB_SIZE_OFFSET_CALLBACK(htype, structname, fieldname) 0
|
|
|
|
|
+#define PB_SIZE_OFFSET_REQUIRED(structname, fieldname) 0
|
|
|
|
|
+#define PB_SIZE_OFFSET_SINGULAR(structname, fieldname) 0
|
|
|
|
|
+#define PB_SIZE_OFFSET_ONEOF(structname, fieldname) PB_SIZE_OFFSET_ONEOF2(structname, PB_ONEOF_NAME(FULL, fieldname), PB_ONEOF_NAME(UNION, fieldname))
|
|
|
|
|
+#define PB_SIZE_OFFSET_ONEOF2(structname, fullname, unionname) PB_SIZE_OFFSET_ONEOF3(structname, fullname, unionname)
|
|
|
|
|
+#define PB_SIZE_OFFSET_ONEOF3(structname, fullname, unionname) pb_delta(structname, fullname, which_ ## unionname)
|
|
|
|
|
+#define PB_SIZE_OFFSET_OPTIONAL(structname, fieldname) pb_delta(structname, fieldname, has_ ## fieldname)
|
|
|
|
|
+#define PB_SIZE_OFFSET_REPEATED(structname, fieldname) pb_delta(structname, fieldname, fieldname ## _count)
|
|
|
|
|
+#define PB_SIZE_OFFSET_FIXARRAY(structname, fieldname) 0
|
|
|
|
|
+#define PB_SIZE_OFFSET_PTR_REQUIRED(structname, fieldname) 0
|
|
|
|
|
+#define PB_SIZE_OFFSET_PTR_SINGULAR(structname, fieldname) 0
|
|
|
|
|
+#define PB_SIZE_OFFSET_PTR_ONEOF(structname, fieldname) PB_SIZE_OFFSET_ONEOF(structname, fieldname)
|
|
|
|
|
+#define PB_SIZE_OFFSET_PTR_OPTIONAL(structname, fieldname) 0
|
|
|
|
|
+#define PB_SIZE_OFFSET_PTR_REPEATED(structname, fieldname) PB_SIZE_OFFSET_REPEATED(structname, fieldname)
|
|
|
|
|
+#define PB_SIZE_OFFSET_PTR_FIXARRAY(structname, fieldname) 0
|
|
|
|
|
+
|
|
|
|
|
+#define PB_ARRAY_SIZE_STATIC(htype, structname, fieldname) PB_ARRAY_SIZE_ ## htype(structname, fieldname)
|
|
|
|
|
+#define PB_ARRAY_SIZE_POINTER(htype, structname, fieldname) 1
|
|
|
|
|
+#define PB_ARRAY_SIZE_CALLBACK(htype, structname, fieldname) 1
|
|
|
|
|
+#define PB_ARRAY_SIZE_REQUIRED(structname, fieldname) 1
|
|
|
|
|
+#define PB_ARRAY_SIZE_SINGULAR(structname, fieldname) 1
|
|
|
|
|
+#define PB_ARRAY_SIZE_OPTIONAL(structname, fieldname) 1
|
|
|
|
|
+#define PB_ARRAY_SIZE_ONEOF(structname, fieldname) 1
|
|
|
|
|
+#define PB_ARRAY_SIZE_REPEATED(structname, fieldname) pb_arraysize(structname, fieldname)
|
|
|
|
|
+#define PB_ARRAY_SIZE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_DATA_SIZE_STATIC(htype, structname, fieldname) PB_DATA_SIZE_ ## htype(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_SIZE_POINTER(htype, structname, fieldname) PB_DATA_SIZE_PTR_ ## htype(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_SIZE_CALLBACK(htype, structname, fieldname) pb_membersize(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_SIZE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_SIZE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_SIZE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname)
|
|
|
|
|
+#define PB_DATA_SIZE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname))
|
|
|
|
|
+#define PB_DATA_SIZE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0])
|
|
|
|
|
+#define PB_DATA_SIZE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0])
|
|
|
|
|
+#define PB_DATA_SIZE_PTR_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname[0])
|
|
|
|
|
+#define PB_DATA_SIZE_PTR_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname[0])
|
|
|
|
|
+#define PB_DATA_SIZE_PTR_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname[0])
|
|
|
|
|
+#define PB_DATA_SIZE_PTR_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)[0])
|
|
|
|
|
+#define PB_DATA_SIZE_PTR_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0])
|
|
|
|
|
+#define PB_DATA_SIZE_PTR_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0])
|
|
|
|
|
+
|
|
|
|
|
+#define PB_ONEOF_NAME(type, tuple) PB_EXPAND(PB_ONEOF_NAME_ ## type tuple)
|
|
|
|
|
+#define PB_ONEOF_NAME_UNION(unionname,membername,fullname) unionname
|
|
|
|
|
+#define PB_ONEOF_NAME_MEMBER(unionname,membername,fullname) membername
|
|
|
|
|
+#define PB_ONEOF_NAME_FULL(unionname,membername,fullname) fullname
|
|
|
|
|
+
|
|
|
|
|
+#define PB_GEN_SUBMSG_INFO(structname, atype, htype, ltype, fieldname, tag) \
|
|
|
|
|
+ PB_SUBMSG_INFO_ ## htype(ltype, structname, fieldname)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_SUBMSG_INFO_REQUIRED(ltype, structname, fieldname) PB_SUBMSG_INFO_ ## ltype(structname ## _ ## fieldname ## _MSGTYPE)
|
|
|
|
|
+#define PB_SUBMSG_INFO_SINGULAR(ltype, structname, fieldname) PB_SUBMSG_INFO_ ## ltype(structname ## _ ## fieldname ## _MSGTYPE)
|
|
|
|
|
+#define PB_SUBMSG_INFO_OPTIONAL(ltype, structname, fieldname) PB_SUBMSG_INFO_ ## ltype(structname ## _ ## fieldname ## _MSGTYPE)
|
|
|
|
|
+#define PB_SUBMSG_INFO_ONEOF(ltype, structname, fieldname) PB_SUBMSG_INFO_ONEOF2(ltype, structname, PB_ONEOF_NAME(UNION, fieldname), PB_ONEOF_NAME(MEMBER, fieldname))
|
|
|
|
|
+#define PB_SUBMSG_INFO_ONEOF2(ltype, structname, unionname, membername) PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername)
|
|
|
|
|
+#define PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) PB_SUBMSG_INFO_ ## ltype(structname ## _ ## unionname ## _ ## membername ## _MSGTYPE)
|
|
|
|
|
+#define PB_SUBMSG_INFO_REPEATED(ltype, structname, fieldname) PB_SUBMSG_INFO_ ## ltype(structname ## _ ## fieldname ## _MSGTYPE)
|
|
|
|
|
+#define PB_SUBMSG_INFO_FIXARRAY(ltype, structname, fieldname) PB_SUBMSG_INFO_ ## ltype(structname ## _ ## fieldname ## _MSGTYPE)
|
|
|
|
|
+#define PB_SUBMSG_INFO_BOOL(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_BYTES(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_DOUBLE(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_ENUM(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_UENUM(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_FIXED32(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_FIXED64(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_FLOAT(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_INT32(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_INT64(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_MESSAGE(t) PB_SUBMSG_DESCRIPTOR(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_SFIXED32(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_SFIXED64(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_SINT32(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_SINT64(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_STRING(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_UINT32(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_UINT64(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_EXTENSION(t)
|
|
|
|
|
+#define PB_SUBMSG_INFO_FIXED_LENGTH_BYTES(t)
|
|
|
|
|
+#define PB_SUBMSG_DESCRIPTOR(t) &(t ## _msg),
|
|
|
|
|
+
|
|
|
|
|
+/* The field descriptors use a variable width format, with width of either
|
|
|
|
|
+ * 1, 2, 4 or 8 of 32-bit words. The two lowest bytes of the first byte always
|
|
|
|
|
+ * encode the descriptor size, 6 lowest bits of field tag number, and 8 bits
|
|
|
|
|
+ * of the field type.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Descriptor size is encoded as 0 = 1 word, 1 = 2 words, 2 = 4 words, 3 = 8 words.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Formats, listed starting with the least significant bit of the first word.
|
|
|
|
|
+ * 1 word: [2-bit len] [6-bit tag] [8-bit type] [8-bit data_offset] [4-bit size_offset] [4-bit data_size]
|
|
|
|
|
+ *
|
|
|
|
|
+ * 2 words: [2-bit len] [6-bit tag] [8-bit type] [12-bit array_size] [4-bit size_offset]
|
|
|
|
|
+ * [16-bit data_offset] [12-bit data_size] [4-bit tag>>6]
|
|
|
|
|
+ *
|
|
|
|
|
+ * 4 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit array_size]
|
|
|
|
|
+ * [8-bit size_offset] [24-bit tag>>6]
|
|
|
|
|
+ * [32-bit data_offset]
|
|
|
|
|
+ * [32-bit data_size]
|
|
|
|
|
+ *
|
|
|
|
|
+ * 8 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit reserved]
|
|
|
|
|
+ * [8-bit size_offset] [24-bit tag>>6]
|
|
|
|
|
+ * [32-bit data_offset]
|
|
|
|
|
+ * [32-bit data_size]
|
|
|
|
|
+ * [32-bit array_size]
|
|
|
|
|
+ * [32-bit reserved]
|
|
|
|
|
+ * [32-bit reserved]
|
|
|
|
|
+ * [32-bit reserved]
|
|
|
*/
|
|
*/
|
|
|
-#define PB_REQUIRED_STATIC(tag, st, m, fd, ltype, ptr) \
|
|
|
|
|
- {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \
|
|
|
|
|
- fd, 0, pb_membersize(st, m), 0, ptr}
|
|
|
|
|
-
|
|
|
|
|
-/* Optional fields add the delta to the has_ variable. */
|
|
|
|
|
-#define PB_OPTIONAL_STATIC(tag, st, m, fd, ltype, ptr) \
|
|
|
|
|
- {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \
|
|
|
|
|
- fd, \
|
|
|
|
|
- pb_delta(st, has_ ## m, m), \
|
|
|
|
|
- pb_membersize(st, m), 0, ptr}
|
|
|
|
|
-
|
|
|
|
|
-/* Repeated fields have a _count field and also the maximum number of entries. */
|
|
|
|
|
-#define PB_REPEATED_STATIC(tag, st, m, fd, ltype, ptr) \
|
|
|
|
|
- {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | ltype, \
|
|
|
|
|
- fd, \
|
|
|
|
|
- pb_delta(st, m ## _count, m), \
|
|
|
|
|
- pb_membersize(st, m[0]), \
|
|
|
|
|
- pb_arraysize(st, m), ptr}
|
|
|
|
|
-
|
|
|
|
|
-/* Allocated fields carry the size of the actual data, not the pointer */
|
|
|
|
|
-#define PB_REQUIRED_POINTER(tag, st, m, fd, ltype, ptr) \
|
|
|
|
|
- {tag, PB_ATYPE_POINTER | PB_HTYPE_REQUIRED | ltype, \
|
|
|
|
|
- fd, 0, pb_membersize(st, m[0]), 0, ptr}
|
|
|
|
|
-
|
|
|
|
|
-/* Optional fields don't need a has_ variable, as information would be redundant */
|
|
|
|
|
-#define PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) \
|
|
|
|
|
- {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \
|
|
|
|
|
- fd, 0, pb_membersize(st, m[0]), 0, ptr}
|
|
|
|
|
-
|
|
|
|
|
-/* Repeated fields have a _count field and a pointer to array of pointers */
|
|
|
|
|
-#define PB_REPEATED_POINTER(tag, st, m, fd, ltype, ptr) \
|
|
|
|
|
- {tag, PB_ATYPE_POINTER | PB_HTYPE_REPEATED | ltype, \
|
|
|
|
|
- fd, pb_delta(st, m ## _count, m), \
|
|
|
|
|
- pb_membersize(st, m[0]), 0, ptr}
|
|
|
|
|
-
|
|
|
|
|
-/* Callbacks are much like required fields except with special datatype. */
|
|
|
|
|
-#define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
|
|
|
|
- {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \
|
|
|
|
|
- fd, 0, pb_membersize(st, m), 0, ptr}
|
|
|
|
|
-
|
|
|
|
|
-#define PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
|
|
|
|
- {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \
|
|
|
|
|
- fd, 0, pb_membersize(st, m), 0, ptr}
|
|
|
|
|
-
|
|
|
|
|
-#define PB_REPEATED_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
|
|
|
|
- {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REPEATED | ltype, \
|
|
|
|
|
- fd, 0, pb_membersize(st, m), 0, ptr}
|
|
|
|
|
|
|
|
|
|
-/* Optional extensions don't have the has_ field, as that would be redundant. */
|
|
|
|
|
-#define PB_OPTEXT_STATIC(tag, st, m, fd, ltype, ptr) \
|
|
|
|
|
- {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \
|
|
|
|
|
- 0, \
|
|
|
|
|
- 0, \
|
|
|
|
|
- pb_membersize(st, m), 0, ptr}
|
|
|
|
|
|
|
+#define PB_FIELDINFO_1(tag, type, data_offset, data_size, size_offset, array_size) \
|
|
|
|
|
+ (0 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(data_offset) & 0xFF) << 16) | \
|
|
|
|
|
+ (((uint32_t)(size_offset) & 0x0F) << 24) | (((uint32_t)(data_size) & 0x0F) << 28)),
|
|
|
|
|
+
|
|
|
|
|
+#define PB_FIELDINFO_2(tag, type, data_offset, data_size, size_offset, array_size) \
|
|
|
|
|
+ (1 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFF) << 16) | (((uint32_t)(size_offset) & 0x0F) << 28)), \
|
|
|
|
|
+ (((uint32_t)(data_offset) & 0xFFFF) | (((uint32_t)(data_size) & 0xFFF) << 16) | (((uint32_t)(tag) & 0x2c0) << 22)),
|
|
|
|
|
+
|
|
|
|
|
+#define PB_FIELDINFO_4(tag, type, data_offset, data_size, size_offset, array_size) \
|
|
|
|
|
+ (2 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFFF) << 16)), \
|
|
|
|
|
+ ((uint32_t)(int8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \
|
|
|
|
|
+ (data_offset), (data_size),
|
|
|
|
|
+
|
|
|
|
|
+#define PB_FIELDINFO_8(tag, type, data_offset, data_size, size_offset, array_size) \
|
|
|
|
|
+ (3 | (((tag) << 2) & 0xFF) | ((type) << 8)), \
|
|
|
|
|
+ ((uint32_t)(int8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \
|
|
|
|
|
+ (data_offset), (data_size), (array_size)
|
|
|
|
|
+
|
|
|
|
|
+/* These assertions verify that the field information fits in the allocated space.
|
|
|
|
|
+ * The generator tries to automatically determine the correct width that can fit all
|
|
|
|
|
+ * data associated with a message. These asserts will fail only if there has been a
|
|
|
|
|
+ * problem in the automatic logic - this may be worth reporting as a bug. As a workaround,
|
|
|
|
|
+ * you can increase the descriptor width by defining PB_FIELDINFO_WIDTH or by setting
|
|
|
|
|
+ * descriptorsize option in .options file.
|
|
|
|
|
+ */
|
|
|
|
|
+#define PB_FITS(value,bits) ((uint32_t)(value) < ((uint32_t)1<<bits))
|
|
|
|
|
+#define PB_FIELDINFO_ASSERT_1(tag, type, data_offset, data_size, size_offset, array_size) \
|
|
|
|
|
+ PB_STATIC_ASSERT(PB_FITS(tag,6) && PB_FITS(data_offset,8) && PB_FITS(size_offset,4) && PB_FITS(data_size,4) && PB_FITS(array_size,1), FIELDINFO_DOES_NOT_FIT_width1_field ## tag)
|
|
|
|
|
|
|
|
-#define PB_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
|
|
|
|
- {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \
|
|
|
|
|
- 0, 0, pb_membersize(st, m), 0, ptr}
|
|
|
|
|
|
|
+#define PB_FIELDINFO_ASSERT_2(tag, type, data_offset, data_size, size_offset, array_size) \
|
|
|
|
|
+ PB_STATIC_ASSERT(PB_FITS(tag,10) && PB_FITS(data_offset,16) && PB_FITS(size_offset,4) && PB_FITS(data_size,12) && PB_FITS(array_size,12), FIELDINFO_DOES_NOT_FIT_width2_field ## tag)
|
|
|
|
|
|
|
|
-/* The mapping from protobuf types to LTYPEs is done using these macros. */
|
|
|
|
|
-#define PB_LTYPE_MAP_BOOL PB_LTYPE_VARINT
|
|
|
|
|
-#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES
|
|
|
|
|
-#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64
|
|
|
|
|
-#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT
|
|
|
|
|
-#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32
|
|
|
|
|
-#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64
|
|
|
|
|
-#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32
|
|
|
|
|
-#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT
|
|
|
|
|
-#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT
|
|
|
|
|
-#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE
|
|
|
|
|
-#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32
|
|
|
|
|
-#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64
|
|
|
|
|
-#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT
|
|
|
|
|
-#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT
|
|
|
|
|
-#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING
|
|
|
|
|
-#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT
|
|
|
|
|
-#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT
|
|
|
|
|
-#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION
|
|
|
|
|
-
|
|
|
|
|
-/* This is the actual macro used in field descriptions.
|
|
|
|
|
- * It takes these arguments:
|
|
|
|
|
- * - Field tag number
|
|
|
|
|
- * - Field type: BOOL, BYTES, DOUBLE, ENUM, FIXED32, FIXED64,
|
|
|
|
|
- * FLOAT, INT32, INT64, MESSAGE, SFIXED32, SFIXED64
|
|
|
|
|
- * SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION
|
|
|
|
|
- * - Field rules: REQUIRED, OPTIONAL or REPEATED
|
|
|
|
|
- * - Allocation: STATIC or CALLBACK
|
|
|
|
|
- * - Placement: FIRST or OTHER, depending on if this is the first field in structure.
|
|
|
|
|
- * - Message name
|
|
|
|
|
- * - Field name
|
|
|
|
|
- * - Previous field name (or field name again for first field)
|
|
|
|
|
- * - Pointer to default value or submsg fields.
|
|
|
|
|
|
|
+#ifndef PB_FIELD_32BIT
|
|
|
|
|
+/* Maximum field sizes are still 16-bit if pb_size_t is 16-bit */
|
|
|
|
|
+#define PB_FIELDINFO_ASSERT_4(tag, type, data_offset, data_size, size_offset, array_size) \
|
|
|
|
|
+ PB_STATIC_ASSERT(PB_FITS(tag,16) && PB_FITS(data_offset,16) && PB_FITS((int8_t)size_offset,8) && PB_FITS(data_size,16) && PB_FITS(array_size,16), FIELDINFO_DOES_NOT_FIT_width4_field ## tag)
|
|
|
|
|
+
|
|
|
|
|
+#define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, array_size) \
|
|
|
|
|
+ PB_STATIC_ASSERT(PB_FITS(tag,16) && PB_FITS(data_offset,16) && PB_FITS((int8_t)size_offset,8) && PB_FITS(data_size,16) && PB_FITS(array_size,16), FIELDINFO_DOES_NOT_FIT_width8_field ## tag)
|
|
|
|
|
+#else
|
|
|
|
|
+/* Up to 32-bit fields supported.
|
|
|
|
|
+ * Note that the checks are against 31 bits to avoid compiler warnings about shift wider than type in the test.
|
|
|
|
|
+ * I expect that there is no reasonable use for >2GB messages with nanopb anyway.
|
|
|
*/
|
|
*/
|
|
|
|
|
+#define PB_FIELDINFO_ASSERT_4(tag, type, data_offset, data_size, size_offset, array_size) \
|
|
|
|
|
+ PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS((int8_t)size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,16), FIELDINFO_DOES_NOT_FIT_width4_field ## tag)
|
|
|
|
|
|
|
|
-#define PB_FIELD(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
|
|
|
|
|
- PB_ ## rules ## _ ## allocation(tag, message, field, \
|
|
|
|
|
- PB_DATAOFFSET_ ## placement(message, field, prevfield), \
|
|
|
|
|
- PB_LTYPE_MAP_ ## type, ptr)
|
|
|
|
|
|
|
+#define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, array_size) \
|
|
|
|
|
+ PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS((int8_t)size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,31), FIELDINFO_DOES_NOT_FIT_width8_field ## tag)
|
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+/* Automatic picking of FIELDINFO width:
|
|
|
|
|
+ * Uses width 1 when possible, otherwise resorts to width 2.
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+#ifndef PB_FIELDINFO_WIDTH
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FIELDINFO_WIDTH_ ## atype(htype, ltype)
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_STATIC(htype, ltype) PB_FIELDINFO_WIDTH_ ## htype(ltype)
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_POINTER(htype, ltype) PB_FIELDINFO_WIDTH_ ## htype(ltype)
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_CALLBACK(htype, ltype) 2
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_REQUIRED(ltype) PB_FIELDINFO_WIDTH_ ## ltype
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_SINGULAR(ltype) PB_FIELDINFO_WIDTH_ ## ltype
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_OPTIONAL(ltype) PB_FIELDINFO_WIDTH_ ## ltype
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_ONEOF(ltype) PB_FIELDINFO_WIDTH_ ## ltype
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_REPEATED(ltype) 2
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_FIXARRAY(ltype) 2
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_BOOL 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_BYTES 2
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_DOUBLE 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_ENUM 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_UENUM 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_FIXED32 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_FIXED64 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_FLOAT 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_INT32 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_INT64 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_MESSAGE 2
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_SFIXED32 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_SFIXED64 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_SINT32 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_SINT64 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_STRING 2
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_UINT32 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_UINT64 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_EXTENSION 1
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_FIXED_LENGTH_BYTES 2
|
|
|
|
|
+#else
|
|
|
|
|
+#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FIELDINFO_WIDTH
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+/* The mapping from protobuf types to LTYPEs is done using these macros. */
|
|
|
|
|
+#define PB_LTYPE_MAP_BOOL PB_LTYPE_VARINT
|
|
|
|
|
+#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES
|
|
|
|
|
+#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64
|
|
|
|
|
+#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT
|
|
|
|
|
+#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT
|
|
|
|
|
+#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32
|
|
|
|
|
+#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64
|
|
|
|
|
+#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32
|
|
|
|
|
+#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT
|
|
|
|
|
+#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT
|
|
|
|
|
+#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE
|
|
|
|
|
+#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32
|
|
|
|
|
+#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64
|
|
|
|
|
+#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT
|
|
|
|
|
+#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT
|
|
|
|
|
+#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING
|
|
|
|
|
+#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT
|
|
|
|
|
+#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT
|
|
|
|
|
+#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION
|
|
|
|
|
+#define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES
|
|
|
|
|
+
|
|
|
/* These macros are used for giving out error messages.
|
|
/* These macros are used for giving out error messages.
|
|
|
* They are mostly a debugging aid; the main error information
|
|
* They are mostly a debugging aid; the main error information
|
|
|
* is the true/false return value from functions.
|
|
* is the true/false return value from functions.
|
|
|
* Some code space can be saved by disabling the error
|
|
* Some code space can be saved by disabling the error
|
|
|
* messages if not used.
|
|
* messages if not used.
|
|
|
|
|
+ *
|
|
|
|
|
+ * PB_SET_ERROR() sets the error message if none has been set yet.
|
|
|
|
|
+ * msg must be a constant string literal.
|
|
|
|
|
+ * PB_GET_ERROR() always returns a pointer to a string.
|
|
|
|
|
+ * PB_RETURN_ERROR() sets the error and returns false from current
|
|
|
|
|
+ * function.
|
|
|
*/
|
|
*/
|
|
|
#ifdef PB_NO_ERRMSG
|
|
#ifdef PB_NO_ERRMSG
|
|
|
-#define PB_RETURN_ERROR(stream,msg) \
|
|
|
|
|
- do {\
|
|
|
|
|
- PB_UNUSED(stream); \
|
|
|
|
|
- return false; \
|
|
|
|
|
- } while(0)
|
|
|
|
|
|
|
+#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream)
|
|
|
#define PB_GET_ERROR(stream) "(errmsg disabled)"
|
|
#define PB_GET_ERROR(stream) "(errmsg disabled)"
|
|
|
#else
|
|
#else
|
|
|
-#define PB_RETURN_ERROR(stream,msg) \
|
|
|
|
|
- do {\
|
|
|
|
|
- if ((stream)->errmsg == NULL) \
|
|
|
|
|
- (stream)->errmsg = (msg); \
|
|
|
|
|
- return false; \
|
|
|
|
|
- } while(0)
|
|
|
|
|
|
|
+#define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg))
|
|
|
#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)")
|
|
#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)")
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
+#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false
|
|
|
|
|
+
|
|
|
|
|
+#ifdef __cplusplus
|
|
|
|
|
+} /* extern "C" */
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#ifdef __cplusplus
|
|
|
|
|
+#if __cplusplus >= 201103L
|
|
|
|
|
+#define PB_CONSTEXPR constexpr
|
|
|
|
|
+#else // __cplusplus >= 201103L
|
|
|
|
|
+#define PB_CONSTEXPR
|
|
|
|
|
+#endif // __cplusplus >= 201103L
|
|
|
|
|
+
|
|
|
|
|
+#if __cplusplus >= 201703L
|
|
|
|
|
+#define PB_INLINE_CONSTEXPR inline constexpr
|
|
|
|
|
+#else // __cplusplus >= 201703L
|
|
|
|
|
+#define PB_INLINE_CONSTEXPR PB_CONSTEXPR
|
|
|
|
|
+#endif // __cplusplus >= 201703L
|
|
|
|
|
+
|
|
|
|
|
+namespace nanopb {
|
|
|
|
|
+// Each type will be partially specialized by the generator.
|
|
|
|
|
+template <typename GenMessageT> struct MessageDescriptor;
|
|
|
|
|
+} // namespace nanopb
|
|
|
|
|
+#endif /* __cplusplus */
|
|
|
|
|
+
|
|
|
#endif
|
|
#endif
|
|
|
|
|
+
|