aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Medeiros <amaurym@google.com>2016-09-05 16:18:54 +0100
committerAmaury Medeiros <amaurym@google.com>2016-09-07 16:27:16 +0100
commitce0567cd1ff5c95a434bb118ba0db224e280e7d5 (patch)
tree25e697b985f5e9e41201bff97d72645a7d8153b5
parent972589286388f16194b988dc0729f8ebfed3eaf9 (diff)
downloadnanopb-c-ce0567cd1ff5c95a434bb118ba0db224e280e7d5.tar.gz
Updates nanopb from upstream/masterstudio-2.3gradle_2.3.0
Updates it to nanopb@91bb64a, which includes nanopb-0.3.6 and also a bazel BUILD file. Change-Id: Ide3d6767d94c2b7bf9a9f902c82ced14be5e1761
-rw-r--r--.gitignore29
-rw-r--r--AUTHORS24
-rw-r--r--BUILD21
-rw-r--r--CHANGELOG.txt9
-rw-r--r--CONTRIBUTING.md32
-rw-r--r--docs/concepts.rst6
-rw-r--r--docs/index.rst4
-rw-r--r--docs/reference.rst49
-rwxr-xr-xgenerator/nanopb_generator.py42
-rw-r--r--generator/proto/nanopb.proto1
-rw-r--r--generator/proto/nanopb_pb2.py13
-rw-r--r--pb.h29
-rw-r--r--pb_decode.c9
-rw-r--r--pb_encode.c15
-rw-r--r--tests/inline/SConscript16
-rw-r--r--tests/inline/inline.expected3
-rw-r--r--tests/inline/inline.proto17
-rw-r--r--tests/inline/inline_unittests.c73
-rw-r--r--tests/multiple_files/SConscript5
-rw-r--r--tests/multiple_files/subdir/multifile2.proto25
-rw-r--r--tests/multiple_files/test_multiple_files.c10
21 files changed, 383 insertions, 49 deletions
diff --git a/.gitignore b/.gitignore
index c9b568f..be0864e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,29 @@
-*.pyc
*.swp
+*.gcda
+*.gcno
+*.gcov
+*.o
+*.pb.c
+*.pb.h
+*.pb
+*.pyc
+*_pb2.py
+*~
+*.tar.gz
+.sconsign.dblite
+config.log
+.sconf_temp
+tests/build
+julkaisu.txt
+dist
+docs/*.html
+docs/generator_flow.png
+examples/simple/simple
+examples/network_server/client
+examples/network_server/server
+examples/using_double_on_avr/decode_double
+examples/using_double_on_avr/encode_double
+examples/using_double_on_avr/test_conversions
+examples/using_union_messages/decode
+examples/using_union_messages/encode
+generator/nanopb_pb2.pyc
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..a967d3e
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,24 @@
+Petteri Aimonen <jpa@npb.mail.kapsi.fi>
+Michael Poole <mdpoole@troilus.org>
+Daniel Kan <extremeblue99@gmail.com>
+Stan Hu <stanhu@aclimalabs.com>
+dch <david.hotham@blueyonder.co.uk>
+Steffen Siering <steffen siering gmail com>
+Jens Steinhauser <jens.steinhauser@gmail.com>
+Pavel Ilin <ilin.pa@gmail.com>
+Kent Ryhorchuk <kryhorchuk@xeralux.com>
+Martin Donath <scifish@gmail.com>
+Oliver Lee <oliverzlee@gmail.com>
+Michael Haberler <git@mah.priv.at>
+Nicolas Colomer <ncolomer@viadeoteam.com>
+Ivan Kravets <me@ikravets.com>
+Kyle Manna <kyle@kylemanna.com>
+Benjamin Kamath <ben.kamath@synapse.com>
+Andrew Ruder <andrew.ruder@elecsyscorp.com>
+Kenshi Kawaguchi <kenshi@recurse.ca>
+isotes <isotes@gmail.com>
+Maxim Khitrov <max@mxcrypt.com>
+Yaniv Mordekhay <yanivmo@users.noreply.github.com>
+Ming Zhao <mzhao@luminatewireless.com>
+Google, Inc.
+Tom Roeder <tmroeder@google.com>
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..f9fc57f
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,21 @@
+licenses(["notice"])
+
+exports_files(["LICENSE.txt"])
+
+package(default_visibility = ["//visibility:public"])
+
+cc_library(
+ name = "nanopb",
+ visibility = ["//visibility:public"],
+ hdrs = [
+ "pb.h",
+ "pb_common.h",
+ "pb_decode.h",
+ "pb_encode.h",
+ ],
+ srcs = [
+ "pb_common.c",
+ "pb_decode.c",
+ "pb_encode.c",
+ ],
+)
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index fd983df..8437688 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,12 @@
+nanopb-0.3.6 (2016-06-19)
+ Protect against corrupted _count fields in pb_release (#205)
+ Fix error in STATIC_ASSERT with multiple files (#203)
+ Add -D option to specify output directory (#193)
+ Generate MIN/MAX/ARRAYSIZE defines for enums (#194)
+ Generate comments about uncalculable message sizes (#195)
+ Documentation updates (#196, #201)
+ Improvements to test cases.
+
nanopb-0.3.5 (2016-02-13)
NOTE: If you are using pb_syshdr.h, you will need to add uint_least8_t
definition. See docs/migration.rst for details.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..4041bc3
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,32 @@
+Contributing to Nanopb development
+==================================
+
+Reporting issues and requesting features
+----------------------------------------
+
+Feel free to report any issues you see or features you would like
+to see in the future to the Github issue tracker. Using the templates
+below is preferred:
+
+* [Report a bug](https://github.com/nanopb/nanopb/issues/new?body=**Steps%20to%20reproduce%20the%20issue**%0a%0a1.%0a2.%0a3.%0a%0a**What%20happens?**%0A%0A**What%20should%20happen?**&labels=Type-Defect)
+* [Request a feature](https://github.com/nanopb/nanopb/issues/new?body=**What%20should%20the%20feature%20do?**%0A%0A**In%20what%20situation%20would%20the%20feature%20be%20useful?**&labels=Type-Enhancement)
+
+Requesting help
+---------------
+
+If there is something strange going on, but you do not know if
+it is actually a bug in nanopb, try asking first on the
+[discussion forum](https://groups.google.com/forum/#!forum/nanopb).
+
+Pull requests
+-------------
+
+Pull requests are welcome!
+
+If it is not obvious from the commit message, please indicate the
+same information as you would for an issue report:
+
+* What functionality it fixes/adds.
+* How can the problem be reproduced / when would the feature be useful.
+
+
diff --git a/docs/concepts.rst b/docs/concepts.rst
index b4f657e..ea33863 100644
--- a/docs/concepts.rst
+++ b/docs/concepts.rst
@@ -148,7 +148,8 @@ Most Protocol Buffers datatypes have directly corresponding C datatypes, such as
1) Strings, bytes and repeated fields of any type map to callback functions by default.
2) If there is a special option *(nanopb).max_size* specified in the .proto file, string maps to null-terminated char array and bytes map to a structure containing a char array and a size field.
-3) If there is a special option *(nanopb).max_count* specified on a repeated field, it maps to an array of whatever type is being repeated. Another field will be created for the actual number of entries stored.
+3) If *(nanopb).type* is set to *FT_INLINE* and *(nanopb).max_size* is also set, then bytes map to an inline byte array of fixed size.
+4) If there is a special option *(nanopb).max_count* specified on a repeated field, it maps to an array of whatever type is being repeated. Another field will be created for the actual number of entries stored.
=============================================================================== =======================
field in .proto autogenerated in .h
@@ -160,9 +161,10 @@ repeated string name = 1 [(nanopb).max_size = 40, (nanopb).max_count = 5];
| char name[5][40];
required bytes data = 1 [(nanopb).max_size = 40]; | typedef struct {
| size_t size;
- | uint8_t bytes[40];
+ | pb_byte_t bytes[40];
| } Person_data_t;
| Person_data_t data;
+required bytes data = 1 [(nanopb).max_size = 40, (nanopb).type = FT_INLINE]; | pb_byte_t data[40];
=============================================================================== =======================
The maximum lengths are checked in runtime. If string/bytes/array exceeds the allocated length, *pb_decode* will return false.
diff --git a/docs/index.rst b/docs/index.rst
index 2432857..afc7ee4 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -7,7 +7,7 @@ Nanopb: Protocol Buffers with small code size
Nanopb is an ANSI-C library for encoding and decoding messages in Google's `Protocol Buffers`__ format with minimal requirements for RAM and code space.
It is primarily suitable for 32-bit microcontrollers.
-__ http://code.google.com/apis/protocolbuffers/
+__ https://developers.google.com/protocol-buffers/docs/reference/overview
Overall structure
=================
@@ -54,7 +54,7 @@ Features and limitations
#) Fields in the generated structs are ordered by the tag number, instead of the natural ordering in .proto file.
#) Unknown fields are not preserved when decoding and re-encoding a message.
#) Reflection (runtime introspection) is not supported. E.g. you can't request a field by giving its name in a string.
-#) Numeric arrays are always encoded as packed, even if not marked as packed in .proto..
+#) Numeric arrays are always encoded as packed, even if not marked as packed in .proto.
#) Cyclic references between messages are supported only in callback and malloc mode.
Getting started
diff --git a/docs/reference.rst b/docs/reference.rst
index 7d27a51..ef3867a 100644
--- a/docs/reference.rst
+++ b/docs/reference.rst
@@ -77,9 +77,11 @@ int_size Override the integer type of a field.
type Type of the generated field. Default value
is *FT_DEFAULT*, which selects automatically.
You can use *FT_CALLBACK*, *FT_POINTER*,
- *FT_STATIC* or *FT_IGNORE* to force a callback
- field, a dynamically allocated field, a static
- field or to completely ignore the field.
+ *FT_STATIC*, *FT_IGNORE*, or *FT_INLINE* to
+ force a callback field, a dynamically
+ allocated field, a static field, to
+ completely ignore the field or to
+ generate an inline bytes field.
long_names Prefix the enum name to the enum value in
definitions, i.e. *EnumName_EnumValue*. Enabled
by default.
@@ -216,17 +218,20 @@ Type used to store the type of each field, to control the encoder/decoder behavi
The low-order nibble of the enumeration values defines the function that can be used for encoding and decoding the field data:
-==================== ===== ================================================
-LTYPE identifier Value Storage format
-==================== ===== ================================================
-PB_LTYPE_VARINT 0x00 Integer.
-PB_LTYPE_SVARINT 0x01 Integer, zigzag encoded.
-PB_LTYPE_FIXED32 0x02 32-bit integer or floating point.
-PB_LTYPE_FIXED64 0x03 64-bit integer or floating point.
-PB_LTYPE_BYTES 0x04 Structure with *size_t* field and byte array.
-PB_LTYPE_STRING 0x05 Null-terminated string.
-PB_LTYPE_SUBMESSAGE 0x06 Submessage structure.
-==================== ===== ================================================
+=========================== ===== ================================================
+LTYPE identifier Value Storage format
+=========================== ===== ================================================
+PB_LTYPE_VARINT 0x00 Integer.
+PB_LTYPE_UVARINT 0x01 Unsigned integer.
+PB_LTYPE_SVARINT 0x02 Integer, zigzag encoded.
+PB_LTYPE_FIXED32 0x03 32-bit integer or floating point.
+PB_LTYPE_FIXED64 0x04 64-bit integer or floating point.
+PB_LTYPE_BYTES 0x05 Structure with *size_t* field and byte array.
+PB_LTYPE_STRING 0x06 Null-terminated string.
+PB_LTYPE_SUBMESSAGE 0x07 Submessage structure.
+PB_LTYPE_EXTENSION 0x08 Point to *pb_extension_t*.
+PB_LTYPE_FIXED_LENGTH_BYTES 0x09 Inline *pb_byte_t* array of fixed size.
+=========================== ===== ================================================
The bits 4-5 define whether the field is required, optional or repeated:
@@ -489,14 +494,14 @@ This function only considers the LTYPE of the field. You can use it from your fi
Wire type mapping is as follows:
-========================= ============
-LTYPEs Wire type
-========================= ============
-VARINT, SVARINT PB_WT_VARINT
-FIXED64 PB_WT_64BIT
-STRING, BYTES, SUBMESSAGE PB_WT_STRING
-FIXED32 PB_WT_32BIT
-========================= ============
+============================================= ============
+LTYPEs Wire type
+============================================= ============
+VARINT, UVARINT, SVARINT PB_WT_VARINT
+FIXED64 PB_WT_64BIT
+STRING, BYTES, SUBMESSAGE, FIXED_LENGTH_BYTES PB_WT_STRING
+FIXED32 PB_WT_32BIT
+============================================= ============
pb_encode_varint
----------------
diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py
index 84f5d09..973c761 100755
--- a/generator/nanopb_generator.py
+++ b/generator/nanopb_generator.py
@@ -3,7 +3,7 @@
from __future__ import unicode_literals
'''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.'''
-nanopb_version = "nanopb-0.3.6-dev"
+nanopb_version = "nanopb-0.3.7-dev"
import sys
import re
@@ -241,6 +241,11 @@ class Field:
self.enc_size = None
self.ctype = None
+ self.inline = None
+ if field_options.type == nanopb_pb2.FT_INLINE:
+ field_options.type = nanopb_pb2.FT_STATIC
+ self.inline = nanopb_pb2.FT_INLINE
+
# Parse field options
if field_options.HasField("max_size"):
self.max_size = field_options.max_size
@@ -319,7 +324,12 @@ class Field:
elif desc.type == FieldD.TYPE_BYTES:
self.pbtype = 'BYTES'
if self.allocation == 'STATIC':
- self.ctype = self.struct_name + self.name + 't'
+ # Inline STATIC for BYTES is like STATIC for STRING.
+ if self.inline:
+ self.ctype = 'pb_byte_t'
+ self.array_decl += '[%d]' % self.max_size
+ else:
+ self.ctype = self.struct_name + self.name + 't'
self.enc_size = varint_max_size(self.max_size) + self.max_size
elif self.allocation == 'POINTER':
self.ctype = 'pb_bytes_array_t'
@@ -359,7 +369,7 @@ class Field:
def types(self):
'''Return definitions for any special types this field might need.'''
- if self.pbtype == 'BYTES' and self.allocation == 'STATIC':
+ if self.pbtype == 'BYTES' and self.allocation == 'STATIC' and not self.inline:
result = 'typedef PB_BYTES_ARRAY_T(%d) %s;\n' % (self.max_size, self.ctype)
else:
result = ''
@@ -388,7 +398,10 @@ class Field:
if self.pbtype == 'STRING':
inner_init = '""'
elif self.pbtype == 'BYTES':
- inner_init = '{0, {0}}'
+ if self.inline:
+ inner_init = '{0}'
+ else:
+ inner_init = '{0, {0}}'
elif self.pbtype in ('ENUM', 'UENUM'):
inner_init = '(%s)0' % self.ctype
else:
@@ -400,9 +413,15 @@ class Field:
elif self.pbtype == 'BYTES':
data = ['0x%02x' % ord(c) for c in self.default]
if len(data) == 0:
- inner_init = '{0, {0}}'
+ if self.inline:
+ inner_init = '{0}'
+ else:
+ inner_init = '{0, {0}}'
else:
- inner_init = '{%d, {%s}}' % (len(data), ','.join(data))
+ if self.inline:
+ inner_init = '{%s}' % ','.join(data)
+ else:
+ inner_init = '{%d, {%s}}' % (len(data), ','.join(data))
elif self.pbtype in ['FIXED32', 'UINT32']:
inner_init = str(self.default) + 'u'
elif self.pbtype in ['FIXED64', 'UINT64']:
@@ -454,6 +473,8 @@ class Field:
elif self.pbtype == 'BYTES':
if self.allocation != 'STATIC':
return None # Not implemented
+ if self.inline:
+ array_decl = '[%d]' % self.max_size
if declaration_only:
return 'extern const %s %s_default%s;' % (ctype, self.struct_name + self.name, array_decl)
@@ -481,7 +502,7 @@ class Field:
result += '%3d, ' % self.tag
result += '%-8s, ' % self.pbtype
result += '%s, ' % self.rules
- result += '%-8s, ' % self.allocation
+ result += '%-8s, ' % (self.allocation if not self.inline else "INLINE")
result += '%s, ' % ("FIRST" if not prev_field_name else "OTHER")
result += '%s, ' % self.struct_name
result += '%s, ' % self.name
@@ -594,6 +615,7 @@ class ExtensionRange(Field):
self.default = None
self.max_size = 0
self.max_count = 0
+ self.inline = None
def __str__(self):
return ' pb_extension_t *extensions;'
@@ -671,6 +693,7 @@ class OneOf(Field):
self.default = None
self.rules = 'ONEOF'
self.anonymous = False
+ self.inline = None
def add_field(self, field):
if field.allocation == 'CALLBACK':
@@ -1045,7 +1068,10 @@ class ProtoFile:
else:
yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime())
- symbol = make_identifier(headername)
+ if self.fdesc.package:
+ symbol = make_identifier(self.fdesc.package + '_' + headername)
+ else:
+ symbol = make_identifier(headername)
yield '#ifndef PB_%s_INCLUDED\n' % symbol
yield '#define PB_%s_INCLUDED\n' % symbol
try:
diff --git a/generator/proto/nanopb.proto b/generator/proto/nanopb.proto
index 9b2f0fb..8aab19a 100644
--- a/generator/proto/nanopb.proto
+++ b/generator/proto/nanopb.proto
@@ -16,6 +16,7 @@ enum FieldType {
FT_POINTER = 4; // Always generate a dynamically allocated field.
FT_STATIC = 2; // Generate a static field or raise an exception if not possible.
FT_IGNORE = 3; // Ignore the field completely.
+ FT_INLINE = 5; // Always generate an inline array of fixed size.
}
enum IntSize {
diff --git a/generator/proto/nanopb_pb2.py b/generator/proto/nanopb_pb2.py
index 3b86d16..31f9cbc 100644
--- a/generator/proto/nanopb_pb2.py
+++ b/generator/proto/nanopb_pb2.py
@@ -15,7 +15,7 @@ import google.protobuf.descriptor_pb2
DESCRIPTOR = _descriptor.FileDescriptor(
name='nanopb.proto',
package='',
- serialized_pb='\n\x0cnanopb.proto\x1a google/protobuf/descriptor.proto\"\xbc\x02\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12&\n\x08int_size\x18\x07 \x01(\x0e\x32\x08.IntSize:\nIS_DEFAULT\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0bpacked_enum\x18\n \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0cskip_message\x18\x06 \x01(\x08:\x05\x66\x61lse\x12\x18\n\tno_unions\x18\x08 \x01(\x08:\x05\x66\x61lse\x12\r\n\x05msgid\x18\t \x01(\r\x12\x1e\n\x0f\x61nonymous_oneof\x18\x0b \x01(\x08:\x05\x66\x61lse*Z\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03*D\n\x07IntSize\x12\x0e\n\nIS_DEFAULT\x10\x00\x12\x08\n\x04IS_8\x10\x08\x12\t\n\x05IS_16\x10\x10\x12\t\n\x05IS_32\x10 \x12\t\n\x05IS_64\x10@:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB\x1a\n\x18\x66i.kapsi.koti.jpa.nanopb')
+ serialized_pb='\n\x0cnanopb.proto\x1a google/protobuf/descriptor.proto\"\xbc\x02\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12&\n\x08int_size\x18\x07 \x01(\x0e\x32\x08.IntSize:\nIS_DEFAULT\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0bpacked_enum\x18\n \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0cskip_message\x18\x06 \x01(\x08:\x05\x66\x61lse\x12\x18\n\tno_unions\x18\x08 \x01(\x08:\x05\x66\x61lse\x12\r\n\x05msgid\x18\t \x01(\r\x12\x1e\n\x0f\x61nonymous_oneof\x18\x0b \x01(\x08:\x05\x66\x61lse*i\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03\x12\r\n\tFT_INLINE\x10\x05*D\n\x07IntSize\x12\x0e\n\nIS_DEFAULT\x10\x00\x12\x08\n\x04IS_8\x10\x08\x12\t\n\x05IS_16\x10\x10\x12\t\n\x05IS_32\x10 \x12\t\n\x05IS_64\x10@:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB\x1a\n\x18\x66i.kapsi.koti.jpa.nanopb')
_FIELDTYPE = _descriptor.EnumDescriptor(
name='FieldType',
@@ -43,11 +43,15 @@ _FIELDTYPE = _descriptor.EnumDescriptor(
name='FT_IGNORE', index=4, number=3,
options=None,
type=None),
+ _descriptor.EnumValueDescriptor(
+ name='FT_INLINE', index=5, number=5,
+ options=None,
+ type=None),
],
containing_type=None,
options=None,
serialized_start=369,
- serialized_end=459,
+ serialized_end=474,
)
FieldType = enum_type_wrapper.EnumTypeWrapper(_FIELDTYPE)
@@ -80,8 +84,8 @@ _INTSIZE = _descriptor.EnumDescriptor(
],
containing_type=None,
options=None,
- serialized_start=461,
- serialized_end=529,
+ serialized_start=476,
+ serialized_end=544,
)
IntSize = enum_type_wrapper.EnumTypeWrapper(_INTSIZE)
@@ -90,6 +94,7 @@ FT_CALLBACK = 1
FT_POINTER = 4
FT_STATIC = 2
FT_IGNORE = 3
+FT_INLINE = 5
IS_DEFAULT = 0
IS_8 = 8
IS_16 = 16
diff --git a/pb.h b/pb.h
index 114c9c7..4576f79 100644
--- a/pb.h
+++ b/pb.h
@@ -46,7 +46,7 @@
/* Version of the nanopb library. Just in case you want to check it in
* your own program. */
-#define NANOPB_VERSION nanopb-0.3.6-dev
+#define NANOPB_VERSION nanopb-0.3.7-dev
/* Include all the system headers needed by nanopb. You will need the
* definitions of the following:
@@ -170,8 +170,14 @@ typedef uint_least8_t pb_type_t;
* The field contains a pointer to pb_extension_t */
#define PB_LTYPE_EXTENSION 0x08
+/* Byte array with inline, pre-allocated byffer.
+ * data_size is the length of the inline, allocated buffer.
+ * This differs from PB_LTYPE_BYTES by defining the element as
+ * pb_byte_t[data_size] rather than pb_bytes_array_t. */
+#define PB_LTYPE_FIXED_LENGTH_BYTES 0x09
+
/* Number of declared LTYPES */
-#define PB_LTYPES_COUNT 9
+#define PB_LTYPES_COUNT 0x0A
#define PB_LTYPE_MASK 0x0F
/**** Field repetition rules ****/
@@ -415,6 +421,19 @@ struct pb_extension_s {
pb_membersize(st, m[0]), \
pb_arraysize(st, m), ptr}
+#define PB_REQUIRED_INLINE(tag, st, m, fd, ltype, ptr) \
+ {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | PB_LTYPE_FIXED_LENGTH_BYTES, \
+ fd, 0, pb_membersize(st, m), 0, ptr}
+
+/* Optional fields add the delta to the has_ variable. */
+#define PB_OPTIONAL_INLINE(tag, st, m, fd, ltype, ptr) \
+ {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | PB_LTYPE_FIXED_LENGTH_BYTES, \
+ fd, \
+ pb_delta(st, has_ ## m, m), \
+ pb_membersize(st, m), 0, ptr}
+
+/* INLINE does not support REPEATED fields. */
+
/* 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, \
@@ -454,6 +473,8 @@ struct pb_extension_s {
#define PB_OPTEXT_POINTER(tag, st, m, fd, ltype, ptr) \
PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr)
+/* INLINE does not support OPTEXT. */
+
#define PB_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \
PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr)
@@ -485,7 +506,7 @@ struct pb_extension_s {
* FLOAT, INT32, INT64, MESSAGE, SFIXED32, SFIXED64
* SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION
* - Field rules: REQUIRED, OPTIONAL or REPEATED
- * - Allocation: STATIC or CALLBACK
+ * - Allocation: STATIC, INLINE, or CALLBACK
* - Placement: FIRST or OTHER, depending on if this is the first field in structure.
* - Message name
* - Field name
@@ -511,6 +532,8 @@ struct pb_extension_s {
fd, pb_delta(st, which_ ## u, u.m), \
pb_membersize(st, u.m[0]), 0, ptr}
+/* INLINE does not support ONEOF. */
+
#define PB_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
PB_ONEOF_ ## allocation(union_name, tag, message, field, \
PB_DATAOFFSET_ ## placement(message, union_name.field, prevfield), \
diff --git a/pb_decode.c b/pb_decode.c
index 78911e7..7a4e29a 100644
--- a/pb_decode.c
+++ b/pb_decode.c
@@ -65,7 +65,8 @@ static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {
&pb_dec_bytes,
&pb_dec_string,
&pb_dec_submessage,
- NULL /* extensions */
+ NULL, /* extensions */
+ &pb_dec_bytes /* PB_LTYPE_FIXED_LENGTH_BYTES */
};
/*******************************
@@ -1272,6 +1273,12 @@ static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *fie
}
else
{
+ if (PB_LTYPE(field->type) == PB_LTYPE_FIXED_LENGTH_BYTES) {
+ if (size != field->data_size)
+ PB_RETURN_ERROR(stream, "incorrect inline bytes size");
+ return pb_read(stream, (pb_byte_t*)dest, field->data_size);
+ }
+
if (alloc_size > field->data_size)
PB_RETURN_ERROR(stream, "bytes overflow");
bdest = (pb_bytes_array_t*)dest;
diff --git a/pb_encode.c b/pb_encode.c
index 9f91c9d..4685614 100644
--- a/pb_encode.c
+++ b/pb_encode.c
@@ -49,7 +49,8 @@ static const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = {
&pb_enc_bytes,
&pb_enc_string,
&pb_enc_submessage,
- NULL /* extensions */
+ NULL, /* extensions */
+ &pb_enc_bytes /* PB_LTYPE_FIXED_LENGTH_BYTES */
};
/*******************************
@@ -498,6 +499,7 @@ bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t
case PB_LTYPE_BYTES:
case PB_LTYPE_STRING:
case PB_LTYPE_SUBMESSAGE:
+ case PB_LTYPE_FIXED_LENGTH_BYTES:
wiretype = PB_WT_STRING;
break;
@@ -636,11 +638,16 @@ static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *f
static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)
{
- const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)src;
+ const pb_bytes_array_t *bytes = NULL;
+
+ if (PB_LTYPE(field->type) == PB_LTYPE_FIXED_LENGTH_BYTES)
+ return pb_encode_string(stream, (const pb_byte_t*)src, field->data_size);
+
+ bytes = (const pb_bytes_array_t*)src;
if (src == NULL)
{
- /* Threat null pointer as an empty bytes field */
+ /* Treat null pointer as an empty bytes field */
return pb_encode_string(stream, NULL, 0);
}
@@ -664,7 +671,7 @@ static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *fi
if (src == NULL)
{
- size = 0; /* Threat null pointer as an empty string */
+ size = 0; /* Treat null pointer as an empty string */
}
else
{
diff --git a/tests/inline/SConscript b/tests/inline/SConscript
new file mode 100644
index 0000000..34371fd
--- /dev/null
+++ b/tests/inline/SConscript
@@ -0,0 +1,16 @@
+# Test that inlined bytes fields work.
+
+Import("env")
+
+env.NanopbProto("inline")
+env.Object("inline.pb.c")
+
+env.Match(["inline.pb.h", "inline.expected"])
+
+p = env.Program(["inline_unittests.c",
+ "inline.pb.c",
+ "$COMMON/pb_encode.o",
+ "$COMMON/pb_decode.o",
+ "$COMMON/pb_common.o"])
+
+env.RunTest(p)
diff --git a/tests/inline/inline.expected b/tests/inline/inline.expected
new file mode 100644
index 0000000..593e972
--- /dev/null
+++ b/tests/inline/inline.expected
@@ -0,0 +1,3 @@
+pb_byte_t data\[32\];
+bool has_data;
+pb_byte_t data\[64\];
diff --git a/tests/inline/inline.proto b/tests/inline/inline.proto
new file mode 100644
index 0000000..6e511f0
--- /dev/null
+++ b/tests/inline/inline.proto
@@ -0,0 +1,17 @@
+/* Test nanopb option parsing.
+ * options.expected lists the patterns that are searched for in the output.
+ */
+
+syntax = "proto2";
+
+import "nanopb.proto";
+
+message Message1
+{
+ required bytes data = 1 [(nanopb).type = FT_INLINE, (nanopb).max_size = 32];
+}
+
+message Message2
+{
+ optional bytes data = 1 [(nanopb).type = FT_INLINE, (nanopb).max_size = 64];
+}
diff --git a/tests/inline/inline_unittests.c b/tests/inline/inline_unittests.c
new file mode 100644
index 0000000..b5834c7
--- /dev/null
+++ b/tests/inline/inline_unittests.c
@@ -0,0 +1,73 @@
+#include <stdio.h>
+#include <string.h>
+#include <pb_decode.h>
+#include <pb_encode.h>
+#include "unittests.h"
+#include "inline.pb.h"
+
+int main()
+{
+ int status = 0;
+ int i = 0;
+ COMMENT("Test inline byte fields");
+
+ {
+ Message1 msg1 = Message1_init_zero;
+ TEST(sizeof(msg1.data) == 32);
+ }
+
+ {
+ Message1 msg1 = Message1_init_zero;
+ pb_byte_t msg1_buffer[Message1_size];
+ pb_ostream_t ostream = pb_ostream_from_buffer(msg1_buffer, Message1_size);
+ Message1 msg1_deserialized = Message1_init_zero;
+ pb_istream_t istream = pb_istream_from_buffer(msg1_buffer, Message1_size);
+
+ for (i = 0; i < 32; i++) {
+ msg1.data[i] = i;
+ }
+
+ TEST(pb_encode(&ostream, Message1_fields, &msg1));
+ TEST(ostream.bytes_written == Message1_size);
+
+ TEST(pb_decode(&istream, Message1_fields, &msg1_deserialized));
+
+ TEST(istream.bytes_left == 0);
+ TEST(memcmp(&msg1_deserialized, &msg1, sizeof(msg1)) == 0);
+ }
+
+ {
+ Message2 msg2 = {true, {0}};
+ Message2 msg2_no_data = {false, {1}};
+ pb_byte_t msg2_buffer[Message2_size];
+ pb_ostream_t ostream = pb_ostream_from_buffer(msg2_buffer, Message2_size);
+ Message2 msg2_deserialized = Message2_init_zero;
+ pb_istream_t istream = pb_istream_from_buffer(msg2_buffer, Message2_size);
+
+ for (i = 0; i < 64; i++) {
+ msg2.data[i] = i;
+ }
+
+ TEST(pb_encode(&ostream, Message2_fields, &msg2));
+ TEST(ostream.bytes_written == Message2_size);
+
+ TEST(pb_decode(&istream, Message2_fields, &msg2_deserialized));
+
+ TEST(istream.bytes_left == 0);
+ TEST(memcmp(&msg2_deserialized, &msg2, sizeof(msg2)) == 0);
+ TEST(msg2_deserialized.has_data);
+
+ memset(msg2_buffer, 0, sizeof(msg2_buffer));
+ ostream = pb_ostream_from_buffer(msg2_buffer, Message2_size);
+ TEST(pb_encode(&ostream, Message2_fields, &msg2_no_data));
+ istream = pb_istream_from_buffer(msg2_buffer, Message2_size);
+ TEST(pb_decode(&istream, Message2_fields, &msg2_deserialized));
+ TEST(!msg2_deserialized.has_data);
+ TEST(memcmp(&msg2_deserialized, &msg2, sizeof(msg2)) != 0);
+ }
+
+ if (status != 0)
+ fprintf(stdout, "\n\nSome tests FAILED!\n");
+
+ return status;
+}
diff --git a/tests/multiple_files/SConscript b/tests/multiple_files/SConscript
index 1689f48..b1281e1 100644
--- a/tests/multiple_files/SConscript
+++ b/tests/multiple_files/SConscript
@@ -4,10 +4,13 @@ Import("env")
incpath = env.Clone()
incpath.Append(PROTOCPATH = '#multiple_files')
+incpath.Append(CPPPATH = '$BUILD/multiple_files')
incpath.NanopbProto(["multifile1", "multifile1.options"])
incpath.NanopbProto("multifile2")
-test = incpath.Program(["test_multiple_files.c", "multifile1.pb.c", "multifile2.pb.c"])
+incpath.NanopbProto("subdir/multifile2")
+test = incpath.Program(["test_multiple_files.c", "multifile1.pb.c",
+ "multifile2.pb.c", "subdir/multifile2.pb.c"])
env.RunTest(test)
diff --git a/tests/multiple_files/subdir/multifile2.proto b/tests/multiple_files/subdir/multifile2.proto
new file mode 100644
index 0000000..847a929
--- /dev/null
+++ b/tests/multiple_files/subdir/multifile2.proto
@@ -0,0 +1,25 @@
+syntax = "proto2";
+
+package subdir;
+
+import "multifile1.proto";
+
+message Callback2Message {
+ required TestMessage tstmsg = 1;
+ required SubMessage submsg = 2;
+}
+
+message OneofMessage {
+ oneof msgs {
+ StaticMessage tstmsg = 1;
+ }
+}
+
+message Enums {
+ required SignedEnum senum = 1;
+ required UnsignedEnum uenum = 2;
+}
+
+message SubdirMessage {
+ required int32 foo = 1 [default = 15];
+}
diff --git a/tests/multiple_files/test_multiple_files.c b/tests/multiple_files/test_multiple_files.c
index 292b8d7..72718ab 100644
--- a/tests/multiple_files/test_multiple_files.c
+++ b/tests/multiple_files/test_multiple_files.c
@@ -6,6 +6,7 @@
#include <pb_encode.h>
#include "unittests.h"
#include "multifile2.pb.h"
+#include "subdir/multifile2.pb.h"
int main()
{
@@ -17,6 +18,13 @@ int main()
/* Check that enum signedness is detected properly */
TEST(PB_LTYPE(Enums_fields[0].type) == PB_LTYPE_VARINT);
TEST(PB_LTYPE(Enums_fields[1].type) == PB_LTYPE_UVARINT);
-
+
+ /* Test that subdir file is correctly included */
+ {
+ subdir_SubdirMessage foo = subdir_SubdirMessage_init_default;
+ TEST(foo.foo == 15);
+ /* TEST(subdir_OneofMessage_size == 27); */ /* TODO: Issue #172 */
+ }
+
return status;
}