X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=pb.h;h=c0c25283e0143b4742ccca81d1cda53e1468f660;hb=f47410ea4b8ae43e19facd378be4cf1073e1813b;hp=d5047ac52f37645ea0e7876be7c81eb418b4ba34;hpb=0ed3158560fe4b96d1d0df7f6b655409917f5989;p=apps%2Fagl-service-can-low-level.git diff --git a/pb.h b/pb.h index d5047ac5..c0c25283 100644 --- a/pb.h +++ b/pb.h @@ -43,7 +43,7 @@ /* Version of the nanopb library. Just in case you want to check it in * your own program. */ -#define NANOPB_VERSION nanopb-0.2.2-dev +#define NANOPB_VERSION nanopb-0.2.3-dev /* Include all the system headers needed by nanopb. You will need the * definitions of the following: @@ -148,8 +148,12 @@ typedef uint8_t pb_type_t; * submsg_fields is pointer to field descriptions */ #define PB_LTYPE_SUBMESSAGE 0x06 +/* Extension pseudo-field + * The field contains a pointer to pb_extension_t */ +#define PB_LTYPE_EXTENSION 0x07 + /* Number of declared LTYPES */ -#define PB_LTYPES_COUNT 7 +#define PB_LTYPES_COUNT 8 #define PB_LTYPE_MASK 0x0F /**** Field repetition rules ****/ @@ -211,6 +215,17 @@ struct _pb_field_t { } pb_packed; PB_PACKED_STRUCT_END +/* Make sure that the standard integer types are of the expected sizes. + * All kinds of things may break otherwise.. atleast all fixed* types. */ +STATIC_ASSERT(sizeof(int8_t) == 1, INT8_T_WRONG_SIZE) +STATIC_ASSERT(sizeof(uint8_t) == 1, UINT8_T_WRONG_SIZE) +STATIC_ASSERT(sizeof(int16_t) == 2, INT16_T_WRONG_SIZE) +STATIC_ASSERT(sizeof(uint16_t) == 2, UINT16_T_WRONG_SIZE) +STATIC_ASSERT(sizeof(int32_t) == 4, INT32_T_WRONG_SIZE) +STATIC_ASSERT(sizeof(uint32_t) == 4, UINT32_T_WRONG_SIZE) +STATIC_ASSERT(sizeof(int64_t) == 8, INT64_T_WRONG_SIZE) +STATIC_ASSERT(sizeof(uint64_t) == 8, UINT64_T_WRONG_SIZE) + /* This structure is used for 'bytes' arrays. * 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. @@ -270,50 +285,117 @@ typedef enum { PB_WT_32BIT = 5 } pb_wire_type_t; +/* Structure for defining the handling of unknown/extension fields. + * Usually the pb_extension_type_t structure is automatically generated, + * while the pb_extension_t structure is created by the user. However, + * if you want to catch all unknown fields, you can also create a custom + * pb_extension_type_t with your own callback. + */ +typedef struct _pb_extension_type_t pb_extension_type_t; +typedef struct _pb_extension_t pb_extension_t; +struct _pb_extension_type_t { + /* Called for each unknown field in the message. + * If you handle the field, read off all of its data and return true. + * If you do not handle the field, do not read anything and return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, + uint32_t tag, pb_wire_type_t wire_type); + + /* Called once after all regular fields have been encoded. + * If you have something to write, do so and return true. + * If you do not have anything to write, just return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); + + /* Free field for use by the callback. */ + const void *arg; +}; + +struct _pb_extension_t { + /* Type describing the extension field. Usually you'll initialize + * this to a pointer to the automatically generated structure. */ + const pb_extension_type_t *type; + + /* Destination for the decoded data. This must match the datatype + * of the extension field. */ + void *dest; + + /* Pointer to the next extension handler, or NULL. + * If this extension does not match a field, the next handler is + * automatically called. */ + pb_extension_t *next; +}; + /* These macros are used to declare pb_field_t's in the constant array. */ +/* Size of a structure member, in bytes. */ #define pb_membersize(st, m) (sizeof ((st*)0)->m) +/* Number of entries in an array. */ #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. */ #define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) -#define pb_delta_end(st, m1, m2) (int)(offsetof(st, m1) == offsetof(st, m2) \ - ? offsetof(st, m1) \ - : offsetof(st, m1) - offsetof(st, m2) - pb_membersize(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. */ -#define PB_REQUIRED_STATIC(tag, st, m, pm, ltype, ptr) \ +#define PB_REQUIRED_STATIC(tag, st, m, fd, ltype, ptr) \ {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \ - pb_delta_end(st, m, pm), 0, pb_membersize(st, m), 0, ptr} + fd, 0, pb_membersize(st, m), 0, ptr} /* Optional fields add the delta to the has_ variable. */ -#define PB_OPTIONAL_STATIC(tag, st, m, pm, ltype, ptr) \ +#define PB_OPTIONAL_STATIC(tag, st, m, fd, ltype, ptr) \ {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \ - pb_delta_end(st, m, pm), \ + 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, pm, ltype, ptr) \ +#define PB_REPEATED_STATIC(tag, st, m, fd, ltype, ptr) \ {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | ltype, \ - pb_delta_end(st, m, pm), \ + fd, \ pb_delta(st, m ## _count, m), \ pb_membersize(st, m[0]), \ pb_arraysize(st, m), ptr} /* Callbacks are much like required fields except with special datatype. */ -#define PB_REQUIRED_CALLBACK(tag, st, m, pm, ltype, ptr) \ +#define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \ {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \ - pb_delta_end(st, m, pm), 0, pb_membersize(st, m), 0, ptr} + fd, 0, pb_membersize(st, m), 0, ptr} -#define PB_OPTIONAL_CALLBACK(tag, st, m, pm, ltype, ptr) \ +#define PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) \ {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \ - pb_delta_end(st, m, pm), 0, pb_membersize(st, m), 0, ptr} + fd, 0, pb_membersize(st, m), 0, ptr} -#define PB_REPEATED_CALLBACK(tag, st, m, pm, ltype, ptr) \ +#define PB_REPEATED_CALLBACK(tag, st, m, fd, ltype, ptr) \ {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REPEATED | ltype, \ - pb_delta_end(st, m, pm), 0, pb_membersize(st, m), 0, ptr} + 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_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \ + 0, 0, pb_membersize(st, m), 0, ptr} /* The mapping from protobuf types to LTYPEs is done using these macros. */ #define PB_LTYPE_MAP_BOOL PB_LTYPE_VARINT @@ -333,13 +415,14 @@ typedef enum { #define PB_LTYPE_MAP_STRING PB_LTYPE_STRING #define PB_LTYPE_MAP_UINT32 PB_LTYPE_VARINT #define PB_LTYPE_MAP_UINT64 PB_LTYPE_VARINT +#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 or UINT64 + * SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION * - Field rules: REQUIRED, OPTIONAL or REPEATED * - Allocation: STATIC or CALLBACK * - Message name @@ -349,8 +432,22 @@ typedef enum { */ #define PB_FIELD(tag, type, rules, allocation, message, field, prevfield, ptr) \ - PB_ ## rules ## _ ## allocation(tag, message, field, prevfield, \ - PB_LTYPE_MAP_ ## type, ptr) + PB_ ## rules ## _ ## allocation(tag, message, field, \ + PB_DATAOFFSET_CHOOSE(message, field, prevfield), \ + PB_LTYPE_MAP_ ## type, ptr) + +/* This is a new version of the macro used by nanopb generator from + * version 0.2.3 onwards. It avoids the use of a ternary expression in + * the initialization, which confused some compilers. + * + * - Placement: FIRST or OTHER, depending on if this is the first field in structure. + * + */ +#define PB_FIELD2(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) + /* These macros are used for giving out error messages. * They are mostly a debugging aid; the main error information