summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>2013-02-21 19:38:56 +0200
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>2013-02-21 19:38:56 +0200
commit5442e690f65fd09e7a44437da02fb7e14af6fe8f (patch)
treeecb8e53aec39dc51f6160d1664e4e50cd4996e64
parent5b536d40a11edb3161f2f19609c2b51899c354b0 (diff)
parent80a2d33fa9a835564b44fe97ba34e713901cf4fb (diff)
Merge branch 'dev-0.2'
-rw-r--r--.gitignore39
-rw-r--r--generator/nanopb_generator.py197
-rw-r--r--pb.h180
-rw-r--r--pb_decode.c164
-rw-r--r--pb_encode.c97
-rw-r--r--tests/bc_alltypes.pb.c361
-rw-r--r--tests/bc_alltypes.pb.h39
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'
# ---------------------------------------------------------------------------
diff --git a/pb.h b/pb.h
index bca31022..dd06c69b 100644
--- a/pb.h
+++ b/pb.h
@@ -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