Compare commits

..

27 Commits

Author SHA1 Message Date
Petteri Aimonen
b2ec9e29b3 Include platform name in also the directory name in binary pkgs 2013-12-29 20:25:36 +02:00
Petteri Aimonen
55bd3d706b Merge branch 'dev_installation_packages' of https://code.google.com/p/nanopb into dev_installation_packages 2013-12-03 20:36:29 +02:00
Petteri Aimonen
a5006cc612 Add packaging script for Mac, add platform name to packages. 2013-12-03 20:35:29 +02:00
Petteri Aimonen
a0f91bbeeb Fixes for pyinstaller 2013-12-03 20:10:48 +02:00
Petteri Aimonen
7723a30bd6 Small fix for previous 2013-12-03 19:30:39 +02:00
Petteri Aimonen
98e01b2b33 Check for supported GCC CCFLAGS when building tests. 2013-12-03 19:27:08 +02:00
Petteri Aimonen
985f1b4943 Make generator print errors to stderr.
Otherwise they won't be visible when run as a protoc plugin.
2013-12-03 18:48:10 +02:00
Petteri Aimonen
df3fd72337 Add a SCons tool for nanopb protos.
This tool script is useful both for building the tests and also for use in other applications.
2013-11-23 11:04:12 +02:00
Petteri Aimonen
5ef9d5b698 Fix protoc-gen-nanopb in linux package 2013-11-17 22:37:48 +02:00
Petteri Aimonen
4ecf27c817 Include libprotoc 2013-11-17 22:33:26 +02:00
Petteri Aimonen
ccf63de0c6 Linux archive 2013-11-17 22:25:52 +02:00
Petteri Aimonen
ece793fbc9 Also include the manifest for MSVCR90.DLL 2013-11-17 22:19:54 +02:00
Petteri Aimonen
6adf4e163c Include MSVCR90.DLL also. 2013-11-17 21:43:50 +02:00
Petteri Aimonen
420ad05e06 Include Visual C++ runtime in the Windows package. 2013-11-17 21:20:12 +02:00
Petteri Aimonen
5e82a426e6 Merge branch 'dev_installation_packages' of https://code.google.com/p/nanopb into dev_installation_packages 2013-11-17 20:57:59 +02:00
Petteri Aimonen
8209a668cd README updates 2013-11-17 20:57:50 +02:00
Petteri Aimonen
be81effcf4 Windows build fixes 2013-11-17 20:37:18 +02:00
Petteri Aimonen
f1b2ba57d3 Fix protoc plugin path 2013-11-17 20:25:18 +02:00
Petteri Aimonen
d2ba776094 Actually no, it was a portability hassle 2013-11-17 20:24:32 +02:00
Petteri Aimonen
97554a41c6 Makefile tuning 2013-11-17 20:09:30 +02:00
Petteri Aimonen
b4457a86d6 Rework the Makefiles to be compatible with binary packages. 2013-11-17 20:06:13 +02:00
Petteri Aimonen
bee09c3a38 Moving files around
Renamed READMEs to README.txt to be more friendly for Windows users.
2013-11-17 20:00:58 +02:00
Petteri Aimonen
8daadc556e Package as .zip, convert linebreaks 2013-11-17 19:09:13 +02:00
Petteri Aimonen
43cc9940ad Add build script for windows package 2013-11-17 18:09:11 +02:00
Petteri Aimonen
85be7a634e Add descriptor.proto to repository to avoid messing with protoc include path. 2013-11-17 16:42:52 +02:00
Petteri Aimonen
b5ae8eb6a5 Add script for making linux binary package 2013-11-17 15:46:41 +02:00
Petteri Aimonen
2f982d30ef Move the generator .proto files to a subdir, and get rid of precompiled versions. 2013-11-17 15:07:12 +02:00
38 changed files with 143 additions and 1566 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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
====================== ======================

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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,15 +799,18 @@ 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
@@ -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 options.verbose:
print 'Reading options from ' + optfilename
if os.path.isfile(optfilename): if os.path.isfile(optfilename):
if options.verbose:
sys.stderr.write('Reading options from ' + optfilename + '\n')
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()

View File

@@ -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=. $<

View File

@@ -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.
} }

View File

@@ -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 {

View File

@@ -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

View File

@@ -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
View File

@@ -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.

View File

@@ -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");

View File

@@ -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,
@@ -118,8 +116,8 @@ 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++;

View File

@@ -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']:

View File

@@ -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"])

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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'])

View File

@@ -1,3 +0,0 @@
# Generate all fields as callbacks.
AllTypes.* type:FT_CALLBACK
SubMessage.substuff1 max_size:16

View File

@@ -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;
}
}

View File

@@ -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 */
}
}
}

View File

@@ -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"])

View File

@@ -1,3 +0,0 @@
# Generate all fields as pointers.
* type:FT_POINTER

View File

@@ -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 */
}
}
}

View File

@@ -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))

View File

@@ -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)

View File

@@ -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'])

View File

@@ -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;

View File

@@ -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;

View File

@@ -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"])

View File

@@ -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()

View File

@@ -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 ''

View File

@@ -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

View File

@@ -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 )