Compare commits
27 Commits
nanopb-0.2
...
dev_instal
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2ec9e29b3 | ||
|
|
55bd3d706b | ||
|
|
a5006cc612 | ||
|
|
a0f91bbeeb | ||
|
|
7723a30bd6 | ||
|
|
98e01b2b33 | ||
|
|
985f1b4943 | ||
|
|
df3fd72337 | ||
|
|
5ef9d5b698 | ||
|
|
4ecf27c817 | ||
|
|
ccf63de0c6 | ||
|
|
ece793fbc9 | ||
|
|
6adf4e163c | ||
|
|
420ad05e06 | ||
|
|
5e82a426e6 | ||
|
|
8209a668cd | ||
|
|
be81effcf4 | ||
|
|
f1b2ba57d3 | ||
|
|
d2ba776094 | ||
|
|
97554a41c6 | ||
|
|
b4457a86d6 | ||
|
|
bee09c3a38 | ||
|
|
8daadc556e | ||
|
|
43cc9940ad | ||
|
|
85be7a634e | ||
|
|
b5ae8eb6a5 | ||
|
|
2f982d30ef |
@@ -1,18 +1,3 @@
|
|||||||
nanopb-0.2.6 (2014-02-15)
|
|
||||||
Fix generator error with bytes callback fields (issue 99)
|
|
||||||
Fix warnings about large integer constants (issue 102)
|
|
||||||
Add comments to where STATIC_ASSERT is used (issue 96)
|
|
||||||
Add warning about unknown field names on .options (issue 105)
|
|
||||||
Move descriptor.proto to google/protobuf subdirectory (issue 104)
|
|
||||||
Improved tests
|
|
||||||
|
|
||||||
nanopb-0.2.5 (2014-01-01)
|
|
||||||
Fix a bug with encoding negative values in int32 fields (issue 97)
|
|
||||||
Create binary packages of the generator + dependencies (issue 47)
|
|
||||||
Add support for pointer-type fields to the encoder (part of issue 80)
|
|
||||||
Fixed path in FindNanopb.cmake (issue 94)
|
|
||||||
Improved tests
|
|
||||||
|
|
||||||
nanopb-0.2.4 (2013-11-07)
|
nanopb-0.2.4 (2013-11-07)
|
||||||
Remove the deprecated NANOPB_INTERNALS functions from public API.
|
Remove the deprecated NANOPB_INTERNALS functions from public API.
|
||||||
Document the security model.
|
Document the security model.
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ compiler. This has the advantage that there is no need to reimplement the
|
|||||||
basic parsing of .proto files. However, it does mean that you need the
|
basic parsing of .proto files. However, it does mean that you need the
|
||||||
Google's protobuf library in order to run the generator.
|
Google's protobuf library in order to run the generator.
|
||||||
|
|
||||||
If you have downloaded a binary package for nanopb (either Windows, Linux or
|
If you have downloaded a binary package for nanopb (either Windows or Linux
|
||||||
Mac OS X version), the 'protoc' binary is included in the 'generator-bin'
|
version), the 'protoc' binary is included in the 'generator-bin' folder. In
|
||||||
folder. In this case, you are ready to go. Simply run this command:
|
this case, you are ready to go. Simply run this command:
|
||||||
|
|
||||||
generator-bin/protoc --nanopb_out=. myprotocol.proto
|
generator-bin/protoc --nanopb_out=. myprotocol.proto
|
||||||
|
|
||||||
|
|||||||
@@ -104,12 +104,11 @@ requires a few header files to be available:
|
|||||||
#) *stdbool.h*, for definition of *bool*
|
#) *stdbool.h*, for definition of *bool*
|
||||||
|
|
||||||
If these header files do not come with your compiler, you can use the
|
If these header files do not come with your compiler, you can use the
|
||||||
file *extra/pb_syshdr.h* instead. It contains an example of how to provide
|
file *compat/pb_syshdr.h* instead. It contains an example of how to provide
|
||||||
the dependencies. You may have to edit it a bit to suit your custom platform.
|
the dependencies. You may have to edit it a bit to suit your custom platform.
|
||||||
|
|
||||||
To use the pb_syshdr.h, define *PB_SYSTEM_HEADER* as *"pb_syshdr.h"* (including the quotes).
|
To use the pb_syshdr.h, define *PB_SYSTEM_HEADER* to be the name of your custom
|
||||||
Similarly, you can provide a custom include file, which should provide all the dependencies
|
header file. It should provide all the dependencies listed above.
|
||||||
listed above.
|
|
||||||
|
|
||||||
Running the test cases
|
Running the test cases
|
||||||
======================
|
======================
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ CFLAGS += -I$(NANOPB_DIR)
|
|||||||
|
|
||||||
all: server client
|
all: server client
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f server client fileproto.pb.c fileproto.pb.h
|
rm -f server client fileproto.pb.c fileproto.pb.h
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ CFLAGS += -I$(NANOPB_DIR)
|
|||||||
|
|
||||||
all: run_tests
|
all: run_tests
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f test_conversions encode_double decode_double doubleproto.pb.c doubleproto.pb.h
|
rm -f test_conversions encode_double decode_double doubleproto.pb.c doubleproto.pb.h
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ all: encode decode
|
|||||||
./encode 2 | ./decode
|
./encode 2 | ./decode
|
||||||
./encode 3 | ./decode
|
./encode 3 | ./decode
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f encode unionproto.pb.h unionproto.pb.c
|
rm -f encode unionproto.pb.h unionproto.pb.c
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
'''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.'''
|
'''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.'''
|
||||||
nanopb_version = "nanopb-0.2.6"
|
nanopb_version = "nanopb-0.2.5-dev"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@@ -15,7 +15,6 @@ except:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import google.protobuf.text_format as text_format
|
import google.protobuf.text_format as text_format
|
||||||
import google.protobuf.descriptor_pb2 as descriptor
|
|
||||||
except:
|
except:
|
||||||
sys.stderr.write('''
|
sys.stderr.write('''
|
||||||
*************************************************************
|
*************************************************************
|
||||||
@@ -27,7 +26,7 @@ except:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import proto.nanopb_pb2 as nanopb_pb2
|
import proto.nanopb_pb2 as nanopb_pb2
|
||||||
import proto.plugin_pb2 as plugin_pb2
|
import proto.descriptor_pb2 as descriptor
|
||||||
except:
|
except:
|
||||||
sys.stderr.write('''
|
sys.stderr.write('''
|
||||||
********************************************************************
|
********************************************************************
|
||||||
@@ -37,6 +36,7 @@ except:
|
|||||||
''' + '\n')
|
''' + '\n')
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Generation of single fields
|
# Generation of single fields
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -52,7 +52,7 @@ datatypes = {
|
|||||||
FieldD.TYPE_FIXED32: ('uint32_t', 'FIXED32', 4),
|
FieldD.TYPE_FIXED32: ('uint32_t', 'FIXED32', 4),
|
||||||
FieldD.TYPE_FIXED64: ('uint64_t', 'FIXED64', 8),
|
FieldD.TYPE_FIXED64: ('uint64_t', 'FIXED64', 8),
|
||||||
FieldD.TYPE_FLOAT: ('float', 'FLOAT', 4),
|
FieldD.TYPE_FLOAT: ('float', 'FLOAT', 4),
|
||||||
FieldD.TYPE_INT32: ('int32_t', 'INT32', 10),
|
FieldD.TYPE_INT32: ('int32_t', 'INT32', 5),
|
||||||
FieldD.TYPE_INT64: ('int64_t', 'INT64', 10),
|
FieldD.TYPE_INT64: ('int64_t', 'INT64', 10),
|
||||||
FieldD.TYPE_SFIXED32: ('int32_t', 'SFIXED32', 4),
|
FieldD.TYPE_SFIXED32: ('int32_t', 'SFIXED32', 4),
|
||||||
FieldD.TYPE_SFIXED64: ('int64_t', 'SFIXED64', 8),
|
FieldD.TYPE_SFIXED64: ('int64_t', 'SFIXED64', 8),
|
||||||
@@ -169,7 +169,6 @@ class Field:
|
|||||||
self.max_count = None
|
self.max_count = None
|
||||||
self.array_decl = ""
|
self.array_decl = ""
|
||||||
self.enc_size = None
|
self.enc_size = None
|
||||||
self.ctype = None
|
|
||||||
|
|
||||||
# Parse field options
|
# Parse field options
|
||||||
if field_options.HasField("max_size"):
|
if field_options.HasField("max_size"):
|
||||||
@@ -196,34 +195,6 @@ class Field:
|
|||||||
else:
|
else:
|
||||||
raise NotImplementedError(desc.label)
|
raise NotImplementedError(desc.label)
|
||||||
|
|
||||||
# Check if the field can be implemented with static allocation
|
|
||||||
# i.e. whether the data size is known.
|
|
||||||
if desc.type == FieldD.TYPE_STRING and self.max_size is None:
|
|
||||||
can_be_static = False
|
|
||||||
|
|
||||||
if desc.type == FieldD.TYPE_BYTES and self.max_size is None:
|
|
||||||
can_be_static = False
|
|
||||||
|
|
||||||
# Decide how the field data will be allocated
|
|
||||||
if field_options.type == nanopb_pb2.FT_DEFAULT:
|
|
||||||
if can_be_static:
|
|
||||||
field_options.type = nanopb_pb2.FT_STATIC
|
|
||||||
else:
|
|
||||||
field_options.type = nanopb_pb2.FT_CALLBACK
|
|
||||||
|
|
||||||
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_STATIC:
|
|
||||||
self.allocation = 'STATIC'
|
|
||||||
elif field_options.type == nanopb_pb2.FT_POINTER:
|
|
||||||
self.allocation = 'POINTER'
|
|
||||||
elif field_options.type == nanopb_pb2.FT_CALLBACK:
|
|
||||||
self.allocation = 'CALLBACK'
|
|
||||||
else:
|
|
||||||
raise NotImplementedError(field_options.type)
|
|
||||||
|
|
||||||
# Decide the C data type to use in the struct.
|
# Decide the C data type to use in the struct.
|
||||||
if datatypes.has_key(desc.type):
|
if datatypes.has_key(desc.type):
|
||||||
self.ctype, self.pbtype, self.enc_size = datatypes[desc.type]
|
self.ctype, self.pbtype, self.enc_size = datatypes[desc.type]
|
||||||
@@ -235,18 +206,19 @@ class Field:
|
|||||||
self.enc_size = 5 # protoc rejects enum values > 32 bits
|
self.enc_size = 5 # protoc rejects enum values > 32 bits
|
||||||
elif desc.type == FieldD.TYPE_STRING:
|
elif desc.type == FieldD.TYPE_STRING:
|
||||||
self.pbtype = 'STRING'
|
self.pbtype = 'STRING'
|
||||||
self.ctype = 'char'
|
if self.max_size is None:
|
||||||
if self.allocation == 'STATIC':
|
can_be_static = False
|
||||||
|
else:
|
||||||
self.ctype = 'char'
|
self.ctype = 'char'
|
||||||
self.array_decl += '[%d]' % self.max_size
|
self.array_decl += '[%d]' % self.max_size
|
||||||
self.enc_size = varint_max_size(self.max_size) + self.max_size
|
self.enc_size = varint_max_size(self.max_size) + self.max_size
|
||||||
elif desc.type == FieldD.TYPE_BYTES:
|
elif desc.type == FieldD.TYPE_BYTES:
|
||||||
self.pbtype = 'BYTES'
|
self.pbtype = 'BYTES'
|
||||||
if self.allocation == 'STATIC':
|
if self.max_size is None:
|
||||||
|
can_be_static = False
|
||||||
|
else:
|
||||||
self.ctype = self.struct_name + self.name + 't'
|
self.ctype = self.struct_name + self.name + 't'
|
||||||
self.enc_size = varint_max_size(self.max_size) + self.max_size
|
self.enc_size = varint_max_size(self.max_size) + self.max_size
|
||||||
elif self.allocation == 'POINTER':
|
|
||||||
self.ctype = 'pb_bytes_ptr_t'
|
|
||||||
elif desc.type == FieldD.TYPE_MESSAGE:
|
elif desc.type == FieldD.TYPE_MESSAGE:
|
||||||
self.pbtype = 'MESSAGE'
|
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)
|
||||||
@@ -254,31 +226,35 @@ class Field:
|
|||||||
else:
|
else:
|
||||||
raise NotImplementedError(desc.type)
|
raise NotImplementedError(desc.type)
|
||||||
|
|
||||||
|
if field_options.type == nanopb_pb2.FT_DEFAULT:
|
||||||
|
if can_be_static:
|
||||||
|
field_options.type = nanopb_pb2.FT_STATIC
|
||||||
|
else:
|
||||||
|
field_options.type = nanopb_pb2.FT_CALLBACK
|
||||||
|
|
||||||
|
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_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):
|
def __cmp__(self, other):
|
||||||
return cmp(self.tag, other.tag)
|
return cmp(self.tag, other.tag)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
result = ''
|
if self.rules == 'OPTIONAL' and self.allocation == 'STATIC':
|
||||||
if self.allocation == 'POINTER':
|
result = ' bool has_' + self.name + ';\n'
|
||||||
if self.rules == 'REPEATED':
|
elif self.rules == 'REPEATED' and self.allocation == 'STATIC':
|
||||||
result += ' size_t ' + self.name + '_count;\n'
|
result = ' size_t ' + self.name + '_count;\n'
|
||||||
|
|
||||||
if self.pbtype == 'MESSAGE':
|
|
||||||
# Use struct definition, so recursive submessages are possible
|
|
||||||
result += ' struct _%s *%s;' % (self.ctype, self.name)
|
|
||||||
elif self.rules == 'REPEATED' and self.pbtype == 'STRING':
|
|
||||||
# String arrays need to be defined as pointers to pointers
|
|
||||||
result += ' %s **%s;' % (self.ctype, self.name)
|
|
||||||
else:
|
|
||||||
result += ' %s *%s;' % (self.ctype, self.name)
|
|
||||||
elif self.allocation == 'CALLBACK':
|
|
||||||
result += ' pb_callback_t %s;' % self.name
|
|
||||||
else:
|
else:
|
||||||
if self.rules == 'OPTIONAL' and self.allocation == 'STATIC':
|
result = ''
|
||||||
result += ' bool has_' + self.name + ';\n'
|
result += ' %s %s%s;' % (self.ctype, self.name, self.array_decl)
|
||||||
elif self.rules == 'REPEATED' and self.allocation == 'STATIC':
|
|
||||||
result += ' size_t ' + self.name + '_count;\n'
|
|
||||||
result += ' %s %s%s;' % (self.ctype, self.name, self.array_decl)
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def types(self):
|
def types(self):
|
||||||
@@ -315,12 +291,6 @@ class Field:
|
|||||||
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]
|
||||||
default = '{%d, {%s}}' % (len(data), ','.join(data))
|
default = '{%d, {%s}}' % (len(data), ','.join(data))
|
||||||
elif self.pbtype in ['FIXED32', 'UINT32']:
|
|
||||||
default += 'u'
|
|
||||||
elif self.pbtype in ['FIXED64', 'UINT64']:
|
|
||||||
default += 'ull'
|
|
||||||
elif self.pbtype in ['SFIXED64', 'INT64']:
|
|
||||||
default += 'll'
|
|
||||||
|
|
||||||
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)
|
||||||
@@ -339,7 +309,7 @@ class Field:
|
|||||||
result = ' PB_FIELD2(%3d, ' % self.tag
|
result = ' PB_FIELD2(%3d, ' % self.tag
|
||||||
result += '%-8s, ' % self.pbtype
|
result += '%-8s, ' % self.pbtype
|
||||||
result += '%s, ' % self.rules
|
result += '%s, ' % self.rules
|
||||||
result += '%-8s, ' % self.allocation
|
result += '%s, ' % self.allocation
|
||||||
result += '%s, ' % ("FIRST" if not prev_field_name else "OTHER")
|
result += '%s, ' % ("FIRST" if not prev_field_name else "OTHER")
|
||||||
result += '%s, ' % self.struct_name
|
result += '%s, ' % self.struct_name
|
||||||
result += '%s, ' % self.name
|
result += '%s, ' % self.name
|
||||||
@@ -822,23 +792,6 @@ def generate_source(headername, enums, messages, extensions, options):
|
|||||||
if worst > 255 or checks:
|
if worst > 255 or checks:
|
||||||
yield '\n/* Check that field information fits in pb_field_t */\n'
|
yield '\n/* Check that field information fits in pb_field_t */\n'
|
||||||
|
|
||||||
if worst > 65535 or checks:
|
|
||||||
yield '#if !defined(PB_FIELD_32BIT)\n'
|
|
||||||
if worst > 65535:
|
|
||||||
yield '#error Field descriptor for %s is too large. Define PB_FIELD_32BIT to fix this.\n' % worst_field
|
|
||||||
else:
|
|
||||||
assertion = ' && '.join(str(c) + ' < 65536' for c in checks)
|
|
||||||
msgs = '_'.join(str(n) for n in checks_msgnames)
|
|
||||||
yield '/* If you get an error here, it means that you need to define PB_FIELD_32BIT\n'
|
|
||||||
yield ' * compile-time option. You can do that in pb.h or on compiler command line.\n'
|
|
||||||
yield ' * \n'
|
|
||||||
yield ' * The reason you need to do this is that some of your messages contain tag\n'
|
|
||||||
yield ' * numbers or field sizes that are larger than what can fit in 8 or 16 bit\n'
|
|
||||||
yield ' * field descriptors.\n'
|
|
||||||
yield ' */\n'
|
|
||||||
yield 'STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs)
|
|
||||||
yield '#endif\n\n'
|
|
||||||
|
|
||||||
if worst < 65536:
|
if worst < 65536:
|
||||||
yield '#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)\n'
|
yield '#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)\n'
|
||||||
if worst > 255:
|
if worst > 255:
|
||||||
@@ -846,16 +799,19 @@ def generate_source(headername, enums, messages, extensions, options):
|
|||||||
else:
|
else:
|
||||||
assertion = ' && '.join(str(c) + ' < 256' for c in checks)
|
assertion = ' && '.join(str(c) + ' < 256' for c in checks)
|
||||||
msgs = '_'.join(str(n) for n in checks_msgnames)
|
msgs = '_'.join(str(n) for n in checks_msgnames)
|
||||||
yield '/* If you get an error here, it means that you need to define PB_FIELD_16BIT\n'
|
|
||||||
yield ' * compile-time option. You can do that in pb.h or on compiler command line.\n'
|
|
||||||
yield ' * \n'
|
|
||||||
yield ' * The reason you need to do this is that some of your messages contain tag\n'
|
|
||||||
yield ' * numbers or field sizes that are larger than what can fit in the default\n'
|
|
||||||
yield ' * 8 bit descriptors.\n'
|
|
||||||
yield ' */\n'
|
|
||||||
yield 'STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs)
|
yield 'STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs)
|
||||||
yield '#endif\n\n'
|
yield '#endif\n\n'
|
||||||
|
|
||||||
|
if worst > 65535 or checks:
|
||||||
|
yield '#if !defined(PB_FIELD_32BIT)\n'
|
||||||
|
if worst > 65535:
|
||||||
|
yield '#error Field descriptor for %s is too large. Define PB_FIELD_32BIT to fix this.\n' % worst_field
|
||||||
|
else:
|
||||||
|
assertion = ' && '.join(str(c) + ' < 65536' for c in checks)
|
||||||
|
msgs = '_'.join(str(n) for n in checks_msgnames)
|
||||||
|
yield 'STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs)
|
||||||
|
yield '#endif\n'
|
||||||
|
|
||||||
# Add check for sizeof(double)
|
# Add check for sizeof(double)
|
||||||
has_double = False
|
has_double = False
|
||||||
for msg in messages:
|
for msg in messages:
|
||||||
@@ -900,7 +856,6 @@ class Globals:
|
|||||||
'''Ugly global variables, should find a good way to pass these.'''
|
'''Ugly global variables, should find a good way to pass these.'''
|
||||||
verbose_options = False
|
verbose_options = False
|
||||||
separate_options = []
|
separate_options = []
|
||||||
matched_namemasks = set()
|
|
||||||
|
|
||||||
def get_nanopb_suboptions(subdesc, options, name):
|
def get_nanopb_suboptions(subdesc, options, name):
|
||||||
'''Get copy of options, and merge information from subdesc.'''
|
'''Get copy of options, and merge information from subdesc.'''
|
||||||
@@ -911,7 +866,6 @@ def get_nanopb_suboptions(subdesc, options, name):
|
|||||||
dotname = '.'.join(name.parts)
|
dotname = '.'.join(name.parts)
|
||||||
for namemask, options in Globals.separate_options:
|
for namemask, options in Globals.separate_options:
|
||||||
if fnmatch(dotname, namemask):
|
if fnmatch(dotname, namemask):
|
||||||
Globals.matched_namemasks.add(namemask)
|
|
||||||
new_options.MergeFrom(options)
|
new_options.MergeFrom(options)
|
||||||
|
|
||||||
# Handle options defined in .proto
|
# Handle options defined in .proto
|
||||||
@@ -931,8 +885,8 @@ def get_nanopb_suboptions(subdesc, options, name):
|
|||||||
new_options.MergeFrom(ext)
|
new_options.MergeFrom(ext)
|
||||||
|
|
||||||
if Globals.verbose_options:
|
if Globals.verbose_options:
|
||||||
sys.stderr.write("Options for " + dotname + ": ")
|
print "Options for " + dotname + ":"
|
||||||
sys.stderr.write(text_format.MessageToString(new_options) + "\n")
|
print text_format.MessageToString(new_options)
|
||||||
|
|
||||||
return new_options
|
return new_options
|
||||||
|
|
||||||
@@ -996,14 +950,13 @@ def process_file(filename, fdesc, options):
|
|||||||
# No %s specified, use the filename as-is
|
# No %s specified, use the filename as-is
|
||||||
optfilename = options.options_file
|
optfilename = options.options_file
|
||||||
|
|
||||||
if os.path.isfile(optfilename):
|
if options.verbose:
|
||||||
if options.verbose:
|
print 'Reading options from ' + optfilename
|
||||||
sys.stderr.write('Reading options from ' + optfilename + '\n')
|
|
||||||
|
|
||||||
|
if os.path.isfile(optfilename):
|
||||||
Globals.separate_options = read_options_file(open(optfilename, "rU"))
|
Globals.separate_options = read_options_file(open(optfilename, "rU"))
|
||||||
else:
|
else:
|
||||||
Globals.separate_options = []
|
Globals.separate_options = []
|
||||||
Globals.matched_namemasks = set()
|
|
||||||
|
|
||||||
# Parse the file
|
# Parse the file
|
||||||
file_options = get_nanopb_suboptions(fdesc, toplevel_options, Names([filename]))
|
file_options = get_nanopb_suboptions(fdesc, toplevel_options, Names([filename]))
|
||||||
@@ -1026,14 +979,6 @@ def process_file(filename, fdesc, options):
|
|||||||
sourcedata = ''.join(generate_source(headerbasename, enums,
|
sourcedata = ''.join(generate_source(headerbasename, enums,
|
||||||
messages, extensions, options))
|
messages, extensions, options))
|
||||||
|
|
||||||
# Check if there were any lines in .options that did not match a member
|
|
||||||
unmatched = [n for n,o in Globals.separate_options if n not in Globals.matched_namemasks]
|
|
||||||
if unmatched and not options.quiet:
|
|
||||||
sys.stderr.write("Following patterns in " + optfilename + " did not match any fields: "
|
|
||||||
+ ', '.join(unmatched) + "\n")
|
|
||||||
if not Globals.verbose_options:
|
|
||||||
sys.stderr.write("Use protoc --nanopb-out=-v:. to see a list of the field names.\n")
|
|
||||||
|
|
||||||
return {'headername': headername, 'headerdata': headerdata,
|
return {'headername': headername, 'headerdata': headerdata,
|
||||||
'sourcename': sourcename, 'sourcedata': sourcedata}
|
'sourcename': sourcename, 'sourcedata': sourcedata}
|
||||||
|
|
||||||
@@ -1055,8 +1000,7 @@ def main_cli():
|
|||||||
results = process_file(filename, None, options)
|
results = process_file(filename, None, options)
|
||||||
|
|
||||||
if not options.quiet:
|
if not options.quiet:
|
||||||
sys.stderr.write("Writing to " + results['headername'] + " and "
|
print "Writing to " + results['headername'] + " and " + results['sourcename']
|
||||||
+ results['sourcename'] + "\n")
|
|
||||||
|
|
||||||
open(results['headername'], 'w').write(results['headerdata'])
|
open(results['headername'], 'w').write(results['headerdata'])
|
||||||
open(results['sourcename'], 'w').write(results['sourcedata'])
|
open(results['sourcename'], 'w').write(results['sourcedata'])
|
||||||
@@ -1071,6 +1015,7 @@ def main_plugin():
|
|||||||
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
|
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
|
||||||
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
|
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
|
||||||
|
|
||||||
|
import proto.plugin_pb2 as plugin_pb2
|
||||||
data = sys.stdin.read()
|
data = sys.stdin.read()
|
||||||
request = plugin_pb2.CodeGeneratorRequest.FromString(data)
|
request = plugin_pb2.CodeGeneratorRequest.FromString(data)
|
||||||
|
|
||||||
@@ -1078,7 +1023,10 @@ def main_plugin():
|
|||||||
args = shlex.split(request.parameter)
|
args = shlex.split(request.parameter)
|
||||||
options, dummy = optparser.parse_args(args)
|
options, dummy = optparser.parse_args(args)
|
||||||
|
|
||||||
Globals.verbose_options = options.verbose
|
# We can't go printing stuff to stdout
|
||||||
|
Globals.verbose_options = False
|
||||||
|
options.verbose = False
|
||||||
|
options.quiet = True
|
||||||
|
|
||||||
response = plugin_pb2.CodeGeneratorResponse()
|
response = plugin_pb2.CodeGeneratorResponse()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
all: nanopb_pb2.py plugin_pb2.py
|
all: nanopb_pb2.py plugin_pb2.py descriptor_pb2.py
|
||||||
|
|
||||||
%_pb2.py: %.proto
|
%_pb2.py: %.proto
|
||||||
protoc --python_out=. $<
|
protoc --python_out=. $<
|
||||||
|
|||||||
@@ -5,14 +5,13 @@
|
|||||||
// These are used by nanopb to generate statically allocable structures
|
// These are used by nanopb to generate statically allocable structures
|
||||||
// for memory-limited environments.
|
// for memory-limited environments.
|
||||||
|
|
||||||
import "google/protobuf/descriptor.proto";
|
import "descriptor.proto";
|
||||||
|
|
||||||
option java_package = "fi.kapsi.koti.jpa.nanopb";
|
option java_package = "fi.kapsi.koti.jpa.nanopb";
|
||||||
|
|
||||||
enum FieldType {
|
enum FieldType {
|
||||||
FT_DEFAULT = 0; // Automatically decide field type, generate static field if possible.
|
FT_DEFAULT = 0; // Automatically decide field type, generate static field if possible.
|
||||||
FT_CALLBACK = 1; // Always generate a callback field.
|
FT_CALLBACK = 1; // Always generate a callback field.
|
||||||
FT_POINTER = 4; // Always generate a dynamically allocated field.
|
|
||||||
FT_STATIC = 2; // Generate a static field or raise an exception if not possible.
|
FT_STATIC = 2; // Generate a static field or raise an exception if not possible.
|
||||||
FT_IGNORE = 3; // Ignore the field completely.
|
FT_IGNORE = 3; // Ignore the field completely.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
package google.protobuf.compiler;
|
package google.protobuf.compiler;
|
||||||
|
|
||||||
import "google/protobuf/descriptor.proto";
|
import "descriptor.proto";
|
||||||
|
|
||||||
// An encoded CodeGeneratorRequest is written to the plugin's stdin.
|
// An encoded CodeGeneratorRequest is written to the plugin's stdin.
|
||||||
message CodeGeneratorRequest {
|
message CodeGeneratorRequest {
|
||||||
|
|||||||
@@ -9,5 +9,4 @@
|
|||||||
# path is already set up properly and there is no need to give
|
# path is already set up properly and there is no need to give
|
||||||
# --plugin= on the command line.
|
# --plugin= on the command line.
|
||||||
|
|
||||||
MYPATH=$(dirname "$0")
|
exec python $(dirname $0)/nanopb_generator.py --protoc-plugin
|
||||||
exec python "$MYPATH/nanopb_generator.py" --protoc-plugin
|
|
||||||
|
|||||||
@@ -9,4 +9,4 @@
|
|||||||
:: --plugin= on the command line.
|
:: --plugin= on the command line.
|
||||||
|
|
||||||
set mydir=%~dp0
|
set mydir=%~dp0
|
||||||
python "%mydir%\nanopb_generator.py" --protoc-plugin
|
python %mydir%\nanopb_generator.py --protoc-plugin
|
||||||
|
|||||||
75
pb.h
75
pb.h
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
/* Version of the nanopb library. Just in case you want to check it in
|
/* Version of the nanopb library. Just in case you want to check it in
|
||||||
* your own program. */
|
* your own program. */
|
||||||
#define NANOPB_VERSION nanopb-0.2.6
|
#define NANOPB_VERSION nanopb-0.2.5-dev
|
||||||
|
|
||||||
/* Include all the system headers needed by nanopb. You will need the
|
/* Include all the system headers needed by nanopb. You will need the
|
||||||
* definitions of the following:
|
* definitions of the following:
|
||||||
@@ -96,14 +96,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Compile-time assertion, used for checking compatible compilation options.
|
/* Compile-time assertion, used for checking compatible compilation options.
|
||||||
* If this does not work properly on your compiler, use #define STATIC_ASSERT
|
* If this fails on your compiler for some reason, use #define STATIC_ASSERT
|
||||||
* to disable it.
|
* to disable it. */
|
||||||
*
|
|
||||||
* But before doing that, check carefully the error message / place where it
|
|
||||||
* comes from to see if the error has a real cause. Unfortunately the error
|
|
||||||
* message is not always very clear to read, but you can see the reason better
|
|
||||||
* in the place where the STATIC_ASSERT macro was called.
|
|
||||||
*/
|
|
||||||
#ifndef STATIC_ASSERT
|
#ifndef STATIC_ASSERT
|
||||||
#define STATIC_ASSERT(COND,MSG) typedef char STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1];
|
#define STATIC_ASSERT(COND,MSG) typedef char STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1];
|
||||||
#define STATIC_ASSERT_MSG(MSG, LINE, COUNTER) STATIC_ASSERT_MSG_(MSG, LINE, COUNTER)
|
#define STATIC_ASSERT_MSG(MSG, LINE, COUNTER) STATIC_ASSERT_MSG_(MSG, LINE, COUNTER)
|
||||||
@@ -122,6 +116,11 @@
|
|||||||
/* List of possible field types. These are used in the autogenerated code.
|
/* List of possible field types. These are used in the autogenerated code.
|
||||||
* Least-significant 4 bits tell the scalar type
|
* Least-significant 4 bits tell the scalar type
|
||||||
* Most-significant 4 bits specify repeated/required/packed etc.
|
* Most-significant 4 bits specify repeated/required/packed etc.
|
||||||
|
*
|
||||||
|
* INT32 and UINT32 are treated the same, as are (U)INT64 and (S)FIXED*
|
||||||
|
* These types are simply casted to correct field type when they are
|
||||||
|
* assigned to the memory pointer.
|
||||||
|
* SINT* is different, though, because it is zig-zag coded.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef uint8_t pb_type_t;
|
typedef uint8_t pb_type_t;
|
||||||
@@ -129,33 +128,32 @@ typedef uint8_t pb_type_t;
|
|||||||
/**** Field data types ****/
|
/**** Field data types ****/
|
||||||
|
|
||||||
/* Numeric types */
|
/* Numeric types */
|
||||||
#define PB_LTYPE_VARINT 0x00 /* int32, int64, enum, bool */
|
#define PB_LTYPE_VARINT 0x00 /* int32, uint32, int64, uint64, bool, enum */
|
||||||
#define PB_LTYPE_UVARINT 0x01 /* uint32, uint64 */
|
#define PB_LTYPE_SVARINT 0x01 /* sint32, sint64 */
|
||||||
#define PB_LTYPE_SVARINT 0x02 /* sint32, sint64 */
|
#define PB_LTYPE_FIXED32 0x02 /* fixed32, sfixed32, float */
|
||||||
#define PB_LTYPE_FIXED32 0x03 /* fixed32, sfixed32, float */
|
#define PB_LTYPE_FIXED64 0x03 /* fixed64, sfixed64, double */
|
||||||
#define PB_LTYPE_FIXED64 0x04 /* fixed64, sfixed64, double */
|
|
||||||
|
|
||||||
/* Marker for last packable field type. */
|
/* Marker for last packable field type. */
|
||||||
#define PB_LTYPE_LAST_PACKABLE 0x04
|
#define PB_LTYPE_LAST_PACKABLE 0x03
|
||||||
|
|
||||||
/* Byte array with pre-allocated buffer.
|
/* Byte array with pre-allocated buffer.
|
||||||
* data_size is the length of the allocated PB_BYTES_ARRAY structure. */
|
* data_size is the length of the allocated PB_BYTES_ARRAY structure. */
|
||||||
#define PB_LTYPE_BYTES 0x05
|
#define PB_LTYPE_BYTES 0x04
|
||||||
|
|
||||||
/* String with pre-allocated buffer.
|
/* String with pre-allocated buffer.
|
||||||
* data_size is the maximum length. */
|
* data_size is the maximum length. */
|
||||||
#define PB_LTYPE_STRING 0x06
|
#define PB_LTYPE_STRING 0x05
|
||||||
|
|
||||||
/* Submessage
|
/* Submessage
|
||||||
* submsg_fields is pointer to field descriptions */
|
* submsg_fields is pointer to field descriptions */
|
||||||
#define PB_LTYPE_SUBMESSAGE 0x07
|
#define PB_LTYPE_SUBMESSAGE 0x06
|
||||||
|
|
||||||
/* Extension pseudo-field
|
/* Extension pseudo-field
|
||||||
* The field contains a pointer to pb_extension_t */
|
* The field contains a pointer to pb_extension_t */
|
||||||
#define PB_LTYPE_EXTENSION 0x08
|
#define PB_LTYPE_EXTENSION 0x07
|
||||||
|
|
||||||
/* Number of declared LTYPES */
|
/* Number of declared LTYPES */
|
||||||
#define PB_LTYPES_COUNT 9
|
#define PB_LTYPES_COUNT 8
|
||||||
#define PB_LTYPE_MASK 0x0F
|
#define PB_LTYPE_MASK 0x0F
|
||||||
|
|
||||||
/**** Field repetition rules ****/
|
/**** Field repetition rules ****/
|
||||||
@@ -168,7 +166,6 @@ typedef uint8_t pb_type_t;
|
|||||||
/**** Field allocation types ****/
|
/**** Field allocation types ****/
|
||||||
|
|
||||||
#define PB_ATYPE_STATIC 0x00
|
#define PB_ATYPE_STATIC 0x00
|
||||||
#define PB_ATYPE_POINTER 0x80
|
|
||||||
#define PB_ATYPE_CALLBACK 0x40
|
#define PB_ATYPE_CALLBACK 0x40
|
||||||
#define PB_ATYPE_MASK 0xC0
|
#define PB_ATYPE_MASK 0xC0
|
||||||
|
|
||||||
@@ -216,11 +213,7 @@ struct _pb_field_t {
|
|||||||
PB_PACKED_STRUCT_END
|
PB_PACKED_STRUCT_END
|
||||||
|
|
||||||
/* Make sure that the standard integer types are of the expected sizes.
|
/* Make sure that the standard integer types are of the expected sizes.
|
||||||
* All kinds of things may break otherwise.. atleast all fixed* types.
|
* All kinds of things may break otherwise.. atleast all fixed* types. */
|
||||||
*
|
|
||||||
* If you get errors here, it probably means that your stdint.h is not
|
|
||||||
* correct for your platform.
|
|
||||||
*/
|
|
||||||
STATIC_ASSERT(sizeof(int8_t) == 1, INT8_T_WRONG_SIZE)
|
STATIC_ASSERT(sizeof(int8_t) == 1, INT8_T_WRONG_SIZE)
|
||||||
STATIC_ASSERT(sizeof(uint8_t) == 1, UINT8_T_WRONG_SIZE)
|
STATIC_ASSERT(sizeof(uint8_t) == 1, UINT8_T_WRONG_SIZE)
|
||||||
STATIC_ASSERT(sizeof(int16_t) == 2, INT16_T_WRONG_SIZE)
|
STATIC_ASSERT(sizeof(int16_t) == 2, INT16_T_WRONG_SIZE)
|
||||||
@@ -238,16 +231,8 @@ struct _pb_bytes_array_t {
|
|||||||
size_t size;
|
size_t size;
|
||||||
uint8_t bytes[1];
|
uint8_t bytes[1];
|
||||||
};
|
};
|
||||||
typedef struct _pb_bytes_array_t pb_bytes_array_t;
|
|
||||||
|
|
||||||
/* Same, except for pointer-type fields. There is no need to variable struct
|
typedef struct _pb_bytes_array_t pb_bytes_array_t;
|
||||||
* length in this case.
|
|
||||||
*/
|
|
||||||
struct _pb_bytes_ptr_t {
|
|
||||||
size_t size;
|
|
||||||
uint8_t *bytes;
|
|
||||||
};
|
|
||||||
typedef struct _pb_bytes_ptr_t pb_bytes_ptr_t;
|
|
||||||
|
|
||||||
/* This structure is used for giving the callback function.
|
/* This structure is used for giving the callback function.
|
||||||
* It is stored in the message structure and filled in by the method that
|
* It is stored in the message structure and filled in by the method that
|
||||||
@@ -385,22 +370,6 @@ struct _pb_extension_t {
|
|||||||
pb_membersize(st, m[0]), \
|
pb_membersize(st, m[0]), \
|
||||||
pb_arraysize(st, m), ptr}
|
pb_arraysize(st, m), ptr}
|
||||||
|
|
||||||
/* Allocated fields carry the size of the actual data, not the pointer */
|
|
||||||
#define PB_REQUIRED_POINTER(tag, st, m, fd, ltype, ptr) \
|
|
||||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_REQUIRED | ltype, \
|
|
||||||
fd, 0, pb_membersize(st, m[0]), 0, ptr}
|
|
||||||
|
|
||||||
/* Optional fields don't need a has_ variable, as information would be redundant */
|
|
||||||
#define PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) \
|
|
||||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \
|
|
||||||
fd, 0, pb_membersize(st, m[0]), 0, ptr}
|
|
||||||
|
|
||||||
/* Repeated fields have a _count field and a pointer to array of pointers */
|
|
||||||
#define PB_REPEATED_POINTER(tag, st, m, fd, ltype, ptr) \
|
|
||||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_REPEATED | ltype, \
|
|
||||||
fd, pb_delta(st, m ## _count, m), \
|
|
||||||
pb_membersize(st, m[0]), 0, ptr}
|
|
||||||
|
|
||||||
/* Callbacks are much like required fields except with special datatype. */
|
/* Callbacks are much like required fields except with special datatype. */
|
||||||
#define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
#define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
||||||
{tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \
|
{tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \
|
||||||
@@ -441,8 +410,8 @@ struct _pb_extension_t {
|
|||||||
#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT
|
#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT
|
||||||
#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT
|
#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT
|
||||||
#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING
|
#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING
|
||||||
#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT
|
#define PB_LTYPE_MAP_UINT32 PB_LTYPE_VARINT
|
||||||
#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT
|
#define PB_LTYPE_MAP_UINT64 PB_LTYPE_VARINT
|
||||||
#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION
|
#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION
|
||||||
|
|
||||||
/* This is the actual macro used in field descriptions.
|
/* This is the actual macro used in field descriptions.
|
||||||
|
|||||||
24
pb_decode.c
24
pb_decode.c
@@ -47,8 +47,7 @@ static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_exten
|
|||||||
static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
|
static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
|
||||||
static bool checkreturn find_extension_field(pb_field_iterator_t *iter);
|
static bool checkreturn find_extension_field(pb_field_iterator_t *iter);
|
||||||
static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct);
|
static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct);
|
||||||
static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
static bool pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
||||||
static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
|
||||||
static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
||||||
static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
||||||
static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
||||||
@@ -63,7 +62,6 @@ static bool checkreturn pb_skip_string(pb_istream_t *stream);
|
|||||||
*/
|
*/
|
||||||
static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {
|
static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {
|
||||||
&pb_dec_varint,
|
&pb_dec_varint,
|
||||||
&pb_dec_uvarint,
|
|
||||||
&pb_dec_svarint,
|
&pb_dec_svarint,
|
||||||
&pb_dec_fixed32,
|
&pb_dec_fixed32,
|
||||||
&pb_dec_fixed64,
|
&pb_dec_fixed64,
|
||||||
@@ -825,24 +823,8 @@ bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, vo
|
|||||||
|
|
||||||
switch (field->data_size)
|
switch (field->data_size)
|
||||||
{
|
{
|
||||||
case 1: *(int8_t*)dest = (int8_t)value; break;
|
case 1: *(uint8_t*)dest = (uint8_t)value; break;
|
||||||
case 2: *(int16_t*)dest = (int16_t)value; break;
|
case 2: *(uint16_t*)dest = (uint16_t)value; break;
|
||||||
case 4: *(int32_t*)dest = (int32_t)value; break;
|
|
||||||
case 8: *(int64_t*)dest = (int64_t)value; break;
|
|
||||||
default: PB_RETURN_ERROR(stream, "invalid data_size");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
|
|
||||||
{
|
|
||||||
uint64_t value;
|
|
||||||
if (!pb_decode_varint(stream, &value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (field->data_size)
|
|
||||||
{
|
|
||||||
case 4: *(uint32_t*)dest = (uint32_t)value; break;
|
case 4: *(uint32_t*)dest = (uint32_t)value; break;
|
||||||
case 8: *(uint64_t*)dest = value; break;
|
case 8: *(uint64_t*)dest = value; break;
|
||||||
default: PB_RETURN_ERROR(stream, "invalid data_size");
|
default: PB_RETURN_ERROR(stream, "invalid data_size");
|
||||||
|
|||||||
105
pb_encode.c
105
pb_encode.c
@@ -28,7 +28,6 @@ static bool checkreturn encode_field(pb_ostream_t *stream, const pb_field_t *fie
|
|||||||
static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension);
|
static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension);
|
||||||
static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData);
|
static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData);
|
||||||
static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
||||||
static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
|
||||||
static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
||||||
static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
||||||
static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
||||||
@@ -41,7 +40,6 @@ static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t
|
|||||||
*/
|
*/
|
||||||
static const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = {
|
static const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = {
|
||||||
&pb_enc_varint,
|
&pb_enc_varint,
|
||||||
&pb_enc_uvarint,
|
|
||||||
&pb_enc_svarint,
|
&pb_enc_svarint,
|
||||||
&pb_enc_fixed32,
|
&pb_enc_fixed32,
|
||||||
&pb_enc_fixed64,
|
&pb_enc_fixed64,
|
||||||
@@ -119,7 +117,7 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie
|
|||||||
if (count == 0)
|
if (count == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size)
|
if (count > field->array_size)
|
||||||
PB_RETURN_ERROR(stream, "array max size exceeded");
|
PB_RETURN_ERROR(stream, "array max size exceeded");
|
||||||
|
|
||||||
/* We always pack arrays if the datatype allows it. */
|
/* We always pack arrays if the datatype allows it. */
|
||||||
@@ -172,22 +170,8 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie
|
|||||||
{
|
{
|
||||||
if (!pb_encode_tag_for_field(stream, field))
|
if (!pb_encode_tag_for_field(stream, field))
|
||||||
return false;
|
return false;
|
||||||
|
if (!func(stream, field, p))
|
||||||
/* Normally the data is stored directly in the array entries, but
|
return false;
|
||||||
* for pointer-type string fields, the array entries are actually
|
|
||||||
* string pointers. So we have to dereference once more to get to
|
|
||||||
* the character data. */
|
|
||||||
if (PB_ATYPE(field->type) == PB_ATYPE_POINTER &&
|
|
||||||
PB_LTYPE(field->type) == PB_LTYPE_STRING)
|
|
||||||
{
|
|
||||||
if (!func(stream, field, *(const void* const*)p))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!func(stream, field, p))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
p = (const char*)p + field->data_size;
|
p = (const char*)p + field->data_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,38 +179,25 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encode a field with static or pointer allocation, i.e. one whose data
|
/* Encode a field with static allocation, i.e. one whose data is stored
|
||||||
* is available to the encoder directly. */
|
* in the structure itself. */
|
||||||
static bool checkreturn encode_basic_field(pb_ostream_t *stream,
|
static bool checkreturn encode_static_field(pb_ostream_t *stream,
|
||||||
const pb_field_t *field, const void *pData)
|
const pb_field_t *field, const void *pData)
|
||||||
{
|
{
|
||||||
pb_encoder_t func;
|
pb_encoder_t func;
|
||||||
const void *pSize;
|
const void *pSize;
|
||||||
bool implicit_has = true;
|
bool dummy = true;
|
||||||
|
|
||||||
func = PB_ENCODERS[PB_LTYPE(field->type)];
|
func = PB_ENCODERS[PB_LTYPE(field->type)];
|
||||||
|
|
||||||
if (field->size_offset)
|
if (field->size_offset)
|
||||||
pSize = (const char*)pData + field->size_offset;
|
pSize = (const char*)pData + field->size_offset;
|
||||||
else
|
else
|
||||||
pSize = &implicit_has;
|
pSize = &dummy;
|
||||||
|
|
||||||
if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
|
|
||||||
{
|
|
||||||
/* pData is a pointer to the field, which contains pointer to
|
|
||||||
* the data. If the 2nd pointer is NULL, it is interpreted as if
|
|
||||||
* the has_field was false.
|
|
||||||
*/
|
|
||||||
|
|
||||||
pData = *(const void* const*)pData;
|
|
||||||
implicit_has = (pData != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (PB_HTYPE(field->type))
|
switch (PB_HTYPE(field->type))
|
||||||
{
|
{
|
||||||
case PB_HTYPE_REQUIRED:
|
case PB_HTYPE_REQUIRED:
|
||||||
if (!pData)
|
|
||||||
PB_RETURN_ERROR(stream, "missing required field");
|
|
||||||
if (!pb_encode_tag_for_field(stream, field))
|
if (!pb_encode_tag_for_field(stream, field))
|
||||||
return false;
|
return false;
|
||||||
if (!func(stream, field, pData))
|
if (!func(stream, field, pData))
|
||||||
@@ -284,8 +255,7 @@ static bool checkreturn encode_field(pb_ostream_t *stream,
|
|||||||
switch (PB_ATYPE(field->type))
|
switch (PB_ATYPE(field->type))
|
||||||
{
|
{
|
||||||
case PB_ATYPE_STATIC:
|
case PB_ATYPE_STATIC:
|
||||||
case PB_ATYPE_POINTER:
|
return encode_static_field(stream, field, pData);
|
||||||
return encode_basic_field(stream, field, pData);
|
|
||||||
|
|
||||||
case PB_ATYPE_CALLBACK:
|
case PB_ATYPE_CALLBACK:
|
||||||
return encode_callback_field(stream, field, pData);
|
return encode_callback_field(stream, field, pData);
|
||||||
@@ -342,10 +312,7 @@ bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], cons
|
|||||||
while (field->tag != 0)
|
while (field->tag != 0)
|
||||||
{
|
{
|
||||||
pData = (const char*)pData + prev_size + field->data_offset;
|
pData = (const char*)pData + prev_size + field->data_offset;
|
||||||
if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
|
prev_size = field->data_size;
|
||||||
prev_size = sizeof(const void*);
|
|
||||||
else
|
|
||||||
prev_size = field->data_size;
|
|
||||||
|
|
||||||
/* Special case for static arrays */
|
/* Special case for static arrays */
|
||||||
if (PB_ATYPE(field->type) == PB_ATYPE_STATIC &&
|
if (PB_ATYPE(field->type) == PB_ATYPE_STATIC &&
|
||||||
@@ -457,7 +424,6 @@ bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t
|
|||||||
switch (PB_LTYPE(field->type))
|
switch (PB_LTYPE(field->type))
|
||||||
{
|
{
|
||||||
case PB_LTYPE_VARINT:
|
case PB_LTYPE_VARINT:
|
||||||
case PB_LTYPE_UVARINT:
|
|
||||||
case PB_LTYPE_SVARINT:
|
case PB_LTYPE_SVARINT:
|
||||||
wiretype = PB_WT_VARINT;
|
wiretype = PB_WT_VARINT;
|
||||||
break;
|
break;
|
||||||
@@ -499,12 +465,7 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fie
|
|||||||
bool status;
|
bool status;
|
||||||
|
|
||||||
if (!pb_encode(&substream, fields, src_struct))
|
if (!pb_encode(&substream, fields, src_struct))
|
||||||
{
|
|
||||||
#ifndef PB_NO_ERRMSG
|
|
||||||
stream->errmsg = substream.errmsg;
|
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
size = substream.bytes_written;
|
size = substream.bytes_written;
|
||||||
|
|
||||||
@@ -544,29 +505,13 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fie
|
|||||||
/* Field encoders */
|
/* Field encoders */
|
||||||
|
|
||||||
bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
|
bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
|
||||||
{
|
|
||||||
int64_t value = 0;
|
|
||||||
|
|
||||||
/* Cases 1 and 2 are for compilers that have smaller types for bool
|
|
||||||
* or enums. */
|
|
||||||
switch (field->data_size)
|
|
||||||
{
|
|
||||||
case 1: value = *(const int8_t*)src; break;
|
|
||||||
case 2: value = *(const int16_t*)src; break;
|
|
||||||
case 4: value = *(const int32_t*)src; break;
|
|
||||||
case 8: value = *(const int64_t*)src; break;
|
|
||||||
default: PB_RETURN_ERROR(stream, "invalid data_size");
|
|
||||||
}
|
|
||||||
|
|
||||||
return pb_encode_varint(stream, (uint64_t)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
|
|
||||||
{
|
{
|
||||||
uint64_t value = 0;
|
uint64_t value = 0;
|
||||||
|
|
||||||
switch (field->data_size)
|
switch (field->data_size)
|
||||||
{
|
{
|
||||||
|
case 1: value = *(const uint8_t*)src; break;
|
||||||
|
case 2: value = *(const uint16_t*)src; break;
|
||||||
case 4: value = *(const uint32_t*)src; break;
|
case 4: value = *(const uint32_t*)src; break;
|
||||||
case 8: value = *(const uint64_t*)src; break;
|
case 8: value = *(const uint64_t*)src; break;
|
||||||
default: PB_RETURN_ERROR(stream, "invalid data_size");
|
default: PB_RETURN_ERROR(stream, "invalid data_size");
|
||||||
@@ -603,32 +548,20 @@ bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, c
|
|||||||
|
|
||||||
bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)
|
bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)
|
||||||
{
|
{
|
||||||
if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
|
const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)src;
|
||||||
{
|
|
||||||
const pb_bytes_ptr_t *bytes = (const pb_bytes_ptr_t*)src;
|
|
||||||
return pb_encode_string(stream, bytes->bytes, bytes->size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)src;
|
|
||||||
if (bytes->size + offsetof(pb_bytes_array_t, bytes) > field->data_size)
|
|
||||||
PB_RETURN_ERROR(stream, "bytes size exceeded");
|
|
||||||
|
|
||||||
return pb_encode_string(stream, bytes->bytes, bytes->size);
|
if (bytes->size + offsetof(pb_bytes_array_t, bytes) > field->data_size)
|
||||||
}
|
PB_RETURN_ERROR(stream, "bytes size exceeded");
|
||||||
|
|
||||||
|
return pb_encode_string(stream, bytes->bytes, bytes->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src)
|
bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src)
|
||||||
{
|
{
|
||||||
/* strnlen() is not always available, so just use a loop */
|
/* strnlen() is not always available, so just use a for-loop */
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
size_t max_size = field->data_size;
|
|
||||||
const char *p = (const char*)src;
|
const char *p = (const char*)src;
|
||||||
|
while (size < field->data_size && *p != '\0')
|
||||||
if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
|
|
||||||
max_size = (size_t)-1;
|
|
||||||
|
|
||||||
while (size < max_size && *p != '\0')
|
|
||||||
{
|
{
|
||||||
size++;
|
size++;
|
||||||
p++;
|
p++;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ if not env.GetOption('clean'):
|
|||||||
string = conf.CheckCHeader('string.h')
|
string = conf.CheckCHeader('string.h')
|
||||||
if not stdbool or not stdint or not stddef or not string:
|
if not stdbool or not stdint or not stddef or not string:
|
||||||
conf.env.Append(CPPDEFINES = {'PB_SYSTEM_HEADER': '\\"pb_syshdr.h\\"'})
|
conf.env.Append(CPPDEFINES = {'PB_SYSTEM_HEADER': '\\"pb_syshdr.h\\"'})
|
||||||
conf.env.Append(CPPPATH = "#../extra")
|
conf.env.Append(CPPPATH = "#../compat")
|
||||||
|
|
||||||
if stdbool: conf.env.Append(CPPDEFINES = {'HAVE_STDBOOL_H': 1})
|
if stdbool: conf.env.Append(CPPDEFINES = {'HAVE_STDBOOL_H': 1})
|
||||||
if stdint: conf.env.Append(CPPDEFINES = {'HAVE_STDINT_H': 1})
|
if stdint: conf.env.Append(CPPDEFINES = {'HAVE_STDINT_H': 1})
|
||||||
@@ -74,7 +74,6 @@ if not env.GetOption('clean'):
|
|||||||
|
|
||||||
# Check if we can use extra strict warning flags (only with GCC)
|
# Check if we can use extra strict warning flags (only with GCC)
|
||||||
extra = '-Wcast-qual -Wlogical-op -Wconversion'
|
extra = '-Wcast-qual -Wlogical-op -Wconversion'
|
||||||
extra += ' -fstrict-aliasing -Wstrict-aliasing=1'
|
|
||||||
extra += ' -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls'
|
extra += ' -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls'
|
||||||
extra += ' -Wstack-protector '
|
extra += ' -Wstack-protector '
|
||||||
if 'gcc' in env['CC']:
|
if 'gcc' in env['CC']:
|
||||||
|
|||||||
@@ -7,29 +7,6 @@ env.NanopbProto(["alltypes", "alltypes.options"])
|
|||||||
enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
|
enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
|
||||||
dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_decode.o"])
|
dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_decode.o"])
|
||||||
|
|
||||||
# Test the round-trip from nanopb encoder to nanopb decoder
|
|
||||||
env.RunTest(enc)
|
env.RunTest(enc)
|
||||||
env.RunTest([dec, "encode_alltypes.output"])
|
env.RunTest([dec, "encode_alltypes.output"])
|
||||||
|
|
||||||
# Re-encode the data using protoc, and check that the results from nanopb
|
|
||||||
# match byte-per-byte to the protoc output.
|
|
||||||
env.Decode("encode_alltypes.output.decoded",
|
|
||||||
["encode_alltypes.output", "alltypes.proto"],
|
|
||||||
MESSAGE='AllTypes')
|
|
||||||
env.Encode("encode_alltypes.output.recoded",
|
|
||||||
["encode_alltypes.output.decoded", "alltypes.proto"],
|
|
||||||
MESSAGE='AllTypes')
|
|
||||||
env.Compare(["encode_alltypes.output", "encode_alltypes.output.recoded"])
|
|
||||||
|
|
||||||
# Do the same checks with the optional fields present.
|
|
||||||
env.RunTest("optionals.output", enc, ARGS = ['1'])
|
|
||||||
env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1'])
|
|
||||||
env.Decode("optionals.output.decoded",
|
|
||||||
["optionals.output", "alltypes.proto"],
|
|
||||||
MESSAGE='AllTypes')
|
|
||||||
env.Encode("optionals.output.recoded",
|
|
||||||
["optionals.output.decoded", "alltypes.proto"],
|
|
||||||
MESSAGE='AllTypes')
|
|
||||||
env.Compare(["optionals.output", "optionals.output.recoded"])
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,24 +8,6 @@ message EmptyMessage {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum HugeEnum {
|
|
||||||
Negative = -2147483647; /* protoc doesn't accept -2147483648 here */
|
|
||||||
Positive = 2147483647;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Limits {
|
|
||||||
required int32 int32_min = 1 [default = 2147483647];
|
|
||||||
required int32 int32_max = 2 [default = -2147483647];
|
|
||||||
required uint32 uint32_min = 3 [default = 4294967295];
|
|
||||||
required uint32 uint32_max = 4 [default = 0];
|
|
||||||
required int64 int64_min = 5 [default = 9223372036854775807];
|
|
||||||
required int64 int64_max = 6 [default = -9223372036854775807];
|
|
||||||
required uint64 uint64_min = 7 [default = 18446744073709551615];
|
|
||||||
required uint64 uint64_max = 8 [default = 0];
|
|
||||||
required HugeEnum enum_min = 9 [default = Positive];
|
|
||||||
required HugeEnum enum_max = 10 [default = Negative];
|
|
||||||
}
|
|
||||||
|
|
||||||
enum MyEnum {
|
enum MyEnum {
|
||||||
Zero = 0;
|
Zero = 0;
|
||||||
First = 1;
|
First = 1;
|
||||||
@@ -57,26 +39,26 @@ message AllTypes {
|
|||||||
required EmptyMessage req_emptymsg = 18;
|
required EmptyMessage req_emptymsg = 18;
|
||||||
|
|
||||||
|
|
||||||
repeated int32 rep_int32 = 21 [packed = true];
|
repeated int32 rep_int32 = 21;
|
||||||
repeated int64 rep_int64 = 22 [packed = true];
|
repeated int64 rep_int64 = 22;
|
||||||
repeated uint32 rep_uint32 = 23 [packed = true];
|
repeated uint32 rep_uint32 = 23;
|
||||||
repeated uint64 rep_uint64 = 24 [packed = true];
|
repeated uint64 rep_uint64 = 24;
|
||||||
repeated sint32 rep_sint32 = 25 [packed = true];
|
repeated sint32 rep_sint32 = 25;
|
||||||
repeated sint64 rep_sint64 = 26 [packed = true];
|
repeated sint64 rep_sint64 = 26;
|
||||||
repeated bool rep_bool = 27 [packed = true];
|
repeated bool rep_bool = 27;
|
||||||
|
|
||||||
repeated fixed32 rep_fixed32 = 28 [packed = true];
|
repeated fixed32 rep_fixed32 = 28;
|
||||||
repeated sfixed32 rep_sfixed32= 29 [packed = true];
|
repeated sfixed32 rep_sfixed32= 29;
|
||||||
repeated float rep_float = 30 [packed = true];
|
repeated float rep_float = 30;
|
||||||
|
|
||||||
repeated fixed64 rep_fixed64 = 31 [packed = true];
|
repeated fixed64 rep_fixed64 = 31;
|
||||||
repeated sfixed64 rep_sfixed64= 32 [packed = true];
|
repeated sfixed64 rep_sfixed64= 32;
|
||||||
repeated double rep_double = 33 [packed = true];
|
repeated double rep_double = 33;
|
||||||
|
|
||||||
repeated string rep_string = 34;
|
repeated string rep_string = 34;
|
||||||
repeated bytes rep_bytes = 35;
|
repeated bytes rep_bytes = 35;
|
||||||
repeated SubMessage rep_submsg = 36;
|
repeated SubMessage rep_submsg = 36;
|
||||||
repeated MyEnum rep_enum = 37 [packed = true];
|
repeated MyEnum rep_enum = 37;
|
||||||
repeated EmptyMessage rep_emptymsg = 38;
|
repeated EmptyMessage rep_emptymsg = 38;
|
||||||
|
|
||||||
optional int32 opt_int32 = 41 [default = 4041];
|
optional int32 opt_int32 = 41 [default = 4041];
|
||||||
@@ -101,9 +83,6 @@ message AllTypes {
|
|||||||
optional MyEnum opt_enum = 57 [default = Second];
|
optional MyEnum opt_enum = 57 [default = Second];
|
||||||
optional EmptyMessage opt_emptymsg = 58;
|
optional EmptyMessage opt_emptymsg = 58;
|
||||||
|
|
||||||
// Check that extreme integer values are handled correctly
|
|
||||||
required Limits req_limits = 98;
|
|
||||||
|
|
||||||
// Just to make sure that the size of the fields has been calculated
|
// Just to make sure that the size of the fields has been calculated
|
||||||
// properly, i.e. otherwise a bug in last field might not be detected.
|
// properly, i.e. otherwise a bug in last field might not be detected.
|
||||||
required int32 end = 99;
|
required int32 end = 99;
|
||||||
|
|||||||
@@ -170,17 +170,6 @@ bool check_alltypes(pb_istream_t *stream, int mode)
|
|||||||
TEST(alltypes.has_opt_emptymsg == true);
|
TEST(alltypes.has_opt_emptymsg == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(alltypes.req_limits.int32_min == INT32_MIN);
|
|
||||||
TEST(alltypes.req_limits.int32_max == INT32_MAX);
|
|
||||||
TEST(alltypes.req_limits.uint32_min == 0);
|
|
||||||
TEST(alltypes.req_limits.uint32_max == UINT32_MAX);
|
|
||||||
TEST(alltypes.req_limits.int64_min == INT64_MIN);
|
|
||||||
TEST(alltypes.req_limits.int64_max == INT64_MAX);
|
|
||||||
TEST(alltypes.req_limits.uint64_min == 0);
|
|
||||||
TEST(alltypes.req_limits.uint64_max == UINT64_MAX);
|
|
||||||
TEST(alltypes.req_limits.enum_min == HugeEnum_Negative);
|
|
||||||
TEST(alltypes.req_limits.enum_max == HugeEnum_Positive);
|
|
||||||
|
|
||||||
TEST(alltypes.end == 1099);
|
TEST(alltypes.end == 1099);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -67,17 +67,6 @@ int main(int argc, char **argv)
|
|||||||
alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth;
|
alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth;
|
||||||
alltypes.rep_emptymsg_count = 5;
|
alltypes.rep_emptymsg_count = 5;
|
||||||
|
|
||||||
alltypes.req_limits.int32_min = INT32_MIN;
|
|
||||||
alltypes.req_limits.int32_max = INT32_MAX;
|
|
||||||
alltypes.req_limits.uint32_min = 0;
|
|
||||||
alltypes.req_limits.uint32_max = UINT32_MAX;
|
|
||||||
alltypes.req_limits.int64_min = INT64_MIN;
|
|
||||||
alltypes.req_limits.int64_max = INT64_MAX;
|
|
||||||
alltypes.req_limits.uint64_min = 0;
|
|
||||||
alltypes.req_limits.uint64_max = UINT64_MAX;
|
|
||||||
alltypes.req_limits.enum_min = HugeEnum_Negative;
|
|
||||||
alltypes.req_limits.enum_max = HugeEnum_Positive;
|
|
||||||
|
|
||||||
if (mode != 0)
|
if (mode != 0)
|
||||||
{
|
{
|
||||||
/* Fill in values for optional fields */
|
/* Fill in values for optional fields */
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
# Test the AllTypes encoding & decoding using callbacks for all fields.
|
|
||||||
|
|
||||||
Import("env")
|
|
||||||
|
|
||||||
c = Copy("$TARGET", "$SOURCE")
|
|
||||||
env.Command("alltypes.proto", "#alltypes/alltypes.proto", c)
|
|
||||||
|
|
||||||
env.NanopbProto(["alltypes", "alltypes.options"])
|
|
||||||
enc = env.Program(["encode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
|
|
||||||
dec = env.Program(["decode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_decode.o"])
|
|
||||||
|
|
||||||
refdec = "$BUILD/alltypes/decode_alltypes$PROGSUFFIX"
|
|
||||||
|
|
||||||
# Encode and compare results
|
|
||||||
env.RunTest(enc)
|
|
||||||
env.RunTest("decode_alltypes.output", [refdec, "encode_alltypes_callback.output"])
|
|
||||||
env.RunTest("decode_alltypes_callback.output", [dec, "encode_alltypes_callback.output"])
|
|
||||||
|
|
||||||
# Do the same thing with the optional fields present
|
|
||||||
env.RunTest("optionals.output", enc, ARGS = ['1'])
|
|
||||||
env.RunTest("optionals.refdecout", [refdec, "optionals.output"], ARGS = ['1'])
|
|
||||||
env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1'])
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Generate all fields as callbacks.
|
|
||||||
AllTypes.* type:FT_CALLBACK
|
|
||||||
SubMessage.substuff1 max_size:16
|
|
||||||
@@ -1,423 +0,0 @@
|
|||||||
/* Attempts to test all the datatypes supported by ProtoBuf when used as callback fields.
|
|
||||||
* Note that normally there would be no reason to use callback fields for this,
|
|
||||||
* because each encoder defined here only gives a single field.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <pb_decode.h>
|
|
||||||
#include "alltypes.pb.h"
|
|
||||||
#include "test_helpers.h"
|
|
||||||
|
|
||||||
#define TEST(x) if (!(x)) { \
|
|
||||||
printf("Test " #x " failed (in field %d).\n", field->tag); \
|
|
||||||
return false; \
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_varint(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
uint64_t value;
|
|
||||||
if (!pb_decode_varint(stream, &value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST((int64_t)value == (long)*arg);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_svarint(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
int64_t value;
|
|
||||||
if (!pb_decode_svarint(stream, &value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(value == (long)*arg);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_fixed32(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
uint32_t value;
|
|
||||||
if (!pb_decode_fixed32(stream, &value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(value == *(uint32_t*)*arg);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_fixed64(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
uint64_t value;
|
|
||||||
if (!pb_decode_fixed64(stream, &value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(value == *(uint64_t*)*arg);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_string(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
uint8_t buf[16] = {0};
|
|
||||||
size_t len = stream->bytes_left;
|
|
||||||
|
|
||||||
if (len > sizeof(buf) - 1 || !pb_read(stream, buf, len))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(strcmp((char*)buf, *arg) == 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_submsg(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
SubMessage submsg = {""};
|
|
||||||
|
|
||||||
if (!pb_decode(stream, SubMessage_fields, &submsg))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(memcmp(&submsg, *arg, sizeof(submsg)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_emptymsg(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
EmptyMessage emptymsg = {0};
|
|
||||||
return pb_decode(stream, EmptyMessage_fields, &emptymsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_repeated_varint(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
int32_t** expected = (int32_t**)arg;
|
|
||||||
uint64_t value;
|
|
||||||
if (!pb_decode_varint(stream, &value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(*(*expected)++ == value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_repeated_svarint(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
int32_t** expected = (int32_t**)arg;
|
|
||||||
int64_t value;
|
|
||||||
if (!pb_decode_svarint(stream, &value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(*(*expected)++ == value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_repeated_fixed32(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
uint32_t** expected = (uint32_t**)arg;
|
|
||||||
uint32_t value;
|
|
||||||
if (!pb_decode_fixed32(stream, &value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(*(*expected)++ == value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_repeated_fixed64(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
uint64_t** expected = (uint64_t**)arg;
|
|
||||||
uint64_t value;
|
|
||||||
if (!pb_decode_fixed64(stream, &value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(*(*expected)++ == value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_repeated_string(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
uint8_t*** expected = (uint8_t***)arg;
|
|
||||||
uint8_t buf[16] = {0};
|
|
||||||
size_t len = stream->bytes_left;
|
|
||||||
|
|
||||||
if (len > sizeof(buf) - 1 || !pb_read(stream, buf, len))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(strcmp((char*)*(*expected)++, (char*)buf) == 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_repeated_submsg(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
SubMessage** expected = (SubMessage**)arg;
|
|
||||||
SubMessage decoded = {""};
|
|
||||||
if (!pb_decode(stream, SubMessage_fields, &decoded))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(memcmp((*expected)++, &decoded, sizeof(decoded)) == 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool read_limits(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
|
||||||
{
|
|
||||||
Limits decoded = {0};
|
|
||||||
if (!pb_decode(stream, Limits_fields, &decoded))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TEST(decoded.int32_min == INT32_MIN);
|
|
||||||
TEST(decoded.int32_max == INT32_MAX);
|
|
||||||
TEST(decoded.uint32_min == 0);
|
|
||||||
TEST(decoded.uint32_max == UINT32_MAX);
|
|
||||||
TEST(decoded.int64_min == INT64_MIN);
|
|
||||||
TEST(decoded.int64_max == INT64_MAX);
|
|
||||||
TEST(decoded.uint64_min == 0);
|
|
||||||
TEST(decoded.uint64_max == UINT64_MAX);
|
|
||||||
TEST(decoded.enum_min == HugeEnum_Negative);
|
|
||||||
TEST(decoded.enum_max == HugeEnum_Positive);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function is called once from main(), it handles
|
|
||||||
the decoding and checks the fields. */
|
|
||||||
bool check_alltypes(pb_istream_t *stream, int mode)
|
|
||||||
{
|
|
||||||
/* Values for use from callbacks through pointers. */
|
|
||||||
uint32_t req_fixed32 = 1008;
|
|
||||||
int32_t req_sfixed32 = -1009;
|
|
||||||
float req_float = 1010.0f;
|
|
||||||
uint64_t req_fixed64 = 1011;
|
|
||||||
int64_t req_sfixed64 = -1012;
|
|
||||||
double req_double = 1013.0;
|
|
||||||
SubMessage req_submsg = {"1016", 1016};
|
|
||||||
|
|
||||||
int32_t rep_int32[5] = {0, 0, 0, 0, -2001};
|
|
||||||
int32_t rep_int64[5] = {0, 0, 0, 0, -2002};
|
|
||||||
int32_t rep_uint32[5] = {0, 0, 0, 0, 2003};
|
|
||||||
int32_t rep_uint64[5] = {0, 0, 0, 0, 2004};
|
|
||||||
int32_t rep_sint32[5] = {0, 0, 0, 0, -2005};
|
|
||||||
int32_t rep_sint64[5] = {0, 0, 0, 0, -2006};
|
|
||||||
int32_t rep_bool[5] = {false, false, false, false, true};
|
|
||||||
uint32_t rep_fixed32[5] = {0, 0, 0, 0, 2008};
|
|
||||||
int32_t rep_sfixed32[5] = {0, 0, 0, 0, -2009};
|
|
||||||
float rep_float[5] = {0, 0, 0, 0, 2010.0f};
|
|
||||||
uint64_t rep_fixed64[5] = {0, 0, 0, 0, 2011};
|
|
||||||
int64_t rep_sfixed64[5] = {0, 0, 0, 0, -2012};
|
|
||||||
double rep_double[5] = {0, 0, 0, 0, 2013.0};
|
|
||||||
char* rep_string[5] = {"", "", "", "", "2014"};
|
|
||||||
char* rep_bytes[5] = {"", "", "", "", "2015"};
|
|
||||||
SubMessage rep_submsg[5] = {{"", 0, 0, 3},
|
|
||||||
{"", 0, 0, 3},
|
|
||||||
{"", 0, 0, 3},
|
|
||||||
{"", 0, 0, 3},
|
|
||||||
{"2016", 2016, true, 2016}};
|
|
||||||
int32_t rep_enum[5] = {0, 0, 0, 0, MyEnum_Truth};
|
|
||||||
|
|
||||||
uint32_t opt_fixed32 = 3048;
|
|
||||||
int32_t opt_sfixed32 = 3049;
|
|
||||||
float opt_float = 3050.0f;
|
|
||||||
uint64_t opt_fixed64 = 3051;
|
|
||||||
int64_t opt_sfixed64 = 3052;
|
|
||||||
double opt_double = 3053.0f;
|
|
||||||
SubMessage opt_submsg = {"3056", 3056};
|
|
||||||
|
|
||||||
/* Bind callbacks for required fields */
|
|
||||||
AllTypes alltypes;
|
|
||||||
|
|
||||||
/* Fill with garbage to better detect initialization errors */
|
|
||||||
memset(&alltypes, 0xAA, sizeof(alltypes));
|
|
||||||
|
|
||||||
alltypes.req_int32.funcs.decode = &read_varint;
|
|
||||||
alltypes.req_int32.arg = (void*)-1001;
|
|
||||||
|
|
||||||
alltypes.req_int64.funcs.decode = &read_varint;
|
|
||||||
alltypes.req_int64.arg = (void*)-1002;
|
|
||||||
|
|
||||||
alltypes.req_uint32.funcs.decode = &read_varint;
|
|
||||||
alltypes.req_uint32.arg = (void*)1003;
|
|
||||||
|
|
||||||
alltypes.req_uint32.funcs.decode = &read_varint;
|
|
||||||
alltypes.req_uint32.arg = (void*)1003;
|
|
||||||
|
|
||||||
alltypes.req_uint64.funcs.decode = &read_varint;
|
|
||||||
alltypes.req_uint64.arg = (void*)1004;
|
|
||||||
|
|
||||||
alltypes.req_sint32.funcs.decode = &read_svarint;
|
|
||||||
alltypes.req_sint32.arg = (void*)-1005;
|
|
||||||
|
|
||||||
alltypes.req_sint64.funcs.decode = &read_svarint;
|
|
||||||
alltypes.req_sint64.arg = (void*)-1006;
|
|
||||||
|
|
||||||
alltypes.req_bool.funcs.decode = &read_varint;
|
|
||||||
alltypes.req_bool.arg = (void*)true;
|
|
||||||
|
|
||||||
alltypes.req_fixed32.funcs.decode = &read_fixed32;
|
|
||||||
alltypes.req_fixed32.arg = &req_fixed32;
|
|
||||||
|
|
||||||
alltypes.req_sfixed32.funcs.decode = &read_fixed32;
|
|
||||||
alltypes.req_sfixed32.arg = &req_sfixed32;
|
|
||||||
|
|
||||||
alltypes.req_float.funcs.decode = &read_fixed32;
|
|
||||||
alltypes.req_float.arg = &req_float;
|
|
||||||
|
|
||||||
alltypes.req_fixed64.funcs.decode = &read_fixed64;
|
|
||||||
alltypes.req_fixed64.arg = &req_fixed64;
|
|
||||||
|
|
||||||
alltypes.req_sfixed64.funcs.decode = &read_fixed64;
|
|
||||||
alltypes.req_sfixed64.arg = &req_sfixed64;
|
|
||||||
|
|
||||||
alltypes.req_double.funcs.decode = &read_fixed64;
|
|
||||||
alltypes.req_double.arg = &req_double;
|
|
||||||
|
|
||||||
alltypes.req_string.funcs.decode = &read_string;
|
|
||||||
alltypes.req_string.arg = "1014";
|
|
||||||
|
|
||||||
alltypes.req_bytes.funcs.decode = &read_string;
|
|
||||||
alltypes.req_bytes.arg = "1015";
|
|
||||||
|
|
||||||
alltypes.req_submsg.funcs.decode = &read_submsg;
|
|
||||||
alltypes.req_submsg.arg = &req_submsg;
|
|
||||||
|
|
||||||
alltypes.req_enum.funcs.decode = &read_varint;
|
|
||||||
alltypes.req_enum.arg = (void*)MyEnum_Truth;
|
|
||||||
|
|
||||||
alltypes.req_emptymsg.funcs.decode = &read_emptymsg;
|
|
||||||
|
|
||||||
/* Bind callbacks for repeated fields */
|
|
||||||
alltypes.rep_int32.funcs.decode = &read_repeated_varint;
|
|
||||||
alltypes.rep_int32.arg = rep_int32;
|
|
||||||
|
|
||||||
alltypes.rep_int64.funcs.decode = &read_repeated_varint;
|
|
||||||
alltypes.rep_int64.arg = rep_int64;
|
|
||||||
|
|
||||||
alltypes.rep_uint32.funcs.decode = &read_repeated_varint;
|
|
||||||
alltypes.rep_uint32.arg = rep_uint32;
|
|
||||||
|
|
||||||
alltypes.rep_uint64.funcs.decode = &read_repeated_varint;
|
|
||||||
alltypes.rep_uint64.arg = rep_uint64;
|
|
||||||
|
|
||||||
alltypes.rep_sint32.funcs.decode = &read_repeated_svarint;
|
|
||||||
alltypes.rep_sint32.arg = rep_sint32;
|
|
||||||
|
|
||||||
alltypes.rep_sint64.funcs.decode = &read_repeated_svarint;
|
|
||||||
alltypes.rep_sint64.arg = rep_sint64;
|
|
||||||
|
|
||||||
alltypes.rep_bool.funcs.decode = &read_repeated_varint;
|
|
||||||
alltypes.rep_bool.arg = rep_bool;
|
|
||||||
|
|
||||||
alltypes.rep_fixed32.funcs.decode = &read_repeated_fixed32;
|
|
||||||
alltypes.rep_fixed32.arg = rep_fixed32;
|
|
||||||
|
|
||||||
alltypes.rep_sfixed32.funcs.decode = &read_repeated_fixed32;
|
|
||||||
alltypes.rep_sfixed32.arg = rep_sfixed32;
|
|
||||||
|
|
||||||
alltypes.rep_float.funcs.decode = &read_repeated_fixed32;
|
|
||||||
alltypes.rep_float.arg = rep_float;
|
|
||||||
|
|
||||||
alltypes.rep_fixed64.funcs.decode = &read_repeated_fixed64;
|
|
||||||
alltypes.rep_fixed64.arg = rep_fixed64;
|
|
||||||
|
|
||||||
alltypes.rep_sfixed64.funcs.decode = &read_repeated_fixed64;
|
|
||||||
alltypes.rep_sfixed64.arg = rep_sfixed64;
|
|
||||||
|
|
||||||
alltypes.rep_double.funcs.decode = &read_repeated_fixed64;
|
|
||||||
alltypes.rep_double.arg = rep_double;
|
|
||||||
|
|
||||||
alltypes.rep_string.funcs.decode = &read_repeated_string;
|
|
||||||
alltypes.rep_string.arg = rep_string;
|
|
||||||
|
|
||||||
alltypes.rep_bytes.funcs.decode = &read_repeated_string;
|
|
||||||
alltypes.rep_bytes.arg = rep_bytes;
|
|
||||||
|
|
||||||
alltypes.rep_submsg.funcs.decode = &read_repeated_submsg;
|
|
||||||
alltypes.rep_submsg.arg = rep_submsg;
|
|
||||||
|
|
||||||
alltypes.rep_enum.funcs.decode = &read_repeated_varint;
|
|
||||||
alltypes.rep_enum.arg = rep_enum;
|
|
||||||
|
|
||||||
alltypes.rep_emptymsg.funcs.decode = &read_emptymsg;
|
|
||||||
|
|
||||||
alltypes.req_limits.funcs.decode = &read_limits;
|
|
||||||
|
|
||||||
alltypes.end.funcs.decode = &read_varint;
|
|
||||||
alltypes.end.arg = (void*)1099;
|
|
||||||
|
|
||||||
/* Bind callbacks for optional fields */
|
|
||||||
if (mode == 1)
|
|
||||||
{
|
|
||||||
alltypes.opt_int32.funcs.decode = &read_varint;
|
|
||||||
alltypes.opt_int32.arg = (void*)3041;
|
|
||||||
|
|
||||||
alltypes.opt_int64.funcs.decode = &read_varint;
|
|
||||||
alltypes.opt_int64.arg = (void*)3042;
|
|
||||||
|
|
||||||
alltypes.opt_uint32.funcs.decode = &read_varint;
|
|
||||||
alltypes.opt_uint32.arg = (void*)3043;
|
|
||||||
|
|
||||||
alltypes.opt_uint64.funcs.decode = &read_varint;
|
|
||||||
alltypes.opt_uint64.arg = (void*)3044;
|
|
||||||
|
|
||||||
alltypes.opt_sint32.funcs.decode = &read_svarint;
|
|
||||||
alltypes.opt_sint32.arg = (void*)3045;
|
|
||||||
|
|
||||||
alltypes.opt_sint64.funcs.decode = &read_svarint;
|
|
||||||
alltypes.opt_sint64.arg = (void*)3046;
|
|
||||||
|
|
||||||
alltypes.opt_bool.funcs.decode = &read_varint;
|
|
||||||
alltypes.opt_bool.arg = (void*)true;
|
|
||||||
|
|
||||||
alltypes.opt_fixed32.funcs.decode = &read_fixed32;
|
|
||||||
alltypes.opt_fixed32.arg = &opt_fixed32;
|
|
||||||
|
|
||||||
alltypes.opt_sfixed32.funcs.decode = &read_fixed32;
|
|
||||||
alltypes.opt_sfixed32.arg = &opt_sfixed32;
|
|
||||||
|
|
||||||
alltypes.opt_float.funcs.decode = &read_fixed32;
|
|
||||||
alltypes.opt_float.arg = &opt_float;
|
|
||||||
|
|
||||||
alltypes.opt_fixed64.funcs.decode = &read_fixed64;
|
|
||||||
alltypes.opt_fixed64.arg = &opt_fixed64;
|
|
||||||
|
|
||||||
alltypes.opt_sfixed64.funcs.decode = &read_fixed64;
|
|
||||||
alltypes.opt_sfixed64.arg = &opt_sfixed64;
|
|
||||||
|
|
||||||
alltypes.opt_double.funcs.decode = &read_fixed64;
|
|
||||||
alltypes.opt_double.arg = &opt_double;
|
|
||||||
|
|
||||||
alltypes.opt_string.funcs.decode = &read_string;
|
|
||||||
alltypes.opt_string.arg = "3054";
|
|
||||||
|
|
||||||
alltypes.opt_bytes.funcs.decode = &read_string;
|
|
||||||
alltypes.opt_bytes.arg = "3055";
|
|
||||||
|
|
||||||
alltypes.opt_submsg.funcs.decode = &read_submsg;
|
|
||||||
alltypes.opt_submsg.arg = &opt_submsg;
|
|
||||||
|
|
||||||
alltypes.opt_enum.funcs.decode = &read_varint;
|
|
||||||
alltypes.opt_enum.arg = (void*)MyEnum_Truth;
|
|
||||||
|
|
||||||
alltypes.opt_emptymsg.funcs.decode = &read_emptymsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pb_decode(stream, AllTypes_fields, &alltypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
uint8_t buffer[1024];
|
|
||||||
size_t count;
|
|
||||||
pb_istream_t stream;
|
|
||||||
|
|
||||||
/* Whether to expect the optional values or the default values. */
|
|
||||||
int mode = (argc > 1) ? atoi(argv[1]) : 0;
|
|
||||||
|
|
||||||
/* Read the data into buffer */
|
|
||||||
SET_BINARY_MODE(stdin);
|
|
||||||
count = fread(buffer, 1, sizeof(buffer), stdin);
|
|
||||||
|
|
||||||
/* Construct a pb_istream_t for reading from the buffer */
|
|
||||||
stream = pb_istream_from_buffer(buffer, count);
|
|
||||||
|
|
||||||
/* Decode and print out the stuff */
|
|
||||||
if (!check_alltypes(&stream, mode))
|
|
||||||
{
|
|
||||||
printf("Parsing failed: %s\n", PB_GET_ERROR(&stream));
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,397 +0,0 @@
|
|||||||
/* Attempts to test all the datatypes supported by ProtoBuf when used as callback fields.
|
|
||||||
* Note that normally there would be no reason to use callback fields for this,
|
|
||||||
* because each encoder defined here only gives a single field.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <pb_encode.h>
|
|
||||||
#include "alltypes.pb.h"
|
|
||||||
#include "test_helpers.h"
|
|
||||||
|
|
||||||
static bool write_varint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_varint(stream, (long)*arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_svarint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_svarint(stream, (long)*arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_fixed32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_fixed32(stream, *arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_fixed64(stream, *arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_string(stream, *arg, strlen(*arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_submsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, SubMessage_fields, *arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_emptymsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
EmptyMessage emptymsg = {0};
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_repeated_varint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_varint(stream, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_varint(stream, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_varint(stream, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_varint(stream, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_varint(stream, (long)*arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_repeated_svarint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_svarint(stream, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_svarint(stream, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_svarint(stream, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_svarint(stream, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_svarint(stream, (long)*arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_repeated_fixed32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
uint32_t dummy = 0;
|
|
||||||
|
|
||||||
/* Make it a packed field */
|
|
||||||
return pb_encode_tag(stream, PB_WT_STRING, field->tag) &&
|
|
||||||
pb_encode_varint(stream, 5 * 4) && /* Number of bytes */
|
|
||||||
pb_encode_fixed32(stream, &dummy) &&
|
|
||||||
pb_encode_fixed32(stream, &dummy) &&
|
|
||||||
pb_encode_fixed32(stream, &dummy) &&
|
|
||||||
pb_encode_fixed32(stream, &dummy) &&
|
|
||||||
pb_encode_fixed32(stream, *arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_repeated_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
uint64_t dummy = 0;
|
|
||||||
|
|
||||||
/* Make it a packed field */
|
|
||||||
return pb_encode_tag(stream, PB_WT_STRING, field->tag) &&
|
|
||||||
pb_encode_varint(stream, 5 * 8) && /* Number of bytes */
|
|
||||||
pb_encode_fixed64(stream, &dummy) &&
|
|
||||||
pb_encode_fixed64(stream, &dummy) &&
|
|
||||||
pb_encode_fixed64(stream, &dummy) &&
|
|
||||||
pb_encode_fixed64(stream, &dummy) &&
|
|
||||||
pb_encode_fixed64(stream, *arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_repeated_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_string(stream, 0, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_string(stream, 0, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_string(stream, 0, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_string(stream, 0, 0) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_string(stream, *arg, strlen(*arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_repeated_submsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
SubMessage dummy = {""};
|
|
||||||
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, SubMessage_fields, *arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_limits(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
Limits limits = {0};
|
|
||||||
limits.int32_min = INT32_MIN;
|
|
||||||
limits.int32_max = INT32_MAX;
|
|
||||||
limits.uint32_min = 0;
|
|
||||||
limits.uint32_max = UINT32_MAX;
|
|
||||||
limits.int64_min = INT64_MIN;
|
|
||||||
limits.int64_max = INT64_MAX;
|
|
||||||
limits.uint64_min = 0;
|
|
||||||
limits.uint64_max = UINT64_MAX;
|
|
||||||
limits.enum_min = HugeEnum_Negative;
|
|
||||||
limits.enum_max = HugeEnum_Positive;
|
|
||||||
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, Limits_fields, &limits);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_repeated_emptymsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
|
|
||||||
{
|
|
||||||
EmptyMessage emptymsg = {0};
|
|
||||||
return pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
|
|
||||||
pb_encode_tag_for_field(stream, field) &&
|
|
||||||
pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int mode = (argc > 1) ? atoi(argv[1]) : 0;
|
|
||||||
|
|
||||||
/* Values for use from callbacks through pointers. */
|
|
||||||
uint32_t req_fixed32 = 1008;
|
|
||||||
int32_t req_sfixed32 = -1009;
|
|
||||||
float req_float = 1010.0f;
|
|
||||||
uint64_t req_fixed64 = 1011;
|
|
||||||
int64_t req_sfixed64 = -1012;
|
|
||||||
double req_double = 1013.0;
|
|
||||||
SubMessage req_submsg = {"1016", 1016};
|
|
||||||
|
|
||||||
uint32_t rep_fixed32 = 2008;
|
|
||||||
int32_t rep_sfixed32 = -2009;
|
|
||||||
float rep_float = 2010.0f;
|
|
||||||
uint64_t rep_fixed64 = 2011;
|
|
||||||
int64_t rep_sfixed64 = -2012;
|
|
||||||
double rep_double = 2013.0;
|
|
||||||
SubMessage rep_submsg = {"2016", 2016, true, 2016};
|
|
||||||
|
|
||||||
uint32_t opt_fixed32 = 3048;
|
|
||||||
int32_t opt_sfixed32 = 3049;
|
|
||||||
float opt_float = 3050.0f;
|
|
||||||
uint64_t opt_fixed64 = 3051;
|
|
||||||
int64_t opt_sfixed64 = 3052;
|
|
||||||
double opt_double = 3053.0f;
|
|
||||||
SubMessage opt_submsg = {"3056", 3056};
|
|
||||||
|
|
||||||
/* Bind callbacks for required fields */
|
|
||||||
AllTypes alltypes = {{{0}}};
|
|
||||||
|
|
||||||
alltypes.req_int32.funcs.encode = &write_varint;
|
|
||||||
alltypes.req_int32.arg = (void*)-1001;
|
|
||||||
|
|
||||||
alltypes.req_int64.funcs.encode = &write_varint;
|
|
||||||
alltypes.req_int64.arg = (void*)-1002;
|
|
||||||
|
|
||||||
alltypes.req_uint32.funcs.encode = &write_varint;
|
|
||||||
alltypes.req_uint32.arg = (void*)1003;
|
|
||||||
|
|
||||||
alltypes.req_uint32.funcs.encode = &write_varint;
|
|
||||||
alltypes.req_uint32.arg = (void*)1003;
|
|
||||||
|
|
||||||
alltypes.req_uint64.funcs.encode = &write_varint;
|
|
||||||
alltypes.req_uint64.arg = (void*)1004;
|
|
||||||
|
|
||||||
alltypes.req_sint32.funcs.encode = &write_svarint;
|
|
||||||
alltypes.req_sint32.arg = (void*)-1005;
|
|
||||||
|
|
||||||
alltypes.req_sint64.funcs.encode = &write_svarint;
|
|
||||||
alltypes.req_sint64.arg = (void*)-1006;
|
|
||||||
|
|
||||||
alltypes.req_bool.funcs.encode = &write_varint;
|
|
||||||
alltypes.req_bool.arg = (void*)true;
|
|
||||||
|
|
||||||
alltypes.req_fixed32.funcs.encode = &write_fixed32;
|
|
||||||
alltypes.req_fixed32.arg = &req_fixed32;
|
|
||||||
|
|
||||||
alltypes.req_sfixed32.funcs.encode = &write_fixed32;
|
|
||||||
alltypes.req_sfixed32.arg = &req_sfixed32;
|
|
||||||
|
|
||||||
alltypes.req_float.funcs.encode = &write_fixed32;
|
|
||||||
alltypes.req_float.arg = &req_float;
|
|
||||||
|
|
||||||
alltypes.req_fixed64.funcs.encode = &write_fixed64;
|
|
||||||
alltypes.req_fixed64.arg = &req_fixed64;
|
|
||||||
|
|
||||||
alltypes.req_sfixed64.funcs.encode = &write_fixed64;
|
|
||||||
alltypes.req_sfixed64.arg = &req_sfixed64;
|
|
||||||
|
|
||||||
alltypes.req_double.funcs.encode = &write_fixed64;
|
|
||||||
alltypes.req_double.arg = &req_double;
|
|
||||||
|
|
||||||
alltypes.req_string.funcs.encode = &write_string;
|
|
||||||
alltypes.req_string.arg = "1014";
|
|
||||||
|
|
||||||
alltypes.req_bytes.funcs.encode = &write_string;
|
|
||||||
alltypes.req_bytes.arg = "1015";
|
|
||||||
|
|
||||||
alltypes.req_submsg.funcs.encode = &write_submsg;
|
|
||||||
alltypes.req_submsg.arg = &req_submsg;
|
|
||||||
|
|
||||||
alltypes.req_enum.funcs.encode = &write_varint;
|
|
||||||
alltypes.req_enum.arg = (void*)MyEnum_Truth;
|
|
||||||
|
|
||||||
alltypes.req_emptymsg.funcs.encode = &write_emptymsg;
|
|
||||||
|
|
||||||
/* Bind callbacks for repeated fields */
|
|
||||||
alltypes.rep_int32.funcs.encode = &write_repeated_varint;
|
|
||||||
alltypes.rep_int32.arg = (void*)-2001;
|
|
||||||
|
|
||||||
alltypes.rep_int64.funcs.encode = &write_repeated_varint;
|
|
||||||
alltypes.rep_int64.arg = (void*)-2002;
|
|
||||||
|
|
||||||
alltypes.rep_uint32.funcs.encode = &write_repeated_varint;
|
|
||||||
alltypes.rep_uint32.arg = (void*)2003;
|
|
||||||
|
|
||||||
alltypes.rep_uint64.funcs.encode = &write_repeated_varint;
|
|
||||||
alltypes.rep_uint64.arg = (void*)2004;
|
|
||||||
|
|
||||||
alltypes.rep_sint32.funcs.encode = &write_repeated_svarint;
|
|
||||||
alltypes.rep_sint32.arg = (void*)-2005;
|
|
||||||
|
|
||||||
alltypes.rep_sint64.funcs.encode = &write_repeated_svarint;
|
|
||||||
alltypes.rep_sint64.arg = (void*)-2006;
|
|
||||||
|
|
||||||
alltypes.rep_bool.funcs.encode = &write_repeated_varint;
|
|
||||||
alltypes.rep_bool.arg = (void*)true;
|
|
||||||
|
|
||||||
alltypes.rep_fixed32.funcs.encode = &write_repeated_fixed32;
|
|
||||||
alltypes.rep_fixed32.arg = &rep_fixed32;
|
|
||||||
|
|
||||||
alltypes.rep_sfixed32.funcs.encode = &write_repeated_fixed32;
|
|
||||||
alltypes.rep_sfixed32.arg = &rep_sfixed32;
|
|
||||||
|
|
||||||
alltypes.rep_float.funcs.encode = &write_repeated_fixed32;
|
|
||||||
alltypes.rep_float.arg = &rep_float;
|
|
||||||
|
|
||||||
alltypes.rep_fixed64.funcs.encode = &write_repeated_fixed64;
|
|
||||||
alltypes.rep_fixed64.arg = &rep_fixed64;
|
|
||||||
|
|
||||||
alltypes.rep_sfixed64.funcs.encode = &write_repeated_fixed64;
|
|
||||||
alltypes.rep_sfixed64.arg = &rep_sfixed64;
|
|
||||||
|
|
||||||
alltypes.rep_double.funcs.encode = &write_repeated_fixed64;
|
|
||||||
alltypes.rep_double.arg = &rep_double;
|
|
||||||
|
|
||||||
alltypes.rep_string.funcs.encode = &write_repeated_string;
|
|
||||||
alltypes.rep_string.arg = "2014";
|
|
||||||
|
|
||||||
alltypes.rep_bytes.funcs.encode = &write_repeated_string;
|
|
||||||
alltypes.rep_bytes.arg = "2015";
|
|
||||||
|
|
||||||
alltypes.rep_submsg.funcs.encode = &write_repeated_submsg;
|
|
||||||
alltypes.rep_submsg.arg = &rep_submsg;
|
|
||||||
|
|
||||||
alltypes.rep_enum.funcs.encode = &write_repeated_varint;
|
|
||||||
alltypes.rep_enum.arg = (void*)MyEnum_Truth;
|
|
||||||
|
|
||||||
alltypes.rep_emptymsg.funcs.encode = &write_repeated_emptymsg;
|
|
||||||
|
|
||||||
alltypes.req_limits.funcs.encode = &write_limits;
|
|
||||||
|
|
||||||
/* Bind callbacks for optional fields */
|
|
||||||
if (mode != 0)
|
|
||||||
{
|
|
||||||
alltypes.opt_int32.funcs.encode = &write_varint;
|
|
||||||
alltypes.opt_int32.arg = (void*)3041;
|
|
||||||
|
|
||||||
alltypes.opt_int64.funcs.encode = &write_varint;
|
|
||||||
alltypes.opt_int64.arg = (void*)3042;
|
|
||||||
|
|
||||||
alltypes.opt_uint32.funcs.encode = &write_varint;
|
|
||||||
alltypes.opt_uint32.arg = (void*)3043;
|
|
||||||
|
|
||||||
alltypes.opt_uint64.funcs.encode = &write_varint;
|
|
||||||
alltypes.opt_uint64.arg = (void*)3044;
|
|
||||||
|
|
||||||
alltypes.opt_sint32.funcs.encode = &write_svarint;
|
|
||||||
alltypes.opt_sint32.arg = (void*)3045;
|
|
||||||
|
|
||||||
alltypes.opt_sint64.funcs.encode = &write_svarint;
|
|
||||||
alltypes.opt_sint64.arg = (void*)3046;
|
|
||||||
|
|
||||||
alltypes.opt_bool.funcs.encode = &write_varint;
|
|
||||||
alltypes.opt_bool.arg = (void*)true;
|
|
||||||
|
|
||||||
alltypes.opt_fixed32.funcs.encode = &write_fixed32;
|
|
||||||
alltypes.opt_fixed32.arg = &opt_fixed32;
|
|
||||||
|
|
||||||
alltypes.opt_sfixed32.funcs.encode = &write_fixed32;
|
|
||||||
alltypes.opt_sfixed32.arg = &opt_sfixed32;
|
|
||||||
|
|
||||||
alltypes.opt_float.funcs.encode = &write_fixed32;
|
|
||||||
alltypes.opt_float.arg = &opt_float;
|
|
||||||
|
|
||||||
alltypes.opt_fixed64.funcs.encode = &write_fixed64;
|
|
||||||
alltypes.opt_fixed64.arg = &opt_fixed64;
|
|
||||||
|
|
||||||
alltypes.opt_sfixed64.funcs.encode = &write_fixed64;
|
|
||||||
alltypes.opt_sfixed64.arg = &opt_sfixed64;
|
|
||||||
|
|
||||||
alltypes.opt_double.funcs.encode = &write_fixed64;
|
|
||||||
alltypes.opt_double.arg = &opt_double;
|
|
||||||
|
|
||||||
alltypes.opt_string.funcs.encode = &write_string;
|
|
||||||
alltypes.opt_string.arg = "3054";
|
|
||||||
|
|
||||||
alltypes.opt_bytes.funcs.encode = &write_string;
|
|
||||||
alltypes.opt_bytes.arg = "3055";
|
|
||||||
|
|
||||||
alltypes.opt_submsg.funcs.encode = &write_submsg;
|
|
||||||
alltypes.opt_submsg.arg = &opt_submsg;
|
|
||||||
|
|
||||||
alltypes.opt_enum.funcs.encode = &write_varint;
|
|
||||||
alltypes.opt_enum.arg = (void*)MyEnum_Truth;
|
|
||||||
|
|
||||||
alltypes.opt_emptymsg.funcs.encode = &write_emptymsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
alltypes.end.funcs.encode = &write_varint;
|
|
||||||
alltypes.end.arg = (void*)1099;
|
|
||||||
|
|
||||||
{
|
|
||||||
uint8_t buffer[2048];
|
|
||||||
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
|
|
||||||
|
|
||||||
/* Now encode it and check if we succeeded. */
|
|
||||||
if (pb_encode(&stream, AllTypes_fields, &alltypes))
|
|
||||||
{
|
|
||||||
SET_BINARY_MODE(stdout);
|
|
||||||
fwrite(buffer, 1, stream.bytes_written, stdout);
|
|
||||||
return 0; /* Success */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
|
|
||||||
return 1; /* Failure */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
# Encode the AllTypes message using pointers for all fields, and verify the
|
|
||||||
# output against the normal AllTypes test case.
|
|
||||||
|
|
||||||
Import("env")
|
|
||||||
|
|
||||||
c = Copy("$TARGET", "$SOURCE")
|
|
||||||
env.Command("alltypes.proto", "#alltypes/alltypes.proto", c)
|
|
||||||
|
|
||||||
env.NanopbProto(["alltypes", "alltypes.options"])
|
|
||||||
enc = env.Program(["encode_alltypes_pointer.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
|
|
||||||
|
|
||||||
refdec = "$BUILD/alltypes/decode_alltypes$PROGSUFFIX"
|
|
||||||
|
|
||||||
# Encode and compare results
|
|
||||||
env.RunTest(enc)
|
|
||||||
env.RunTest("decode_alltypes.output", [refdec, "encode_alltypes_pointer.output"])
|
|
||||||
env.Compare(["encode_alltypes_pointer.output", "$BUILD/alltypes/encode_alltypes.output"])
|
|
||||||
|
|
||||||
# Do the same thing with the optional fields present
|
|
||||||
env.RunTest("optionals.output", enc, ARGS = ['1'])
|
|
||||||
env.RunTest("optionals.decout", [refdec, "optionals.output"], ARGS = ['1'])
|
|
||||||
env.Compare(["optionals.output", "$BUILD/alltypes/optionals.output"])
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Generate all fields as pointers.
|
|
||||||
* type:FT_POINTER
|
|
||||||
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
/* Attempts to test all the datatypes supported by ProtoBuf.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <pb_encode.h>
|
|
||||||
#include "alltypes.pb.h"
|
|
||||||
#include "test_helpers.h"
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int mode = (argc > 1) ? atoi(argv[1]) : 0;
|
|
||||||
|
|
||||||
/* Values for required fields */
|
|
||||||
int32_t req_int32 = -1001;
|
|
||||||
int64_t req_int64 = -1002;
|
|
||||||
uint32_t req_uint32 = 1003;
|
|
||||||
uint64_t req_uint64 = 1004;
|
|
||||||
int32_t req_sint32 = -1005;
|
|
||||||
int64_t req_sint64 = -1006;
|
|
||||||
bool req_bool = true;
|
|
||||||
uint32_t req_fixed32 = 1008;
|
|
||||||
int32_t req_sfixed32 = -1009;
|
|
||||||
float req_float = 1010.0f;
|
|
||||||
uint64_t req_fixed64 = 1011;
|
|
||||||
int64_t req_sfixed64 = -1012;
|
|
||||||
double req_double = 1013.0;
|
|
||||||
char* req_string = "1014";
|
|
||||||
pb_bytes_ptr_t req_bytes = {4, (uint8_t*)"1015"};
|
|
||||||
static int32_t req_substuff = 1016;
|
|
||||||
SubMessage req_submsg = {"1016", &req_substuff};
|
|
||||||
MyEnum req_enum = MyEnum_Truth;
|
|
||||||
EmptyMessage req_emptymsg = {0};
|
|
||||||
|
|
||||||
int32_t end = 1099;
|
|
||||||
|
|
||||||
/* Values for repeated fields */
|
|
||||||
int32_t rep_int32[5] = {0, 0, 0, 0, -2001};
|
|
||||||
int64_t rep_int64[5] = {0, 0, 0, 0, -2002};
|
|
||||||
uint32_t rep_uint32[5] = {0, 0, 0, 0, 2003};
|
|
||||||
uint64_t rep_uint64[5] = {0, 0, 0, 0, 2004};
|
|
||||||
int32_t rep_sint32[5] = {0, 0, 0, 0, -2005};
|
|
||||||
int64_t rep_sint64[5] = {0, 0, 0, 0, -2006};
|
|
||||||
bool rep_bool[5] = {false, false, false, false, true};
|
|
||||||
uint32_t rep_fixed32[5] = {0, 0, 0, 0, 2008};
|
|
||||||
int32_t rep_sfixed32[5] = {0, 0, 0, 0, -2009};
|
|
||||||
float rep_float[5] = {0, 0, 0, 0, 2010.0f};
|
|
||||||
uint64_t rep_fixed64[5] = {0, 0, 0, 0, 2011};
|
|
||||||
int64_t rep_sfixed64[5] = {0, 0, 0, 0, -2012};
|
|
||||||
double rep_double[5] = {0, 0, 0, 0, 2013.0f};
|
|
||||||
char* rep_string[5] = {"", "", "", "", "2014"};
|
|
||||||
pb_bytes_ptr_t rep_bytes[5] = {{0,0}, {0,0}, {0,0}, {0,0}, {4, (uint8_t*)"2015"}};
|
|
||||||
static int32_t rep_sub2zero = 0;
|
|
||||||
static int32_t rep_substuff2 = 2016;
|
|
||||||
static uint32_t rep_substuff3 = 2016;
|
|
||||||
SubMessage rep_submsg[5] = {{"", &rep_sub2zero},
|
|
||||||
{"", &rep_sub2zero},
|
|
||||||
{"", &rep_sub2zero},
|
|
||||||
{"", &rep_sub2zero},
|
|
||||||
{"2016", &rep_substuff2, &rep_substuff3}};
|
|
||||||
MyEnum rep_enum[5] = {0, 0, 0, 0, MyEnum_Truth};
|
|
||||||
EmptyMessage rep_emptymsg[5] = {{0}, {0}, {0}, {0}, {0}};
|
|
||||||
|
|
||||||
/* Values for optional fields */
|
|
||||||
int32_t opt_int32 = 3041;
|
|
||||||
int64_t opt_int64 = 3042;
|
|
||||||
uint32_t opt_uint32 = 3043;
|
|
||||||
uint64_t opt_uint64 = 3044;
|
|
||||||
int32_t opt_sint32 = 3045;
|
|
||||||
int64_t opt_sint64 = 3046;
|
|
||||||
bool opt_bool = true;
|
|
||||||
uint32_t opt_fixed32 = 3048;
|
|
||||||
int32_t opt_sfixed32 = 3049;
|
|
||||||
float opt_float = 3050.0f;
|
|
||||||
uint64_t opt_fixed64 = 3051;
|
|
||||||
int64_t opt_sfixed64 = 3052;
|
|
||||||
double opt_double = 3053.0;
|
|
||||||
char* opt_string = "3054";
|
|
||||||
pb_bytes_ptr_t opt_bytes = {4, (uint8_t*)"3055"};
|
|
||||||
static int32_t opt_substuff = 3056;
|
|
||||||
SubMessage opt_submsg = {"3056", &opt_substuff};
|
|
||||||
MyEnum opt_enum = MyEnum_Truth;
|
|
||||||
EmptyMessage opt_emptymsg = {0};
|
|
||||||
|
|
||||||
/* Values for the Limits message. */
|
|
||||||
static int32_t int32_min = INT32_MIN;
|
|
||||||
static int32_t int32_max = INT32_MAX;
|
|
||||||
static uint32_t uint32_min = 0;
|
|
||||||
static uint32_t uint32_max = UINT32_MAX;
|
|
||||||
static int64_t int64_min = INT64_MIN;
|
|
||||||
static int64_t int64_max = INT64_MAX;
|
|
||||||
static uint64_t uint64_min = 0;
|
|
||||||
static uint64_t uint64_max = UINT64_MAX;
|
|
||||||
static HugeEnum enum_min = HugeEnum_Negative;
|
|
||||||
static HugeEnum enum_max = HugeEnum_Positive;
|
|
||||||
Limits req_limits = {&int32_min, &int32_max,
|
|
||||||
&uint32_min, &uint32_max,
|
|
||||||
&int64_min, &int64_max,
|
|
||||||
&uint64_min, &uint64_max,
|
|
||||||
&enum_min, &enum_max};
|
|
||||||
|
|
||||||
/* Initialize the message struct with pointers to the fields. */
|
|
||||||
AllTypes alltypes = {0};
|
|
||||||
|
|
||||||
alltypes.req_int32 = &req_int32;
|
|
||||||
alltypes.req_int64 = &req_int64;
|
|
||||||
alltypes.req_uint32 = &req_uint32;
|
|
||||||
alltypes.req_uint64 = &req_uint64;
|
|
||||||
alltypes.req_sint32 = &req_sint32;
|
|
||||||
alltypes.req_sint64 = &req_sint64;
|
|
||||||
alltypes.req_bool = &req_bool;
|
|
||||||
alltypes.req_fixed32 = &req_fixed32;
|
|
||||||
alltypes.req_sfixed32 = &req_sfixed32;
|
|
||||||
alltypes.req_float = &req_float;
|
|
||||||
alltypes.req_fixed64 = &req_fixed64;
|
|
||||||
alltypes.req_sfixed64 = &req_sfixed64;
|
|
||||||
alltypes.req_double = &req_double;
|
|
||||||
alltypes.req_string = req_string;
|
|
||||||
alltypes.req_bytes = &req_bytes;
|
|
||||||
alltypes.req_submsg = &req_submsg;
|
|
||||||
alltypes.req_enum = &req_enum;
|
|
||||||
alltypes.req_emptymsg = &req_emptymsg;
|
|
||||||
alltypes.req_limits = &req_limits;
|
|
||||||
|
|
||||||
alltypes.rep_int32_count = 5; alltypes.rep_int32 = rep_int32;
|
|
||||||
alltypes.rep_int64_count = 5; alltypes.rep_int64 = rep_int64;
|
|
||||||
alltypes.rep_uint32_count = 5; alltypes.rep_uint32 = rep_uint32;
|
|
||||||
alltypes.rep_uint64_count = 5; alltypes.rep_uint64 = rep_uint64;
|
|
||||||
alltypes.rep_sint32_count = 5; alltypes.rep_sint32 = rep_sint32;
|
|
||||||
alltypes.rep_sint64_count = 5; alltypes.rep_sint64 = rep_sint64;
|
|
||||||
alltypes.rep_bool_count = 5; alltypes.rep_bool = rep_bool;
|
|
||||||
alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32 = rep_fixed32;
|
|
||||||
alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32 = rep_sfixed32;
|
|
||||||
alltypes.rep_float_count = 5; alltypes.rep_float = rep_float;
|
|
||||||
alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64 = rep_fixed64;
|
|
||||||
alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64 = rep_sfixed64;
|
|
||||||
alltypes.rep_double_count = 5; alltypes.rep_double = rep_double;
|
|
||||||
alltypes.rep_string_count = 5; alltypes.rep_string = rep_string;
|
|
||||||
alltypes.rep_bytes_count = 5; alltypes.rep_bytes = rep_bytes;
|
|
||||||
alltypes.rep_submsg_count = 5; alltypes.rep_submsg = rep_submsg;
|
|
||||||
alltypes.rep_enum_count = 5; alltypes.rep_enum = rep_enum;
|
|
||||||
alltypes.rep_emptymsg_count = 5; alltypes.rep_emptymsg = rep_emptymsg;
|
|
||||||
|
|
||||||
if (mode != 0)
|
|
||||||
{
|
|
||||||
/* Fill in values for optional fields */
|
|
||||||
alltypes.opt_int32 = &opt_int32;
|
|
||||||
alltypes.opt_int64 = &opt_int64;
|
|
||||||
alltypes.opt_uint32 = &opt_uint32;
|
|
||||||
alltypes.opt_uint64 = &opt_uint64;
|
|
||||||
alltypes.opt_sint32 = &opt_sint32;
|
|
||||||
alltypes.opt_sint64 = &opt_sint64;
|
|
||||||
alltypes.opt_bool = &opt_bool;
|
|
||||||
alltypes.opt_fixed32 = &opt_fixed32;
|
|
||||||
alltypes.opt_sfixed32 = &opt_sfixed32;
|
|
||||||
alltypes.opt_float = &opt_float;
|
|
||||||
alltypes.opt_fixed64 = &opt_fixed64;
|
|
||||||
alltypes.opt_sfixed64 = &opt_sfixed64;
|
|
||||||
alltypes.opt_double = &opt_double;
|
|
||||||
alltypes.opt_string = opt_string;
|
|
||||||
alltypes.opt_bytes = &opt_bytes;
|
|
||||||
alltypes.opt_submsg = &opt_submsg;
|
|
||||||
alltypes.opt_enum = &opt_enum;
|
|
||||||
alltypes.opt_emptymsg = &opt_emptymsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
alltypes.end = &end;
|
|
||||||
|
|
||||||
{
|
|
||||||
uint8_t buffer[4096];
|
|
||||||
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
|
|
||||||
|
|
||||||
/* Now encode it and check if we succeeded. */
|
|
||||||
if (pb_encode(&stream, AllTypes_fields, &alltypes))
|
|
||||||
{
|
|
||||||
SET_BINARY_MODE(stdout);
|
|
||||||
fwrite(buffer, 1, stream.bytes_written, stdout);
|
|
||||||
return 0; /* Success */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
|
|
||||||
return 1; /* Failure */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <pb_decode.h>
|
#include <pb_decode.h>
|
||||||
#include "alltypes_legacy.h"
|
#include "alltypes_legacy.h"
|
||||||
#include "test_helpers.h"
|
|
||||||
|
|
||||||
#define TEST(x) if (!(x)) { \
|
#define TEST(x) if (!(x)) { \
|
||||||
printf("Test " #x " failed.\n"); \
|
printf("Test " #x " failed.\n"); \
|
||||||
@@ -177,19 +176,15 @@ bool check_alltypes(pb_istream_t *stream, int mode)
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
uint8_t buffer[1024];
|
|
||||||
size_t count;
|
|
||||||
pb_istream_t stream;
|
|
||||||
|
|
||||||
/* Whether to expect the optional values or the default values. */
|
/* Whether to expect the optional values or the default values. */
|
||||||
int mode = (argc > 1) ? atoi(argv[1]) : 0;
|
int mode = (argc > 1) ? atoi(argv[1]) : 0;
|
||||||
|
|
||||||
/* Read the data into buffer */
|
/* Read the data into buffer */
|
||||||
SET_BINARY_MODE(stdin);
|
uint8_t buffer[1024];
|
||||||
count = fread(buffer, 1, sizeof(buffer), stdin);
|
size_t count = fread(buffer, 1, sizeof(buffer), stdin);
|
||||||
|
|
||||||
/* Construct a pb_istream_t for reading from the buffer */
|
/* Construct a pb_istream_t for reading from the buffer */
|
||||||
stream = pb_istream_from_buffer(buffer, count);
|
pb_istream_t stream = pb_istream_from_buffer(buffer, count);
|
||||||
|
|
||||||
/* Decode and print out the stuff */
|
/* Decode and print out the stuff */
|
||||||
if (!check_alltypes(&stream, mode))
|
if (!check_alltypes(&stream, mode))
|
||||||
|
|||||||
@@ -3,10 +3,6 @@
|
|||||||
|
|
||||||
Import("env")
|
Import("env")
|
||||||
|
|
||||||
# This is needed to get INT32_MIN etc. macros defined
|
|
||||||
env = env.Clone()
|
|
||||||
env.Append(CPPDEFINES = ['__STDC_LIMIT_MACROS'])
|
|
||||||
|
|
||||||
# Copy the files to .cxx extension in order to force C++ build.
|
# Copy the files to .cxx extension in order to force C++ build.
|
||||||
c = Copy("$TARGET", "$SOURCE")
|
c = Copy("$TARGET", "$SOURCE")
|
||||||
env.Command("pb_encode.cxx", "#../pb_encode.c", c)
|
env.Command("pb_encode.cxx", "#../pb_encode.c", c)
|
||||||
|
|||||||
@@ -10,7 +10,5 @@ dec = env.GetBuildPath('$BUILD/basic_stream/${PROGPREFIX}decode_stream${PROGSUFF
|
|||||||
env.RunTest('person_with_extra_field_stream.output', [dec, "person_with_extra_field.pb"])
|
env.RunTest('person_with_extra_field_stream.output', [dec, "person_with_extra_field.pb"])
|
||||||
env.Compare(["person_with_extra_field_stream.output", "person_with_extra_field.expected"])
|
env.Compare(["person_with_extra_field_stream.output", "person_with_extra_field.expected"])
|
||||||
|
|
||||||
# This uses the backwards compatibility alltypes test, so that
|
dec2 = env.GetBuildPath('$BUILD/alltypes/${PROGPREFIX}decode_alltypes${PROGSUFFIX}')
|
||||||
# alltypes_with_extra_fields.pb doesn't have to be remade so often.
|
|
||||||
dec2 = env.GetBuildPath('$BUILD/backwards_compatibility/${PROGPREFIX}decode_legacy${PROGSUFFIX}')
|
|
||||||
env.RunTest('alltypes_with_extra_fields.output', [dec2, 'alltypes_with_extra_fields.pb'])
|
env.RunTest('alltypes_with_extra_fields.output', [dec2, 'alltypes_with_extra_fields.pb'])
|
||||||
|
|||||||
@@ -8,24 +8,6 @@ message EmptyMessage {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum HugeEnum {
|
|
||||||
Negative = -2147483647; /* protoc doesn't accept -2147483648 here */
|
|
||||||
Positive = 2147483647;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Limits {
|
|
||||||
required int32 int32_min = 1;
|
|
||||||
required int32 int32_max = 2;
|
|
||||||
required uint32 uint32_min = 3;
|
|
||||||
required uint32 uint32_max = 4;
|
|
||||||
required int64 int64_min = 5;
|
|
||||||
required int64 int64_max = 6;
|
|
||||||
required uint64 uint64_min = 7;
|
|
||||||
required uint64 uint64_max = 8;
|
|
||||||
required HugeEnum enum_min = 9;
|
|
||||||
required HugeEnum enum_max = 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum MyEnum {
|
enum MyEnum {
|
||||||
Zero = 0;
|
Zero = 0;
|
||||||
First = 1;
|
First = 1;
|
||||||
@@ -101,9 +83,6 @@ message AllTypes {
|
|||||||
optional MyEnum opt_enum = 10057 [default = Second];
|
optional MyEnum opt_enum = 10057 [default = Second];
|
||||||
optional EmptyMessage opt_emptymsg = 10058;
|
optional EmptyMessage opt_emptymsg = 10058;
|
||||||
|
|
||||||
// Check that extreme integer values are handled correctly
|
|
||||||
required Limits req_limits = 98;
|
|
||||||
|
|
||||||
// Just to make sure that the size of the fields has been calculated
|
// Just to make sure that the size of the fields has been calculated
|
||||||
// properly, i.e. otherwise a bug in last field might not be detected.
|
// properly, i.e. otherwise a bug in last field might not be detected.
|
||||||
required int32 end = 10099;
|
required int32 end = 10099;
|
||||||
|
|||||||
@@ -8,24 +8,6 @@ message EmptyMessage {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum HugeEnum {
|
|
||||||
Negative = -2147483647; /* protoc doesn't accept -2147483648 here */
|
|
||||||
Positive = 2147483647;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Limits {
|
|
||||||
required int32 int32_min = 1;
|
|
||||||
required int32 int32_max = 2;
|
|
||||||
required uint32 uint32_min = 3;
|
|
||||||
required uint32 uint32_max = 4;
|
|
||||||
required int64 int64_min = 5;
|
|
||||||
required int64 int64_max = 6;
|
|
||||||
required uint64 uint64_min = 7;
|
|
||||||
required uint64 uint64_max = 8;
|
|
||||||
required HugeEnum enum_min = 9;
|
|
||||||
required HugeEnum enum_max = 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum MyEnum {
|
enum MyEnum {
|
||||||
Zero = 0;
|
Zero = 0;
|
||||||
First = 1;
|
First = 1;
|
||||||
@@ -101,9 +83,6 @@ message AllTypes {
|
|||||||
optional MyEnum opt_enum = 10057 [default = Second];
|
optional MyEnum opt_enum = 10057 [default = Second];
|
||||||
optional EmptyMessage opt_emptymsg = 10058;
|
optional EmptyMessage opt_emptymsg = 10058;
|
||||||
|
|
||||||
// Check that extreme integer values are handled correctly
|
|
||||||
required Limits req_limits = 98;
|
|
||||||
|
|
||||||
// Just to make sure that the size of the fields has been calculated
|
// Just to make sure that the size of the fields has been calculated
|
||||||
// properly, i.e. otherwise a bug in last field might not be detected.
|
// properly, i.e. otherwise a bug in last field might not be detected.
|
||||||
required int32 end = 13432099;
|
required int32 end = 13432099;
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
# Check that alltypes test case works also when the .proto file defines
|
|
||||||
# a package name.
|
|
||||||
|
|
||||||
Import("env")
|
|
||||||
|
|
||||||
# Build a modified alltypes.proto
|
|
||||||
def modify_proto(target, source, env):
|
|
||||||
'''Add a "package test.package;" directive to the beginning of the .proto file.'''
|
|
||||||
data = open(str(source[0]), 'r').read()
|
|
||||||
open(str(target[0]), 'w').write("package test.package;\n\n" + data)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
env.Command("alltypes.proto", "#alltypes/alltypes.proto", modify_proto)
|
|
||||||
env.Command("alltypes.options", "#alltypes/alltypes.options", Copy("$TARGET", "$SOURCE"))
|
|
||||||
env.NanopbProto(["alltypes", "alltypes.options"])
|
|
||||||
|
|
||||||
# Build a modified encode_alltypes.c
|
|
||||||
def modify_c(target, source, env):
|
|
||||||
'''Add package name to type names in .c file.'''
|
|
||||||
|
|
||||||
data = open(str(source[0]), 'r').read()
|
|
||||||
|
|
||||||
type_names = ['AllTypes', 'MyEnum', 'HugeEnum']
|
|
||||||
for name in type_names:
|
|
||||||
data = data.replace(name, 'test_package_' + name)
|
|
||||||
|
|
||||||
open(str(target[0]), 'w').write(data)
|
|
||||||
return 0
|
|
||||||
env.Command("encode_alltypes.c", "#alltypes/encode_alltypes.c", modify_c)
|
|
||||||
|
|
||||||
# Encode and compare results to original alltypes testcase
|
|
||||||
enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
|
|
||||||
refdec = "$BUILD/alltypes/decode_alltypes$PROGSUFFIX"
|
|
||||||
env.RunTest(enc)
|
|
||||||
env.Compare(["encode_alltypes.output", "$BUILD/alltypes/encode_alltypes.output"])
|
|
||||||
|
|
||||||
@@ -19,11 +19,7 @@ def add_nanopb_builders(env):
|
|||||||
else:
|
else:
|
||||||
infile = None
|
infile = None
|
||||||
|
|
||||||
args = [str(source[0])]
|
pipe = subprocess.Popen(str(source[0]),
|
||||||
if env.has_key('ARGS'):
|
|
||||||
args.extend(env['ARGS'])
|
|
||||||
|
|
||||||
pipe = subprocess.Popen(args,
|
|
||||||
stdin = infile,
|
stdin = infile,
|
||||||
stdout = open(str(target[0]), 'w'),
|
stdout = open(str(target[0]), 'w'),
|
||||||
stderr = sys.stderr)
|
stderr = sys.stderr)
|
||||||
@@ -49,17 +45,6 @@ def add_nanopb_builders(env):
|
|||||||
suffix = '.decoded')
|
suffix = '.decoded')
|
||||||
env.Append(BUILDERS = {'Decode': decode_builder})
|
env.Append(BUILDERS = {'Decode': decode_builder})
|
||||||
|
|
||||||
# Build command that encodes a message using protoc
|
|
||||||
def encode_actions(source, target, env, for_signature):
|
|
||||||
esc = env['ESCAPE']
|
|
||||||
dirs = ' '.join(['-I' + esc(env.GetBuildPath(d)) for d in env['PROTOCPATH']])
|
|
||||||
return '$PROTOC $PROTOCFLAGS %s --encode=%s %s <%s >%s' % (
|
|
||||||
dirs, env['MESSAGE'], esc(str(source[1])), esc(str(source[0])), esc(str(target[0])))
|
|
||||||
|
|
||||||
encode_builder = Builder(generator = encode_actions,
|
|
||||||
suffix = '.encoded')
|
|
||||||
env.Append(BUILDERS = {'Encode': encode_builder})
|
|
||||||
|
|
||||||
# Build command that asserts that two files be equal
|
# Build command that asserts that two files be equal
|
||||||
def compare_files(target, source, env):
|
def compare_files(target, source, env):
|
||||||
data1 = open(str(source[0]), 'rb').read()
|
data1 = open(str(source[0]), 'rb').read()
|
||||||
|
|||||||
@@ -57,16 +57,16 @@ def _detect_protoc(env):
|
|||||||
# Use protoc defined by user
|
# Use protoc defined by user
|
||||||
return env['PROTOC']
|
return env['PROTOC']
|
||||||
|
|
||||||
n = _detect_nanopb(env)
|
p = _detect_nanopb(env)
|
||||||
p1 = os.path.join(n, 'generator-bin', 'protoc' + env['PROGSUFFIX'])
|
p1 = os.path.join(p, 'generator-bin', 'protoc')
|
||||||
if os.path.exists(p1):
|
if os.path.exists(p1):
|
||||||
# Use protoc bundled with binary package
|
# Use protoc bundled with binary package
|
||||||
return env['ESCAPE'](p1)
|
return p1
|
||||||
|
|
||||||
p = env.WhereIs('protoc')
|
p = env.WhereIs('protoc')
|
||||||
if p:
|
if p:
|
||||||
# Use protoc from path
|
# Use protoc from path
|
||||||
return env['ESCAPE'](p)
|
return p
|
||||||
|
|
||||||
raise SCons.Errors.StopError(NanopbWarning,
|
raise SCons.Errors.StopError(NanopbWarning,
|
||||||
"Could not find the protoc compiler")
|
"Could not find the protoc compiler")
|
||||||
@@ -78,8 +78,7 @@ def _detect_protocflags(env):
|
|||||||
|
|
||||||
p = _detect_protoc(env)
|
p = _detect_protoc(env)
|
||||||
n = _detect_nanopb(env)
|
n = _detect_nanopb(env)
|
||||||
p1 = os.path.join(n, 'generator-bin', 'protoc' + env['PROGSUFFIX'])
|
if p == os.path.join(n, 'generator-bin', 'protoc'):
|
||||||
if p == env['ESCAPE'](p1):
|
|
||||||
# Using the bundled protoc, no options needed
|
# Using the bundled protoc, no options needed
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ LIBPROTOC=$(ldd `which protoc` | grep -o '/.*libprotoc[^ ]*')
|
|||||||
cp $LIBPROTOC $DEST/generator-bin/
|
cp $LIBPROTOC $DEST/generator-bin/
|
||||||
cat > $DEST/generator-bin/protoc << EOF
|
cat > $DEST/generator-bin/protoc << EOF
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
SCRIPTDIR=\$(dirname "\$0")
|
SCRIPTDIR=\$(dirname \$(readlink -f \$0))
|
||||||
export LD_LIBRARY_PATH=\$SCRIPTDIR
|
export LD_LIBRARY_PATH=\$SCRIPTDIR
|
||||||
export PATH=\$SCRIPTDIR:\$PATH
|
export PATH=\$SCRIPTDIR:\$PATH
|
||||||
exec "\$SCRIPTDIR/protoc.bin" "\$@"
|
exec \$SCRIPTDIR/protoc.bin "\$@"
|
||||||
EOF
|
EOF
|
||||||
chmod +x $DEST/generator-bin/protoc
|
chmod +x $DEST/generator-bin/protoc
|
||||||
|
|
||||||
|
|||||||
@@ -37,13 +37,13 @@ LIBPROTOBUF=$(otool -L `which protoc` | grep -o '/.*libprotobuf[^ ]*')
|
|||||||
cp $LIBPROTOC $LIBPROTOBUF $DEST/generator-bin/
|
cp $LIBPROTOC $LIBPROTOBUF $DEST/generator-bin/
|
||||||
cat > $DEST/generator-bin/protoc << EOF
|
cat > $DEST/generator-bin/protoc << EOF
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
SCRIPTDIR=\$(dirname "\$0")
|
SCRIPTDIR=\$(cd \$(dirname \$0); pwd)
|
||||||
export DYLD_LIBRARY_PATH=\$SCRIPTDIR
|
export DYLD_LIBRARY_PATH=\$SCRIPTDIR
|
||||||
export PATH=\$SCRIPTDIR:\$PATH
|
export PATH=\$SCRIPTDIR:\$PATH
|
||||||
exec "\$SCRIPTDIR/protoc.bin" "\$@"
|
exec \$SCRIPTDIR/protoc.bin "\$@"
|
||||||
EOF
|
EOF
|
||||||
chmod +x $DEST/generator-bin/protoc
|
chmod +x $DEST/generator-bin/protoc
|
||||||
|
|
||||||
# Tar it all up
|
# Tar it all up
|
||||||
( cd dist; zip -r $VERSION.zip $VERSION )
|
( cd dist; tar -czf $VERSION.tgz $VERSION )
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user