diff options
author | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2013-02-21 19:38:56 +0200 |
---|---|---|
committer | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2013-02-21 19:38:56 +0200 |
commit | 5442e690f65fd09e7a44437da02fb7e14af6fe8f (patch) | |
tree | ecb8e53aec39dc51f6160d1664e4e50cd4996e64 | |
parent | 5b536d40a11edb3161f2f19609c2b51899c354b0 (diff) | |
parent | 80a2d33fa9a835564b44fe97ba34e713901cf4fb (diff) |
Merge branch 'dev-0.2'
-rw-r--r-- | .gitignore | 39 | ||||
-rw-r--r-- | generator/nanopb_generator.py | 197 | ||||
-rw-r--r-- | pb.h | 180 | ||||
-rw-r--r-- | pb_decode.c | 164 | ||||
-rw-r--r-- | pb_encode.c | 97 | ||||
-rw-r--r-- | tests/bc_alltypes.pb.c | 361 | ||||
-rw-r--r-- | tests/bc_alltypes.pb.h | 39 |
7 files changed, 507 insertions, 570 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..dec8b00e --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +*.gcda +*.gcno +*.gcov +*.o +*.pb.c +*.pb.h +*.pb +*~ +*.tar.gz +julkaisu.txt +docs/*.html +docs/generator_flow.png +example/client +example/server +example_avr_double/decode_double +example_avr_double/encode_double +example_avr_double/test_conversions +example_unions/decode +example_unions/encode +generator/nanopb_pb2.pyc +tests/decode_unittests +tests/encode_unittests +tests/test_compiles +tests/test_decode1 +tests/test_decode2 +tests/test_decode3 +tests/test_decode3_buf +tests/test_decode_callbacks +tests/test_encode1 +tests/test_encode2 +tests/test_encode3 +tests/test_encode3_buf +tests/test_encode_callbacks +tests/test_missing_fields +tests/test_multiple_files +tests/bc_decode +tests/bc_encode +tests/breakpoints + diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py index ca81adf5..45b2ac68 100644 --- a/generator/nanopb_generator.py +++ b/generator/nanopb_generator.py @@ -1,5 +1,5 @@ '''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.''' -nanopb_version = "nanopb-0.1.9.1-dev" +nanopb_version = "0.2.0-dev" try: import google.protobuf.descriptor_pb2 as descriptor @@ -35,22 +35,22 @@ except: import time import os.path -# Values are tuple (c type, pb ltype) +# Values are tuple (c type, pb type) FieldD = descriptor.FieldDescriptorProto datatypes = { - FieldD.TYPE_BOOL: ('bool', 'PB_LTYPE_VARINT'), - FieldD.TYPE_DOUBLE: ('double', 'PB_LTYPE_FIXED64'), - FieldD.TYPE_FIXED32: ('uint32_t', 'PB_LTYPE_FIXED32'), - FieldD.TYPE_FIXED64: ('uint64_t', 'PB_LTYPE_FIXED64'), - FieldD.TYPE_FLOAT: ('float', 'PB_LTYPE_FIXED32'), - FieldD.TYPE_INT32: ('int32_t', 'PB_LTYPE_VARINT'), - FieldD.TYPE_INT64: ('int64_t', 'PB_LTYPE_VARINT'), - FieldD.TYPE_SFIXED32: ('int32_t', 'PB_LTYPE_FIXED32'), - FieldD.TYPE_SFIXED64: ('int64_t', 'PB_LTYPE_FIXED64'), - FieldD.TYPE_SINT32: ('int32_t', 'PB_LTYPE_SVARINT'), - FieldD.TYPE_SINT64: ('int64_t', 'PB_LTYPE_SVARINT'), - FieldD.TYPE_UINT32: ('uint32_t', 'PB_LTYPE_VARINT'), - FieldD.TYPE_UINT64: ('uint64_t', 'PB_LTYPE_VARINT') + FieldD.TYPE_BOOL: ('bool', 'BOOL'), + FieldD.TYPE_DOUBLE: ('double', 'DOUBLE'), + FieldD.TYPE_FIXED32: ('uint32_t', 'FIXED32'), + FieldD.TYPE_FIXED64: ('uint64_t', 'FIXED64'), + FieldD.TYPE_FLOAT: ('float', 'FLOAT'), + FieldD.TYPE_INT32: ('int32_t', 'INT32'), + FieldD.TYPE_INT64: ('int64_t', 'INT64'), + FieldD.TYPE_SFIXED32: ('int32_t', 'SFIXED32'), + FieldD.TYPE_SFIXED64: ('int64_t', 'SFIXED64'), + FieldD.TYPE_SINT32: ('int32_t', 'SINT32'), + FieldD.TYPE_SINT64: ('int64_t', 'SINT64'), + FieldD.TYPE_UINT32: ('uint32_t', 'UINT32'), + FieldD.TYPE_UINT64: ('uint64_t', 'UINT64') } class Names: @@ -123,49 +123,44 @@ class Field: if desc.HasField('default_value'): self.default = desc.default_value - # Decide HTYPE - # HTYPE is the high-order nibble of nanopb field description, - # defining whether value is required/optional/repeated. + # Check field rules, i.e. required/optional/repeated. can_be_static = True if desc.label == FieldD.LABEL_REQUIRED: - self.htype = 'PB_HTYPE_REQUIRED' + self.rules = 'REQUIRED' elif desc.label == FieldD.LABEL_OPTIONAL: - self.htype = 'PB_HTYPE_OPTIONAL' + self.rules = 'OPTIONAL' elif desc.label == FieldD.LABEL_REPEATED: + self.rules = 'REPEATED' if self.max_count is None: can_be_static = False else: - self.htype = 'PB_HTYPE_ARRAY' self.array_decl = '[%d]' % self.max_count else: raise NotImplementedError(desc.label) - # Decide LTYPE and CTYPE - # LTYPE is the low-order nibble of nanopb field description, - # defining how to decode an individual value. - # CTYPE is the name of the c type to use in the struct. + # Decide the C data type to use in the struct. if datatypes.has_key(desc.type): - self.ctype, self.ltype = datatypes[desc.type] + self.ctype, self.pbtype = datatypes[desc.type] elif desc.type == FieldD.TYPE_ENUM: - self.ltype = 'PB_LTYPE_VARINT' + self.pbtype = 'ENUM' self.ctype = names_from_type_name(desc.type_name) if self.default is not None: self.default = self.ctype + self.default elif desc.type == FieldD.TYPE_STRING: - self.ltype = 'PB_LTYPE_STRING' + self.pbtype = 'STRING' if self.max_size is None: can_be_static = False else: self.ctype = 'char' self.array_decl += '[%d]' % self.max_size elif desc.type == FieldD.TYPE_BYTES: - self.ltype = 'PB_LTYPE_BYTES' + self.pbtype = 'BYTES' if self.max_size is None: can_be_static = False else: self.ctype = self.struct_name + self.name + 't' elif desc.type == FieldD.TYPE_MESSAGE: - self.ltype = 'PB_LTYPE_SUBMESSAGE' + self.pbtype = 'MESSAGE' self.ctype = self.submsgname = names_from_type_name(desc.type_name) else: raise NotImplementedError(desc.type) @@ -179,18 +174,22 @@ class Field: if field_options.type == nanopb_pb2.FT_STATIC and not can_be_static: raise Exception("Field %s is defined as static, but max_size or max_count is not given." % self.name) - if field_options.type == nanopb_pb2.FT_CALLBACK: - self.htype = 'PB_HTYPE_CALLBACK' + if field_options.type == nanopb_pb2.FT_STATIC: + self.allocation = 'STATIC' + elif field_options.type == nanopb_pb2.FT_CALLBACK: + self.allocation = 'CALLBACK' self.ctype = 'pb_callback_t' self.array_decl = '' + else: + raise NotImplementedError(field_options.type) def __cmp__(self, other): return cmp(self.tag, other.tag) def __str__(self): - if self.htype == 'PB_HTYPE_OPTIONAL': + if self.rules == 'OPTIONAL': result = ' bool has_' + self.name + ';\n' - elif self.htype == 'PB_HTYPE_ARRAY': + elif self.rules == 'REPEATED' and self.allocation == 'STATIC': result = ' size_t ' + self.name + '_count;\n' else: result = '' @@ -199,7 +198,7 @@ class Field: def types(self): '''Return definitions for any special types this field might need.''' - if self.ltype == 'PB_LTYPE_BYTES' and self.max_size is not None: + if self.pbtype == 'BYTES' and self.allocation == 'STATIC': result = 'typedef struct {\n' result += ' size_t size;\n' result += ' uint8_t bytes[%d];\n' % self.max_size @@ -212,30 +211,25 @@ class Field: '''Return definition for this field's default value.''' if self.default is None: return None + + ctype, default = self.ctype, self.default + array_decl = '' - if self.ltype == 'PB_LTYPE_STRING': - ctype = 'char' - if self.max_size is None: + if self.pbtype == 'STRING': + if self.allocation != 'STATIC': return None # Not implemented - else: - array_decl = '[%d]' % (self.max_size + 1) + + array_decl = '[%d]' % self.max_size default = str(self.default).encode('string_escape') default = default.replace('"', '\\"') default = '"' + default + '"' - elif self.ltype == 'PB_LTYPE_BYTES': + elif self.pbtype == 'BYTES': + if self.allocation != 'STATIC': + return None # Not implemented + data = self.default.decode('string_escape') data = ['0x%02x' % ord(c) for c in data] - - if self.max_size is None: - return None # Not implemented - else: - ctype = self.ctype - default = '{%d, {%s}}' % (len(data), ','.join(data)) - array_decl = '' - else: - ctype, default = self.ctype, self.default - array_decl = '' if declaration_only: return 'extern const %s %s_default%s;' % (ctype, self.struct_name + self.name, array_decl) @@ -246,47 +240,30 @@ class Field: '''Return the pb_field_t initializer to use in the constant array. prev_field_name is the name of the previous field or None. ''' - result = ' {%d, ' % self.tag - result += '(pb_type_t) ((int) ' + self.htype - if self.ltype is not None: - result += ' | (int) ' + self.ltype - result += '),\n' - - if prev_field_name is None: - result += ' offsetof(%s, %s),' % (self.struct_name, self.name) - else: - result += ' pb_delta_end(%s, %s, %s),' % (self.struct_name, self.name, prev_field_name) - - if self.htype == 'PB_HTYPE_OPTIONAL': - result += '\n pb_delta(%s, has_%s, %s),' % (self.struct_name, self.name, self.name) - elif self.htype == 'PB_HTYPE_ARRAY': - result += '\n pb_delta(%s, %s_count, %s),' % (self.struct_name, self.name, self.name) - else: - result += ' 0,' - - - if self.htype == 'PB_HTYPE_ARRAY': - result += '\n pb_membersize(%s, %s[0]),' % (self.struct_name, self.name) - result += ('\n pb_membersize(%s, %s) / pb_membersize(%s, %s[0]),' - % (self.struct_name, self.name, self.struct_name, self.name)) + result = ' PB_FIELD(%3d, ' % self.tag + result += '%-8s, ' % self.pbtype + result += '%s, ' % self.rules + result += '%s, ' % self.allocation + result += '%s, ' % self.struct_name + result += '%s, ' % self.name + result += '%s, ' % (prev_field_name or self.name) + + if self.pbtype == 'MESSAGE': + result += '&%s_fields)' % self.submsgname + elif self.default is None: + result += '0)' + elif self.pbtype in ['BYTES', 'STRING'] and self.allocation != 'STATIC': + result += '0)' # Arbitrary size default values not implemented else: - result += '\n pb_membersize(%s, %s),' % (self.struct_name, self.name) - result += ' 0,' - - if self.ltype == 'PB_LTYPE_SUBMESSAGE': - result += '\n &%s_fields}' % self.submsgname - elif self.default is None or self.htype == 'PB_HTYPE_CALLBACK': - result += ' 0}' - else: - result += '\n &%s_default}' % (self.struct_name + self.name) + result += '&%s_default)' % (self.struct_name + self.name) return result def largest_field_value(self): '''Determine if this field needs 16bit or 32bit pb_field_t structure to compile properly. Returns numeric value or a C-expression for assert.''' - if self.ltype == 'PB_LTYPE_SUBMESSAGE': - if self.htype == 'PB_HTYPE_ARRAY': + if self.pbtype == 'MESSAGE': + if self.rules == 'REPEATED' and self.allocation == 'STATIC': return 'pb_membersize(%s, %s[0])' % (self.struct_name, self.name) else: return 'pb_membersize(%s, %s)' % (self.struct_name, self.name) @@ -358,7 +335,7 @@ class Message: prev = None for field in self.ordered_fields: result += field.pb_field_t(prev) - result += ',\n\n' + result += ',\n' prev = field.name result += ' PB_LAST_FIELD\n};' @@ -501,8 +478,30 @@ def generate_header(dependencies, headername, enums, messages): for msg in messages: yield msg.fields_declaration() + '\n' + yield '\n#ifdef __cplusplus\n' + yield '} /* extern "C" */\n' + yield '#endif\n' + + # End of header + yield '\n#endif\n' + +def generate_source(headername, enums, messages): + '''Generate content for a source file.''' + + yield '/* Automatically generated nanopb constant definitions */\n' + yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime()) + yield '#include "%s"\n\n' % headername + + for msg in messages: + yield msg.default_decl(False) + + yield '\n\n' + + for msg in messages: + yield msg.fields_definition() + '\n\n' + if messages: - count_required_fields = lambda m: len([f for f in msg.fields if f.htype == 'PB_HTYPE_REQUIRED']) + count_required_fields = lambda m: len([f for f in msg.fields if f.rules == 'REQUIRED']) largest_msg = max(messages, key = count_required_fields) largest_count = count_required_fields(largest_msg) if largest_count > 64: @@ -561,31 +560,11 @@ def generate_header(dependencies, headername, enums, messages): yield '\n' yield '/* On some platforms (such as AVR), double is really float.\n' yield ' * These are not directly supported by nanopb, but see example_avr_double.\n' + yield ' * To get rid of this error, remove any double fields from your .proto.\n' yield ' */\n' yield 'STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)\n' - yield '\n#ifdef __cplusplus\n' - yield '} /* extern "C" */\n' - yield '#endif\n' - - # End of header - yield '\n#endif\n' - -def generate_source(headername, enums, messages): - '''Generate content for a source file.''' - - yield '/* Automatically generated nanopb constant definitions */\n' - yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime()) - yield '#include "%s"\n\n' % headername - - for msg in messages: - yield msg.default_decl(False) - - yield '\n\n' - - for msg in messages: - yield msg.fields_definition() + '\n\n' - + yield '\n' # --------------------------------------------------------------------------- @@ -6,7 +6,7 @@ * see pb_encode.h or pb_decode.h */ -#define NANOPB_VERSION nanopb-0.1.9.1-dev +#define NANOPB_VERSION nanopb-0.2.0-dev #include <stdint.h> #include <stddef.h> @@ -53,60 +53,55 @@ * SINT* is different, though, because it is zig-zag coded. */ -typedef enum { - /************************ - * Field contents types * - ************************/ - - /* Numeric types */ - PB_LTYPE_VARINT = 0x00, /* int32, uint32, int64, uint64, bool, enum */ - PB_LTYPE_SVARINT = 0x01, /* sint32, sint64 */ - PB_LTYPE_FIXED32 = 0x02, /* fixed32, sfixed32, float */ - PB_LTYPE_FIXED64 = 0x03, /* fixed64, sfixed64, double */ - - /* Marker for last packable field type. */ - PB_LTYPE_LAST_PACKABLE = 0x03, - - /* Byte array with pre-allocated buffer. - * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ - PB_LTYPE_BYTES = 0x04, - - /* String with pre-allocated buffer. - * data_size is the maximum length. */ - PB_LTYPE_STRING = 0x05, - - /* Submessage - * submsg_fields is pointer to field descriptions */ - PB_LTYPE_SUBMESSAGE = 0x06, - - /* Number of declared LTYPES */ - PB_LTYPES_COUNT = 7, - PB_LTYPE_MASK = 0x0F, - - /****************** - * Modifier flags * - ******************/ - - /* Just the basic, write data at data_offset */ - PB_HTYPE_REQUIRED = 0x00, - - /* Write true at size_offset */ - PB_HTYPE_OPTIONAL = 0x10, - - /* Read to pre-allocated array - * Maximum number of entries is array_size, - * actual number is stored at size_offset */ - PB_HTYPE_ARRAY = 0x20, - - /* Works for all required/optional/repeated fields. - * data_offset points to pb_callback_t structure. - * LTYPE should be valid or 0 (it is ignored, but - * sometimes used to speculatively index an array). */ - PB_HTYPE_CALLBACK = 0x30, - - PB_HTYPE_MASK = 0xF0 -} pb_packed pb_type_t; +typedef uint8_t pb_type_t; + +/************************ + * Field contents types * + ************************/ + +/* Numeric types */ +#define PB_LTYPE_VARINT 0x00 /* int32, uint32, int64, uint64, bool, enum */ +#define PB_LTYPE_SVARINT 0x01 /* sint32, sint64 */ +#define PB_LTYPE_FIXED32 0x02 /* fixed32, sfixed32, float */ +#define PB_LTYPE_FIXED64 0x03 /* fixed64, sfixed64, double */ + +/* Marker for last packable field type. */ +#define PB_LTYPE_LAST_PACKABLE 0x03 + +/* Byte array with pre-allocated buffer. + * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ +#define PB_LTYPE_BYTES 0x04 +/* String with pre-allocated buffer. + * data_size is the maximum length. */ +#define PB_LTYPE_STRING 0x05 + +/* Submessage + * submsg_fields is pointer to field descriptions */ +#define PB_LTYPE_SUBMESSAGE 0x06 + +/* Number of declared LTYPES */ +#define PB_LTYPES_COUNT 7 +#define PB_LTYPE_MASK 0x0F + +/************************** + * Field repetition rules * + **************************/ + +#define PB_HTYPE_REQUIRED 0x00 +#define PB_HTYPE_OPTIONAL 0x10 +#define PB_HTYPE_REPEATED 0x20 +#define PB_HTYPE_MASK 0x30 + +/******************** + * Allocation types * + ********************/ + +#define PB_ATYPE_STATIC 0x00 +#define PB_ATYPE_CALLBACK 0x40 +#define PB_ATYPE_MASK 0xC0 + +#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) #define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) #define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) @@ -204,9 +199,84 @@ typedef enum { #define pb_membersize(st, m) (sizeof ((st*)0)->m) #define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) #define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) -#define pb_delta_end(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2)) +#define pb_delta_end(st, m1, m2) (offsetof(st, m1) == offsetof(st, m2) \ + ? offsetof(st, m1) \ + : offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2)) #define PB_LAST_FIELD {0,(pb_type_t) 0,0,0,0,0,0} +/* 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) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \ + pb_delta_end(st, m, pm), 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) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \ + pb_delta_end(st, m, pm), \ + 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) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | ltype, \ + pb_delta_end(st, m, pm), \ + 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) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \ + pb_delta_end(st, m, pm), 0, pb_membersize(st, m), 0, ptr} + +#define PB_OPTIONAL_CALLBACK(tag, st, m, pm, ltype, ptr) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \ + pb_delta_end(st, m, pm), 0, pb_membersize(st, m), 0, ptr} + +#define PB_REPEATED_CALLBACK(tag, st, m, pm, ltype, ptr) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REPEATED | ltype, \ + pb_delta_end(st, m, pm), 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 +#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_VARINT +#define PB_LTYPE_MAP_UINT64 PB_LTYPE_VARINT + +/* 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 + * - Field rules: REQUIRED, OPTIONAL or REPEATED + * - Allocation: STATIC or CALLBACK + * - Message name + * - Field name + * - Previous field name (or field name again for first field) + * - Pointer to default value or submsg fields. + */ + +#define PB_FIELD(tag, type, rules, allocation, message, field, prevfield, ptr) \ + PB_ ## rules ## _ ## allocation(tag, 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 * is the true/false return value from functions. diff --git a/pb_decode.c b/pb_decode.c index d4741130..bc6df7b9 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -303,8 +303,11 @@ static bool pb_field_next(pb_field_iterator_t *iter) bool notwrapped = true; size_t prev_size = iter->current->data_size; - if (PB_HTYPE(iter->current->type) == PB_HTYPE_ARRAY) + if (PB_ATYPE(iter->current->type) == PB_ATYPE_STATIC && + PB_HTYPE(iter->current->type) == PB_HTYPE_REPEATED) + { prev_size *= iter->current->array_size; + } if (PB_HTYPE(iter->current->type) == PB_HTYPE_REQUIRED) iter->required_field_index++; @@ -343,11 +346,15 @@ static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag) * Decode a single field * *************************/ -static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) { - pb_decoder_t func = PB_DECODERS[PB_LTYPE(iter->current->type)]; + pb_type_t type; + pb_decoder_t func; - switch (PB_HTYPE(iter->current->type)) + type = iter->current->type; + func = PB_DECODERS[PB_LTYPE(type)]; + + switch (PB_HTYPE(type)) { case PB_HTYPE_REQUIRED: return func(stream, iter->current, iter->pData); @@ -356,9 +363,9 @@ static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_t *(bool*)iter->pSize = true; return func(stream, iter->current, iter->pData); - case PB_HTYPE_ARRAY: + case PB_HTYPE_REPEATED: if (wire_type == PB_WT_STRING - && PB_LTYPE(iter->current->type) <= PB_LTYPE_LAST_PACKABLE) + && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) { /* Packed array */ bool status = true; @@ -395,48 +402,63 @@ static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_t (*size)++; return func(stream, iter->current, pItem); } + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) +{ + pb_callback_t *pCallback = (pb_callback_t*)iter->pData; + + if (pCallback->funcs.decode == NULL) + return pb_skip_field(stream, wire_type); + + if (wire_type == PB_WT_STRING) + { + pb_istream_t substream; - case PB_HTYPE_CALLBACK: + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left) { - pb_callback_t *pCallback = (pb_callback_t*)iter->pData; - - if (pCallback->funcs.decode == NULL) - return pb_skip_field(stream, wire_type); - - if (wire_type == PB_WT_STRING) - { - pb_istream_t substream; - - if (!pb_make_string_substream(stream, &substream)) - return false; - - while (substream.bytes_left) - { - if (!pCallback->funcs.decode(&substream, iter->current, pCallback->arg)) - PB_RETURN_ERROR(stream, "callback failed"); - } - - pb_close_string_substream(stream, &substream); - return true; - } - else - { - /* Copy the single scalar value to stack. - * This is required so that we can limit the stream length, - * which in turn allows to use same callback for packed and - * not-packed fields. */ - pb_istream_t substream; - uint8_t buffer[10]; - size_t size = sizeof(buffer); - - if (!read_raw_value(stream, wire_type, buffer, &size)) - return false; - substream = pb_istream_from_buffer(buffer, size); - - return pCallback->funcs.decode(&substream, iter->current, pCallback->arg); - } + if (!pCallback->funcs.decode(&substream, iter->current, pCallback->arg)) + PB_RETURN_ERROR(stream, "callback failed"); } + pb_close_string_substream(stream, &substream); + return true; + } + else + { + /* Copy the single scalar value to stack. + * This is required so that we can limit the stream length, + * which in turn allows to use same callback for packed and + * not-packed fields. */ + pb_istream_t substream; + uint8_t buffer[10]; + size_t size = sizeof(buffer); + + if (!read_raw_value(stream, wire_type, buffer, &size)) + return false; + substream = pb_istream_from_buffer(buffer, size); + + return pCallback->funcs.decode(&substream, iter->current, pCallback->arg); + } +} + +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) +{ + switch (PB_ATYPE(iter->current->type)) + { + case PB_ATYPE_STATIC: + return decode_static_field(stream, wire_type, iter); + + case PB_ATYPE_CALLBACK: + return decode_callback_field(stream, wire_type, iter); + default: PB_RETURN_ERROR(stream, "invalid field type"); } @@ -451,37 +473,43 @@ static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_str /* Initialize size/has fields and apply default values */ do { + pb_type_t type; + type = iter.current->type; + if (iter.current->tag == 0) continue; - /* Initialize the size field for optional/repeated fields to 0. */ - if (PB_HTYPE(iter.current->type) == PB_HTYPE_OPTIONAL) - { - *(bool*)iter.pSize = false; - } - else if (PB_HTYPE(iter.current->type) == PB_HTYPE_ARRAY) + if (PB_ATYPE(type) == PB_ATYPE_STATIC) { - *(size_t*)iter.pSize = 0; - continue; /* Array is empty, no need to initialize contents */ + /* Initialize the size field for optional/repeated fields to 0. */ + if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL) + { + *(bool*)iter.pSize = false; + } + else if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + *(size_t*)iter.pSize = 0; + continue; /* Array is empty, no need to initialize contents */ + } + + /* Initialize field contents to default value */ + if (PB_LTYPE(iter.current->type) == PB_LTYPE_SUBMESSAGE) + { + pb_message_set_to_defaults((const pb_field_t *) iter.current->ptr, iter.pData); + } + else if (iter.current->ptr != NULL) + { + memcpy(iter.pData, iter.current->ptr, iter.current->data_size); + } + else + { + memset(iter.pData, 0, iter.current->data_size); + } } - - /* Initialize field contents to default value */ - if (PB_HTYPE(iter.current->type) == PB_HTYPE_CALLBACK) + else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) { continue; /* Don't overwrite callback */ } - else if (PB_LTYPE(iter.current->type) == PB_LTYPE_SUBMESSAGE) - { - pb_message_set_to_defaults((const pb_field_t *) iter.current->ptr, iter.pData); - } - else if (iter.current->ptr != NULL) - { - memcpy(iter.pData, iter.current->ptr, iter.current->data_size); - } - else - { - memset(iter.pData, 0, iter.current->data_size); - } } while (pb_field_next(&iter)); } @@ -715,7 +743,7 @@ bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field /* New array entries need to be initialized, while required and optional * submessages have already been initialized in the top-level pb_decode. */ - if (PB_HTYPE(field->type) == PB_HTYPE_ARRAY) + if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED) status = pb_decode(&substream, submsg_fields, dest); else status = pb_decode_noinit(&substream, submsg_fields, dest); diff --git a/pb_encode.c b/pb_encode.c index bba5dc19..fbeeacfc 100644 --- a/pb_encode.c +++ b/pb_encode.c @@ -153,58 +153,89 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie return true; } +bool checkreturn encode_static_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData) +{ + pb_encoder_t func; + const void *pSize; + + func = PB_ENCODERS[PB_LTYPE(field->type)]; + pSize = (const char*)pData + field->size_offset; + + switch (PB_HTYPE(field->type)) + { + case PB_HTYPE_REQUIRED: + if (!pb_encode_tag_for_field(stream, field)) + return false; + if (!func(stream, field, pData)) + return false; + break; + + case PB_HTYPE_OPTIONAL: + if (*(const bool*)pSize) + { + if (!pb_encode_tag_for_field(stream, field)) + return false; + + if (!func(stream, field, pData)) + return false; + } + break; + + case PB_HTYPE_REPEATED: + if (!encode_array(stream, field, pData, *(const size_t*)pSize, func)) + return false; + break; + + default: + return false; + } + + return true; +} + +bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData) +{ + const pb_callback_t *callback = (const pb_callback_t*)pData; + if (callback->funcs.encode != NULL) + { + if (!callback->funcs.encode(stream, field, callback->arg)) + return false; + } + return true; +} + bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) { const pb_field_t *field = fields; const void *pData = src_struct; - const void *pSize; size_t prev_size = 0; while (field->tag != 0) { - pb_encoder_t func = PB_ENCODERS[PB_LTYPE(field->type)]; pData = (const char*)pData + prev_size + field->data_offset; - pSize = (const char*)pData + field->size_offset; - prev_size = field->data_size; - if (PB_HTYPE(field->type) == PB_HTYPE_ARRAY) + + /* Special case for static arrays */ + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && + PB_HTYPE(field->type) == PB_HTYPE_REPEATED) + { prev_size *= field->array_size; + } - switch (PB_HTYPE(field->type)) + switch (PB_ATYPE(field->type)) { - case PB_HTYPE_REQUIRED: - if (!pb_encode_tag_for_field(stream, field)) + case PB_ATYPE_STATIC: + if (!encode_static_field(stream, field, pData)) return false; - if (!func(stream, field, pData)) - return false; - break; - - case PB_HTYPE_OPTIONAL: - if (*(const bool*)pSize) - { - if (!pb_encode_tag_for_field(stream, field)) - return false; - - if (!func(stream, field, pData)) - return false; - } break; - case PB_HTYPE_ARRAY: - if (!encode_array(stream, field, pData, *(const size_t*)pSize, func)) + case PB_ATYPE_CALLBACK: + if (!encode_callback_field(stream, field, pData)) return false; break; - case PB_HTYPE_CALLBACK: - { - const pb_callback_t *callback = (const pb_callback_t*)pData; - if (callback->funcs.encode != NULL) - { - if (!callback->funcs.encode(stream, field, callback->arg)) - return false; - } - break; - } + default: + return false; } field++; diff --git a/tests/bc_alltypes.pb.c b/tests/bc_alltypes.pb.c index 322b634e..7d1edf57 100644 --- a/tests/bc_alltypes.pb.c +++ b/tests/bc_alltypes.pb.c @@ -1,7 +1,13 @@ /* Automatically generated nanopb constant definitions */ -#include "bc_alltypes.pb.h" +/* Generated by 0.2.0-dev at Sun Feb 17 00:09:53 2013. */ +/* This is a file generated using nanopb-0.2.0-dev. + * It is used as a part of test suite in order to detect any + * incompatible changes made to the generator in future versions. + */ -const char SubMessage_substuff1_default[17] = "1"; +#include "alltypes.pb.h" + +const char SubMessage_substuff1_default[16] = "1"; const int32_t SubMessage_substuff2_default = 2; const uint32_t SubMessage_substuff3_default = 3; const int32_t AllTypes_opt_int32_default = 4041; @@ -17,310 +23,71 @@ const float AllTypes_opt_float_default = 4050; const uint64_t AllTypes_opt_fixed64_default = 4051; const int64_t AllTypes_opt_sfixed64_default = 4052; const double AllTypes_opt_double_default = 4053; -const char AllTypes_opt_string_default[17] = "4054"; +const char AllTypes_opt_string_default[16] = "4054"; const AllTypes_opt_bytes_t AllTypes_opt_bytes_default = {4, {0x34,0x30,0x35,0x35}}; const MyEnum AllTypes_opt_enum_default = MyEnum_Second; const pb_field_t SubMessage_fields[4] = { - {1, PB_HTYPE_REQUIRED | PB_LTYPE_STRING, - offsetof(SubMessage, substuff1), 0, - pb_membersize(SubMessage, substuff1), 0, - &SubMessage_substuff1_default}, - - {2, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, - pb_delta_end(SubMessage, substuff2, substuff1), 0, - pb_membersize(SubMessage, substuff2), 0, - &SubMessage_substuff2_default}, - - {3, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED32, - pb_delta_end(SubMessage, substuff3, substuff2), - pb_delta(SubMessage, has_substuff3, substuff3), - pb_membersize(SubMessage, substuff3), 0, - &SubMessage_substuff3_default}, - + PB_FIELD( 1, STRING , REQUIRED, STATIC, SubMessage, substuff1, substuff1, &SubMessage_substuff1_default), + PB_FIELD( 2, INT32 , REQUIRED, STATIC, SubMessage, substuff2, substuff1, &SubMessage_substuff2_default), + PB_FIELD( 3, FIXED32 , OPTIONAL, STATIC, SubMessage, substuff3, substuff2, &SubMessage_substuff3_default), PB_LAST_FIELD }; const pb_field_t AllTypes_fields[53] = { - {1, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, - offsetof(AllTypes, req_int32), 0, - pb_membersize(AllTypes, req_int32), 0, 0}, - - {2, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, req_int64, req_int32), 0, - pb_membersize(AllTypes, req_int64), 0, 0}, - - {3, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, req_uint32, req_int64), 0, - pb_membersize(AllTypes, req_uint32), 0, 0}, - - {4, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, req_uint64, req_uint32), 0, - pb_membersize(AllTypes, req_uint64), 0, 0}, - - {5, PB_HTYPE_REQUIRED | PB_LTYPE_SVARINT, - pb_delta_end(AllTypes, req_sint32, req_uint64), 0, - pb_membersize(AllTypes, req_sint32), 0, 0}, - - {6, PB_HTYPE_REQUIRED | PB_LTYPE_SVARINT, - pb_delta_end(AllTypes, req_sint64, req_sint32), 0, - pb_membersize(AllTypes, req_sint64), 0, 0}, - - {7, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, req_bool, req_sint64), 0, - pb_membersize(AllTypes, req_bool), 0, 0}, - - {8, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED32, - pb_delta_end(AllTypes, req_fixed32, req_bool), 0, - pb_membersize(AllTypes, req_fixed32), 0, 0}, - - {9, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED32, - pb_delta_end(AllTypes, req_sfixed32, req_fixed32), 0, - pb_membersize(AllTypes, req_sfixed32), 0, 0}, - - {10, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED32, - pb_delta_end(AllTypes, req_float, req_sfixed32), 0, - pb_membersize(AllTypes, req_float), 0, 0}, - - {11, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED64, - pb_delta_end(AllTypes, req_fixed64, req_float), 0, - pb_membersize(AllTypes, req_fixed64), 0, 0}, - - {12, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED64, - pb_delta_end(AllTypes, req_sfixed64, req_fixed64), 0, - pb_membersize(AllTypes, req_sfixed64), 0, 0}, - - {13, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED64, - pb_delta_end(AllTypes, req_double, req_sfixed64), 0, - pb_membersize(AllTypes, req_double), 0, 0}, - - {14, PB_HTYPE_REQUIRED | PB_LTYPE_STRING, - pb_delta_end(AllTypes, req_string, req_double), 0, - pb_membersize(AllTypes, req_string), 0, 0}, - - {15, PB_HTYPE_REQUIRED | PB_LTYPE_BYTES, - pb_delta_end(AllTypes, req_bytes, req_string), 0, - pb_membersize(AllTypes, req_bytes), 0, 0}, - - {16, PB_HTYPE_REQUIRED | PB_LTYPE_SUBMESSAGE, - pb_delta_end(AllTypes, req_submsg, req_bytes), 0, - pb_membersize(AllTypes, req_submsg), 0, - &SubMessage_fields}, - - {17, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, req_enum, req_submsg), 0, - pb_membersize(AllTypes, req_enum), 0, 0}, - - {21, PB_HTYPE_ARRAY | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, rep_int32, req_enum), - pb_delta(AllTypes, rep_int32_count, rep_int32), - pb_membersize(AllTypes, rep_int32[0]), - pb_membersize(AllTypes, rep_int32) / pb_membersize(AllTypes, rep_int32[0]), 0}, - - {22, PB_HTYPE_ARRAY | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, rep_int64, rep_int32), - pb_delta(AllTypes, rep_int64_count, rep_int64), - pb_membersize(AllTypes, rep_int64[0]), - pb_membersize(AllTypes, rep_int64) / pb_membersize(AllTypes, rep_int64[0]), 0}, - - {23, PB_HTYPE_ARRAY | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, rep_uint32, rep_int64), - pb_delta(AllTypes, rep_uint32_count, rep_uint32), - pb_membersize(AllTypes, rep_uint32[0]), - pb_membersize(AllTypes, rep_uint32) / pb_membersize(AllTypes, rep_uint32[0]), 0}, - - {24, PB_HTYPE_ARRAY | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, rep_uint64, rep_uint32), - pb_delta(AllTypes, rep_uint64_count, rep_uint64), - pb_membersize(AllTypes, rep_uint64[0]), - pb_membersize(AllTypes, rep_uint64) / pb_membersize(AllTypes, rep_uint64[0]), 0}, - - {25, PB_HTYPE_ARRAY | PB_LTYPE_SVARINT, - pb_delta_end(AllTypes, rep_sint32, rep_uint64), - pb_delta(AllTypes, rep_sint32_count, rep_sint32), - pb_membersize(AllTypes, rep_sint32[0]), - pb_membersize(AllTypes, rep_sint32) / pb_membersize(AllTypes, rep_sint32[0]), 0}, - - {26, PB_HTYPE_ARRAY | PB_LTYPE_SVARINT, - pb_delta_end(AllTypes, rep_sint64, rep_sint32), - pb_delta(AllTypes, rep_sint64_count, rep_sint64), - pb_membersize(AllTypes, rep_sint64[0]), - pb_membersize(AllTypes, rep_sint64) / pb_membersize(AllTypes, rep_sint64[0]), 0}, - - {27, PB_HTYPE_ARRAY | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, rep_bool, rep_sint64), - pb_delta(AllTypes, rep_bool_count, rep_bool), - pb_membersize(AllTypes, rep_bool[0]), - pb_membersize(AllTypes, rep_bool) / pb_membersize(AllTypes, rep_bool[0]), 0}, - - {28, PB_HTYPE_ARRAY | PB_LTYPE_FIXED32, - pb_delta_end(AllTypes, rep_fixed32, rep_bool), - pb_delta(AllTypes, rep_fixed32_count, rep_fixed32), - pb_membersize(AllTypes, rep_fixed32[0]), - pb_membersize(AllTypes, rep_fixed32) / pb_membersize(AllTypes, rep_fixed32[0]), 0}, - - {29, PB_HTYPE_ARRAY | PB_LTYPE_FIXED32, - pb_delta_end(AllTypes, rep_sfixed32, rep_fixed32), - pb_delta(AllTypes, rep_sfixed32_count, rep_sfixed32), - pb_membersize(AllTypes, rep_sfixed32[0]), - pb_membersize(AllTypes, rep_sfixed32) / pb_membersize(AllTypes, rep_sfixed32[0]), 0}, - - {30, PB_HTYPE_ARRAY | PB_LTYPE_FIXED32, - pb_delta_end(AllTypes, rep_float, rep_sfixed32), - pb_delta(AllTypes, rep_float_count, rep_float), - pb_membersize(AllTypes, rep_float[0]), - pb_membersize(AllTypes, rep_float) / pb_membersize(AllTypes, rep_float[0]), 0}, - - {31, PB_HTYPE_ARRAY | PB_LTYPE_FIXED64, - pb_delta_end(AllTypes, rep_fixed64, rep_float), - pb_delta(AllTypes, rep_fixed64_count, rep_fixed64), - pb_membersize(AllTypes, rep_fixed64[0]), - pb_membersize(AllTypes, rep_fixed64) / pb_membersize(AllTypes, rep_fixed64[0]), 0}, - - {32, PB_HTYPE_ARRAY | PB_LTYPE_FIXED64, - pb_delta_end(AllTypes, rep_sfixed64, rep_fixed64), - pb_delta(AllTypes, rep_sfixed64_count, rep_sfixed64), - pb_membersize(AllTypes, rep_sfixed64[0]), - pb_membersize(AllTypes, rep_sfixed64) / pb_membersize(AllTypes, rep_sfixed64[0]), 0}, - - {33, PB_HTYPE_ARRAY | PB_LTYPE_FIXED64, - pb_delta_end(AllTypes, rep_double, rep_sfixed64), - pb_delta(AllTypes, rep_double_count, rep_double), - pb_membersize(AllTypes, rep_double[0]), - pb_membersize(AllTypes, rep_double) / pb_membersize(AllTypes, rep_double[0]), 0}, - - {34, PB_HTYPE_ARRAY | PB_LTYPE_STRING, - pb_delta_end(AllTypes, rep_string, rep_double), - pb_delta(AllTypes, rep_string_count, rep_string), - pb_membersize(AllTypes, rep_string[0]), - pb_membersize(AllTypes, rep_string) / pb_membersize(AllTypes, rep_string[0]), 0}, - - {35, PB_HTYPE_ARRAY | PB_LTYPE_BYTES, - pb_delta_end(AllTypes, rep_bytes, rep_string), - pb_delta(AllTypes, rep_bytes_count, rep_bytes), - pb_membersize(AllTypes, rep_bytes[0]), - pb_membersize(AllTypes, rep_bytes) / pb_membersize(AllTypes, rep_bytes[0]), 0}, - - {36, PB_HTYPE_ARRAY | PB_LTYPE_SUBMESSAGE, - pb_delta_end(AllTypes, rep_submsg, rep_bytes), - pb_delta(AllTypes, rep_submsg_count, rep_submsg), - pb_membersize(AllTypes, rep_submsg[0]), - pb_membersize(AllTypes, rep_submsg) / pb_membersize(AllTypes, rep_submsg[0]), - &SubMessage_fields}, - - {37, PB_HTYPE_ARRAY | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, rep_enum, rep_submsg), - pb_delta(AllTypes, rep_enum_count, rep_enum), - pb_membersize(AllTypes, rep_enum[0]), - pb_membersize(AllTypes, rep_enum) / pb_membersize(AllTypes, rep_enum[0]), 0}, - - {41, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, opt_int32, rep_enum), - pb_delta(AllTypes, has_opt_int32, opt_int32), - pb_membersize(AllTypes, opt_int32), 0, - &AllTypes_opt_int32_default}, - - {42, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, opt_int64, opt_int32), - pb_delta(AllTypes, has_opt_int64, opt_int64), - pb_membersize(AllTypes, opt_int64), 0, - &AllTypes_opt_int64_default}, - - {43, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, opt_uint32, opt_int64), - pb_delta(AllTypes, has_opt_uint32, opt_uint32), - pb_membersize(AllTypes, opt_uint32), 0, - &AllTypes_opt_uint32_default}, - - {44, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, opt_uint64, opt_uint32), - pb_delta(AllTypes, has_opt_uint64, opt_uint64), - pb_membersize(AllTypes, opt_uint64), 0, - &AllTypes_opt_uint64_default}, - - {45, PB_HTYPE_OPTIONAL | PB_LTYPE_SVARINT, - pb_delta_end(AllTypes, opt_sint32, opt_uint64), - pb_delta(AllTypes, has_opt_sint32, opt_sint32), - pb_membersize(AllTypes, opt_sint32), 0, - &AllTypes_opt_sint32_default}, - - {46, PB_HTYPE_OPTIONAL | PB_LTYPE_SVARINT, - pb_delta_end(AllTypes, opt_sint64, opt_sint32), - pb_delta(AllTypes, has_opt_sint64, opt_sint64), - pb_membersize(AllTypes, opt_sint64), 0, - &AllTypes_opt_sint64_default}, - - {47, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, opt_bool, opt_sint64), - pb_delta(AllTypes, has_opt_bool, opt_bool), - pb_membersize(AllTypes, opt_bool), 0, - &AllTypes_opt_bool_default}, - - {48, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED32, - pb_delta_end(AllTypes, opt_fixed32, opt_bool), - pb_delta(AllTypes, has_opt_fixed32, opt_fixed32), - pb_membersize(AllTypes, opt_fixed32), 0, - &AllTypes_opt_fixed32_default}, - - {49, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED32, - pb_delta_end(AllTypes, opt_sfixed32, opt_fixed32), - pb_delta(AllTypes, has_opt_sfixed32, opt_sfixed32), - pb_membersize(AllTypes, opt_sfixed32), 0, - &AllTypes_opt_sfixed32_default}, - - {50, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED32, - pb_delta_end(AllTypes, opt_float, opt_sfixed32), - pb_delta(AllTypes, has_opt_float, opt_float), - pb_membersize(AllTypes, opt_float), 0, - &AllTypes_opt_float_default}, - - {51, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED64, - pb_delta_end(AllTypes, opt_fixed64, opt_float), - pb_delta(AllTypes, has_opt_fixed64, opt_fixed64), - pb_membersize(AllTypes, opt_fixed64), 0, - &AllTypes_opt_fixed64_default}, - - {52, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED64, - pb_delta_end(AllTypes, opt_sfixed64, opt_fixed64), - pb_delta(AllTypes, has_opt_sfixed64, opt_sfixed64), - pb_membersize(AllTypes, opt_sfixed64), 0, - &AllTypes_opt_sfixed64_default}, - - {53, PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED64, - pb_delta_end(AllTypes, opt_double, opt_sfixed64), - pb_delta(AllTypes, has_opt_double, opt_double), - pb_membersize(AllTypes, opt_double), 0, - &AllTypes_opt_double_default}, - - {54, PB_HTYPE_OPTIONAL | PB_LTYPE_STRING, - pb_delta_end(AllTypes, opt_string, opt_double), - pb_delta(AllTypes, has_opt_string, opt_string), - pb_membersize(AllTypes, opt_string), 0, - &AllTypes_opt_string_default}, - - {55, PB_HTYPE_OPTIONAL | PB_LTYPE_BYTES, - pb_delta_end(AllTypes, opt_bytes, opt_string), - pb_delta(AllTypes, has_opt_bytes, opt_bytes), - pb_membersize(AllTypes, opt_bytes), 0, - &AllTypes_opt_bytes_default}, - - {56, PB_HTYPE_OPTIONAL | PB_LTYPE_SUBMESSAGE, - pb_delta_end(AllTypes, opt_submsg, opt_bytes), - pb_delta(AllTypes, has_opt_submsg, opt_submsg), - pb_membersize(AllTypes, opt_submsg), 0, - &SubMessage_fields}, - - {57, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, opt_enum, opt_submsg), - pb_delta(AllTypes, has_opt_enum, opt_enum), - pb_membersize(AllTypes, opt_enum), 0, - &AllTypes_opt_enum_default}, - - {99, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, - pb_delta_end(AllTypes, end, opt_enum), 0, - pb_membersize(AllTypes, end), 0, 0}, - + PB_FIELD( 1, INT32 , REQUIRED, STATIC, AllTypes, req_int32, req_int32, 0), + PB_FIELD( 2, INT64 , REQUIRED, STATIC, AllTypes, req_int64, req_int32, 0), + PB_FIELD( 3, UINT32 , REQUIRED, STATIC, AllTypes, req_uint32, req_int64, 0), + PB_FIELD( 4, UINT64 , REQUIRED, STATIC, AllTypes, req_uint64, req_uint32, 0), + PB_FIELD( 5, SINT32 , REQUIRED, STATIC, AllTypes, req_sint32, req_uint64, 0), + PB_FIELD( 6, SINT64 , REQUIRED, STATIC, AllTypes, req_sint64, req_sint32, 0), + PB_FIELD( 7, BOOL , REQUIRED, STATIC, AllTypes, req_bool, req_sint64, 0), + PB_FIELD( 8, FIXED32 , REQUIRED, STATIC, AllTypes, req_fixed32, req_bool, 0), + PB_FIELD( 9, SFIXED32, REQUIRED, STATIC, AllTypes, req_sfixed32, req_fixed32, 0), + PB_FIELD( 10, FLOAT , REQUIRED, STATIC, AllTypes, req_float, req_sfixed32, 0), + PB_FIELD( 11, FIXED64 , REQUIRED, STATIC, AllTypes, req_fixed64, req_float, 0), + PB_FIELD( 12, SFIXED64, REQUIRED, STATIC, AllTypes, req_sfixed64, req_fixed64, 0), + PB_FIELD( 13, DOUBLE , REQUIRED, STATIC, AllTypes, req_double, req_sfixed64, 0), + PB_FIELD( 14, STRING , REQUIRED, STATIC, AllTypes, req_string, req_double, 0), + PB_FIELD( 15, BYTES , REQUIRED, STATIC, AllTypes, req_bytes, req_string, 0), + PB_FIELD( 16, MESSAGE , REQUIRED, STATIC, AllTypes, req_submsg, req_bytes, &SubMessage_fields), + PB_FIELD( 17, ENUM , REQUIRED, STATIC, AllTypes, req_enum, req_submsg, 0), + PB_FIELD( 21, INT32 , REPEATED, STATIC, AllTypes, rep_int32, req_enum, 0), + PB_FIELD( 22, INT64 , REPEATED, STATIC, AllTypes, rep_int64, rep_int32, 0), + PB_FIELD( 23, UINT32 , REPEATED, STATIC, AllTypes, rep_uint32, rep_int64, 0), + PB_FIELD( 24, UINT64 , REPEATED, STATIC, AllTypes, rep_uint64, rep_uint32, 0), + PB_FIELD( 25, SINT32 , REPEATED, STATIC, AllTypes, rep_sint32, rep_uint64, 0), + PB_FIELD( 26, SINT64 , REPEATED, STATIC, AllTypes, rep_sint64, rep_sint32, 0), + PB_FIELD( 27, BOOL , REPEATED, STATIC, AllTypes, rep_bool, rep_sint64, 0), + PB_FIELD( 28, FIXED32 , REPEATED, STATIC, AllTypes, rep_fixed32, rep_bool, 0), + PB_FIELD( 29, SFIXED32, REPEATED, STATIC, AllTypes, rep_sfixed32, rep_fixed32, 0), + PB_FIELD( 30, FLOAT , REPEATED, STATIC, AllTypes, rep_float, rep_sfixed32, 0), + PB_FIELD( 31, FIXED64 , REPEATED, STATIC, AllTypes, rep_fixed64, rep_float, 0), + PB_FIELD( 32, SFIXED64, REPEATED, STATIC, AllTypes, rep_sfixed64, rep_fixed64, 0), + PB_FIELD( 33, DOUBLE , REPEATED, STATIC, AllTypes, rep_double, rep_sfixed64, 0), + PB_FIELD( 34, STRING , REPEATED, STATIC, AllTypes, rep_string, rep_double, 0), + PB_FIELD( 35, BYTES , REPEATED, STATIC, AllTypes, rep_bytes, rep_string, 0), + PB_FIELD( 36, MESSAGE , REPEATED, STATIC, AllTypes, rep_submsg, rep_bytes, &SubMessage_fields), + PB_FIELD( 37, ENUM , REPEATED, STATIC, AllTypes, rep_enum, rep_submsg, 0), + PB_FIELD( 41, INT32 , OPTIONAL, STATIC, AllTypes, opt_int32, rep_enum, &AllTypes_opt_int32_default), + PB_FIELD( 42, INT64 , OPTIONAL, STATIC, AllTypes, opt_int64, opt_int32, &AllTypes_opt_int64_default), + PB_FIELD( 43, UINT32 , OPTIONAL, STATIC, AllTypes, opt_uint32, opt_int64, &AllTypes_opt_uint32_default), + PB_FIELD( 44, UINT64 , OPTIONAL, STATIC, AllTypes, opt_uint64, opt_uint32, &AllTypes_opt_uint64_default), + PB_FIELD( 45, SINT32 , OPTIONAL, STATIC, AllTypes, opt_sint32, opt_uint64, &AllTypes_opt_sint32_default), + PB_FIELD( 46, SINT64 , OPTIONAL, STATIC, AllTypes, opt_sint64, opt_sint32, &AllTypes_opt_sint64_default), + PB_FIELD( 47, BOOL , OPTIONAL, STATIC, AllTypes, opt_bool, opt_sint64, &AllTypes_opt_bool_default), + PB_FIELD( 48, FIXED32 , OPTIONAL, STATIC, AllTypes, opt_fixed32, opt_bool, &AllTypes_opt_fixed32_default), + PB_FIELD( 49, SFIXED32, OPTIONAL, STATIC, AllTypes, opt_sfixed32, opt_fixed32, &AllTypes_opt_sfixed32_default), + PB_FIELD( 50, FLOAT , OPTIONAL, STATIC, AllTypes, opt_float, opt_sfixed32, &AllTypes_opt_float_default), + PB_FIELD( 51, FIXED64 , OPTIONAL, STATIC, AllTypes, opt_fixed64, opt_float, &AllTypes_opt_fixed64_default), + PB_FIELD( 52, SFIXED64, OPTIONAL, STATIC, AllTypes, opt_sfixed64, opt_fixed64, &AllTypes_opt_sfixed64_default), + PB_FIELD( 53, DOUBLE , OPTIONAL, STATIC, AllTypes, opt_double, opt_sfixed64, &AllTypes_opt_double_default), + PB_FIELD( 54, STRING , OPTIONAL, STATIC, AllTypes, opt_string, opt_double, &AllTypes_opt_string_default), + PB_FIELD( 55, BYTES , OPTIONAL, STATIC, AllTypes, opt_bytes, opt_string, &AllTypes_opt_bytes_default), + PB_FIELD( 56, MESSAGE , OPTIONAL, STATIC, AllTypes, opt_submsg, opt_bytes, &SubMessage_fields), + PB_FIELD( 57, ENUM , OPTIONAL, STATIC, AllTypes, opt_enum, opt_submsg, &AllTypes_opt_enum_default), + PB_FIELD( 99, INT32 , REQUIRED, STATIC, AllTypes, end, opt_enum, 0), PB_LAST_FIELD }; diff --git a/tests/bc_alltypes.pb.h b/tests/bc_alltypes.pb.h index fe0b8f76..037b3478 100644 --- a/tests/bc_alltypes.pb.h +++ b/tests/bc_alltypes.pb.h @@ -1,14 +1,19 @@ /* Automatically generated nanopb header */ -/* This is a file generated using nanopb-0.1.1. +/* This is a file generated using nanopb-0.2.0-dev. * It is used as a part of test suite in order to detect any * incompatible changes made to the generator in future versions. */ -#ifndef _PB_BC_ALLTYPES_PB_H_ -#define _PB_BC_ALLTYPES_PB_H_ + +#ifndef _PB_ALLTYPES_PB_H_ +#define _PB_ALLTYPES_PB_H_ #include <pb.h> +#ifdef __cplusplus +extern "C" { +#endif + /* Enum definitions */ -typedef enum { +typedef enum _MyEnum { MyEnum_Zero = 0, MyEnum_First = 1, MyEnum_Second = 2, @@ -16,7 +21,7 @@ typedef enum { } MyEnum; /* Struct definitions */ -typedef struct { +typedef struct _SubMessage { char substuff1[16]; int32_t substuff2; bool has_substuff3; @@ -38,7 +43,7 @@ typedef struct { uint8_t bytes[16]; } AllTypes_opt_bytes_t; -typedef struct { +typedef struct _AllTypes { int32_t req_int32; int64_t req_int64; uint32_t req_uint32; @@ -128,7 +133,7 @@ typedef struct { } AllTypes; /* Default values for struct fields */ -extern const char SubMessage_substuff1_default[17]; +extern const char SubMessage_substuff1_default[16]; extern const int32_t SubMessage_substuff2_default; extern const uint32_t SubMessage_substuff3_default; extern const int32_t AllTypes_opt_int32_default; @@ -144,7 +149,7 @@ extern const float AllTypes_opt_float_default; extern const uint64_t AllTypes_opt_fixed64_default; extern const int64_t AllTypes_opt_sfixed64_default; extern const double AllTypes_opt_double_default; -extern const char AllTypes_opt_string_default[17]; +extern const char AllTypes_opt_string_default[16]; extern const AllTypes_opt_bytes_t AllTypes_opt_bytes_default; extern const MyEnum AllTypes_opt_enum_default; @@ -152,4 +157,22 @@ extern const MyEnum AllTypes_opt_enum_default; extern const pb_field_t SubMessage_fields[4]; extern const pb_field_t AllTypes_fields[53]; +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +STATIC_ASSERT((pb_membersize(AllTypes, req_submsg) < 256 && pb_membersize(AllTypes, rep_submsg[0]) < 256 && pb_membersize(AllTypes, opt_submsg) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_SubMessage_AllTypes) +#endif + +#if !defined(PB_FIELD_32BIT) +STATIC_ASSERT((pb_membersize(AllTypes, req_submsg) < 65536 && pb_membersize(AllTypes, rep_submsg[0]) < 65536 && pb_membersize(AllTypes, opt_submsg) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_SubMessage_AllTypes) +#endif + +/* On some platforms (such as AVR), double is really float. + * These are not directly supported by nanopb, but see example_avr_double. + */ +STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif |