Compare commits
7 Commits
nanopb-0.1
...
dev-0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80a2d33fa9 | ||
|
|
41f98343c8 | ||
|
|
69085d9387 | ||
|
|
258ba8335d | ||
|
|
9d3d7b5730 | ||
|
|
ec4a7a0cce | ||
|
|
c1a355b23e |
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
@@ -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
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
'''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.'''
|
'''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.'''
|
||||||
nanopb_version = "nanopb-0.1.9-dev"
|
nanopb_version = "0.2.0-dev"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import google.protobuf.descriptor_pb2 as descriptor
|
import google.protobuf.descriptor_pb2 as descriptor
|
||||||
@@ -35,22 +35,22 @@ except:
|
|||||||
import time
|
import time
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
# Values are tuple (c type, pb ltype)
|
# Values are tuple (c type, pb type)
|
||||||
FieldD = descriptor.FieldDescriptorProto
|
FieldD = descriptor.FieldDescriptorProto
|
||||||
datatypes = {
|
datatypes = {
|
||||||
FieldD.TYPE_BOOL: ('bool', 'PB_LTYPE_VARINT'),
|
FieldD.TYPE_BOOL: ('bool', 'BOOL'),
|
||||||
FieldD.TYPE_DOUBLE: ('double', 'PB_LTYPE_FIXED64'),
|
FieldD.TYPE_DOUBLE: ('double', 'DOUBLE'),
|
||||||
FieldD.TYPE_FIXED32: ('uint32_t', 'PB_LTYPE_FIXED32'),
|
FieldD.TYPE_FIXED32: ('uint32_t', 'FIXED32'),
|
||||||
FieldD.TYPE_FIXED64: ('uint64_t', 'PB_LTYPE_FIXED64'),
|
FieldD.TYPE_FIXED64: ('uint64_t', 'FIXED64'),
|
||||||
FieldD.TYPE_FLOAT: ('float', 'PB_LTYPE_FIXED32'),
|
FieldD.TYPE_FLOAT: ('float', 'FLOAT'),
|
||||||
FieldD.TYPE_INT32: ('int32_t', 'PB_LTYPE_VARINT'),
|
FieldD.TYPE_INT32: ('int32_t', 'INT32'),
|
||||||
FieldD.TYPE_INT64: ('int64_t', 'PB_LTYPE_VARINT'),
|
FieldD.TYPE_INT64: ('int64_t', 'INT64'),
|
||||||
FieldD.TYPE_SFIXED32: ('int32_t', 'PB_LTYPE_FIXED32'),
|
FieldD.TYPE_SFIXED32: ('int32_t', 'SFIXED32'),
|
||||||
FieldD.TYPE_SFIXED64: ('int64_t', 'PB_LTYPE_FIXED64'),
|
FieldD.TYPE_SFIXED64: ('int64_t', 'SFIXED64'),
|
||||||
FieldD.TYPE_SINT32: ('int32_t', 'PB_LTYPE_SVARINT'),
|
FieldD.TYPE_SINT32: ('int32_t', 'SINT32'),
|
||||||
FieldD.TYPE_SINT64: ('int64_t', 'PB_LTYPE_SVARINT'),
|
FieldD.TYPE_SINT64: ('int64_t', 'SINT64'),
|
||||||
FieldD.TYPE_UINT32: ('uint32_t', 'PB_LTYPE_VARINT'),
|
FieldD.TYPE_UINT32: ('uint32_t', 'UINT32'),
|
||||||
FieldD.TYPE_UINT64: ('uint64_t', 'PB_LTYPE_VARINT')
|
FieldD.TYPE_UINT64: ('uint64_t', 'UINT64')
|
||||||
}
|
}
|
||||||
|
|
||||||
class Names:
|
class Names:
|
||||||
@@ -123,49 +123,44 @@ class Field:
|
|||||||
if desc.HasField('default_value'):
|
if desc.HasField('default_value'):
|
||||||
self.default = desc.default_value
|
self.default = desc.default_value
|
||||||
|
|
||||||
# Decide HTYPE
|
# Check field rules, i.e. required/optional/repeated.
|
||||||
# HTYPE is the high-order nibble of nanopb field description,
|
|
||||||
# defining whether value is required/optional/repeated.
|
|
||||||
can_be_static = True
|
can_be_static = True
|
||||||
if desc.label == FieldD.LABEL_REQUIRED:
|
if desc.label == FieldD.LABEL_REQUIRED:
|
||||||
self.htype = 'PB_HTYPE_REQUIRED'
|
self.rules = 'REQUIRED'
|
||||||
elif desc.label == FieldD.LABEL_OPTIONAL:
|
elif desc.label == FieldD.LABEL_OPTIONAL:
|
||||||
self.htype = 'PB_HTYPE_OPTIONAL'
|
self.rules = 'OPTIONAL'
|
||||||
elif desc.label == FieldD.LABEL_REPEATED:
|
elif desc.label == FieldD.LABEL_REPEATED:
|
||||||
|
self.rules = 'REPEATED'
|
||||||
if self.max_count is None:
|
if self.max_count is None:
|
||||||
can_be_static = False
|
can_be_static = False
|
||||||
else:
|
else:
|
||||||
self.htype = 'PB_HTYPE_ARRAY'
|
|
||||||
self.array_decl = '[%d]' % self.max_count
|
self.array_decl = '[%d]' % self.max_count
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(desc.label)
|
raise NotImplementedError(desc.label)
|
||||||
|
|
||||||
# Decide LTYPE and CTYPE
|
# Decide the C data type to use in the struct.
|
||||||
# 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.
|
|
||||||
if datatypes.has_key(desc.type):
|
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:
|
elif desc.type == FieldD.TYPE_ENUM:
|
||||||
self.ltype = 'PB_LTYPE_VARINT'
|
self.pbtype = 'ENUM'
|
||||||
self.ctype = names_from_type_name(desc.type_name)
|
self.ctype = names_from_type_name(desc.type_name)
|
||||||
if self.default is not None:
|
if self.default is not None:
|
||||||
self.default = self.ctype + self.default
|
self.default = self.ctype + self.default
|
||||||
elif desc.type == FieldD.TYPE_STRING:
|
elif desc.type == FieldD.TYPE_STRING:
|
||||||
self.ltype = 'PB_LTYPE_STRING'
|
self.pbtype = 'STRING'
|
||||||
if self.max_size is None:
|
if self.max_size is None:
|
||||||
can_be_static = False
|
can_be_static = False
|
||||||
else:
|
else:
|
||||||
self.ctype = 'char'
|
self.ctype = 'char'
|
||||||
self.array_decl += '[%d]' % self.max_size
|
self.array_decl += '[%d]' % self.max_size
|
||||||
elif desc.type == FieldD.TYPE_BYTES:
|
elif desc.type == FieldD.TYPE_BYTES:
|
||||||
self.ltype = 'PB_LTYPE_BYTES'
|
self.pbtype = 'BYTES'
|
||||||
if self.max_size is None:
|
if self.max_size is None:
|
||||||
can_be_static = False
|
can_be_static = False
|
||||||
else:
|
else:
|
||||||
self.ctype = self.struct_name + self.name + 't'
|
self.ctype = self.struct_name + self.name + 't'
|
||||||
elif desc.type == FieldD.TYPE_MESSAGE:
|
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)
|
self.ctype = self.submsgname = names_from_type_name(desc.type_name)
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(desc.type)
|
raise NotImplementedError(desc.type)
|
||||||
@@ -179,18 +174,22 @@ class Field:
|
|||||||
if field_options.type == nanopb_pb2.FT_STATIC and not can_be_static:
|
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)
|
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:
|
if field_options.type == nanopb_pb2.FT_STATIC:
|
||||||
self.htype = 'PB_HTYPE_CALLBACK'
|
self.allocation = 'STATIC'
|
||||||
|
elif field_options.type == nanopb_pb2.FT_CALLBACK:
|
||||||
|
self.allocation = 'CALLBACK'
|
||||||
self.ctype = 'pb_callback_t'
|
self.ctype = 'pb_callback_t'
|
||||||
self.array_decl = ''
|
self.array_decl = ''
|
||||||
|
else:
|
||||||
|
raise NotImplementedError(field_options.type)
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
return cmp(self.tag, other.tag)
|
return cmp(self.tag, other.tag)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.htype == 'PB_HTYPE_OPTIONAL':
|
if self.rules == 'OPTIONAL':
|
||||||
result = ' bool has_' + self.name + ';\n'
|
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'
|
result = ' size_t ' + self.name + '_count;\n'
|
||||||
else:
|
else:
|
||||||
result = ''
|
result = ''
|
||||||
@@ -199,7 +198,7 @@ class Field:
|
|||||||
|
|
||||||
def types(self):
|
def types(self):
|
||||||
'''Return definitions for any special types this field might need.'''
|
'''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 = 'typedef struct {\n'
|
||||||
result += ' size_t size;\n'
|
result += ' size_t size;\n'
|
||||||
result += ' uint8_t bytes[%d];\n' % self.max_size
|
result += ' uint8_t bytes[%d];\n' % self.max_size
|
||||||
@@ -212,30 +211,25 @@ class Field:
|
|||||||
'''Return definition for this field's default value.'''
|
'''Return definition for this field's default value.'''
|
||||||
if self.default is None:
|
if self.default is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
ctype, default = self.ctype, self.default
|
||||||
|
array_decl = ''
|
||||||
|
|
||||||
if self.ltype == 'PB_LTYPE_STRING':
|
if self.pbtype == 'STRING':
|
||||||
ctype = 'char'
|
if self.allocation != 'STATIC':
|
||||||
if self.max_size is None:
|
|
||||||
return None # Not implemented
|
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 = str(self.default).encode('string_escape')
|
||||||
default = default.replace('"', '\\"')
|
default = default.replace('"', '\\"')
|
||||||
default = '"' + default + '"'
|
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 = self.default.decode('string_escape')
|
||||||
data = ['0x%02x' % ord(c) for c in data]
|
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))
|
default = '{%d, {%s}}' % (len(data), ','.join(data))
|
||||||
array_decl = ''
|
|
||||||
else:
|
|
||||||
ctype, default = self.ctype, self.default
|
|
||||||
array_decl = ''
|
|
||||||
|
|
||||||
if declaration_only:
|
if declaration_only:
|
||||||
return 'extern const %s %s_default%s;' % (ctype, self.struct_name + self.name, array_decl)
|
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.
|
'''Return the pb_field_t initializer to use in the constant array.
|
||||||
prev_field_name is the name of the previous field or None.
|
prev_field_name is the name of the previous field or None.
|
||||||
'''
|
'''
|
||||||
result = ' {%d, ' % self.tag
|
result = ' PB_FIELD(%3d, ' % self.tag
|
||||||
result += '(pb_type_t) ((int) ' + self.htype
|
result += '%-8s, ' % self.pbtype
|
||||||
if self.ltype is not None:
|
result += '%s, ' % self.rules
|
||||||
result += ' | (int) ' + self.ltype
|
result += '%s, ' % self.allocation
|
||||||
result += '),\n'
|
result += '%s, ' % self.struct_name
|
||||||
|
result += '%s, ' % self.name
|
||||||
|
result += '%s, ' % (prev_field_name or self.name)
|
||||||
|
|
||||||
if prev_field_name is None:
|
if self.pbtype == 'MESSAGE':
|
||||||
result += ' offsetof(%s, %s),' % (self.struct_name, self.name)
|
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:
|
else:
|
||||||
result += ' pb_delta_end(%s, %s, %s),' % (self.struct_name, self.name, prev_field_name)
|
result += '&%s_default)' % (self.struct_name + self.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))
|
|
||||||
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)
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def largest_field_value(self):
|
def largest_field_value(self):
|
||||||
'''Determine if this field needs 16bit or 32bit pb_field_t structure to compile properly.
|
'''Determine if this field needs 16bit or 32bit pb_field_t structure to compile properly.
|
||||||
Returns numeric value or a C-expression for assert.'''
|
Returns numeric value or a C-expression for assert.'''
|
||||||
if self.ltype == 'PB_LTYPE_SUBMESSAGE':
|
if self.pbtype == 'MESSAGE':
|
||||||
if self.htype == 'PB_HTYPE_ARRAY':
|
if self.rules == 'REPEATED' and self.allocation == 'STATIC':
|
||||||
return 'pb_membersize(%s, %s[0])' % (self.struct_name, self.name)
|
return 'pb_membersize(%s, %s[0])' % (self.struct_name, self.name)
|
||||||
else:
|
else:
|
||||||
return 'pb_membersize(%s, %s)' % (self.struct_name, self.name)
|
return 'pb_membersize(%s, %s)' % (self.struct_name, self.name)
|
||||||
@@ -358,7 +335,7 @@ class Message:
|
|||||||
prev = None
|
prev = None
|
||||||
for field in self.ordered_fields:
|
for field in self.ordered_fields:
|
||||||
result += field.pb_field_t(prev)
|
result += field.pb_field_t(prev)
|
||||||
result += ',\n\n'
|
result += ',\n'
|
||||||
prev = field.name
|
prev = field.name
|
||||||
|
|
||||||
result += ' PB_LAST_FIELD\n};'
|
result += ' PB_LAST_FIELD\n};'
|
||||||
@@ -501,8 +478,30 @@ def generate_header(dependencies, headername, enums, messages):
|
|||||||
for msg in messages:
|
for msg in messages:
|
||||||
yield msg.fields_declaration() + '\n'
|
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:
|
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_msg = max(messages, key = count_required_fields)
|
||||||
largest_count = count_required_fields(largest_msg)
|
largest_count = count_required_fields(largest_msg)
|
||||||
if largest_count > 64:
|
if largest_count > 64:
|
||||||
@@ -561,31 +560,11 @@ def generate_header(dependencies, headername, enums, messages):
|
|||||||
yield '\n'
|
yield '\n'
|
||||||
yield '/* On some platforms (such as AVR), double is really float.\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 ' * 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 ' */\n'
|
||||||
yield 'STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)\n'
|
yield 'STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)\n'
|
||||||
|
|
||||||
yield '\n#ifdef __cplusplus\n'
|
yield '\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'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
180
pb.h
180
pb.h
@@ -6,7 +6,7 @@
|
|||||||
* see pb_encode.h or pb_decode.h
|
* see pb_encode.h or pb_decode.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NANOPB_VERSION nanopb-0.1.9-dev
|
#define NANOPB_VERSION nanopb-0.2.0-dev
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -53,60 +53,55 @@
|
|||||||
* SINT* is different, though, because it is zig-zag coded.
|
* SINT* is different, though, because it is zig-zag coded.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum {
|
typedef uint8_t pb_type_t;
|
||||||
/************************
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
|
/************************
|
||||||
|
* 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_HTYPE(x) ((x) & PB_HTYPE_MASK)
|
||||||
#define PB_LTYPE(x) ((x) & PB_LTYPE_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_membersize(st, m) (sizeof ((st*)0)->m)
|
||||||
#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0]))
|
#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0]))
|
||||||
#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2))
|
#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2))
|
||||||
#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}
|
#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.
|
/* These macros are used for giving out error messages.
|
||||||
* They are mostly a debugging aid; the main error information
|
* They are mostly a debugging aid; the main error information
|
||||||
* is the true/false return value from functions.
|
* is the true/false return value from functions.
|
||||||
|
|||||||
164
pb_decode.c
164
pb_decode.c
@@ -303,8 +303,11 @@ static bool pb_field_next(pb_field_iterator_t *iter)
|
|||||||
bool notwrapped = true;
|
bool notwrapped = true;
|
||||||
size_t prev_size = iter->current->data_size;
|
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;
|
prev_size *= iter->current->array_size;
|
||||||
|
}
|
||||||
|
|
||||||
if (PB_HTYPE(iter->current->type) == PB_HTYPE_REQUIRED)
|
if (PB_HTYPE(iter->current->type) == PB_HTYPE_REQUIRED)
|
||||||
iter->required_field_index++;
|
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 *
|
* 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:
|
case PB_HTYPE_REQUIRED:
|
||||||
return func(stream, iter->current, iter->pData);
|
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;
|
*(bool*)iter->pSize = true;
|
||||||
return func(stream, iter->current, iter->pData);
|
return func(stream, iter->current, iter->pData);
|
||||||
|
|
||||||
case PB_HTYPE_ARRAY:
|
case PB_HTYPE_REPEATED:
|
||||||
if (wire_type == PB_WT_STRING
|
if (wire_type == PB_WT_STRING
|
||||||
&& PB_LTYPE(iter->current->type) <= PB_LTYPE_LAST_PACKABLE)
|
&& PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE)
|
||||||
{
|
{
|
||||||
/* Packed array */
|
/* Packed array */
|
||||||
bool status = true;
|
bool status = true;
|
||||||
@@ -395,48 +402,63 @@ static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_t
|
|||||||
(*size)++;
|
(*size)++;
|
||||||
return func(stream, iter->current, pItem);
|
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(&substream, iter->current, pCallback->arg))
|
||||||
|
PB_RETURN_ERROR(stream, "callback failed");
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
default:
|
||||||
PB_RETURN_ERROR(stream, "invalid field type");
|
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 */
|
/* Initialize size/has fields and apply default values */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
pb_type_t type;
|
||||||
|
type = iter.current->type;
|
||||||
|
|
||||||
if (iter.current->tag == 0)
|
if (iter.current->tag == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Initialize the size field for optional/repeated fields to 0. */
|
if (PB_ATYPE(type) == PB_ATYPE_STATIC)
|
||||||
if (PB_HTYPE(iter.current->type) == PB_HTYPE_OPTIONAL)
|
|
||||||
{
|
{
|
||||||
*(bool*)iter.pSize = false;
|
/* 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (PB_HTYPE(iter.current->type) == PB_HTYPE_ARRAY)
|
else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK)
|
||||||
{
|
|
||||||
*(size_t*)iter.pSize = 0;
|
|
||||||
continue; /* Array is empty, no need to initialize contents */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize field contents to default value */
|
|
||||||
if (PB_HTYPE(iter.current->type) == PB_HTYPE_CALLBACK)
|
|
||||||
{
|
{
|
||||||
continue; /* Don't overwrite 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));
|
} 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
|
/* New array entries need to be initialized, while required and optional
|
||||||
* submessages have already been initialized in the top-level pb_decode. */
|
* 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);
|
status = pb_decode(&substream, submsg_fields, dest);
|
||||||
else
|
else
|
||||||
status = pb_decode_noinit(&substream, submsg_fields, dest);
|
status = pb_decode_noinit(&substream, submsg_fields, dest);
|
||||||
|
|||||||
103
pb_encode.c
103
pb_encode.c
@@ -153,58 +153,89 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie
|
|||||||
return true;
|
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)
|
bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
|
||||||
{
|
{
|
||||||
const pb_field_t *field = fields;
|
const pb_field_t *field = fields;
|
||||||
const void *pData = src_struct;
|
const void *pData = src_struct;
|
||||||
const void *pSize;
|
|
||||||
size_t prev_size = 0;
|
size_t prev_size = 0;
|
||||||
|
|
||||||
while (field->tag != 0)
|
while (field->tag != 0)
|
||||||
{
|
{
|
||||||
pb_encoder_t func = PB_ENCODERS[PB_LTYPE(field->type)];
|
|
||||||
pData = (const char*)pData + prev_size + field->data_offset;
|
pData = (const char*)pData + prev_size + field->data_offset;
|
||||||
pSize = (const char*)pData + field->size_offset;
|
|
||||||
|
|
||||||
prev_size = field->data_size;
|
prev_size = field->data_size;
|
||||||
if (PB_HTYPE(field->type) == PB_HTYPE_ARRAY)
|
|
||||||
prev_size *= field->array_size;
|
/* Special case for static arrays */
|
||||||
|
if (PB_ATYPE(field->type) == PB_ATYPE_STATIC &&
|
||||||
switch (PB_HTYPE(field->type))
|
PB_HTYPE(field->type) == PB_HTYPE_REPEATED)
|
||||||
{
|
{
|
||||||
case PB_HTYPE_REQUIRED:
|
prev_size *= field->array_size;
|
||||||
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))
|
switch (PB_ATYPE(field->type))
|
||||||
return false;
|
{
|
||||||
}
|
case PB_ATYPE_STATIC:
|
||||||
break;
|
if (!encode_static_field(stream, field, pData))
|
||||||
|
|
||||||
case PB_HTYPE_ARRAY:
|
|
||||||
if (!encode_array(stream, field, pData, *(const size_t*)pSize, func))
|
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PB_HTYPE_CALLBACK:
|
case PB_ATYPE_CALLBACK:
|
||||||
{
|
if (!encode_callback_field(stream, field, pData))
|
||||||
const pb_callback_t *callback = (const pb_callback_t*)pData;
|
return false;
|
||||||
if (callback->funcs.encode != NULL)
|
|
||||||
{
|
|
||||||
if (!callback->funcs.encode(stream, field, callback->arg))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
field++;
|
field++;
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
/* Automatically generated nanopb constant definitions */
|
/* 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 int32_t SubMessage_substuff2_default = 2;
|
||||||
const uint32_t SubMessage_substuff3_default = 3;
|
const uint32_t SubMessage_substuff3_default = 3;
|
||||||
const int32_t AllTypes_opt_int32_default = 4041;
|
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 uint64_t AllTypes_opt_fixed64_default = 4051;
|
||||||
const int64_t AllTypes_opt_sfixed64_default = 4052;
|
const int64_t AllTypes_opt_sfixed64_default = 4052;
|
||||||
const double AllTypes_opt_double_default = 4053;
|
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 AllTypes_opt_bytes_t AllTypes_opt_bytes_default = {4, {0x34,0x30,0x35,0x35}};
|
||||||
const MyEnum AllTypes_opt_enum_default = MyEnum_Second;
|
const MyEnum AllTypes_opt_enum_default = MyEnum_Second;
|
||||||
|
|
||||||
|
|
||||||
const pb_field_t SubMessage_fields[4] = {
|
const pb_field_t SubMessage_fields[4] = {
|
||||||
{1, PB_HTYPE_REQUIRED | PB_LTYPE_STRING,
|
PB_FIELD( 1, STRING , REQUIRED, STATIC, SubMessage, substuff1, substuff1, &SubMessage_substuff1_default),
|
||||||
offsetof(SubMessage, substuff1), 0,
|
PB_FIELD( 2, INT32 , REQUIRED, STATIC, SubMessage, substuff2, substuff1, &SubMessage_substuff2_default),
|
||||||
pb_membersize(SubMessage, substuff1), 0,
|
PB_FIELD( 3, FIXED32 , OPTIONAL, STATIC, SubMessage, substuff3, substuff2, &SubMessage_substuff3_default),
|
||||||
&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_LAST_FIELD
|
PB_LAST_FIELD
|
||||||
};
|
};
|
||||||
|
|
||||||
const pb_field_t AllTypes_fields[53] = {
|
const pb_field_t AllTypes_fields[53] = {
|
||||||
{1, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
|
PB_FIELD( 1, INT32 , REQUIRED, STATIC, AllTypes, req_int32, req_int32, 0),
|
||||||
offsetof(AllTypes, req_int32), 0,
|
PB_FIELD( 2, INT64 , REQUIRED, STATIC, AllTypes, req_int64, req_int32, 0),
|
||||||
pb_membersize(AllTypes, req_int32), 0, 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),
|
||||||
{2, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
|
PB_FIELD( 5, SINT32 , REQUIRED, STATIC, AllTypes, req_sint32, req_uint64, 0),
|
||||||
pb_delta_end(AllTypes, req_int64, req_int32), 0,
|
PB_FIELD( 6, SINT64 , REQUIRED, STATIC, AllTypes, req_sint64, req_sint32, 0),
|
||||||
pb_membersize(AllTypes, req_int64), 0, 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),
|
||||||
{3, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
|
PB_FIELD( 9, SFIXED32, REQUIRED, STATIC, AllTypes, req_sfixed32, req_fixed32, 0),
|
||||||
pb_delta_end(AllTypes, req_uint32, req_int64), 0,
|
PB_FIELD( 10, FLOAT , REQUIRED, STATIC, AllTypes, req_float, req_sfixed32, 0),
|
||||||
pb_membersize(AllTypes, req_uint32), 0, 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),
|
||||||
{4, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
|
PB_FIELD( 13, DOUBLE , REQUIRED, STATIC, AllTypes, req_double, req_sfixed64, 0),
|
||||||
pb_delta_end(AllTypes, req_uint64, req_uint32), 0,
|
PB_FIELD( 14, STRING , REQUIRED, STATIC, AllTypes, req_string, req_double, 0),
|
||||||
pb_membersize(AllTypes, req_uint64), 0, 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),
|
||||||
{5, PB_HTYPE_REQUIRED | PB_LTYPE_SVARINT,
|
PB_FIELD( 17, ENUM , REQUIRED, STATIC, AllTypes, req_enum, req_submsg, 0),
|
||||||
pb_delta_end(AllTypes, req_sint32, req_uint64), 0,
|
PB_FIELD( 21, INT32 , REPEATED, STATIC, AllTypes, rep_int32, req_enum, 0),
|
||||||
pb_membersize(AllTypes, req_sint32), 0, 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),
|
||||||
{6, PB_HTYPE_REQUIRED | PB_LTYPE_SVARINT,
|
PB_FIELD( 24, UINT64 , REPEATED, STATIC, AllTypes, rep_uint64, rep_uint32, 0),
|
||||||
pb_delta_end(AllTypes, req_sint64, req_sint32), 0,
|
PB_FIELD( 25, SINT32 , REPEATED, STATIC, AllTypes, rep_sint32, rep_uint64, 0),
|
||||||
pb_membersize(AllTypes, req_sint64), 0, 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),
|
||||||
{7, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT,
|
PB_FIELD( 28, FIXED32 , REPEATED, STATIC, AllTypes, rep_fixed32, rep_bool, 0),
|
||||||
pb_delta_end(AllTypes, req_bool, req_sint64), 0,
|
PB_FIELD( 29, SFIXED32, REPEATED, STATIC, AllTypes, rep_sfixed32, rep_fixed32, 0),
|
||||||
pb_membersize(AllTypes, req_bool), 0, 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),
|
||||||
{8, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED32,
|
PB_FIELD( 32, SFIXED64, REPEATED, STATIC, AllTypes, rep_sfixed64, rep_fixed64, 0),
|
||||||
pb_delta_end(AllTypes, req_fixed32, req_bool), 0,
|
PB_FIELD( 33, DOUBLE , REPEATED, STATIC, AllTypes, rep_double, rep_sfixed64, 0),
|
||||||
pb_membersize(AllTypes, req_fixed32), 0, 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),
|
||||||
{9, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED32,
|
PB_FIELD( 36, MESSAGE , REPEATED, STATIC, AllTypes, rep_submsg, rep_bytes, &SubMessage_fields),
|
||||||
pb_delta_end(AllTypes, req_sfixed32, req_fixed32), 0,
|
PB_FIELD( 37, ENUM , REPEATED, STATIC, AllTypes, rep_enum, rep_submsg, 0),
|
||||||
pb_membersize(AllTypes, req_sfixed32), 0, 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),
|
||||||
{10, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED32,
|
PB_FIELD( 43, UINT32 , OPTIONAL, STATIC, AllTypes, opt_uint32, opt_int64, &AllTypes_opt_uint32_default),
|
||||||
pb_delta_end(AllTypes, req_float, req_sfixed32), 0,
|
PB_FIELD( 44, UINT64 , OPTIONAL, STATIC, AllTypes, opt_uint64, opt_uint32, &AllTypes_opt_uint64_default),
|
||||||
pb_membersize(AllTypes, req_float), 0, 0},
|
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),
|
||||||
{11, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED64,
|
PB_FIELD( 47, BOOL , OPTIONAL, STATIC, AllTypes, opt_bool, opt_sint64, &AllTypes_opt_bool_default),
|
||||||
pb_delta_end(AllTypes, req_fixed64, req_float), 0,
|
PB_FIELD( 48, FIXED32 , OPTIONAL, STATIC, AllTypes, opt_fixed32, opt_bool, &AllTypes_opt_fixed32_default),
|
||||||
pb_membersize(AllTypes, req_fixed64), 0, 0},
|
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),
|
||||||
{12, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED64,
|
PB_FIELD( 51, FIXED64 , OPTIONAL, STATIC, AllTypes, opt_fixed64, opt_float, &AllTypes_opt_fixed64_default),
|
||||||
pb_delta_end(AllTypes, req_sfixed64, req_fixed64), 0,
|
PB_FIELD( 52, SFIXED64, OPTIONAL, STATIC, AllTypes, opt_sfixed64, opt_fixed64, &AllTypes_opt_sfixed64_default),
|
||||||
pb_membersize(AllTypes, req_sfixed64), 0, 0},
|
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),
|
||||||
{13, PB_HTYPE_REQUIRED | PB_LTYPE_FIXED64,
|
PB_FIELD( 55, BYTES , OPTIONAL, STATIC, AllTypes, opt_bytes, opt_string, &AllTypes_opt_bytes_default),
|
||||||
pb_delta_end(AllTypes, req_double, req_sfixed64), 0,
|
PB_FIELD( 56, MESSAGE , OPTIONAL, STATIC, AllTypes, opt_submsg, opt_bytes, &SubMessage_fields),
|
||||||
pb_membersize(AllTypes, req_double), 0, 0},
|
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),
|
||||||
{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_LAST_FIELD
|
PB_LAST_FIELD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
/* Automatically generated nanopb header */
|
/* 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
|
* It is used as a part of test suite in order to detect any
|
||||||
* incompatible changes made to the generator in future versions.
|
* 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>
|
#include <pb.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Enum definitions */
|
/* Enum definitions */
|
||||||
typedef enum {
|
typedef enum _MyEnum {
|
||||||
MyEnum_Zero = 0,
|
MyEnum_Zero = 0,
|
||||||
MyEnum_First = 1,
|
MyEnum_First = 1,
|
||||||
MyEnum_Second = 2,
|
MyEnum_Second = 2,
|
||||||
@@ -16,7 +21,7 @@ typedef enum {
|
|||||||
} MyEnum;
|
} MyEnum;
|
||||||
|
|
||||||
/* Struct definitions */
|
/* Struct definitions */
|
||||||
typedef struct {
|
typedef struct _SubMessage {
|
||||||
char substuff1[16];
|
char substuff1[16];
|
||||||
int32_t substuff2;
|
int32_t substuff2;
|
||||||
bool has_substuff3;
|
bool has_substuff3;
|
||||||
@@ -38,7 +43,7 @@ typedef struct {
|
|||||||
uint8_t bytes[16];
|
uint8_t bytes[16];
|
||||||
} AllTypes_opt_bytes_t;
|
} AllTypes_opt_bytes_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct _AllTypes {
|
||||||
int32_t req_int32;
|
int32_t req_int32;
|
||||||
int64_t req_int64;
|
int64_t req_int64;
|
||||||
uint32_t req_uint32;
|
uint32_t req_uint32;
|
||||||
@@ -128,7 +133,7 @@ typedef struct {
|
|||||||
} AllTypes;
|
} AllTypes;
|
||||||
|
|
||||||
/* Default values for struct fields */
|
/* 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 int32_t SubMessage_substuff2_default;
|
||||||
extern const uint32_t SubMessage_substuff3_default;
|
extern const uint32_t SubMessage_substuff3_default;
|
||||||
extern const int32_t AllTypes_opt_int32_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 uint64_t AllTypes_opt_fixed64_default;
|
||||||
extern const int64_t AllTypes_opt_sfixed64_default;
|
extern const int64_t AllTypes_opt_sfixed64_default;
|
||||||
extern const double AllTypes_opt_double_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 AllTypes_opt_bytes_t AllTypes_opt_bytes_default;
|
||||||
extern const MyEnum AllTypes_opt_enum_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 SubMessage_fields[4];
|
||||||
extern const pb_field_t AllTypes_fields[53];
|
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
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user