diff options
| author | Trygve Laugstøl <trygvis@inamo.no> | 2018-08-23 17:08:59 +0200 | 
|---|---|---|
| committer | Trygve Laugstøl <trygvis@inamo.no> | 2018-08-23 17:12:21 +0200 | 
| commit | 3061ecca3d0fdfb87dabbf5f63c9e06c2a30f53a (patch) | |
| tree | ab49cc16ed0b853452c5c2ed2d3042416d628986 /thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb | |
| download | iot-sensors-master.tar.gz iot-sensors-master.tar.bz2 iot-sensors-master.tar.xz iot-sensors-master.zip | |
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb')
19 files changed, 6131 insertions, 0 deletions
| diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/LICENSE.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/LICENSE.txt new file mode 100644 index 0000000..d11c9af --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2011 Petteri Aimonen <jpa at nanopb.mail.kapsi.fi> + +This software is provided 'as-is', without any express or  +implied warranty. In no event will the authors be held liable  +for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any  +purpose, including commercial applications, and to alter it and  +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you  +   must not claim that you wrote the original software. If you use  +   this software in a product, an acknowledgment in the product  +   documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and  +   must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source  +   distribution. diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/camel_case_splitter.py b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/camel_case_splitter.py new file mode 100644 index 0000000..4397b66 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/camel_case_splitter.py @@ -0,0 +1,35 @@ +def split_camel_case(input): +    def remove_camel_case(camel_case_input): +        no_camel_case = "" +        if len(camel_case_input) <= 0: +            return "" +        no_camel_case += camel_case_input[0].lower() +        for c in camel_case_input[1:]: +            if c.isupper(): +                no_camel_case += "_" + c.lower() +            else: +                no_camel_case += c +        return no_camel_case + +    underscore_split = input.split("_") +    retval = "" +    for i in underscore_split: +        if is_camel_case_name(i): +            retval += remove_camel_case(i) + "_" +        else: +            retval += i + "_" + +    return retval[:-1].replace("__", "_") + + +def is_camel_case_name(input): +    if '_' in input: +        return False + +    if input.islower(): +        return False + +    if input.isupper(): +        return False + +    return True
\ No newline at end of file diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/nanopb_generator.py b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/nanopb_generator.py new file mode 100644 index 0000000..aec5123 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/nanopb_generator.py @@ -0,0 +1,1604 @@ +#!/usr/bin/env python + +from __future__ import unicode_literals + +'''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.''' +nanopb_version = "nanopb-0.3.6-dev" + +import sys +import re +from functools import reduce + +try: +    # Add some dummy imports to keep packaging tools happy. +    import google, distutils.util # bbfreeze seems to need these +    import pkg_resources # pyinstaller / protobuf 2.5 seem to need these +except: +    # Don't care, we will error out later if it is actually important. +    pass + +try: +    import google.protobuf.text_format as text_format +    import google.protobuf.descriptor_pb2 as descriptor +except: +    sys.stderr.write(''' +         ************************************************************* +         *** Could not import the Google protobuf Python libraries *** +         *** Try installing package 'python-protobuf' or similar.  *** +         ************************************************************* +    ''' + '\n') +    raise + +try: +    import proto.nanopb_pb2 as nanopb_pb2 +    import proto.plugin_pb2 as plugin_pb2 +except: +    sys.stderr.write(''' +         ******************************************************************** +         *** Failed to import the protocol definitions for generator.     *** +         *** You have to run 'make' in the nanopb/generator/proto folder. *** +         ******************************************************************** +    ''' + '\n') +    raise + +# --------------------------------------------------------------------------- +#                     Generation of single fields +# --------------------------------------------------------------------------- + +import time +import os.path + +# Values are tuple (c type, pb type, encoded size, int_size_allowed) +FieldD = descriptor.FieldDescriptorProto +datatypes = { +    FieldD.TYPE_BOOL:       ('bool',     'BOOL',        1,  False), +    FieldD.TYPE_DOUBLE:     ('double',   'DOUBLE',      8,  False), +    FieldD.TYPE_FIXED32:    ('uint32_t', 'FIXED32',     4,  False), +    FieldD.TYPE_FIXED64:    ('uint64_t', 'FIXED64',     8,  False), +    FieldD.TYPE_FLOAT:      ('float',    'FLOAT',       4,  False), +    FieldD.TYPE_INT32:      ('int32_t',  'INT32',      10,  True), +    FieldD.TYPE_INT64:      ('int64_t',  'INT64',      10,  True), +    FieldD.TYPE_SFIXED32:   ('int32_t',  'SFIXED32',    4,  False), +    FieldD.TYPE_SFIXED64:   ('int64_t',  'SFIXED64',    8,  False), +    FieldD.TYPE_SINT32:     ('int32_t',  'SINT32',      5,  True), +    FieldD.TYPE_SINT64:     ('int64_t',  'SINT64',     10,  True), +    FieldD.TYPE_UINT32:     ('uint32_t', 'UINT32',      5,  True), +    FieldD.TYPE_UINT64:     ('uint64_t', 'UINT64',     10,  True) +} + +# Integer size overrides (from .proto settings) +intsizes = { +    nanopb_pb2.IS_8:     'int8_t', +    nanopb_pb2.IS_16:    'int16_t', +    nanopb_pb2.IS_32:    'int32_t', +    nanopb_pb2.IS_64:    'int64_t', +} + +# String types (for python 2 / python 3 compatibility) +try: +    strtypes = (unicode, str) +except NameError: +    strtypes = (str, ) + +from camel_case_splitter import split_camel_case + +class Names: +    '''Keeps a set of nested names and formats them to C identifier.''' +    def __init__(self, parts = ()): +        if isinstance(parts, Names): +            parts = parts.parts +        self.parts = tuple(parts) + +    def __str__(self): +        name_str = '_'.join(self.parts) +        return split_camel_case(name_str) + +    def __add__(self, other): +        if isinstance(other, strtypes): +            return Names(self.parts + (other,)) +        elif isinstance(other, tuple): +            return Names(self.parts + other) +        else: +            raise ValueError("Name parts should be of type str") + +    def __eq__(self, other): +        return isinstance(other, Names) and self.parts == other.parts + +def names_from_type_name(type_name): +    '''Parse Names() from FieldDescriptorProto type_name''' +    if type_name[0] != '.': +        raise NotImplementedError("Lookup of non-absolute type names is not supported") +    return Names(type_name[1:].split('.')) + +def varint_max_size(max_value): +    '''Returns the maximum number of bytes a varint can take when encoded.''' +    if max_value < 0: +        max_value = 2**64 - max_value +    for i in range(1, 11): +        if (max_value >> (i * 7)) == 0: +            return i +    raise ValueError("Value too large for varint: " + str(max_value)) + +assert varint_max_size(-1) == 10 +assert varint_max_size(0) == 1 +assert varint_max_size(127) == 1 +assert varint_max_size(128) == 2 + +class EncodedSize: +    '''Class used to represent the encoded size of a field or a message. +    Consists of a combination of symbolic sizes and integer sizes.''' +    def __init__(self, value = 0, symbols = []): +        if isinstance(value, EncodedSize): +            self.value = value.value +            self.symbols = value.symbols +        elif isinstance(value, strtypes + (Names,)): +            self.symbols = [str(value)] +            self.value = 0 +        else: +            self.value = value +            self.symbols = symbols + +    def __add__(self, other): +        if isinstance(other, int): +            return EncodedSize(self.value + other, self.symbols) +        elif isinstance(other, strtypes + (Names,)): +            return EncodedSize(self.value, self.symbols + [str(other)]) +        elif isinstance(other, EncodedSize): +            return EncodedSize(self.value + other.value, self.symbols + other.symbols) +        else: +            raise ValueError("Cannot add size: " + repr(other)) + +    def __mul__(self, other): +        if isinstance(other, int): +            return EncodedSize(self.value * other, [str(other) + '*' + s for s in self.symbols]) +        else: +            raise ValueError("Cannot multiply size: " + repr(other)) + +    def __str__(self): +        if not self.symbols: +            return str(self.value) +        else: +            return '(' + str(self.value) + ' + ' + ' + '.join(self.symbols) + ')' + +    def upperlimit(self): +        if not self.symbols: +            return self.value +        else: +            return 2**32 - 1 + +class Enum: +    def __init__(self, names, desc, enum_options): +        '''desc is EnumDescriptorProto''' + +        self.options = enum_options +        self.names = names + desc.name +        self.names_t = self.names + "_t" +        self.names_upper = str(self.names).upper() + +        if enum_options.long_names: +            self.values = [(str(self.names + x.name).upper(), x.number) for x in desc.value] +        else: +            self.values = [(str(names + x.name).upper(), x.number) for x in desc.value] + +        self.value_longnames = [str(self.names + x.name).upper() for x in desc.value] +        self.packed = enum_options.packed_enum + +    def has_negative(self): +        for n, v in self.values: +            if v < 0: +                return True +        return False + +    def encoded_size(self): +        return max([varint_max_size(v) for n,v in self.values]) + +    def __str__(self): +        # result = 'typedef enum _%s {\n' % self.names_t +        result = 'typedef enum\n{\n' +        result += ',\n'.join(["    %s = %d" % x for x in self.values]) +        result += '\n}' + +        if self.packed: +            result += ' pb_packed' + +        result += ' %s;' % self.names_t + +        result += '\n#define %s_MIN %s' % (self.names_upper, self.values[0][0]) +        result += '\n#define %s_MAX %s' % (self.names_upper, self.values[-1][0]) +        result += '\n#define %s_ARRAYSIZE ((%s)(%s+1))' % (self.names_upper, str(self.names_t), self.values[-1][0]) + +        if not self.options.long_names: +            # Define the long names always so that enum value references +            # from other files work properly. +            for i, x in enumerate(self.values): +                result += '\n#define %s %s' % (self.value_longnames[i], x[0]) + +        return result + +class FieldMaxSize: +    def __init__(self, worst = 0, checks = [], field_name = 'undefined'): +        if isinstance(worst, list): +            self.worst = max(i for i in worst if i is not None) +        else: +            self.worst = worst + +        self.worst_field = field_name +        self.checks = checks + +    def extend(self, extend, field_name = None): +        self.worst = max(self.worst, extend.worst) + +        if self.worst == extend.worst: +            self.worst_field = extend.worst_field + +        self.checks.extend(extend.checks) + +class Field: +    def __init__(self, struct_name, desc, field_options): +        '''desc is FieldDescriptorProto''' +        self.tag = desc.number +        self.struct_name = struct_name +        self.union_name = None +        self.name = desc.name +        self.default = None +        self.max_size = None +        self.max_count = None +        self.array_decl = "" +        self.enc_size = None +        self.ctype = None +        self.ctype_t = None + +        # Parse field options +        if field_options.HasField("max_size"): +            self.max_size = field_options.max_size + +        if field_options.HasField("max_count"): +            self.max_count = field_options.max_count + +        if desc.HasField('default_value'): +            self.default = desc.default_value + +        # Check field rules, i.e. required/optional/repeated. +        can_be_static = True +        if desc.label == FieldD.LABEL_REQUIRED: +            self.rules = 'REQUIRED' +        elif desc.label == FieldD.LABEL_OPTIONAL: +            self.rules = 'OPTIONAL' +        elif desc.label == FieldD.LABEL_REPEATED: +            self.rules = 'REPEATED' +            if self.max_count is None: +                can_be_static = False +            else: +                self.array_decl = '[%d]' % self.max_count +        else: +            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. +        if desc.type in datatypes: +            self.ctype, self.pbtype, self.enc_size, isa = datatypes[desc.type] +            self.ctype_t = self.ctype + +            # Override the field size if user wants to use smaller integers +            if isa and field_options.int_size != nanopb_pb2.IS_DEFAULT: +                self.ctype = intsizes[field_options.int_size] +                self.ctype_t = self.ctype +                if desc.type == FieldD.TYPE_UINT32 or desc.type == FieldD.TYPE_UINT64: +                    self.ctype = 'u' + self.ctype; +                    self.ctype_t = self.ctype +        elif desc.type == FieldD.TYPE_ENUM: +            self.pbtype = 'ENUM' +            self.ctype = names_from_type_name(desc.type_name) +            self.ctype_t = self.ctype + "_t" +            if self.default is not None: +                self.default = self.ctype + self.default +            self.enc_size = None # Needs to be filled in when enum values are known +        elif desc.type == FieldD.TYPE_STRING: +            self.pbtype = 'STRING' +            self.ctype = 'char' +            self.ctype_t = self.ctype +            if self.allocation == 'STATIC': +                self.ctype = 'char' +                self.array_decl += '[%d]' % self.max_size +                self.enc_size = varint_max_size(self.max_size) + self.max_size +        elif desc.type == FieldD.TYPE_BYTES: +            self.pbtype = 'BYTES' +            if self.allocation == 'STATIC': +                self.ctype = self.struct_name + self.name + 't' +                self.ctype_t = self.ctype +                self.enc_size = varint_max_size(self.max_size) + self.max_size +            elif self.allocation == 'POINTER': +                self.ctype = 'pb_bytes_array_t' +                self.ctype_t = self.ctype +        elif desc.type == FieldD.TYPE_MESSAGE: +            self.pbtype = 'MESSAGE' +            self.ctype = self.submsgname = names_from_type_name(desc.type_name) +            self.ctype_t = self.ctype + "_t" +            self.enc_size = None # Needs to be filled in after the message type is available +        else: +            raise NotImplementedError(desc.type) + +    def __lt__(self, other): +        return self.tag < other.tag + +    def __str__(self): +        result = '' +        if self.allocation == 'POINTER': +            if self.rules == 'REPEATED': +                result += '    pb_size_t ' + self.name + '_count;\n' + +            if self.pbtype == 'MESSAGE': +                # Use struct definition, so recursive submessages are possible +                result += '    struct _%s *%s;' % (self.ctype_t, self.name) +            elif self.rules == 'REPEATED' and self.pbtype in ['STRING', 'BYTES']: +                # String/bytes arrays need to be defined as pointers to pointers +                result += '    %s **%s;' % (self.ctype_t, self.name) +            else: +                result += '    %s *%s;' % (self.ctype_t, self.name) +        elif self.allocation == 'CALLBACK': +            result += '    pb_callback_t %s;' % self.name +        else: +            if self.rules == 'OPTIONAL' and self.allocation == 'STATIC': +                result += '    bool has_' + self.name + ';\n' +            elif self.rules == 'REPEATED' and self.allocation == 'STATIC': +                result += '    pb_size_t ' + self.name + '_count;\n' +            result += '    %s %s%s;' % (self.ctype_t, self.name, self.array_decl) +        return result + +    def types(self): +        '''Return definitions for any special types this field might need.''' +        if self.pbtype == 'BYTES' and self.allocation == 'STATIC': +            result = 'typedef PB_BYTES_ARRAY_T(%d) %s;\n' % (self.max_size, self.ctype) +        else: +            result = '' +        return result + +    def get_dependencies(self): +        '''Get list of type names used by this field.''' +        if self.allocation == 'STATIC': +            return [str(self.ctype)] +        else: +            return [] + +    def get_initializer(self, null_init, inner_init_only = False): +        '''Return literal expression for this field's default value. +        null_init: If True, initialize to a 0 value instead of default from .proto +        inner_init_only: If True, exclude initialization for any count/has fields +        ''' + +        inner_init = None +        if self.pbtype == 'MESSAGE': +            if null_init: +                inner_init = '%s_init_zero' % self.ctype +            else: +                inner_init = '%s_init_default' % self.ctype +        elif self.default is None or null_init: +            if self.pbtype == 'STRING': +                inner_init = '""' +            elif self.pbtype == 'BYTES': +                inner_init = '{0, {0}}' +            elif self.pbtype in ('ENUM', 'UENUM'): +                inner_init = '(%s)0' % self.ctype_t +            else: +                inner_init = '0' +        else: +            if self.pbtype == 'STRING': +                inner_init = self.default.replace('"', '\\"') +                inner_init = '"' + inner_init + '"' +            elif self.pbtype == 'BYTES': +                data = ['0x%02x' % ord(c) for c in self.default] +                if len(data) == 0: +                    inner_init = '{0, {0}}' +                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']: +                inner_init = str(self.default) + 'ull' +            elif self.pbtype in ['SFIXED64', 'INT64']: +                inner_init = str(self.default) + 'll' +            elif self.pbtype in ('ENUM', 'UENUM'): +                inner_init = str(self.default).upper() +            else: +                inner_init = str(self.default) + +        if inner_init_only: +            return inner_init + +        outer_init = None +        if self.allocation == 'STATIC': +            if self.rules == 'REPEATED': +                outer_init = '0, {' +                outer_init += ', '.join([inner_init] * self.max_count) +                outer_init += '}' +            elif self.rules == 'OPTIONAL': +                outer_init = 'false, ' + inner_init +            else: +                outer_init = inner_init +        elif self.allocation == 'POINTER': +            if self.rules == 'REPEATED': +                outer_init = '0, NULL' +            else: +                outer_init = 'NULL' +        elif self.allocation == 'CALLBACK': +            if self.pbtype == 'EXTENSION': +                outer_init = 'NULL' +            else: +                outer_init = '{{NULL}, NULL}' + +        return outer_init + +    def default_decl(self, declaration_only = False): +        '''Return definition for this field's default value.''' +        if self.default is None: +            return None + +        ctype = self.ctype_t +        default = self.get_initializer(False, True) +        array_decl = '' + +        if self.pbtype == 'STRING': +            if self.allocation != 'STATIC': +                return None # Not implemented +            array_decl = '[%d]' % self.max_size +        elif self.pbtype == 'BYTES': +            if self.allocation != 'STATIC': +                return None # Not implemented + +        if declaration_only: +            return 'extern const %s %s_default%s;' % (ctype, self.struct_name + self.name, array_decl) +        else: +            return 'const %s %s_default%s = %s;' % (ctype, self.struct_name + self.name, array_decl, default) + +    def tags(self): +        '''Return the #define for the tag number of this field.''' +        identifier = ('%s_%s_tag' % (self.struct_name, self.name)).upper() +        return '#define %-40s %d\n' % (identifier, self.tag) + +    def pb_field_t(self, prev_field_name): +        '''Return the pb_field_t initializer to use in the constant array. +        prev_field_name is the name of the previous field or None. +        ''' + +        if self.rules == 'ONEOF': +            if self.anonymous: +                result = '    PB_ANONYMOUS_ONEOF_FIELD(%s, ' % self.union_name +            else: +                result = '    PB_ONEOF_FIELD(%s, ' % self.union_name +        else: +            result = '    PB_FIELD(' + +        result += '%3d, ' % self.tag +        result += '%-8s, ' % self.pbtype +        result += '%s, ' % self.rules +        result += '%-8s, ' % self.allocation +        result += '%s, ' % ("FIRST" if not prev_field_name else "OTHER") +        result += '%s, ' % (str(self.struct_name) + "_t") +        result += '%s, ' % self.name +        result += '%s, ' % (prev_field_name or self.name) + +        if self.pbtype == 'MESSAGE': +            result += '&%s_fields)' % str(self.submsgname) +        elif self.default is None: +            result += '0)' +        elif self.pbtype in ['BYTES', 'STRING'] and self.allocation != 'STATIC': +            result += '0)' # Arbitrary size default values not implemented +        elif self.rules == 'OPTEXT': +            result += '0)' # Default value for extensions is not implemented +        else: +            result += '&%s_default)' % (self.struct_name + self.name) + +        return result + +    def get_last_field_name(self): +        return self.name + +    def largest_field_value(self): +        '''Determine if this field needs 16bit or 32bit pb_field_t structure to compile properly. +        Returns numeric value or a C-expression for assert.''' +        check = [] +        if self.pbtype == 'MESSAGE': +            if self.rules == 'REPEATED' and self.allocation == 'STATIC': +                check.append('pb_membersize(%s, %s[0])' % (self.struct_name+"_t", self.name)) +            elif self.rules == 'ONEOF': +                if self.anonymous: +                    check.append('pb_membersize(%s, %s)' % (self.struct_name+"_t", self.name)) +                else: +                    check.append('pb_membersize(%s, %s.%s)' % (self.struct_name+"_t", self.union_name, self.name)) +            else: +                check.append('pb_membersize(%s, %s)' % (self.struct_name+"_t", self.name)) + +        return FieldMaxSize([self.tag, self.max_size, self.max_count], +                            check, +                            ('%s.%s' % (self.struct_name, self.name))) + +    def encoded_size(self, dependencies): +        '''Return the maximum size that this field can take when encoded, +        including the field tag. If the size cannot be determined, returns +        None.''' + +        if self.allocation != 'STATIC': +            return None + +        if self.pbtype == 'MESSAGE': +            encsize = None +            if str(self.submsgname) in dependencies: +                submsg = dependencies[str(self.submsgname)] +                encsize = submsg.encoded_size(dependencies) +                if encsize is not None: +                    # Include submessage length prefix +                    encsize += varint_max_size(encsize.upperlimit()) + +            if encsize is None: +                # Submessage or its size cannot be found. +                # This can occur if submessage is defined in different +                # file, and it or its .options could not be found. +                # Instead of direct numeric value, reference the size that +                # has been #defined in the other file. +                encsize = EncodedSize(self.submsgname + 'size') + +                # We will have to make a conservative assumption on the length +                # prefix size, though. +                encsize += 5 + +        elif self.pbtype in ['ENUM', 'UENUM']: +            if str(self.ctype) in dependencies: +                enumtype = dependencies[str(self.ctype)] +                encsize = enumtype.encoded_size() +            else: +                # Conservative assumption +                encsize = 10 + +        elif self.enc_size is None: +            raise RuntimeError("Could not determine encoded size for %s.%s" +                               % (self.struct_name, self.name)) +        else: +            encsize = EncodedSize(self.enc_size) + +        encsize += varint_max_size(self.tag << 3) # Tag + wire type + +        if self.rules == 'REPEATED': +            # Decoders must be always able to handle unpacked arrays. +            # Therefore we have to reserve space for it, even though +            # we emit packed arrays ourselves. +            encsize *= self.max_count + +        return encsize + + +class ExtensionRange(Field): +    def __init__(self, struct_name, range_start, field_options): +        '''Implements a special pb_extension_t* field in an extensible message +        structure. The range_start signifies the index at which the extensions +        start. Not necessarily all tags above this are extensions, it is merely +        a speed optimization. +        ''' +        self.tag = range_start +        self.struct_name = struct_name +        self.name = 'extensions' +        self.pbtype = 'EXTENSION' +        self.rules = 'OPTIONAL' +        self.allocation = 'CALLBACK' +        self.ctype = 'pb_extension_t' +        self.array_decl = '' +        self.default = None +        self.max_size = 0 +        self.max_count = 0 + +    def __str__(self): +        return '    pb_extension_t *extensions;' + +    def types(self): +        return '' + +    def tags(self): +        return '' + +    def encoded_size(self, dependencies): +        # We exclude extensions from the count, because they cannot be known +        # until runtime. Other option would be to return None here, but this +        # way the value remains useful if extensions are not used. +        return EncodedSize(0) + +class ExtensionField(Field): +    def __init__(self, struct_name, desc, field_options): +        self.fullname = struct_name + desc.name +        self.extendee_name = names_from_type_name(desc.extendee) +        Field.__init__(self, self.fullname + 'struct', desc, field_options) + +        if self.rules != 'OPTIONAL': +            self.skip = True +        else: +            self.skip = False +            self.rules = 'OPTEXT' + +    def tags(self): +        '''Return the #define for the tag number of this field.''' +        identifier = ('%s_tag' % self.fullname).upper() +        return '#define %-40s %d\n' % (identifier, self.tag) + +    def extension_decl(self): +        '''Declaration of the extension type in the .pb.h file''' +        if self.skip: +            msg = '/* Extension field %s was skipped because only "optional"\n' % self.fullname +            msg +='   type of extension fields is currently supported. */\n' +            return msg + +        return ('extern const pb_extension_type_t %s; /* field type: %s */\n' % +            (self.fullname, str(self).strip())) + +    def extension_def(self): +        '''Definition of the extension type in the .pb.c file''' + +        if self.skip: +            return '' + +        result  = 'typedef struct {\n' +        result += str(self) +        result += '\n} %s_t;\n\n' % self.struct_name +        result += ('static const pb_field_t %s_field = \n  %s;\n\n' % +                    (self.fullname, self.pb_field_t(None))) +        result += 'const pb_extension_type_t %s = {\n' % self.fullname +        result += '    NULL,\n' +        result += '    NULL,\n' +        result += '    &%s_field\n' % self.fullname +        result += '};\n' +        return result + + +# --------------------------------------------------------------------------- +#                   Generation of oneofs (unions) +# --------------------------------------------------------------------------- + +class OneOf(Field): +    def __init__(self, struct_name, oneof_desc): +        self.struct_name = struct_name +        self.name = oneof_desc.name +        self.ctype = 'union' +        self.pbtype = 'oneof' +        self.fields = [] +        self.allocation = 'ONEOF' +        self.default = None +        self.rules = 'ONEOF' +        self.anonymous = False + +    def add_field(self, field): +        if field.allocation == 'CALLBACK': +            raise Exception("Callback fields inside of oneof are not supported" +                            + " (field %s)" % field.name) + +        field.union_name = self.name +        field.rules = 'ONEOF' +        field.anonymous = self.anonymous +        self.fields.append(field) +        self.fields.sort(key = lambda f: f.tag) + +        # Sort by the lowest tag number inside union +        self.tag = min([f.tag for f in self.fields]) + +    def __str__(self): +        result = '' +        if self.fields: +            result += '    pb_size_t which_' + self.name + ";\n" +            result += '    union {\n' +            for f in self.fields: +                result += '    ' + str(f).replace('\n', '\n    ') + '\n' +            if self.anonymous: +                result += '    };' +            else: +                result += '    } ' + self.name + ';' +        return result + +    def types(self): +        return ''.join([f.types() for f in self.fields]) + +    def get_dependencies(self): +        deps = [] +        for f in self.fields: +            deps += f.get_dependencies() +        return deps + +    def get_initializer(self, null_init): +        return '0, {' + self.fields[0].get_initializer(null_init) + '}' + +    def default_decl(self, declaration_only = False): +        return None + +    def tags(self): +        return ''.join([f.tags() for f in self.fields]) + +    def pb_field_t(self, prev_field_name): +        result = ',\n'.join([f.pb_field_t(prev_field_name) for f in self.fields]) +        return result + +    def get_last_field_name(self): +        if self.anonymous: +            return self.fields[-1].name +        else: +            return self.name + '.' + self.fields[-1].name + +    def largest_field_value(self): +        largest = FieldMaxSize() +        for f in self.fields: +            largest.extend(f.largest_field_value()) +        return largest + +    def encoded_size(self, dependencies): +        '''Returns the size of the largest oneof field.''' +        largest = EncodedSize(0) +        for f in self.fields: +            size = EncodedSize(f.encoded_size(dependencies)) +            if size.value is None: +                return None +            elif size.symbols: +                return None # Cannot resolve maximum of symbols +            elif size.value > largest.value: +                largest = size + +        return largest + +# --------------------------------------------------------------------------- +#                   Generation of messages (structures) +# --------------------------------------------------------------------------- + + +class Message: +    def __init__(self, names, desc, message_options): +        self.name = names +        self.name_t = self.name + "_t" +        self.fields = [] +        self.oneofs = {} +        no_unions = [] + +        if message_options.msgid: +            self.msgid = message_options.msgid + +        if hasattr(desc, 'oneof_decl'): +            for i, f in enumerate(desc.oneof_decl): +                oneof_options = get_nanopb_suboptions(desc, message_options, self.name + f.name) +                if oneof_options.no_unions: +                    no_unions.append(i) # No union, but add fields normally +                elif oneof_options.type == nanopb_pb2.FT_IGNORE: +                    pass # No union and skip fields also +                else: +                    oneof = OneOf(self.name, f) +                    if oneof_options.anonymous_oneof: +                        oneof.anonymous = True +                    self.oneofs[i] = oneof +                    self.fields.append(oneof) + +        for f in desc.field: +            field_options = get_nanopb_suboptions(f, message_options, self.name + f.name) +            if field_options.type == nanopb_pb2.FT_IGNORE: +                continue + +            field = Field(self.name, f, field_options) +            if (hasattr(f, 'oneof_index') and +                f.HasField('oneof_index') and +                f.oneof_index not in no_unions): +                if f.oneof_index in self.oneofs: +                    self.oneofs[f.oneof_index].add_field(field) +            else: +                self.fields.append(field) + +        if len(desc.extension_range) > 0: +            field_options = get_nanopb_suboptions(desc, message_options, self.name + 'extensions') +            range_start = min([r.start for r in desc.extension_range]) +            if field_options.type != nanopb_pb2.FT_IGNORE: +                self.fields.append(ExtensionRange(self.name, range_start, field_options)) + +        self.packed = message_options.packed_struct +        self.ordered_fields = self.fields[:] +        self.ordered_fields.sort() + +    def get_dependencies(self): +        '''Get list of type names that this structure refers to.''' +        deps = [] +        for f in self.fields: +            deps += f.get_dependencies() +        return deps + +    def __str__(self): +        # result = 'typedef struct _%s {\n' % self.name_t +        result = 'typedef struct {\n' + +        if not self.ordered_fields: +            # Empty structs are not allowed in C standard. +            # Therefore add a dummy field if an empty message occurs. +            result += '    char dummy_field;' +        result += '\n'.join([str(f) for f in self.ordered_fields]) +        result += '\n/* @@protoc_insertion_point(struct:%s) */' % self.name_t +        result += '\n}' + +        if self.packed: +            result += ' pb_packed' + +        result += ' %s;' % self.name_t + +        if self.packed: +            result = 'PB_PACKED_STRUCT_START\n' + result +            result += '\nPB_PACKED_STRUCT_END' + +        return result + +    def types(self): +        return ''.join([f.types() for f in self.fields]) + +    def get_initializer(self, null_init): +        if not self.ordered_fields: +            return '{0}' + +        parts = [] +        for field in self.ordered_fields: +            to_append = '' +            for i in field.get_initializer(null_init).split(', '): +                if 'init_default' in i or 'init_zero' in i: +                    to_append += i.upper() +                else: +                    to_append += i +                to_append += ", " + +            to_append = to_append[:-2] + +            parts.append(to_append) +        return '{' + ', '.join(parts) + '}' + +    def default_decl(self, declaration_only = False): +        result = "" +        for field in self.fields: +            default = field.default_decl(declaration_only) +            if default is not None: +                result += default + '\n' +        return result + +    def count_required_fields(self): +        '''Returns number of required fields inside this message''' +        count = 0 +        for f in self.fields: +            if not isinstance(f, OneOf): +                if f.rules == 'REQUIRED': +                    count += 1 +        return count + +    def count_all_fields(self): +        count = 0 +        for f in self.fields: +            if isinstance(f, OneOf): +                count += len(f.fields) +            else: +                count += 1 +        return count + +    def fields_declaration(self): +        result = 'extern const pb_field_t %s_fields[%d];' % (self.name, self.count_all_fields() + 1) +        return result + +    def fields_definition(self): +        result = 'const pb_field_t %s_fields[%d] = {\n' % (self.name, self.count_all_fields() + 1) + +        prev = None +        for field in self.ordered_fields: +            result += field.pb_field_t(prev) +            result += ',\n' +            prev = field.get_last_field_name() + +        result += '    PB_LAST_FIELD\n};' +        return result + +    def encoded_size(self, dependencies): +        '''Return the maximum size that this message can take when encoded. +        If the size cannot be determined, returns None. +        ''' +        size = EncodedSize(0) +        for field in self.fields: +            fsize = field.encoded_size(dependencies) +            if fsize is None: +                return None +            size += fsize + +        return size + + +# --------------------------------------------------------------------------- +#                    Processing of entire .proto files +# --------------------------------------------------------------------------- + +def iterate_messages(desc, names = Names()): +    '''Recursively find all messages. For each, yield name, DescriptorProto.''' +    if hasattr(desc, 'message_type'): +        submsgs = desc.message_type +    else: +        submsgs = desc.nested_type + +    for submsg in submsgs: +        sub_names = names + submsg.name +        yield sub_names, submsg + +        for x in iterate_messages(submsg, sub_names): +            yield x + +def iterate_extensions(desc, names = Names()): +    '''Recursively find all extensions. +    For each, yield name, FieldDescriptorProto. +    ''' +    for extension in desc.extension: +        yield names, extension + +    for subname, subdesc in iterate_messages(desc, names): +        for extension in subdesc.extension: +            yield subname, extension + +def toposort2(data): +    '''Topological sort. +    From http://code.activestate.com/recipes/577413-topological-sort/ +    This function is under the MIT license. +    ''' +    for k, v in list(data.items()): +        v.discard(k) # Ignore self dependencies +    extra_items_in_deps = reduce(set.union, list(data.values()), set()) - set(data.keys()) +    data.update(dict([(item, set()) for item in extra_items_in_deps])) +    while True: +        ordered = set(item for item,dep in list(data.items()) if not dep) +        if not ordered: +            break +        for item in sorted(ordered): +            yield item +        data = dict([(item, (dep - ordered)) for item,dep in list(data.items()) +                if item not in ordered]) +    assert not data, "A cyclic dependency exists amongst %r" % data + +def sort_dependencies(messages): +    '''Sort a list of Messages based on dependencies.''' +    dependencies = {} +    message_by_name = {} +    for message in messages: +        dependencies[str(message.name)] = set(message.get_dependencies()) +        message_by_name[str(message.name)] = message + +    for msgname in toposort2(dependencies): +        if msgname in message_by_name: +            yield message_by_name[msgname] + +def make_identifier(headername): +    '''Make #ifndef identifier that contains uppercase A-Z and digits 0-9''' +    result = "" +    for c in headername.upper(): +        if c.isalnum(): +            result += c +        else: +            result += '_' +    return result + +class ProtoFile: +    def __init__(self, fdesc, file_options): +        '''Takes a FileDescriptorProto and parses it.''' +        self.fdesc = fdesc +        self.file_options = file_options +        self.dependencies = {} +        self.parse() + +        # Some of types used in this file probably come from the file itself. +        # Thus it has implicit dependency on itself. +        self.add_dependency(self) + +    def parse(self): +        self.enums = [] +        self.messages = [] +        self.extensions = [] + +        if self.fdesc.package: +            base_name = Names(self.fdesc.package.split('.')) +        else: +            base_name = Names() + +        for enum in self.fdesc.enum_type: +            enum_options = get_nanopb_suboptions(enum, self.file_options, base_name + enum.name) +            self.enums.append(Enum(base_name, enum, enum_options)) + +        for names, message in iterate_messages(self.fdesc, base_name): +            message_options = get_nanopb_suboptions(message, self.file_options, names) + +            if message_options.skip_message: +                continue + +            self.messages.append(Message(names, message, message_options)) +            for enum in message.enum_type: +                enum_options = get_nanopb_suboptions(enum, message_options, names + enum.name) +                self.enums.append(Enum(names, enum, enum_options)) + +        for names, extension in iterate_extensions(self.fdesc, base_name): +            field_options = get_nanopb_suboptions(extension, self.file_options, names + extension.name) +            if field_options.type != nanopb_pb2.FT_IGNORE: +                self.extensions.append(ExtensionField(names, extension, field_options)) + +    def add_dependency(self, other): +        for enum in other.enums: +            self.dependencies[str(enum.names)] = enum + +        for msg in other.messages: +            self.dependencies[str(msg.name)] = msg + +        # Fix field default values where enum short names are used. +        for enum in other.enums: +            if not enum.options.long_names: +                for message in self.messages: +                    for field in message.fields: +                        if field.default in enum.value_longnames: +                            idx = enum.value_longnames.index(field.default) +                            field.default = enum.values[idx][0] + +        # Fix field data types where enums have negative values. +        for enum in other.enums: +            if not enum.has_negative(): +                for message in self.messages: +                    for field in message.fields: +                        if field.pbtype == 'ENUM' and field.ctype == enum.names: +                            field.pbtype = 'UENUM' + +    def generate_header(self, includes, headername, options): +        '''Generate content for a header file. +        Generates strings, which should be concatenated and stored to file. +        ''' + +        yield '/* Automatically generated nanopb header */\n' +        if options.notimestamp: +            yield '/* Generated by %s */\n\n' % (nanopb_version) +        else: +            yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime()) + +        symbol = make_identifier(headername) +        yield '#ifndef PB_%s_INCLUDED\n' % symbol +        yield '#define PB_%s_INCLUDED\n' % symbol +        try: +            yield options.libformat % ('pb.h') +        except TypeError: +            # no %s specified - use whatever was passed in as options.libformat +            yield options.libformat +        yield '\n' + +        for incfile in includes: +            noext = os.path.splitext(incfile)[0] +            yield options.genformat % (noext + options.extension + '.h') +            yield '\n' + +        yield '/* @@protoc_insertion_point(includes) */\n' + +        yield '#if PB_PROTO_HEADER_VERSION != 30\n' +        yield '#error Regenerate this file with the current version of nanopb generator.\n' +        yield '#endif\n' +        yield '\n' + +        yield '#ifdef __cplusplus\n' +        yield 'extern "C" {\n' +        yield '#endif\n\n' + +        if self.enums: +            yield '/* Enum definitions */\n' +            for enum in self.enums: +                yield str(enum) + '\n\n' + +        if self.messages: +            yield '/* Struct definitions */\n' +            for msg in sort_dependencies(self.messages): +                yield msg.types() +                yield str(msg) + '\n\n' + +        if self.extensions: +            yield '/* Extensions */\n' +            for extension in self.extensions: +                yield extension.extension_decl() +            yield '\n' + +        if self.messages: +            yield '/* Default values for struct fields */\n' +            for msg in self.messages: +                yield msg.default_decl(True) +            yield '\n' + +            yield '/* Initializer values for message structs */\n' +            for msg in self.messages: +                identifier = ('%s_init_default' % msg.name).upper() +                yield '#define %-40s %s\n' % (identifier, msg.get_initializer(False)) +            for msg in self.messages: +                identifier = ('%s_init_zero' % msg.name).upper() +                yield '#define %-40s %s\n' % (identifier, msg.get_initializer(True)) +            yield '\n' + +            yield '/* Field tags (for use in manual encoding/decoding) */\n' +            for msg in sort_dependencies(self.messages): +                for field in msg.fields: +                    yield field.tags() +            for extension in self.extensions: +                yield extension.tags() +            yield '\n' + +            yield '/* Struct field encoding specification for nanopb */\n' +            for msg in self.messages: +                yield msg.fields_declaration() + '\n' +            yield '\n' + +            yield '/* Maximum encoded size of messages (where known) */\n' +            for msg in self.messages: +                msize = msg.encoded_size(self.dependencies) +                identifier = ('%s_size' % msg.name).upper() +                if msize is not None: +                    yield '#define %-40s %s\n' % (identifier, str(msize).upper()) +                else: +                    yield '/* %s depends on runtime parameters */\n' % identifier +            yield '\n' + +            yield '/* Message IDs (where set with "msgid" option) */\n' + +            yield '#ifdef PB_MSGID\n' +            for msg in self.messages: +                if hasattr(msg,'msgid'): +                    yield '#define PB_MSG_%d %s\n' % (msg.msgid, msg.name) +            yield '\n' + +            symbol = make_identifier(headername.split('.')[0]) +            yield '#define %s_MESSAGES \\\n' % symbol + +            for msg in self.messages: +                m = "-1" +                msize = msg.encoded_size(self.dependencies) +                if msize is not None: +                    m = msize +                if hasattr(msg,'msgid'): +                    yield '\tPB_MSG(%d,%s,%s) \\\n' % (msg.msgid, m, msg.name) +            yield '\n' + +            for msg in self.messages: +                if hasattr(msg,'msgid'): +                    yield '#define %s_msgid %d\n' % (msg.name, msg.msgid) +            yield '\n' + +            yield '#endif\n\n' + +        yield '#ifdef __cplusplus\n' +        yield '} /* extern "C" */\n' +        yield '#endif\n' + +        # End of header +        yield '/* @@protoc_insertion_point(eof) */\n' +        yield '\n#endif\n' + +    def generate_source(self, headername, options): +        '''Generate content for a source file.''' + +        yield '/* Automatically generated nanopb constant definitions */\n' +        if options.notimestamp: +            yield '/* Generated by %s */\n\n' % (nanopb_version) +        else: +            yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime()) +        yield options.genformat % (headername) +        yield '\n' +        yield '/* @@protoc_insertion_point(includes) */\n' + +        yield '#if PB_PROTO_HEADER_VERSION != 30\n' +        yield '#error Regenerate this file with the current version of nanopb generator.\n' +        yield '#endif\n' +        yield '\n' + +        for msg in self.messages: +            yield msg.default_decl(False) + +        yield '\n\n' + +        for msg in self.messages: +            yield msg.fields_definition() + '\n\n' + +        for ext in self.extensions: +            yield ext.extension_def() + '\n' + +        # Add checks for numeric limits +        if self.messages: +            largest_msg = max(self.messages, key = lambda m: m.count_required_fields()) +            largest_count = largest_msg.count_required_fields() +            if largest_count > 64: +                yield '\n/* Check that missing required fields will be properly detected */\n' +                yield '#if PB_MAX_REQUIRED_FIELDS < %d\n' % largest_count +                yield '#error Properly detecting missing required fields in %s requires \\\n' % largest_msg.name +                yield '       setting PB_MAX_REQUIRED_FIELDS to %d or more.\n' % largest_count +                yield '#endif\n' + +        max_field = FieldMaxSize() +        checks_msgnames = [] +        for msg in self.messages: +            checks_msgnames.append(msg.name) +            for field in msg.fields: +                max_field.extend(field.largest_field_value()) + +        worst = max_field.worst +        worst_field = max_field.worst_field +        checks = max_field.checks + +        if worst > 255 or checks: +            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 'PB_STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs) +                yield '#endif\n\n' + +            if worst < 65536: +                yield '#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)\n' +                if worst > 255: +                    yield '#error Field descriptor for %s is too large. Define PB_FIELD_16BIT to fix this.\n' % worst_field +                else: +                    assertion = ' && '.join(str(c) + ' < 256' 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_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 'PB_STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs) +                yield '#endif\n\n' + +        # Add check for sizeof(double) +        has_double = False +        for msg in self.messages: +            for field in msg.fields: +                if field.ctype == 'double': +                    has_double = True + +        if has_double: +            yield '\n' +            yield '/* On some platforms (such as AVR), double is really float.\n' +            yield ' * These are not directly supported by nanopb, but see example_avr_double.\n' +            yield ' * To get rid of this error, remove any double fields from your .proto.\n' +            yield ' */\n' +            yield 'PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)\n' + +        yield '\n' +        yield '/* @@protoc_insertion_point(eof) */\n' + +# --------------------------------------------------------------------------- +#                    Options parsing for the .proto files +# --------------------------------------------------------------------------- + +from fnmatch import fnmatch + +def read_options_file(infile): +    '''Parse a separate options file to list: +        [(namemask, options), ...] +    ''' +    results = [] +    data = infile.read() +    data = re.sub('/\*.*?\*/', '', data, flags = re.MULTILINE) +    data = re.sub('//.*?$', '', data, flags = re.MULTILINE) +    data = re.sub('#.*?$', '', data, flags = re.MULTILINE) +    for i, line in enumerate(data.split('\n')): +        line = line.strip() +        if not line: +            continue + +        parts = line.split(None, 1) + +        if len(parts) < 2: +            sys.stderr.write("%s:%d: " % (infile.name, i + 1) + +                             "Option lines should have space between field name and options. " + +                             "Skipping line: '%s'\n" % line) +            continue + +        opts = nanopb_pb2.NanoPBOptions() + +        try: +            text_format.Merge(parts[1], opts) +        except Exception as e: +            sys.stderr.write("%s:%d: " % (infile.name, i + 1) + +                             "Unparseable option line: '%s'. " % line + +                             "Error: %s\n" % str(e)) +            continue +        results.append((parts[0], opts)) + +    return results + +class Globals: +    '''Ugly global variables, should find a good way to pass these.''' +    verbose_options = False +    separate_options = [] +    matched_namemasks = set() + +def get_nanopb_suboptions(subdesc, options, name): +    '''Get copy of options, and merge information from subdesc.''' +    new_options = nanopb_pb2.NanoPBOptions() +    new_options.CopyFrom(options) + +    # Handle options defined in a separate file +    dotname = '.'.join(name.parts) +    for namemask, options in Globals.separate_options: +        if fnmatch(dotname, namemask): +            Globals.matched_namemasks.add(namemask) +            new_options.MergeFrom(options) + +    # Handle options defined in .proto +    if isinstance(subdesc.options, descriptor.FieldOptions): +        ext_type = nanopb_pb2.nanopb +    elif isinstance(subdesc.options, descriptor.FileOptions): +        ext_type = nanopb_pb2.nanopb_fileopt +    elif isinstance(subdesc.options, descriptor.MessageOptions): +        ext_type = nanopb_pb2.nanopb_msgopt +    elif isinstance(subdesc.options, descriptor.EnumOptions): +        ext_type = nanopb_pb2.nanopb_enumopt +    else: +        raise Exception("Unknown options type") + +    if subdesc.options.HasExtension(ext_type): +        ext = subdesc.options.Extensions[ext_type] +        new_options.MergeFrom(ext) + +    if Globals.verbose_options: +        sys.stderr.write("Options for " + dotname + ": ") +        sys.stderr.write(text_format.MessageToString(new_options) + "\n") + +    return new_options + + +# --------------------------------------------------------------------------- +#                         Command line interface +# --------------------------------------------------------------------------- + +import sys +import os.path +from optparse import OptionParser + +optparser = OptionParser( +    usage = "Usage: nanopb_generator.py [options] file.pb ...", +    epilog = "Compile file.pb from file.proto by: 'protoc -ofile.pb file.proto'. " + +             "Output will be written to file.pb.h and file.pb.c.") +optparser.add_option("-x", dest="exclude", metavar="FILE", action="append", default=[], +    help="Exclude file from generated #include list.") +optparser.add_option("-e", "--extension", dest="extension", metavar="EXTENSION", default=".pb", +    help="Set extension to use instead of '.pb' for generated files. [default: %default]") +optparser.add_option("-f", "--options-file", dest="options_file", metavar="FILE", default="%s.options", +    help="Set name of a separate generator options file.") +optparser.add_option("-I", "--options-path", dest="options_path", metavar="DIR", +    action="append", default = [], +    help="Search for .options files additionally in this path") +optparser.add_option("-D", "--output-dir", dest="output_dir", +                     metavar="OUTPUTDIR", default=None, +                     help="Output directory of .pb.h and .pb.c files") +optparser.add_option("-Q", "--generated-include-format", dest="genformat", +    metavar="FORMAT", default='#include "%s"\n', +    help="Set format string to use for including other .pb.h files. [default: %default]") +optparser.add_option("-L", "--library-include-format", dest="libformat", +    metavar="FORMAT", default='#include <%s>\n', +    help="Set format string to use for including the nanopb pb.h header. [default: %default]") +optparser.add_option("-T", "--no-timestamp", dest="notimestamp", action="store_true", default=False, +    help="Don't add timestamp to .pb.h and .pb.c preambles") +optparser.add_option("-q", "--quiet", dest="quiet", action="store_true", default=False, +    help="Don't print anything except errors.") +optparser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False, +    help="Print more information.") +optparser.add_option("-s", dest="settings", metavar="OPTION:VALUE", action="append", default=[], +    help="Set generator option (max_size, max_count etc.).") + +def parse_file(filename, fdesc, options): +    '''Parse a single file. Returns a ProtoFile instance.''' +    toplevel_options = nanopb_pb2.NanoPBOptions() +    for s in options.settings: +        text_format.Merge(s, toplevel_options) + +    if not fdesc: +        data = open(filename, 'rb').read() +        fdesc = descriptor.FileDescriptorSet.FromString(data).file[0] + +    # Check if there is a separate .options file +    had_abspath = False +    try: +        optfilename = options.options_file % os.path.splitext(filename)[0] +    except TypeError: +        # No %s specified, use the filename as-is +        optfilename = options.options_file +        had_abspath = True + +    paths = ['.'] + options.options_path +    for p in paths: +        if os.path.isfile(os.path.join(p, optfilename)): +            optfilename = os.path.join(p, optfilename) +            if options.verbose: +                sys.stderr.write('Reading options from ' + optfilename + '\n') +            Globals.separate_options = read_options_file(open(optfilename, "rU")) +            break +    else: +        # If we are given a full filename and it does not exist, give an error. +        # However, don't give error when we automatically look for .options file +        # with the same name as .proto. +        if options.verbose or had_abspath: +            sys.stderr.write('Options file not found: ' + optfilename + '\n') +        Globals.separate_options = [] + +    Globals.matched_namemasks = set() + +    # Parse the file +    file_options = get_nanopb_suboptions(fdesc, toplevel_options, Names([filename])) +    f = ProtoFile(fdesc, file_options) +    f.optfilename = optfilename + +    return f + +def process_file(filename, fdesc, options, other_files = {}): +    '''Process a single file. +    filename: The full path to the .proto or .pb source file, as string. +    fdesc: The loaded FileDescriptorSet, or None to read from the input file. +    options: Command line options as they come from OptionsParser. + +    Returns a dict: +        {'headername': Name of header file, +         'headerdata': Data for the .h header file, +         'sourcename': Name of the source code file, +         'sourcedata': Data for the .c source code file +        } +    ''' +    f = parse_file(filename, fdesc, options) + +    # Provide dependencies if available +    for dep in f.fdesc.dependency: +        if dep in other_files: +            f.add_dependency(other_files[dep]) + +    # Decide the file names +    noext = os.path.splitext(filename)[0] +    headername = noext + options.extension + '.h' +    sourcename = noext + options.extension + '.c' +    headerbasename = os.path.basename(headername) + +    # List of .proto files that should not be included in the C header file +    # even if they are mentioned in the source .proto. +    excludes = ['nanopb.proto', 'google/protobuf/descriptor.proto'] + options.exclude +    includes = [d for d in f.fdesc.dependency if d not in excludes] + +    headerdata = ''.join(f.generate_header(includes, headerbasename, options)) +    sourcedata = ''.join(f.generate_source(headerbasename, 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 " + f.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, +            'sourcename': sourcename, 'sourcedata': sourcedata} + +def main_cli(): +    '''Main function when invoked directly from the command line.''' + +    options, filenames = optparser.parse_args() + +    if not filenames: +        optparser.print_help() +        sys.exit(1) + +    if options.quiet: +        options.verbose = False + +    if options.output_dir and not os.path.exists(options.output_dir): +        optparser.print_help() +        sys.stderr.write("\noutput_dir does not exist: %s\n" % options.output_dir) +        sys.exit(1) + + +    Globals.verbose_options = options.verbose +    for filename in filenames: +        results = process_file(filename, None, options) + +        base_dir = options.output_dir or '' +        to_write = [ +            (os.path.join(base_dir, results['headername']), results['headerdata']), +            (os.path.join(base_dir, results['sourcename']), results['sourcedata']), +        ] + +        if not options.quiet: +            paths = " and ".join([x[0] for x in to_write]) +            sys.stderr.write("Writing to %s\n" % paths) + +        for path, data in to_write: +            with open(path, 'w') as f: +                f.write(data) + +def main_plugin(): +    '''Main function when invoked as a protoc plugin.''' + +    import io, sys +    if sys.platform == "win32": +        import os, msvcrt +        # Set stdin and stdout to binary mode +        msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) +        msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) + +    data = io.open(sys.stdin.fileno(), "rb").read() + +    request = plugin_pb2.CodeGeneratorRequest.FromString(data) + +    try: +        # Versions of Python prior to 2.7.3 do not support unicode +        # input to shlex.split(). Try to convert to str if possible. +        params = str(request.parameter) +    except UnicodeEncodeError: +        params = request.parameter + +    import shlex +    args = shlex.split(params) +    options, dummy = optparser.parse_args(args) + +    Globals.verbose_options = options.verbose + +    response = plugin_pb2.CodeGeneratorResponse() + +    # Google's protoc does not currently indicate the full path of proto files. +    # Instead always add the main file path to the search dirs, that works for +    # the common case. +    import os.path +    options.options_path.append(os.path.dirname(request.file_to_generate[0])) + +    # Process any include files first, in order to have them +    # available as dependencies +    other_files = {} +    for fdesc in request.proto_file: +        other_files[fdesc.name] = parse_file(fdesc.name, fdesc, options) + +    for filename in request.file_to_generate: +        for fdesc in request.proto_file: +            if fdesc.name == filename: +                results = process_file(filename, fdesc, options, other_files) + +                f = response.file.add() +                f.name = results['headername'] +                f.content = results['headerdata'] + +                f = response.file.add() +                f.name = results['sourcename'] +                f.content = results['sourcedata'] + +    io.open(sys.stdout.fileno(), "wb").write(response.SerializeToString()) + +if __name__ == '__main__': +    # Check if we are running as a plugin under protoc +    if 'protoc-gen-' in sys.argv[0] or '--protoc-plugin' in sys.argv: +        main_plugin() +    else: +        main_cli() diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/Makefile b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/Makefile new file mode 100644 index 0000000..89bfe52 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/Makefile @@ -0,0 +1,4 @@ +all: nanopb_pb2.py plugin_pb2.py + +%_pb2.py: %.proto +	protoc --python_out=. $< diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/__init__.py b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/__init__.py diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/google/protobuf/descriptor.proto b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/google/protobuf/descriptor.proto new file mode 100644 index 0000000..e17c0cc --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/google/protobuf/descriptor.proto @@ -0,0 +1,714 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc.  All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +//     * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +//     * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +//     * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +//  Based on original Protocol Buffers design by +//  Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + + +syntax = "proto2"; + +package google.protobuf; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { +  repeated FileDescriptorProto file = 1; +} + +// Describes a complete .proto file. +message FileDescriptorProto { +  optional string name = 1;       // file name, relative to root of source tree +  optional string package = 2;    // e.g. "foo", "foo.bar", etc. + +  // Names of files imported by this file. +  repeated string dependency = 3; +  // Indexes of the public imported files in the dependency list above. +  repeated int32 public_dependency = 10; +  // Indexes of the weak imported files in the dependency list. +  // For Google-internal migration only. Do not use. +  repeated int32 weak_dependency = 11; + +  // All top-level definitions in this file. +  repeated DescriptorProto message_type = 4; +  repeated EnumDescriptorProto enum_type = 5; +  repeated ServiceDescriptorProto service = 6; +  repeated FieldDescriptorProto extension = 7; + +  optional FileOptions options = 8; + +  // This field contains optional information about the original source code. +  // You may safely remove this entire field without harming runtime +  // functionality of the descriptors -- the information is needed only by +  // development tools. +  optional SourceCodeInfo source_code_info = 9; + +  // The syntax of the proto file. +  // The supported values are "proto2" and "proto3". +  optional string syntax = 12; +} + +// Describes a message type. +message DescriptorProto { +  optional string name = 1; + +  repeated FieldDescriptorProto field = 2; +  repeated FieldDescriptorProto extension = 6; + +  repeated DescriptorProto nested_type = 3; +  repeated EnumDescriptorProto enum_type = 4; + +  message ExtensionRange { +    optional int32 start = 1; +    optional int32 end = 2; +  } +  repeated ExtensionRange extension_range = 5; + +  repeated OneofDescriptorProto oneof_decl = 8; + +  optional MessageOptions options = 7; +} + +// Describes a field within a message. +message FieldDescriptorProto { +  enum Type { +    // 0 is reserved for errors. +    // Order is weird for historical reasons. +    TYPE_DOUBLE         = 1; +    TYPE_FLOAT          = 2; +    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if +    // negative values are likely. +    TYPE_INT64          = 3; +    TYPE_UINT64         = 4; +    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if +    // negative values are likely. +    TYPE_INT32          = 5; +    TYPE_FIXED64        = 6; +    TYPE_FIXED32        = 7; +    TYPE_BOOL           = 8; +    TYPE_STRING         = 9; +    TYPE_GROUP          = 10;  // Tag-delimited aggregate. +    TYPE_MESSAGE        = 11;  // Length-delimited aggregate. + +    // New in version 2. +    TYPE_BYTES          = 12; +    TYPE_UINT32         = 13; +    TYPE_ENUM           = 14; +    TYPE_SFIXED32       = 15; +    TYPE_SFIXED64       = 16; +    TYPE_SINT32         = 17;  // Uses ZigZag encoding. +    TYPE_SINT64         = 18;  // Uses ZigZag encoding. +  }; + +  enum Label { +    // 0 is reserved for errors +    LABEL_OPTIONAL      = 1; +    LABEL_REQUIRED      = 2; +    LABEL_REPEATED      = 3; +    // TODO(sanjay): Should we add LABEL_MAP? +  }; + +  optional string name = 1; +  optional int32 number = 3; +  optional Label label = 4; + +  // If type_name is set, this need not be set.  If both this and type_name +  // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. +  optional Type type = 5; + +  // For message and enum types, this is the name of the type.  If the name +  // starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping +  // rules are used to find the type (i.e. first the nested types within this +  // message are searched, then within the parent, on up to the root +  // namespace). +  optional string type_name = 6; + +  // For extensions, this is the name of the type being extended.  It is +  // resolved in the same manner as type_name. +  optional string extendee = 2; + +  // For numeric types, contains the original text representation of the value. +  // For booleans, "true" or "false". +  // For strings, contains the default text contents (not escaped in any way). +  // For bytes, contains the C escaped value.  All bytes >= 128 are escaped. +  // TODO(kenton):  Base-64 encode? +  optional string default_value = 7; + +  // If set, gives the index of a oneof in the containing type's oneof_decl +  // list.  This field is a member of that oneof.  Extensions of a oneof should +  // not set this since the oneof to which they belong will be inferred based +  // on the extension range containing the extension's field number. +  optional int32 oneof_index = 9; + +  optional FieldOptions options = 8; +} + +// Describes a oneof. +message OneofDescriptorProto { +  optional string name = 1; +} + +// Describes an enum type. +message EnumDescriptorProto { +  optional string name = 1; + +  repeated EnumValueDescriptorProto value = 2; + +  optional EnumOptions options = 3; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { +  optional string name = 1; +  optional int32 number = 2; + +  optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { +  optional string name = 1; +  repeated MethodDescriptorProto method = 2; + +  optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { +  optional string name = 1; + +  // Input and output type names.  These are resolved in the same way as +  // FieldDescriptorProto.type_name, but must refer to a message type. +  optional string input_type = 2; +  optional string output_type = 3; + +  optional MethodOptions options = 4; + +  // Identifies if client streams multiple client messages +  optional bool client_streaming = 5 [default=false]; +  // Identifies if server streams multiple server messages +  optional bool server_streaming = 6 [default=false]; +} + + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached.  These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them.  Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +//   organization, or for experimental options, use field numbers 50000 +//   through 99999.  It is up to you to ensure that you do not use the +//   same number for multiple options. +// * For options which will be published and used publicly by multiple +//   independent entities, e-mail protobuf-global-extension-registry@google.com +//   to reserve extension numbers. Simply provide your project name (e.g. +//   Object-C plugin) and your porject website (if available) -- there's no need +//   to explain how you intend to use them. Usually you only need one extension +//   number. You can declare multiple options with only one extension number by +//   putting them in a sub-message. See the Custom Options section of the docs +//   for examples: +//   https://developers.google.com/protocol-buffers/docs/proto#options +//   If this turns out to be popular, a web service will be set up +//   to automatically assign option numbers. + + +message FileOptions { + +  // Sets the Java package where classes generated from this .proto will be +  // placed.  By default, the proto package is used, but this is often +  // inappropriate because proto packages do not normally start with backwards +  // domain names. +  optional string java_package = 1; + + +  // If set, all the classes from the .proto file are wrapped in a single +  // outer class with the given name.  This applies to both Proto1 +  // (equivalent to the old "--one_java_file" option) and Proto2 (where +  // a .proto always translates to a single class, but you may want to +  // explicitly choose the class name). +  optional string java_outer_classname = 8; + +  // If set true, then the Java code generator will generate a separate .java +  // file for each top-level message, enum, and service defined in the .proto +  // file.  Thus, these types will *not* be nested inside the outer class +  // named by java_outer_classname.  However, the outer class will still be +  // generated to contain the file's getDescriptor() method as well as any +  // top-level extensions defined in the file. +  optional bool java_multiple_files = 10 [default=false]; + +  // If set true, then the Java code generator will generate equals() and +  // hashCode() methods for all messages defined in the .proto file. +  // - In the full runtime, this is purely a speed optimization, as the +  // AbstractMessage base class includes reflection-based implementations of +  // these methods. +  //- In the lite runtime, setting this option changes the semantics of +  // equals() and hashCode() to more closely match those of the full runtime; +  // the generated methods compute their results based on field values rather +  // than object identity. (Implementations should not assume that hashcodes +  // will be consistent across runtimes or versions of the protocol compiler.) +  optional bool java_generate_equals_and_hash = 20 [default=false]; + +  // If set true, then the Java2 code generator will generate code that +  // throws an exception whenever an attempt is made to assign a non-UTF-8 +  // byte sequence to a string field. +  // Message reflection will do the same. +  // However, an extension field still accepts non-UTF-8 byte sequences. +  // This option has no effect on when used with the lite runtime. +  optional bool java_string_check_utf8 = 27 [default=false]; + + +  // Generated classes can be optimized for speed or code size. +  enum OptimizeMode { +    SPEED = 1;        // Generate complete code for parsing, serialization, +                      // etc. +    CODE_SIZE = 2;    // Use ReflectionOps to implement these methods. +    LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. +  } +  optional OptimizeMode optimize_for = 9 [default=SPEED]; + +  // Sets the Go package where structs generated from this .proto will be +  // placed. If omitted, the Go package will be derived from the following: +  //   - The basename of the package import path, if provided. +  //   - Otherwise, the package statement in the .proto file, if present. +  //   - Otherwise, the basename of the .proto file, without extension. +  optional string go_package = 11; + + + +  // Should generic services be generated in each language?  "Generic" services +  // are not specific to any particular RPC system.  They are generated by the +  // main code generators in each language (without additional plugins). +  // Generic services were the only kind of service generation supported by +  // early versions of google.protobuf. +  // +  // Generic services are now considered deprecated in favor of using plugins +  // that generate code specific to your particular RPC system.  Therefore, +  // these default to false.  Old code which depends on generic services should +  // explicitly set them to true. +  optional bool cc_generic_services = 16 [default=false]; +  optional bool java_generic_services = 17 [default=false]; +  optional bool py_generic_services = 18 [default=false]; + +  // Is this file deprecated? +  // Depending on the target platform, this can emit Deprecated annotations +  // for everything in the file, or it will be completely ignored; in the very +  // least, this is a formalization for deprecating files. +  optional bool deprecated = 23 [default=false]; + + +  // Enables the use of arenas for the proto messages in this file. This applies +  // only to generated classes for C++. +  optional bool cc_enable_arenas = 31 [default=false]; + + +  // The parser stores options it doesn't recognize here. See above. +  repeated UninterpretedOption uninterpreted_option = 999; + +  // Clients can define custom options in extensions of this message. See above. +  extensions 1000 to max; +} + +message MessageOptions { +  // Set true to use the old proto1 MessageSet wire format for extensions. +  // This is provided for backwards-compatibility with the MessageSet wire +  // format.  You should not use this for any other reason:  It's less +  // efficient, has fewer features, and is more complicated. +  // +  // The message must be defined exactly as follows: +  //   message Foo { +  //     option message_set_wire_format = true; +  //     extensions 4 to max; +  //   } +  // Note that the message cannot have any defined fields; MessageSets only +  // have extensions. +  // +  // All extensions of your type must be singular messages; e.g. they cannot +  // be int32s, enums, or repeated messages. +  // +  // Because this is an option, the above two restrictions are not enforced by +  // the protocol compiler. +  optional bool message_set_wire_format = 1 [default=false]; + +  // Disables the generation of the standard "descriptor()" accessor, which can +  // conflict with a field of the same name.  This is meant to make migration +  // from proto1 easier; new code should avoid fields named "descriptor". +  optional bool no_standard_descriptor_accessor = 2 [default=false]; + +  // Is this message deprecated? +  // Depending on the target platform, this can emit Deprecated annotations +  // for the message, or it will be completely ignored; in the very least, +  // this is a formalization for deprecating messages. +  optional bool deprecated = 3 [default=false]; + +  // Whether the message is an automatically generated map entry type for the +  // maps field. +  // +  // For maps fields: +  //     map<KeyType, ValueType> map_field = 1; +  // The parsed descriptor looks like: +  //     message MapFieldEntry { +  //         option map_entry = true; +  //         optional KeyType key = 1; +  //         optional ValueType value = 2; +  //     } +  //     repeated MapFieldEntry map_field = 1; +  // +  // Implementations may choose not to generate the map_entry=true message, but +  // use a native map in the target language to hold the keys and values. +  // The reflection APIs in such implementions still need to work as +  // if the field is a repeated message field. +  // +  // NOTE: Do not set the option in .proto files. Always use the maps syntax +  // instead. The option should only be implicitly set by the proto compiler +  // parser. +  optional bool map_entry = 7; + +  // The parser stores options it doesn't recognize here. See above. +  repeated UninterpretedOption uninterpreted_option = 999; + +  // Clients can define custom options in extensions of this message. See above. +  extensions 1000 to max; +} + +message FieldOptions { +  // The ctype option instructs the C++ code generator to use a different +  // representation of the field than it normally would.  See the specific +  // options below.  This option is not yet implemented in the open source +  // release -- sorry, we'll try to include it in a future version! +  optional CType ctype = 1 [default = STRING]; +  enum CType { +    // Default mode. +    STRING = 0; + +    CORD = 1; + +    STRING_PIECE = 2; +  } +  // The packed option can be enabled for repeated primitive fields to enable +  // a more efficient representation on the wire. Rather than repeatedly +  // writing the tag and type for each element, the entire array is encoded as +  // a single length-delimited blob. +  optional bool packed = 2; + + + +  // Should this field be parsed lazily?  Lazy applies only to message-type +  // fields.  It means that when the outer message is initially parsed, the +  // inner message's contents will not be parsed but instead stored in encoded +  // form.  The inner message will actually be parsed when it is first accessed. +  // +  // This is only a hint.  Implementations are free to choose whether to use +  // eager or lazy parsing regardless of the value of this option.  However, +  // setting this option true suggests that the protocol author believes that +  // using lazy parsing on this field is worth the additional bookkeeping +  // overhead typically needed to implement it. +  // +  // This option does not affect the public interface of any generated code; +  // all method signatures remain the same.  Furthermore, thread-safety of the +  // interface is not affected by this option; const methods remain safe to +  // call from multiple threads concurrently, while non-const methods continue +  // to require exclusive access. +  // +  // +  // Note that implementations may choose not to check required fields within +  // a lazy sub-message.  That is, calling IsInitialized() on the outher message +  // may return true even if the inner message has missing required fields. +  // This is necessary because otherwise the inner message would have to be +  // parsed in order to perform the check, defeating the purpose of lazy +  // parsing.  An implementation which chooses not to check required fields +  // must be consistent about it.  That is, for any particular sub-message, the +  // implementation must either *always* check its required fields, or *never* +  // check its required fields, regardless of whether or not the message has +  // been parsed. +  optional bool lazy = 5 [default=false]; + +  // Is this field deprecated? +  // Depending on the target platform, this can emit Deprecated annotations +  // for accessors, or it will be completely ignored; in the very least, this +  // is a formalization for deprecating fields. +  optional bool deprecated = 3 [default=false]; + +  // For Google-internal migration only. Do not use. +  optional bool weak = 10 [default=false]; + + + +  // The parser stores options it doesn't recognize here. See above. +  repeated UninterpretedOption uninterpreted_option = 999; + +  // Clients can define custom options in extensions of this message. See above. +  extensions 1000 to max; +} + +message EnumOptions { + +  // Set this option to true to allow mapping different tag names to the same +  // value. +  optional bool allow_alias = 2; + +  // Is this enum deprecated? +  // Depending on the target platform, this can emit Deprecated annotations +  // for the enum, or it will be completely ignored; in the very least, this +  // is a formalization for deprecating enums. +  optional bool deprecated = 3 [default=false]; + +  // The parser stores options it doesn't recognize here. See above. +  repeated UninterpretedOption uninterpreted_option = 999; + +  // Clients can define custom options in extensions of this message. See above. +  extensions 1000 to max; +} + +message EnumValueOptions { +  // Is this enum value deprecated? +  // Depending on the target platform, this can emit Deprecated annotations +  // for the enum value, or it will be completely ignored; in the very least, +  // this is a formalization for deprecating enum values. +  optional bool deprecated = 1 [default=false]; + +  // The parser stores options it doesn't recognize here. See above. +  repeated UninterpretedOption uninterpreted_option = 999; + +  // Clients can define custom options in extensions of this message. See above. +  extensions 1000 to max; +} + +message ServiceOptions { + +  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC +  //   framework.  We apologize for hoarding these numbers to ourselves, but +  //   we were already using them long before we decided to release Protocol +  //   Buffers. + +  // Is this service deprecated? +  // Depending on the target platform, this can emit Deprecated annotations +  // for the service, or it will be completely ignored; in the very least, +  // this is a formalization for deprecating services. +  optional bool deprecated = 33 [default=false]; + +  // The parser stores options it doesn't recognize here. See above. +  repeated UninterpretedOption uninterpreted_option = 999; + +  // Clients can define custom options in extensions of this message. See above. +  extensions 1000 to max; +} + +message MethodOptions { + +  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC +  //   framework.  We apologize for hoarding these numbers to ourselves, but +  //   we were already using them long before we decided to release Protocol +  //   Buffers. + +  // Is this method deprecated? +  // Depending on the target platform, this can emit Deprecated annotations +  // for the method, or it will be completely ignored; in the very least, +  // this is a formalization for deprecating methods. +  optional bool deprecated = 33 [default=false]; + +  // The parser stores options it doesn't recognize here. See above. +  repeated UninterpretedOption uninterpreted_option = 999; + +  // Clients can define custom options in extensions of this message. See above. +  extensions 1000 to max; +} + + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { +  // The name of the uninterpreted option.  Each string represents a segment in +  // a dot-separated name.  is_extension is true iff a segment represents an +  // extension (denoted with parentheses in options specs in .proto files). +  // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents +  // "foo.(bar.baz).qux". +  message NamePart { +    required string name_part = 1; +    required bool is_extension = 2; +  } +  repeated NamePart name = 2; + +  // The value of the uninterpreted option, in whatever type the tokenizer +  // identified it as during parsing. Exactly one of these should be set. +  optional string identifier_value = 3; +  optional uint64 positive_int_value = 4; +  optional int64 negative_int_value = 5; +  optional double double_value = 6; +  optional bytes string_value = 7; +  optional string aggregate_value = 8; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { +  // A Location identifies a piece of source code in a .proto file which +  // corresponds to a particular definition.  This information is intended +  // to be useful to IDEs, code indexers, documentation generators, and similar +  // tools. +  // +  // For example, say we have a file like: +  //   message Foo { +  //     optional string foo = 1; +  //   } +  // Let's look at just the field definition: +  //   optional string foo = 1; +  //   ^       ^^     ^^  ^  ^^^ +  //   a       bc     de  f  ghi +  // We have the following locations: +  //   span   path               represents +  //   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition. +  //   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional). +  //   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string). +  //   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo). +  //   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1). +  // +  // Notes: +  // - A location may refer to a repeated field itself (i.e. not to any +  //   particular index within it).  This is used whenever a set of elements are +  //   logically enclosed in a single code segment.  For example, an entire +  //   extend block (possibly containing multiple extension definitions) will +  //   have an outer location whose path refers to the "extensions" repeated +  //   field without an index. +  // - Multiple locations may have the same path.  This happens when a single +  //   logical declaration is spread out across multiple places.  The most +  //   obvious example is the "extend" block again -- there may be multiple +  //   extend blocks in the same scope, each of which will have the same path. +  // - A location's span is not always a subset of its parent's span.  For +  //   example, the "extendee" of an extension declaration appears at the +  //   beginning of the "extend" block and is shared by all extensions within +  //   the block. +  // - Just because a location's span is a subset of some other location's span +  //   does not mean that it is a descendent.  For example, a "group" defines +  //   both a type and a field in a single declaration.  Thus, the locations +  //   corresponding to the type and field and their components will overlap. +  // - Code which tries to interpret locations should probably be designed to +  //   ignore those that it doesn't understand, as more types of locations could +  //   be recorded in the future. +  repeated Location location = 1; +  message Location { +    // Identifies which part of the FileDescriptorProto was defined at this +    // location. +    // +    // Each element is a field number or an index.  They form a path from +    // the root FileDescriptorProto to the place where the definition.  For +    // example, this path: +    //   [ 4, 3, 2, 7, 1 ] +    // refers to: +    //   file.message_type(3)  // 4, 3 +    //       .field(7)         // 2, 7 +    //       .name()           // 1 +    // This is because FileDescriptorProto.message_type has field number 4: +    //   repeated DescriptorProto message_type = 4; +    // and DescriptorProto.field has field number 2: +    //   repeated FieldDescriptorProto field = 2; +    // and FieldDescriptorProto.name has field number 1: +    //   optional string name = 1; +    // +    // Thus, the above path gives the location of a field name.  If we removed +    // the last element: +    //   [ 4, 3, 2, 7 ] +    // this path refers to the whole field declaration (from the beginning +    // of the label to the terminating semicolon). +    repeated int32 path = 1 [packed=true]; + +    // Always has exactly three or four elements: start line, start column, +    // end line (optional, otherwise assumed same as start line), end column. +    // These are packed into a single field for efficiency.  Note that line +    // and column numbers are zero-based -- typically you will want to add +    // 1 to each before displaying to a user. +    repeated int32 span = 2 [packed=true]; + +    // If this SourceCodeInfo represents a complete declaration, these are any +    // comments appearing before and after the declaration which appear to be +    // attached to the declaration. +    // +    // A series of line comments appearing on consecutive lines, with no other +    // tokens appearing on those lines, will be treated as a single comment. +    // +    // Only the comment content is provided; comment markers (e.g. //) are +    // stripped out.  For block comments, leading whitespace and an asterisk +    // will be stripped from the beginning of each line other than the first. +    // Newlines are included in the output. +    // +    // Examples: +    // +    //   optional int32 foo = 1;  // Comment attached to foo. +    //   // Comment attached to bar. +    //   optional int32 bar = 2; +    // +    //   optional string baz = 3; +    //   // Comment attached to baz. +    //   // Another line attached to baz. +    // +    //   // Comment attached to qux. +    //   // +    //   // Another line attached to qux. +    //   optional double qux = 4; +    // +    //   optional string corge = 5; +    //   /* Block comment attached +    //    * to corge.  Leading asterisks +    //    * will be removed. */ +    //   /* Block comment attached to +    //    * grault. */ +    //   optional int32 grault = 6; +    optional string leading_comments = 3; +    optional string trailing_comments = 4; +  } +} diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/nanopb.proto b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/nanopb.proto new file mode 100644 index 0000000..9b2f0fb --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/nanopb.proto @@ -0,0 +1,97 @@ +// Custom options for defining: +// - Maximum size of string/bytes +// - Maximum number of elements in array +// +// These are used by nanopb to generate statically allocable structures +// for memory-limited environments. + +syntax = "proto2"; +import "google/protobuf/descriptor.proto"; + +option java_package = "fi.kapsi.koti.jpa.nanopb"; + +enum FieldType { +    FT_DEFAULT = 0; // Automatically decide field type, generate static field if possible. +    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_IGNORE = 3; // Ignore the field completely. +} + +enum IntSize { +    IS_DEFAULT = 0; // Default, 32/64bit based on type in .proto +    IS_8 = 8; +    IS_16 = 16; +    IS_32 = 32; +    IS_64 = 64; +} + +// This is the inner options message, which basically defines options for +// a field. When it is used in message or file scope, it applies to all +// fields. +message NanoPBOptions { +  // Allocated size for 'bytes' and 'string' fields. +  optional int32 max_size = 1; +   +  // Allocated number of entries in arrays ('repeated' fields) +  optional int32 max_count = 2; +   +  // Size of integer fields. Can save some memory if you don't need +  // full 32 bits for the value. +  optional IntSize int_size = 7 [default = IS_DEFAULT]; + +  // Force type of field (callback or static allocation) +  optional FieldType type = 3 [default = FT_DEFAULT]; +   +  // Use long names for enums, i.e. EnumName_EnumValue. +  optional bool long_names = 4 [default = true]; +   +  // Add 'packed' attribute to generated structs. +  // Note: this cannot be used on CPUs that break on unaligned +  // accesses to variables. +  optional bool packed_struct = 5 [default = false]; +   +  // Add 'packed' attribute to generated enums. +  optional bool packed_enum = 10 [default = false]; +   +  // Skip this message +  optional bool skip_message = 6 [default = false]; + +  // Generate oneof fields as normal optional fields instead of union. +  optional bool no_unions = 8 [default = false]; + +  // integer type tag for a message +  optional uint32 msgid = 9; + +  // decode oneof as anonymous union +  optional bool anonymous_oneof = 11 [default = false]; +} + +// Extensions to protoc 'Descriptor' type in order to define options +// inside a .proto file. +// +// Protocol Buffers extension number registry +// -------------------------------- +// Project:  Nanopb +// Contact:  Petteri Aimonen <jpa@kapsi.fi> +// Web site: http://kapsi.fi/~jpa/nanopb +// Extensions: 1010 (all types) +// -------------------------------- + +extend google.protobuf.FileOptions { +    optional NanoPBOptions nanopb_fileopt = 1010; +} + +extend google.protobuf.MessageOptions { +    optional NanoPBOptions nanopb_msgopt = 1010; +} + +extend google.protobuf.EnumOptions { +    optional NanoPBOptions nanopb_enumopt = 1010; +} + +extend google.protobuf.FieldOptions { +    optional NanoPBOptions nanopb = 1010; +} + + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/nanopb_pb2.py b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/nanopb_pb2.py new file mode 100644 index 0000000..b386775 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/nanopb_pb2.py @@ -0,0 +1,270 @@ +# Generated by the protocol buffer compiler.  DO NOT EDIT! +# source: nanopb.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf.internal import enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import google.protobuf.descriptor_pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( +  name='nanopb.proto', +  package='', +  serialized_pb=_b('\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') +  , +  dependencies=[google.protobuf.descriptor_pb2.DESCRIPTOR,]) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +_FIELDTYPE = _descriptor.EnumDescriptor( +  name='FieldType', +  full_name='FieldType', +  filename=None, +  file=DESCRIPTOR, +  values=[ +    _descriptor.EnumValueDescriptor( +      name='FT_DEFAULT', index=0, number=0, +      options=None, +      type=None), +    _descriptor.EnumValueDescriptor( +      name='FT_CALLBACK', index=1, number=1, +      options=None, +      type=None), +    _descriptor.EnumValueDescriptor( +      name='FT_POINTER', index=2, number=4, +      options=None, +      type=None), +    _descriptor.EnumValueDescriptor( +      name='FT_STATIC', index=3, number=2, +      options=None, +      type=None), +    _descriptor.EnumValueDescriptor( +      name='FT_IGNORE', index=4, number=3, +      options=None, +      type=None), +  ], +  containing_type=None, +  options=None, +  serialized_start=369, +  serialized_end=459, +) +_sym_db.RegisterEnumDescriptor(_FIELDTYPE) + +FieldType = enum_type_wrapper.EnumTypeWrapper(_FIELDTYPE) +_INTSIZE = _descriptor.EnumDescriptor( +  name='IntSize', +  full_name='IntSize', +  filename=None, +  file=DESCRIPTOR, +  values=[ +    _descriptor.EnumValueDescriptor( +      name='IS_DEFAULT', index=0, number=0, +      options=None, +      type=None), +    _descriptor.EnumValueDescriptor( +      name='IS_8', index=1, number=8, +      options=None, +      type=None), +    _descriptor.EnumValueDescriptor( +      name='IS_16', index=2, number=16, +      options=None, +      type=None), +    _descriptor.EnumValueDescriptor( +      name='IS_32', index=3, number=32, +      options=None, +      type=None), +    _descriptor.EnumValueDescriptor( +      name='IS_64', index=4, number=64, +      options=None, +      type=None), +  ], +  containing_type=None, +  options=None, +  serialized_start=461, +  serialized_end=529, +) +_sym_db.RegisterEnumDescriptor(_INTSIZE) + +IntSize = enum_type_wrapper.EnumTypeWrapper(_INTSIZE) +FT_DEFAULT = 0 +FT_CALLBACK = 1 +FT_POINTER = 4 +FT_STATIC = 2 +FT_IGNORE = 3 +IS_DEFAULT = 0 +IS_8 = 8 +IS_16 = 16 +IS_32 = 32 +IS_64 = 64 + +NANOPB_FILEOPT_FIELD_NUMBER = 1010 +nanopb_fileopt = _descriptor.FieldDescriptor( +  name='nanopb_fileopt', full_name='nanopb_fileopt', index=0, +  number=1010, type=11, cpp_type=10, label=1, +  has_default_value=False, default_value=None, +  message_type=None, enum_type=None, containing_type=None, +  is_extension=True, extension_scope=None, +  options=None) +NANOPB_MSGOPT_FIELD_NUMBER = 1010 +nanopb_msgopt = _descriptor.FieldDescriptor( +  name='nanopb_msgopt', full_name='nanopb_msgopt', index=1, +  number=1010, type=11, cpp_type=10, label=1, +  has_default_value=False, default_value=None, +  message_type=None, enum_type=None, containing_type=None, +  is_extension=True, extension_scope=None, +  options=None) +NANOPB_ENUMOPT_FIELD_NUMBER = 1010 +nanopb_enumopt = _descriptor.FieldDescriptor( +  name='nanopb_enumopt', full_name='nanopb_enumopt', index=2, +  number=1010, type=11, cpp_type=10, label=1, +  has_default_value=False, default_value=None, +  message_type=None, enum_type=None, containing_type=None, +  is_extension=True, extension_scope=None, +  options=None) +NANOPB_FIELD_NUMBER = 1010 +nanopb = _descriptor.FieldDescriptor( +  name='nanopb', full_name='nanopb', index=3, +  number=1010, type=11, cpp_type=10, label=1, +  has_default_value=False, default_value=None, +  message_type=None, enum_type=None, containing_type=None, +  is_extension=True, extension_scope=None, +  options=None) + + +_NANOPBOPTIONS = _descriptor.Descriptor( +  name='NanoPBOptions', +  full_name='NanoPBOptions', +  filename=None, +  file=DESCRIPTOR, +  containing_type=None, +  fields=[ +    _descriptor.FieldDescriptor( +      name='max_size', full_name='NanoPBOptions.max_size', index=0, +      number=1, type=5, cpp_type=1, label=1, +      has_default_value=False, default_value=0, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='max_count', full_name='NanoPBOptions.max_count', index=1, +      number=2, type=5, cpp_type=1, label=1, +      has_default_value=False, default_value=0, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='int_size', full_name='NanoPBOptions.int_size', index=2, +      number=7, type=14, cpp_type=8, label=1, +      has_default_value=True, default_value=0, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='type', full_name='NanoPBOptions.type', index=3, +      number=3, type=14, cpp_type=8, label=1, +      has_default_value=True, default_value=0, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='long_names', full_name='NanoPBOptions.long_names', index=4, +      number=4, type=8, cpp_type=7, label=1, +      has_default_value=True, default_value=True, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='packed_struct', full_name='NanoPBOptions.packed_struct', index=5, +      number=5, type=8, cpp_type=7, label=1, +      has_default_value=True, default_value=False, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='packed_enum', full_name='NanoPBOptions.packed_enum', index=6, +      number=10, type=8, cpp_type=7, label=1, +      has_default_value=True, default_value=False, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='skip_message', full_name='NanoPBOptions.skip_message', index=7, +      number=6, type=8, cpp_type=7, label=1, +      has_default_value=True, default_value=False, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='no_unions', full_name='NanoPBOptions.no_unions', index=8, +      number=8, type=8, cpp_type=7, label=1, +      has_default_value=True, default_value=False, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='msgid', full_name='NanoPBOptions.msgid', index=9, +      number=9, type=13, cpp_type=3, label=1, +      has_default_value=False, default_value=0, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='anonymous_oneof', full_name='NanoPBOptions.anonymous_oneof', index=10, +      number=11, type=8, cpp_type=7, label=1, +      has_default_value=True, default_value=False, +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +  ], +  extensions=[ +  ], +  nested_types=[], +  enum_types=[ +  ], +  options=None, +  is_extendable=False, +  extension_ranges=[], +  oneofs=[ +  ], +  serialized_start=51, +  serialized_end=367, +) + +_NANOPBOPTIONS.fields_by_name['int_size'].enum_type = _INTSIZE +_NANOPBOPTIONS.fields_by_name['type'].enum_type = _FIELDTYPE +DESCRIPTOR.message_types_by_name['NanoPBOptions'] = _NANOPBOPTIONS +DESCRIPTOR.enum_types_by_name['FieldType'] = _FIELDTYPE +DESCRIPTOR.enum_types_by_name['IntSize'] = _INTSIZE +DESCRIPTOR.extensions_by_name['nanopb_fileopt'] = nanopb_fileopt +DESCRIPTOR.extensions_by_name['nanopb_msgopt'] = nanopb_msgopt +DESCRIPTOR.extensions_by_name['nanopb_enumopt'] = nanopb_enumopt +DESCRIPTOR.extensions_by_name['nanopb'] = nanopb + +NanoPBOptions = _reflection.GeneratedProtocolMessageType('NanoPBOptions', (_message.Message,), dict( +  DESCRIPTOR = _NANOPBOPTIONS, +  __module__ = 'nanopb_pb2' +  # @@protoc_insertion_point(class_scope:NanoPBOptions) +  )) +_sym_db.RegisterMessage(NanoPBOptions) + +nanopb_fileopt.message_type = _NANOPBOPTIONS +google.protobuf.descriptor_pb2.FileOptions.RegisterExtension(nanopb_fileopt) +nanopb_msgopt.message_type = _NANOPBOPTIONS +google.protobuf.descriptor_pb2.MessageOptions.RegisterExtension(nanopb_msgopt) +nanopb_enumopt.message_type = _NANOPBOPTIONS +google.protobuf.descriptor_pb2.EnumOptions.RegisterExtension(nanopb_enumopt) +nanopb.message_type = _NANOPBOPTIONS +google.protobuf.descriptor_pb2.FieldOptions.RegisterExtension(nanopb) + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\030fi.kapsi.koti.jpa.nanopb')) +# @@protoc_insertion_point(module_scope) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/plugin.proto b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/plugin.proto new file mode 100644 index 0000000..e627289 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/plugin.proto @@ -0,0 +1,148 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc.  All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +//     * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +//     * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +//     * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// WARNING:  The plugin interface is currently EXPERIMENTAL and is subject to +//   change. +// +// protoc (aka the Protocol Compiler) can be extended via plugins.  A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path.  The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +syntax = "proto2"; +package google.protobuf.compiler; +option java_package = "com.google.protobuf.compiler"; +option java_outer_classname = "PluginProtos"; + +import "google/protobuf/descriptor.proto"; + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { +  // The .proto files that were explicitly listed on the command-line.  The +  // code generator should generate code only for these files.  Each file's +  // descriptor will be included in proto_file, below. +  repeated string file_to_generate = 1; + +  // The generator parameter passed on the command-line. +  optional string parameter = 2; + +  // FileDescriptorProtos for all files in files_to_generate and everything +  // they import.  The files will appear in topological order, so each file +  // appears before any file that imports it. +  // +  // protoc guarantees that all proto_files will be written after +  // the fields above, even though this is not technically guaranteed by the +  // protobuf wire format.  This theoretically could allow a plugin to stream +  // in the FileDescriptorProtos and handle them one by one rather than read +  // the entire set into memory at once.  However, as of this writing, this +  // is not similarly optimized on protoc's end -- it will store all fields in +  // memory at once before sending them to the plugin. +  repeated FileDescriptorProto proto_file = 15; +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { +  // Error message.  If non-empty, code generation failed.  The plugin process +  // should exit with status code zero even if it reports an error in this way. +  // +  // This should be used to indicate errors in .proto files which prevent the +  // code generator from generating correct code.  Errors which indicate a +  // problem in protoc itself -- such as the input CodeGeneratorRequest being +  // unparseable -- should be reported by writing a message to stderr and +  // exiting with a non-zero status code. +  optional string error = 1; + +  // Represents a single generated file. +  message File { +    // The file name, relative to the output directory.  The name must not +    // contain "." or ".." components and must be relative, not be absolute (so, +    // the file cannot lie outside the output directory).  "/" must be used as +    // the path separator, not "\". +    // +    // If the name is omitted, the content will be appended to the previous +    // file.  This allows the generator to break large files into small chunks, +    // and allows the generated text to be streamed back to protoc so that large +    // files need not reside completely in memory at one time.  Note that as of +    // this writing protoc does not optimize for this -- it will read the entire +    // CodeGeneratorResponse before writing files to disk. +    optional string name = 1; + +    // If non-empty, indicates that the named file should already exist, and the +    // content here is to be inserted into that file at a defined insertion +    // point.  This feature allows a code generator to extend the output +    // produced by another code generator.  The original generator may provide +    // insertion points by placing special annotations in the file that look +    // like: +    //   @@protoc_insertion_point(NAME) +    // The annotation can have arbitrary text before and after it on the line, +    // which allows it to be placed in a comment.  NAME should be replaced with +    // an identifier naming the point -- this is what other generators will use +    // as the insertion_point.  Code inserted at this point will be placed +    // immediately above the line containing the insertion point (thus multiple +    // insertions to the same point will come out in the order they were added). +    // The double-@ is intended to make it unlikely that the generated code +    // could contain things that look like insertion points by accident. +    // +    // For example, the C++ code generator places the following line in the +    // .pb.h files that it generates: +    //   // @@protoc_insertion_point(namespace_scope) +    // This line appears within the scope of the file's package namespace, but +    // outside of any particular class.  Another plugin can then specify the +    // insertion_point "namespace_scope" to generate additional classes or +    // other declarations that should be placed in this scope. +    // +    // Note that if the line containing the insertion point begins with +    // whitespace, the same whitespace will be added to every line of the +    // inserted text.  This is useful for languages like Python, where +    // indentation matters.  In these languages, the insertion point comment +    // should be indented the same amount as any inserted code will need to be +    // in order to work correctly in that context. +    // +    // The code generator that generates the initial file and the one which +    // inserts into it must both run as part of a single invocation of protoc. +    // Code generators are executed in the order in which they appear on the +    // command line. +    // +    // If |insertion_point| is present, |name| must also be present. +    optional string insertion_point = 2; + +    // The file contents. +    optional string content = 15; +  } +  repeated File file = 15; +} diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/plugin_pb2.py b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/plugin_pb2.py new file mode 100644 index 0000000..481d0d7 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/proto/plugin_pb2.py @@ -0,0 +1,184 @@ +# Generated by the protocol buffer compiler.  DO NOT EDIT! +# source: plugin.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import google.protobuf.descriptor_pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( +  name='plugin.proto', +  package='google.protobuf.compiler', +  serialized_pb=_b('\n\x0cplugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"}\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xaa\x01\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a>\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\tB,\n\x1c\x63om.google.protobuf.compilerB\x0cPluginProtos') +  , +  dependencies=[google.protobuf.descriptor_pb2.DESCRIPTOR,]) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + + +_CODEGENERATORREQUEST = _descriptor.Descriptor( +  name='CodeGeneratorRequest', +  full_name='google.protobuf.compiler.CodeGeneratorRequest', +  filename=None, +  file=DESCRIPTOR, +  containing_type=None, +  fields=[ +    _descriptor.FieldDescriptor( +      name='file_to_generate', full_name='google.protobuf.compiler.CodeGeneratorRequest.file_to_generate', index=0, +      number=1, type=9, cpp_type=9, label=3, +      has_default_value=False, default_value=[], +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='parameter', full_name='google.protobuf.compiler.CodeGeneratorRequest.parameter', index=1, +      number=2, type=9, cpp_type=9, label=1, +      has_default_value=False, default_value=_b("").decode('utf-8'), +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='proto_file', full_name='google.protobuf.compiler.CodeGeneratorRequest.proto_file', index=2, +      number=15, type=11, cpp_type=10, label=3, +      has_default_value=False, default_value=[], +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +  ], +  extensions=[ +  ], +  nested_types=[], +  enum_types=[ +  ], +  options=None, +  is_extendable=False, +  extension_ranges=[], +  oneofs=[ +  ], +  serialized_start=76, +  serialized_end=201, +) + + +_CODEGENERATORRESPONSE_FILE = _descriptor.Descriptor( +  name='File', +  full_name='google.protobuf.compiler.CodeGeneratorResponse.File', +  filename=None, +  file=DESCRIPTOR, +  containing_type=None, +  fields=[ +    _descriptor.FieldDescriptor( +      name='name', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.name', index=0, +      number=1, type=9, cpp_type=9, label=1, +      has_default_value=False, default_value=_b("").decode('utf-8'), +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='insertion_point', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point', index=1, +      number=2, type=9, cpp_type=9, label=1, +      has_default_value=False, default_value=_b("").decode('utf-8'), +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='content', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.content', index=2, +      number=15, type=9, cpp_type=9, label=1, +      has_default_value=False, default_value=_b("").decode('utf-8'), +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +  ], +  extensions=[ +  ], +  nested_types=[], +  enum_types=[ +  ], +  options=None, +  is_extendable=False, +  extension_ranges=[], +  oneofs=[ +  ], +  serialized_start=312, +  serialized_end=374, +) + +_CODEGENERATORRESPONSE = _descriptor.Descriptor( +  name='CodeGeneratorResponse', +  full_name='google.protobuf.compiler.CodeGeneratorResponse', +  filename=None, +  file=DESCRIPTOR, +  containing_type=None, +  fields=[ +    _descriptor.FieldDescriptor( +      name='error', full_name='google.protobuf.compiler.CodeGeneratorResponse.error', index=0, +      number=1, type=9, cpp_type=9, label=1, +      has_default_value=False, default_value=_b("").decode('utf-8'), +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +    _descriptor.FieldDescriptor( +      name='file', full_name='google.protobuf.compiler.CodeGeneratorResponse.file', index=1, +      number=15, type=11, cpp_type=10, label=3, +      has_default_value=False, default_value=[], +      message_type=None, enum_type=None, containing_type=None, +      is_extension=False, extension_scope=None, +      options=None), +  ], +  extensions=[ +  ], +  nested_types=[_CODEGENERATORRESPONSE_FILE, ], +  enum_types=[ +  ], +  options=None, +  is_extendable=False, +  extension_ranges=[], +  oneofs=[ +  ], +  serialized_start=204, +  serialized_end=374, +) + +_CODEGENERATORREQUEST.fields_by_name['proto_file'].message_type = google.protobuf.descriptor_pb2._FILEDESCRIPTORPROTO +_CODEGENERATORRESPONSE_FILE.containing_type = _CODEGENERATORRESPONSE +_CODEGENERATORRESPONSE.fields_by_name['file'].message_type = _CODEGENERATORRESPONSE_FILE +DESCRIPTOR.message_types_by_name['CodeGeneratorRequest'] = _CODEGENERATORREQUEST +DESCRIPTOR.message_types_by_name['CodeGeneratorResponse'] = _CODEGENERATORRESPONSE + +CodeGeneratorRequest = _reflection.GeneratedProtocolMessageType('CodeGeneratorRequest', (_message.Message,), dict( +  DESCRIPTOR = _CODEGENERATORREQUEST, +  __module__ = 'plugin_pb2' +  # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) +  )) +_sym_db.RegisterMessage(CodeGeneratorRequest) + +CodeGeneratorResponse = _reflection.GeneratedProtocolMessageType('CodeGeneratorResponse', (_message.Message,), dict( + +  File = _reflection.GeneratedProtocolMessageType('File', (_message.Message,), dict( +    DESCRIPTOR = _CODEGENERATORRESPONSE_FILE, +    __module__ = 'plugin_pb2' +    # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) +    )) +  , +  DESCRIPTOR = _CODEGENERATORRESPONSE, +  __module__ = 'plugin_pb2' +  # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse) +  )) +_sym_db.RegisterMessage(CodeGeneratorResponse) +_sym_db.RegisterMessage(CodeGeneratorResponse.File) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\034com.google.protobuf.compilerB\014PluginProtos')) +# @@protoc_insertion_point(module_scope) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/protoc-gen-nanopb b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/protoc-gen-nanopb new file mode 100644 index 0000000..358f97c --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/protoc-gen-nanopb @@ -0,0 +1,13 @@ +#!/bin/sh + +# This file is used to invoke nanopb_generator.py as a plugin +# to protoc on Linux and other *nix-style systems. +# Use it like this: +# protoc --plugin=nanopb=..../protoc-gen-nanopb --nanopb_out=dir foo.proto +# +# Note that if you use the binary package of nanopb, the protoc +# path is already set up properly and there is no need to give +# --plugin= on the command line. + +MYPATH=$(dirname "$0") +exec "$MYPATH/nanopb_generator.py" --protoc-plugin diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/protoc-gen-nanopb.bat b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/protoc-gen-nanopb.bat new file mode 100644 index 0000000..7624984 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/generator/protoc-gen-nanopb.bat @@ -0,0 +1,12 @@ +@echo off +:: This file is used to invoke nanopb_generator.py as a plugin +:: to protoc on Windows. +:: Use it like this: +:: protoc --plugin=nanopb=..../protoc-gen-nanopb.bat --nanopb_out=dir foo.proto +:: +:: Note that if you use the binary package of nanopb, the protoc +:: path is already set up properly and there is no need to give +:: --plugin= on the command line. + +set mydir=%~dp0 +python "%mydir%\nanopb_generator.py" --protoc-plugin diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb.h new file mode 100644 index 0000000..a17280d --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb.h @@ -0,0 +1,556 @@ +/* Common parts of the nanopb library. Most of these are quite low-level + * stuff. For the high-level interface, see pb_encode.h and pb_decode.h. + */ + +#ifndef PB_H_INCLUDED +#define PB_H_INCLUDED + +/***************************************************************** + * Nanopb compilation time options. You can change these here by * + * uncommenting the lines, or on the compiler command line.      * + *****************************************************************/ + +/* Enable support for dynamically allocated fields */ +/* #define PB_ENABLE_MALLOC 1 */ + +/* Define this if your CPU / compiler combination does not support + * unaligned memory access to packed structures. */ +#define PB_NO_PACKED_STRUCTS 1 + +/* Increase the number of required fields that are tracked. + * A compiler warning will tell if you need this. */ +/* #define PB_MAX_REQUIRED_FIELDS 256 */ + +/* Add support for tag numbers > 255 and fields larger than 255 bytes. */ +/* #define PB_FIELD_16BIT 1 */ + +/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */ +/* #define PB_FIELD_32BIT 1 */ + +/* Disable support for error messages in order to save some code space. */ +#define PB_NO_ERRMSG 1 + +/* Disable support for custom streams (support only memory buffers). */ +/* #define PB_BUFFER_ONLY 1 */ + +/* Switch back to the old-style callback function signature. + * This was the default until nanopb-0.2.1. */ +/* #define PB_OLD_CALLBACK_STYLE */ + + +/****************************************************************** + * You usually don't need to change anything below this line.     * + * Feel free to look around and use the defined macros, though.   * + ******************************************************************/ + + +/* 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 + +/* Include all the system headers needed by nanopb. You will need the + * definitions of the following: + * - strlen, memcpy, memset functions + * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t + * - size_t + * - bool + * + * If you don't have the standard header files, you can instead provide + * a custom header that defines or includes all this. In that case, + * define PB_SYSTEM_HEADER to the path of this file. + */ +#ifdef PB_SYSTEM_HEADER +#include PB_SYSTEM_HEADER +#else +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> +#include <string.h> + +#ifdef PB_ENABLE_MALLOC +#include <stdlib.h> +#endif +#endif + +/* Macro for defining packed structures (compiler dependent). + * This just reduces memory requirements, but is not required. + */ +#if defined(PB_NO_PACKED_STRUCTS) +    /* Disable struct packing */ +#   define PB_PACKED_STRUCT_START +#   define PB_PACKED_STRUCT_END +#   define pb_packed +#elif defined(__GNUC__) || defined(__clang__) +    /* For GCC and clang */ +#   define PB_PACKED_STRUCT_START +#   define PB_PACKED_STRUCT_END +#   define pb_packed __attribute__((packed)) +#elif defined(__ICCARM__) || defined(__CC_ARM) +    /* For IAR ARM and Keil MDK-ARM compilers */ +#   define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") +#   define PB_PACKED_STRUCT_END _Pragma("pack(pop)") +#   define pb_packed +#elif defined(_MSC_VER) && (_MSC_VER >= 1500) +    /* For Microsoft Visual C++ */ +#   define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) +#   define PB_PACKED_STRUCT_END __pragma(pack(pop)) +#   define pb_packed +#else +    /* Unknown compiler */ +#   define PB_PACKED_STRUCT_START +#   define PB_PACKED_STRUCT_END +#   define pb_packed +#endif + +/* Handly macro for suppressing unreferenced-parameter compiler warnings. */ +#ifndef PB_UNUSED +#define PB_UNUSED(x) (void)(x) +#endif + +/* Compile-time assertion, used for checking compatible compilation options. + * If this does not work properly on your compiler, use + * #define PB_NO_STATIC_ASSERT 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 PB_STATIC_ASSERT macro was called. + */ +#ifndef PB_NO_STATIC_ASSERT +#ifndef PB_STATIC_ASSERT +#define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; +#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) +#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##LINE##COUNTER +#endif +#else +#define PB_STATIC_ASSERT(COND,MSG) +#endif + +/* Number of required fields to keep track of. */ +#ifndef PB_MAX_REQUIRED_FIELDS +#define PB_MAX_REQUIRED_FIELDS 64 +#endif + +#if PB_MAX_REQUIRED_FIELDS < 64 +#error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64). +#endif + +/* List of possible field types. These are used in the autogenerated code. + * Least-significant 4 bits tell the scalar type + * Most-significant 4 bits specify repeated/required/packed etc. + */ + +typedef uint_least8_t pb_type_t; + +/**** Field data types ****/ + +/* Numeric types */ +#define PB_LTYPE_VARINT  0x00 /* int32, int64, enum, bool */ +#define PB_LTYPE_UVARINT 0x01 /* uint32, uint64 */ +#define PB_LTYPE_SVARINT 0x02 /* sint32, sint64 */ +#define PB_LTYPE_FIXED32 0x03 /* fixed32, sfixed32, float */ +#define PB_LTYPE_FIXED64 0x04 /* fixed64, sfixed64, double */ + +/* Marker for last packable field type. */ +#define PB_LTYPE_LAST_PACKABLE 0x04 + +/* Byte array with pre-allocated buffer. + * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ +#define PB_LTYPE_BYTES 0x05 + +/* String with pre-allocated buffer. + * data_size is the maximum length. */ +#define PB_LTYPE_STRING 0x06 + +/* Submessage + * submsg_fields is pointer to field descriptions */ +#define PB_LTYPE_SUBMESSAGE 0x07 + +/* Extension pseudo-field + * The field contains a pointer to pb_extension_t */ +#define PB_LTYPE_EXTENSION 0x08 + +/* Number of declared LTYPES */ +#define PB_LTYPES_COUNT 9 +#define PB_LTYPE_MASK 0x0F + +/**** Field repetition rules ****/ + +#define PB_HTYPE_REQUIRED 0x00 +#define PB_HTYPE_OPTIONAL 0x10 +#define PB_HTYPE_REPEATED 0x20 +#define PB_HTYPE_ONEOF    0x30 +#define PB_HTYPE_MASK     0x30 + +/**** Field allocation types ****/ +  +#define PB_ATYPE_STATIC   0x00 +#define PB_ATYPE_POINTER  0x80 +#define PB_ATYPE_CALLBACK 0x40 +#define PB_ATYPE_MASK     0xC0 + +#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) +#define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) +#define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) + +/* Data type used for storing sizes of struct fields + * and array counts. + */ +#if defined(PB_FIELD_32BIT) +    typedef uint32_t pb_size_t; +    typedef int32_t pb_ssize_t; +#elif defined(PB_FIELD_16BIT) +    typedef uint_least16_t pb_size_t; +    typedef int_least16_t pb_ssize_t; +#else +    typedef uint_least8_t pb_size_t; +    typedef int_least8_t pb_ssize_t; +#endif +#define PB_SIZE_MAX ((pb_size_t)-1) + +/* Data type for storing encoded data and other byte streams. + * This typedef exists to support platforms where uint8_t does not exist. + * You can regard it as equivalent on uint8_t on other platforms. + */ +typedef uint_least8_t pb_byte_t; + +/* This structure is used in auto-generated constants + * to specify struct fields. + * You can change field sizes if you need structures + * larger than 256 bytes or field tags larger than 256. + * The compiler should complain if your .proto has such + * structures. Fix that by defining PB_FIELD_16BIT or + * PB_FIELD_32BIT. + */ +PB_PACKED_STRUCT_START +typedef struct pb_field_s pb_field_t; +struct pb_field_s { +    pb_size_t tag; +    pb_type_t type; +    pb_size_t data_offset; /* Offset of field data, relative to previous field. */ +    pb_ssize_t size_offset; /* Offset of array size or has-boolean, relative to data */ +    pb_size_t data_size; /* Data size in bytes for a single item */ +    pb_size_t array_size; /* Maximum number of entries in array */ +     +    /* Field definitions for submessage +     * OR default value for all other non-array, non-callback types +     * If null, then field will zeroed. */ +    const void *ptr; +} pb_packed; +PB_PACKED_STRUCT_END + +/* Make sure that the standard integer types are of the expected sizes. + * Otherwise fixed32/fixed64 fields can break. + * + * If you get errors here, it probably means that your stdint.h is not + * correct for your platform. + */ +PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) + +/* This structure is used for 'bytes' arrays. + * It has the number of bytes in the beginning, and after that an array. + * Note that actual structs used will have a different length of bytes array. + */ +#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; } +#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) + +struct pb_bytes_array_s { +    pb_size_t size; +    pb_byte_t bytes[1]; +}; +typedef struct pb_bytes_array_s pb_bytes_array_t; + +/* This structure is used for giving the callback function. + * It is stored in the message structure and filled in by the method that + * calls pb_decode. + * + * The decoding callback will be given a limited-length stream + * If the wire type was string, the length is the length of the string. + * If the wire type was a varint/fixed32/fixed64, the length is the length + * of the actual value. + * The function may be called multiple times (especially for repeated types, + * but also otherwise if the message happens to contain the field multiple + * times.) + * + * The encoding callback will receive the actual output stream. + * It should write all the data in one call, including the field tag and + * wire type. It can write multiple fields. + * + * The callback can be null if you want to skip a field. + */ +typedef struct pb_istream_s pb_istream_t; +typedef struct pb_ostream_s pb_ostream_t; +typedef struct pb_callback_s pb_callback_t; +struct pb_callback_s { +#ifdef PB_OLD_CALLBACK_STYLE +    /* Deprecated since nanopb-0.2.1 */ +    union { +        bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void *arg); +        bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, const void *arg); +    } funcs; +#else +    /* New function signature, which allows modifying arg contents in callback. */ +    union { +        bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); +        bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); +    } funcs; +#endif     +     +    /* Free arg for use by callback */ +    void *arg; +}; + +/* Wire types. Library user needs these only in encoder callbacks. */ +typedef enum { +    PB_WT_VARINT = 0, +    PB_WT_64BIT  = 1, +    PB_WT_STRING = 2, +    PB_WT_32BIT  = 5 +} pb_wire_type_t; + +/* Structure for defining the handling of unknown/extension fields. + * Usually the pb_extension_type_t structure is automatically generated, + * while the pb_extension_t structure is created by the user. However, + * if you want to catch all unknown fields, you can also create a custom + * pb_extension_type_t with your own callback. + */ +typedef struct pb_extension_type_s pb_extension_type_t; +typedef struct pb_extension_s pb_extension_t; +struct pb_extension_type_s { +    /* Called for each unknown field in the message. +     * If you handle the field, read off all of its data and return true. +     * If you do not handle the field, do not read anything and return true. +     * If you run into an error, return false. +     * Set to NULL for default handler. +     */ +    bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, +                   uint32_t tag, pb_wire_type_t wire_type); +     +    /* Called once after all regular fields have been encoded. +     * If you have something to write, do so and return true. +     * If you do not have anything to write, just return true. +     * If you run into an error, return false. +     * Set to NULL for default handler. +     */ +    bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); +     +    /* Free field for use by the callback. */ +    const void *arg; +}; + +struct pb_extension_s { +    /* Type describing the extension field. Usually you'll initialize +     * this to a pointer to the automatically generated structure. */ +    const pb_extension_type_t *type; +     +    /* Destination for the decoded data. This must match the datatype +     * of the extension field. */ +    void *dest; +     +    /* Pointer to the next extension handler, or NULL. +     * If this extension does not match a field, the next handler is +     * automatically called. */ +    pb_extension_t *next; + +    /* The decoder sets this to true if the extension was found. +     * Ignored for encoding. */ +    bool found; +}; + +/* Memory allocation functions to use. You can define pb_realloc and + * pb_free to custom functions if you want. */ +#ifdef PB_ENABLE_MALLOC +#   ifndef pb_realloc +#       define pb_realloc(ptr, size) realloc(ptr, size) +#   endif +#   ifndef pb_free +#       define pb_free(ptr) free(ptr) +#   endif +#endif + +/* This is used to inform about need to regenerate .pb.h/.pb.c files. */ +#define PB_PROTO_HEADER_VERSION 30 + +/* These macros are used to declare pb_field_t's in the constant array. */ +/* Size of a structure member, in bytes. */ +#define pb_membersize(st, m) (sizeof ((st*)0)->m) +/* Number of entries in an array. */ +#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) +/* Delta from start of one member to the start of another member. */ +#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) +/* Marks the end of the field list */ +#define PB_LAST_FIELD {0,(pb_type_t) 0,0,0,0,0,0} + +/* Macros for filling in the data_offset field */ +/* data_offset for first field in a message */ +#define PB_DATAOFFSET_FIRST(st, m1, m2) (offsetof(st, m1)) +/* data_offset for subsequent fields */ +#define PB_DATAOFFSET_OTHER(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2)) +/* Choose first/other based on m1 == m2 (deprecated, remains for backwards compatibility) */ +#define PB_DATAOFFSET_CHOOSE(st, m1, m2) (int)(offsetof(st, m1) == offsetof(st, m2) \ +                                  ? PB_DATAOFFSET_FIRST(st, m1, m2) \ +                                  : PB_DATAOFFSET_OTHER(st, m1, m2)) + +/* Required fields are the simplest. They just have delta (padding) from + * previous field end, and the size of the field. Pointer is used for + * submessages and default values. + */ +#define PB_REQUIRED_STATIC(tag, st, m, fd, ltype, ptr) \ +    {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \ +    fd, 0, pb_membersize(st, m), 0, ptr} + +/* Optional fields add the delta to the has_ variable. */ +#define PB_OPTIONAL_STATIC(tag, st, m, fd, ltype, ptr) \ +    {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \ +    fd, \ +    pb_delta(st, has_ ## m, m), \ +    pb_membersize(st, m), 0, ptr} + +/* Repeated fields have a _count field and also the maximum number of entries. */ +#define PB_REPEATED_STATIC(tag, st, m, fd, ltype, ptr) \ +    {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | ltype, \ +    fd, \ +    pb_delta(st, m ## _count, m), \ +    pb_membersize(st, m[0]), \ +    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. */ +#define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \ +    {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \ +    fd, 0, pb_membersize(st, m), 0, ptr} + +#define PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) \ +    {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \ +    fd, 0, pb_membersize(st, m), 0, ptr} +     +#define PB_REPEATED_CALLBACK(tag, st, m, fd, ltype, ptr) \ +    {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REPEATED | ltype, \ +    fd, 0, pb_membersize(st, m), 0, ptr} + +/* Optional extensions don't have the has_ field, as that would be redundant. */ +#define PB_OPTEXT_STATIC(tag, st, m, fd, ltype, ptr) \ +    {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \ +    0, \ +    0, \ +    pb_membersize(st, m), 0, ptr} + +#define PB_OPTEXT_POINTER(tag, st, m, fd, ltype, ptr) \ +    PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) + +#define PB_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \ +    PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) + +/* The mapping from protobuf types to LTYPEs is done using these macros. */ +#define PB_LTYPE_MAP_BOOL       PB_LTYPE_VARINT +#define PB_LTYPE_MAP_BYTES      PB_LTYPE_BYTES +#define PB_LTYPE_MAP_DOUBLE     PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_ENUM       PB_LTYPE_VARINT +#define PB_LTYPE_MAP_UENUM      PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_FIXED32    PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_FIXED64    PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_FLOAT      PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_INT32      PB_LTYPE_VARINT +#define PB_LTYPE_MAP_INT64      PB_LTYPE_VARINT +#define PB_LTYPE_MAP_MESSAGE    PB_LTYPE_SUBMESSAGE +#define PB_LTYPE_MAP_SFIXED32   PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_SFIXED64   PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_SINT32     PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_SINT64     PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_STRING     PB_LTYPE_STRING +#define PB_LTYPE_MAP_UINT32     PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_UINT64     PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_EXTENSION  PB_LTYPE_EXTENSION + +/* This is the actual macro used in field descriptions. + * It takes these arguments: + * - Field tag number + * - Field type:   BOOL, BYTES, DOUBLE, ENUM, UENUM, FIXED32, FIXED64, + *                 FLOAT, INT32, INT64, MESSAGE, SFIXED32, SFIXED64 + *                 SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION + * - Field rules:  REQUIRED, OPTIONAL or REPEATED + * - Allocation:   STATIC or CALLBACK + * - Placement: FIRST or OTHER, depending on if this is the first field in structure. + * - Message name + * - Field name + * - Previous field name (or field name again for first field) + * - Pointer to default value or submsg fields. + */ + +#define PB_FIELD(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ +        PB_ ## rules ## _ ## allocation(tag, message, field, \ +        PB_DATAOFFSET_ ## placement(message, field, prevfield), \ +        PB_LTYPE_MAP_ ## type, ptr) + +/* Field description for oneof fields. This requires taking into account the + * union name also, that's why a separate set of macros is needed. + */ +#define PB_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \ +    {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \ +    fd, pb_delta(st, which_ ## u, u.m), \ +    pb_membersize(st, u.m), 0, ptr} + +#define PB_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \ +    {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \ +    fd, pb_delta(st, which_ ## u, u.m), \ +    pb_membersize(st, u.m[0]), 0, ptr} + +#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), \ +        PB_LTYPE_MAP_ ## type, ptr) + +#define PB_ANONYMOUS_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \ +    {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \ +    fd, pb_delta(st, which_ ## u, m), \ +    pb_membersize(st, m), 0, ptr} + +#define PB_ANONYMOUS_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \ +    {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \ +    fd, pb_delta(st, which_ ## u, m), \ +    pb_membersize(st, m[0]), 0, ptr} + +#define PB_ANONYMOUS_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ +        PB_ANONYMOUS_ONEOF_ ## allocation(union_name, tag, message, field, \ +        PB_DATAOFFSET_ ## placement(message, field, prevfield), \ +        PB_LTYPE_MAP_ ## type, ptr) + +/* These macros are used for giving out error messages. + * They are mostly a debugging aid; the main error information + * is the true/false return value from functions. + * Some code space can be saved by disabling the error + * messages if not used. + * + * PB_SET_ERROR() sets the error message if none has been set yet. + *                msg must be a constant string literal. + * PB_GET_ERROR() always returns a pointer to a string. + * PB_RETURN_ERROR() sets the error and returns false from current + *                   function. + */ +#ifdef PB_NO_ERRMSG +#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream) +#define PB_GET_ERROR(stream) "(errmsg disabled)" +#else +#define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg)) +#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)") +#endif + +#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false + +#endif diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_common.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_common.c new file mode 100644 index 0000000..385c019 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_common.c @@ -0,0 +1,97 @@ +/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c. + * + * 2014 Petteri Aimonen <jpa@kapsi.fi> + */ + +#include "pb_common.h" + +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct) +{ +    iter->start = fields; +    iter->pos = fields; +    iter->required_field_index = 0; +    iter->dest_struct = dest_struct; +    iter->pData = (char*)dest_struct + iter->pos->data_offset; +    iter->pSize = (char*)iter->pData + iter->pos->size_offset; +     +    return (iter->pos->tag != 0); +} + +bool pb_field_iter_next(pb_field_iter_t *iter) +{ +    const pb_field_t *prev_field = iter->pos; + +    if (prev_field->tag == 0) +    { +        /* Handle empty message types, where the first field is already the terminator. +         * In other cases, the iter->pos never points to the terminator. */ +        return false; +    } +     +    iter->pos++; +     +    if (iter->pos->tag == 0) +    { +        /* Wrapped back to beginning, reinitialize */ +        (void)pb_field_iter_begin(iter, iter->start, iter->dest_struct); +        return false; +    } +    else +    { +        /* Increment the pointers based on previous field size */ +        size_t prev_size = prev_field->data_size; +     +        if (PB_HTYPE(prev_field->type) == PB_HTYPE_ONEOF && +            PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF) +        { +            /* Don't advance pointers inside unions */ +            prev_size = 0; +            iter->pData = (char*)iter->pData - prev_field->data_offset; +        } +        else if (PB_ATYPE(prev_field->type) == PB_ATYPE_STATIC && +                 PB_HTYPE(prev_field->type) == PB_HTYPE_REPEATED) +        { +            /* In static arrays, the data_size tells the size of a single entry and +             * array_size is the number of entries */ +            prev_size *= prev_field->array_size; +        } +        else if (PB_ATYPE(prev_field->type) == PB_ATYPE_POINTER) +        { +            /* Pointer fields always have a constant size in the main structure. +             * The data_size only applies to the dynamically allocated area. */ +            prev_size = sizeof(void*); +        } + +        if (PB_HTYPE(prev_field->type) == PB_HTYPE_REQUIRED) +        { +            /* Count the required fields, in order to check their presence in the +             * decoder. */ +            iter->required_field_index++; +        } +     +        iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset; +        iter->pSize = (char*)iter->pData + iter->pos->size_offset; +        return true; +    } +} + +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag) +{ +    const pb_field_t *start = iter->pos; +     +    do { +        if (iter->pos->tag == tag && +            PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION) +        { +            /* Found the wanted field */ +            return true; +        } +         +        (void)pb_field_iter_next(iter); +    } while (iter->pos != start); +     +    /* Searched all the way back to start, and found nothing. */ +    return false; +} + + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_common.h new file mode 100644 index 0000000..60b3d37 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_common.h @@ -0,0 +1,42 @@ +/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c. + * These functions are rarely needed by applications directly. + */ + +#ifndef PB_COMMON_H_INCLUDED +#define PB_COMMON_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Iterator for pb_field_t list */ +struct pb_field_iter_s { +    const pb_field_t *start;       /* Start of the pb_field_t array */ +    const pb_field_t *pos;         /* Current position of the iterator */ +    unsigned required_field_index; /* Zero-based index that counts only the required fields */ +    void *dest_struct;             /* Pointer to start of the structure */ +    void *pData;                   /* Pointer to current field value */ +    void *pSize;                   /* Pointer to count/has field */ +}; +typedef struct pb_field_iter_s pb_field_iter_t; + +/* Initialize the field iterator structure to beginning. + * Returns false if the message type is empty. */ +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct); + +/* Advance the iterator to the next field. + * Returns false when the iterator wraps back to the first field. */ +bool pb_field_iter_next(pb_field_iter_t *iter); + +/* Advance the iterator until it points at a field with the given tag. + * Returns false if no such field exists. */ +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_decode.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_decode.c new file mode 100644 index 0000000..ef69efe --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_decode.c @@ -0,0 +1,1340 @@ +/* pb_decode.c -- decode a protobuf using minimal resources + * + * 2011 Petteri Aimonen <jpa@kapsi.fi> + */ + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) +    #define checkreturn +#else +    #define checkreturn __attribute__((warn_unused_result)) +#endif + +#include "pb.h" +#include "pb_decode.h" +#include "pb_common.h" + +/************************************** + * Declarations internal to this file * + **************************************/ + +typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn; + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); +static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); +static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size); +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension); +static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type); +static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn find_extension_field(pb_field_iter_t *iter); +static void pb_field_set_to_default(pb_field_iter_t *iter); +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 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_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_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_skip_varint(pb_istream_t *stream); +static bool checkreturn pb_skip_string(pb_istream_t *stream); + +#ifdef PB_ENABLE_MALLOC +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size); +static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter); +static void pb_release_single_field(const pb_field_iter_t *iter); +#endif + +/* --- Function pointers to field decoders --- + * Order in the array must match pb_action_t LTYPE numbering. + */ +static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = { +    &pb_dec_varint, +    &pb_dec_uvarint, +    &pb_dec_svarint, +    &pb_dec_fixed32, +    &pb_dec_fixed64, +     +    &pb_dec_bytes, +    &pb_dec_string, +    &pb_dec_submessage, +    NULL /* extensions */ +}; + +/******************************* + * pb_istream_t implementation * + *******************************/ + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +{ +    const pb_byte_t *source = (const pb_byte_t*)stream->state; +    stream->state = (pb_byte_t*)stream->state + count; +     +    if (buf != NULL) +    { +        while (count--) +            *buf++ = *source++; +    } +     +    return true; +} + +bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +{ +#ifndef PB_BUFFER_ONLY +	if (buf == NULL && stream->callback != buf_read) +	{ +		/* Skip input bytes */ +		pb_byte_t tmp[16]; +		while (count > 16) +		{ +			if (!pb_read(stream, tmp, 16)) +				return false; +			 +			count -= 16; +		} +		 +		return pb_read(stream, tmp, count); +	} +#endif + +    if (stream->bytes_left < count) +        PB_RETURN_ERROR(stream, "end-of-stream"); +     +#ifndef PB_BUFFER_ONLY +    if (!stream->callback(stream, buf, count)) +        PB_RETURN_ERROR(stream, "io error"); +#else +    if (!buf_read(stream, buf, count)) +        return false; +#endif +     +    stream->bytes_left -= count; +    return true; +} + +/* Read a single byte from input stream. buf may not be NULL. + * This is an optimization for the varint decoding. */ +static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf) +{ +    if (stream->bytes_left == 0) +        PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY +    if (!stream->callback(stream, buf, 1)) +        PB_RETURN_ERROR(stream, "io error"); +#else +    *buf = *(const pb_byte_t*)stream->state; +    stream->state = (pb_byte_t*)stream->state + 1; +#endif + +    stream->bytes_left--; +     +    return true;     +} + +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize) +{ +    pb_istream_t stream; +    /* Cast away the const from buf without a compiler error.  We are +     * careful to use it only in a const manner in the callbacks. +     */ +    union { +        void *state; +        const void *c_state; +    } state; +#ifdef PB_BUFFER_ONLY +    stream.callback = NULL; +#else +    stream.callback = &buf_read; +#endif +    state.c_state = buf; +    stream.state = state.state; +    stream.bytes_left = bufsize; +    stream.decoding_callback = NULL; +#ifndef PB_NO_ERRMSG +    stream.errmsg = NULL; +#endif +    return stream; +} + +/******************** + * Helper functions * + ********************/ + +static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) +{ +    pb_byte_t byte; +    uint32_t result; +     +    if (!pb_readbyte(stream, &byte)) +        return false; +     +    if ((byte & 0x80) == 0) +    { +        /* Quick case, 1 byte value */ +        result = byte; +    } +    else +    { +        /* Multibyte case */ +        uint_fast8_t bitpos = 7; +        result = byte & 0x7F; +         +        do +        { +            if (bitpos >= 32) +                PB_RETURN_ERROR(stream, "varint overflow"); +             +            if (!pb_readbyte(stream, &byte)) +                return false; +             +            result |= (uint32_t)(byte & 0x7F) << bitpos; +            bitpos = (uint_fast8_t)(bitpos + 7); +        } while (byte & 0x80); +   } +    +   *dest = result; +   return true; +} + +bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) +{ +    pb_byte_t byte; +    uint_fast8_t bitpos = 0; +    uint64_t result = 0; +     +    do +    { +        if (bitpos >= 64) +            PB_RETURN_ERROR(stream, "varint overflow"); +         +        if (!pb_readbyte(stream, &byte)) +            return false; + +        result |= (uint64_t)(byte & 0x7F) << bitpos; +        bitpos = (uint_fast8_t)(bitpos + 7); +    } while (byte & 0x80); +     +    *dest = result; +    return true; +} + +bool checkreturn pb_skip_varint(pb_istream_t *stream) +{ +    pb_byte_t byte; +    do +    { +        if (!pb_read(stream, &byte, 1)) +            return false; +    } while (byte & 0x80); +    return true; +} + +bool checkreturn pb_skip_string(pb_istream_t *stream) +{ +    uint32_t length; +    if (!pb_decode_varint32(stream, &length)) +        return false; +     +    return pb_read(stream, NULL, length); +} + +bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof) +{ +    uint32_t temp; +    *eof = false; +    *wire_type = (pb_wire_type_t) 0; +    *tag = 0; +     +    if (!pb_decode_varint32(stream, &temp)) +    { +        if (stream->bytes_left == 0) +            *eof = true; + +        return false; +    } +     +    if (temp == 0) +    { +        *eof = true; /* Special feature: allow 0-terminated messages. */ +        return false; +    } +     +    *tag = temp >> 3; +    *wire_type = (pb_wire_type_t)(temp & 7); +    return true; +} + +bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type) +{ +    switch (wire_type) +    { +        case PB_WT_VARINT: return pb_skip_varint(stream); +        case PB_WT_64BIT: return pb_read(stream, NULL, 8); +        case PB_WT_STRING: return pb_skip_string(stream); +        case PB_WT_32BIT: return pb_read(stream, NULL, 4); +        default: PB_RETURN_ERROR(stream, "invalid wire_type"); +    } +} + +/* Read a raw value to buffer, for the purpose of passing it to callback as + * a substream. Size is maximum size on call, and actual size on return. + */ +static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size) +{ +    size_t max_size = *size; +    switch (wire_type) +    { +        case PB_WT_VARINT: +            *size = 0; +            do +            { +                (*size)++; +                if (*size > max_size) return false; +                if (!pb_read(stream, buf, 1)) return false; +            } while (*buf++ & 0x80); +            return true; +             +        case PB_WT_64BIT: +            *size = 8; +            return pb_read(stream, buf, 8); +         +        case PB_WT_32BIT: +            *size = 4; +            return pb_read(stream, buf, 4); +         +        default: PB_RETURN_ERROR(stream, "invalid wire_type"); +    } +} + +/* Decode string length from stream and return a substream with limited length. + * Remember to close the substream using pb_close_string_substream(). + */ +bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream) +{ +    uint32_t size; +    if (!pb_decode_varint32(stream, &size)) +        return false; +     +    *substream = *stream; +    if (substream->bytes_left < size) +        PB_RETURN_ERROR(stream, "parent stream too short"); +     +    substream->bytes_left = size; +    stream->bytes_left -= size; +    return true; +} + +void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) +{ +    stream->state = substream->state; + +#ifndef PB_NO_ERRMSG +    stream->errmsg = substream->errmsg; +#endif +} + +/************************* + * Decode a single field * + *************************/ + +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ +    pb_type_t type; +    pb_decoder_t func; +     +    type = iter->pos->type; +    func = PB_DECODERS[PB_LTYPE(type)]; + +    switch (PB_HTYPE(type)) +    { +        case PB_HTYPE_REQUIRED: +            return func(stream, iter->pos, iter->pData); +             +        case PB_HTYPE_OPTIONAL: +            *(bool*)iter->pSize = true; +            return func(stream, iter->pos, iter->pData); +     +        case PB_HTYPE_REPEATED: +            if (wire_type == PB_WT_STRING +                && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) +            { +                /* Packed array */ +                bool status = true; +                pb_size_t *size = (pb_size_t*)iter->pSize; +                pb_istream_t substream; +                if (!pb_make_string_substream(stream, &substream)) +                    return false; +                 +                while (substream.bytes_left > 0 && *size < iter->pos->array_size) +                { +                    void *pItem = (char*)iter->pData + iter->pos->data_size * (*size); +                    if (!func(&substream, iter->pos, pItem)) +                    { +                        status = false; +                        break; +                    } +                    (*size)++; +                } +                pb_close_string_substream(stream, &substream); +                 +                if (substream.bytes_left != 0) +                    PB_RETURN_ERROR(stream, "array overflow"); +                 +                return status; +            } +            else +            { +                /* Repeated field */ +                pb_size_t *size = (pb_size_t*)iter->pSize; +                void *pItem = (char*)iter->pData + iter->pos->data_size * (*size); +                if (*size >= iter->pos->array_size) +                    PB_RETURN_ERROR(stream, "array overflow"); +                 +                (*size)++; +                return func(stream, iter->pos, pItem); +            } + +        case PB_HTYPE_ONEOF: +            *(pb_size_t*)iter->pSize = iter->pos->tag; +            if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) +            { +                /* We memset to zero so that any callbacks are set to NULL. +                 * Then set any default values. */ +                memset(iter->pData, 0, iter->pos->data_size); +                pb_message_set_to_defaults((const pb_field_t*)iter->pos->ptr, iter->pData); +            } +            return func(stream, iter->pos, iter->pData); + +        default: +            PB_RETURN_ERROR(stream, "invalid field type"); +    } +} + +#ifdef PB_ENABLE_MALLOC +/* Allocate storage for the field and store the pointer at iter->pData. + * array_size is the number of entries to reserve in an array. + * Zero size is not allowed, use pb_free() for releasing. + */ +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size) +{     +    void *ptr = *(void**)pData; +     +    if (data_size == 0 || array_size == 0) +        PB_RETURN_ERROR(stream, "invalid size"); +     +    /* Check for multiplication overflows. +     * This code avoids the costly division if the sizes are small enough. +     * Multiplication is safe as long as only half of bits are set +     * in either multiplicand. +     */ +    { +        const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); +        if (data_size >= check_limit || array_size >= check_limit) +        { +            const size_t size_max = (size_t)-1; +            if (size_max / array_size < data_size) +            { +                PB_RETURN_ERROR(stream, "size too large"); +            } +        } +    } +     +    /* Allocate new or expand previous allocation */ +    /* Note: on failure the old pointer will remain in the structure, +     * the message must be freed by caller also on error return. */ +    ptr = pb_realloc(ptr, array_size * data_size); +    if (ptr == NULL) +        PB_RETURN_ERROR(stream, "realloc failed"); +     +    *(void**)pData = ptr; +    return true; +} + +/* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ +static void initialize_pointer_field(void *pItem, pb_field_iter_t *iter) +{ +    if (PB_LTYPE(iter->pos->type) == PB_LTYPE_STRING || +        PB_LTYPE(iter->pos->type) == PB_LTYPE_BYTES) +    { +        *(void**)pItem = NULL; +    } +    else if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE) +    { +        pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, pItem); +    } +} +#endif + +static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ +#ifndef PB_ENABLE_MALLOC +    PB_UNUSED(wire_type); +    PB_UNUSED(iter); +    PB_RETURN_ERROR(stream, "no malloc support"); +#else +    pb_type_t type; +    pb_decoder_t func; +     +    type = iter->pos->type; +    func = PB_DECODERS[PB_LTYPE(type)]; +     +    switch (PB_HTYPE(type)) +    { +        case PB_HTYPE_REQUIRED: +        case PB_HTYPE_OPTIONAL: +        case PB_HTYPE_ONEOF: +            if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE && +                *(void**)iter->pData != NULL) +            { +                /* Duplicate field, have to release the old allocation first. */ +                pb_release_single_field(iter); +            } +         +            if (PB_HTYPE(type) == PB_HTYPE_ONEOF) +            { +                *(pb_size_t*)iter->pSize = iter->pos->tag; +            } + +            if (PB_LTYPE(type) == PB_LTYPE_STRING || +                PB_LTYPE(type) == PB_LTYPE_BYTES) +            { +                return func(stream, iter->pos, iter->pData); +            } +            else +            { +                if (!allocate_field(stream, iter->pData, iter->pos->data_size, 1)) +                    return false; +                 +                initialize_pointer_field(*(void**)iter->pData, iter); +                return func(stream, iter->pos, *(void**)iter->pData); +            } +     +        case PB_HTYPE_REPEATED: +            if (wire_type == PB_WT_STRING +                && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) +            { +                /* Packed array, multiple items come in at once. */ +                bool status = true; +                pb_size_t *size = (pb_size_t*)iter->pSize; +                size_t allocated_size = *size; +                void *pItem; +                pb_istream_t substream; +                 +                if (!pb_make_string_substream(stream, &substream)) +                    return false; +                 +                while (substream.bytes_left) +                { +                    if ((size_t)*size + 1 > allocated_size) +                    { +                        /* Allocate more storage. This tries to guess the +                         * number of remaining entries. Round the division +                         * upwards. */ +                        allocated_size += (substream.bytes_left - 1) / iter->pos->data_size + 1; +                         +                        if (!allocate_field(&substream, iter->pData, iter->pos->data_size, allocated_size)) +                        { +                            status = false; +                            break; +                        } +                    } + +                    /* Decode the array entry */ +                    pItem = *(char**)iter->pData + iter->pos->data_size * (*size); +                    initialize_pointer_field(pItem, iter); +                    if (!func(&substream, iter->pos, pItem)) +                    { +                        status = false; +                        break; +                    } +                     +                    if (*size == PB_SIZE_MAX) +                    { +#ifndef PB_NO_ERRMSG +                        stream->errmsg = "too many array entries"; +#endif +                        status = false; +                        break; +                    } +                     +                    (*size)++; +                } +                pb_close_string_substream(stream, &substream); +                 +                return status; +            } +            else +            { +                /* Normal repeated field, i.e. only one item at a time. */ +                pb_size_t *size = (pb_size_t*)iter->pSize; +                void *pItem; +                 +                if (*size == PB_SIZE_MAX) +                    PB_RETURN_ERROR(stream, "too many array entries"); +                 +                (*size)++; +                if (!allocate_field(stream, iter->pData, iter->pos->data_size, *size)) +                    return false; +             +                pItem = *(char**)iter->pData + iter->pos->data_size * (*size - 1); +                initialize_pointer_field(pItem, iter); +                return func(stream, iter->pos, pItem); +            } + +        default: +            PB_RETURN_ERROR(stream, "invalid field type"); +    } +#endif +} + +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ +    pb_callback_t *pCallback = (pb_callback_t*)iter->pData; +     +#ifdef PB_OLD_CALLBACK_STYLE +    void *arg = pCallback->arg; +#else +    void **arg = &(pCallback->arg); +#endif +     +    if (pCallback->funcs.decode == NULL) +        return pb_skip_field(stream, wire_type); +     +    if (wire_type == PB_WT_STRING) +    { +        pb_istream_t substream; +         +        if (!pb_make_string_substream(stream, &substream)) +            return false; +         +        do +        { +            if (!pCallback->funcs.decode(&substream, iter->pos, arg)) +                PB_RETURN_ERROR(stream, "callback failed"); +        } while (substream.bytes_left); +         +        pb_close_string_substream(stream, &substream); +        return true; +    } +    else +    { +        /* Copy the single scalar value to stack. +         * This is required so that we can limit the stream length, +         * which in turn allows to use same callback for packed and +         * not-packed fields. */ +        pb_istream_t substream; +        pb_byte_t buffer[10]; +        size_t size = sizeof(buffer); +         +        if (!read_raw_value(stream, wire_type, buffer, &size)) +            return false; +        substream = pb_istream_from_buffer(buffer, size); +         +        return pCallback->funcs.decode(&substream, iter->pos, arg); +    } +} + +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ +#ifdef PB_ENABLE_MALLOC +    /* When decoding an oneof field, check if there is old data that must be +     * released first. */ +    if (PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF) +    { +        if (!pb_release_union_field(stream, iter)) +            return false; +    } +#endif + +    switch (PB_ATYPE(iter->pos->type)) +    { +        case PB_ATYPE_STATIC: +            return decode_static_field(stream, wire_type, iter); +         +        case PB_ATYPE_POINTER: +            return decode_pointer_field(stream, wire_type, iter); +         +        case PB_ATYPE_CALLBACK: +            return decode_callback_field(stream, wire_type, iter); +         +        default: +            PB_RETURN_ERROR(stream, "invalid field type"); +    } +} + +static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension) +{ +    /* Fake a field iterator for the extension field. +     * It is not actually safe to advance this iterator, but decode_field +     * will not even try to. */ +    const pb_field_t *field = (const pb_field_t*)extension->type->arg; +    (void)pb_field_iter_begin(iter, field, extension->dest); +    iter->pData = extension->dest; +    iter->pSize = &extension->found; +     +    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) +    { +        /* For pointer extensions, the pointer is stored directly +         * in the extension structure. This avoids having an extra +         * indirection. */ +        iter->pData = &extension->dest; +    } +} + +/* Default handler for extension fields. Expects a pb_field_t structure + * in extension->type->arg. */ +static bool checkreturn default_extension_decoder(pb_istream_t *stream, +    pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type) +{ +    const pb_field_t *field = (const pb_field_t*)extension->type->arg; +    pb_field_iter_t iter; +     +    if (field->tag != tag) +        return true; +     +    iter_from_extension(&iter, extension); +    extension->found = true; +    return decode_field(stream, wire_type, &iter); +} + +/* Try to decode an unknown field as an extension field. Tries each extension + * decoder in turn, until one of them handles the field or loop ends. */ +static bool checkreturn decode_extension(pb_istream_t *stream, +    uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ +    pb_extension_t *extension = *(pb_extension_t* const *)iter->pData; +    size_t pos = stream->bytes_left; +     +    while (extension != NULL && pos == stream->bytes_left) +    { +        bool status; +        if (extension->type->decode) +            status = extension->type->decode(stream, extension, tag, wire_type); +        else +            status = default_extension_decoder(stream, extension, tag, wire_type); + +        if (!status) +            return false; +         +        extension = extension->next; +    } +     +    return true; +} + +/* Step through the iterator until an extension field is found or until all + * entries have been checked. There can be only one extension field per + * message. Returns false if no extension field is found. */ +static bool checkreturn find_extension_field(pb_field_iter_t *iter) +{ +    const pb_field_t *start = iter->pos; +     +    do { +        if (PB_LTYPE(iter->pos->type) == PB_LTYPE_EXTENSION) +            return true; +        (void)pb_field_iter_next(iter); +    } while (iter->pos != start); +     +    return false; +} + +/* Initialize message fields to default values, recursively */ +static void pb_field_set_to_default(pb_field_iter_t *iter) +{ +    pb_type_t type; +    type = iter->pos->type; +     +    if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) +    { +        pb_extension_t *ext = *(pb_extension_t* const *)iter->pData; +        while (ext != NULL) +        { +            pb_field_iter_t ext_iter; +            ext->found = false; +            iter_from_extension(&ext_iter, ext); +            pb_field_set_to_default(&ext_iter); +            ext = ext->next; +        } +    } +    else if (PB_ATYPE(type) == PB_ATYPE_STATIC) +    { +        bool init_data = true; +        if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL) +        { +            /* Set has_field to false. Still initialize the optional field +             * itself also. */ +            *(bool*)iter->pSize = false; +        } +        else if (PB_HTYPE(type) == PB_HTYPE_REPEATED || +                 PB_HTYPE(type) == PB_HTYPE_ONEOF) +        { +            /* REPEATED: Set array count to 0, no need to initialize contents. +               ONEOF: Set which_field to 0. */ +            *(pb_size_t*)iter->pSize = 0; +            init_data = false; +        } + +        if (init_data) +        { +            if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE) +            { +                /* Initialize submessage to defaults */ +                pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, iter->pData); +            } +            else if (iter->pos->ptr != NULL) +            { +                /* Initialize to default value */ +                memcpy(iter->pData, iter->pos->ptr, iter->pos->data_size); +            } +            else +            { +                /* Initialize to zeros */ +                memset(iter->pData, 0, iter->pos->data_size); +            } +        } +    } +    else if (PB_ATYPE(type) == PB_ATYPE_POINTER) +    { +        /* Initialize the pointer to NULL. */ +        *(void**)iter->pData = NULL; +         +        /* Initialize array count to 0. */ +        if (PB_HTYPE(type) == PB_HTYPE_REPEATED || +            PB_HTYPE(type) == PB_HTYPE_ONEOF) +        { +            *(pb_size_t*)iter->pSize = 0; +        } +    } +    else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) +    { +        /* Don't overwrite callback */ +    } +} + +static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct) +{ +    pb_field_iter_t iter; + +    if (!pb_field_iter_begin(&iter, fields, dest_struct)) +        return; /* Empty message type */ +     +    do +    { +        pb_field_set_to_default(&iter); +    } while (pb_field_iter_next(&iter)); +} + +/********************* + * Decode all fields * + *********************/ + +bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ +    uint32_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 31) / 32] = {0, 0}; +    const uint32_t allbits = ~(uint32_t)0; +    uint32_t extension_range_start = 0; +    pb_field_iter_t iter; +     +    /* Return value ignored, as empty message types will be correctly handled by +     * pb_field_iter_find() anyway. */ +    (void)pb_field_iter_begin(&iter, fields, dest_struct); +     +    while (stream->bytes_left) +    { +        uint32_t tag; +        pb_wire_type_t wire_type; +        bool eof; +         +        if (!pb_decode_tag(stream, &wire_type, &tag, &eof)) +        { +            if (eof) +                break; +            else +                return false; +        } +         +        if (!pb_field_iter_find(&iter, tag)) +        { +            /* No match found, check if it matches an extension. */ +            if (tag >= extension_range_start) +            { +                if (!find_extension_field(&iter)) +                    extension_range_start = (uint32_t)-1; +                else +                    extension_range_start = iter.pos->tag; +                 +                if (tag >= extension_range_start) +                { +                    size_t pos = stream->bytes_left; +                 +                    if (!decode_extension(stream, tag, wire_type, &iter)) +                        return false; +                     +                    if (pos != stream->bytes_left) +                    { +                        /* The field was handled */ +                        continue;                     +                    } +                } +            } +         +            /* No match found, skip data */ +            if (!pb_skip_field(stream, wire_type)) +                return false; +            continue; +        } +         +        if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REQUIRED +            && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) +        { +            uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31)); +            fields_seen[iter.required_field_index >> 5] |= tmp; +        } + +        if(stream->decoding_callback) +        { +            stream->decoding_callback(stream, tag, wire_type, &iter); +        } + +        if (!decode_field(stream, wire_type, &iter)) +            return false; +    } +     +    /* Check that all required fields were present. */ +    { +        /* First figure out the number of required fields by +         * seeking to the end of the field array. Usually we +         * are already close to end after decoding. +         */ +        unsigned req_field_count; +        pb_type_t last_type; +        unsigned i; +        do { +            req_field_count = iter.required_field_index; +            last_type = iter.pos->type; +        } while (pb_field_iter_next(&iter)); +         +        /* Fixup if last field was also required. */ +        if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag != 0) +            req_field_count++; +         +        if (req_field_count > 0) +        { +            /* Check the whole words */ +            for (i = 0; i < (req_field_count >> 5); i++) +            { +                if (fields_seen[i] != allbits) +                    PB_RETURN_ERROR(stream, "missing required field"); +            } +             +            /* Check the remaining bits */ +            if (fields_seen[req_field_count >> 5] != (allbits >> (32 - (req_field_count & 31)))) +                PB_RETURN_ERROR(stream, "missing required field"); +        } +    } +     +    return true; +} + +bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ +    bool status; +    pb_message_set_to_defaults(fields, dest_struct); +    status = pb_decode_noinit(stream, fields, dest_struct); +     +#ifdef PB_ENABLE_MALLOC +    if (!status) +        pb_release(fields, dest_struct); +#endif +     +    return status; +} + +bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ +    pb_istream_t substream; +    bool status; +     +    if (!pb_make_string_substream(stream, &substream)) +        return false; +     +    status = pb_decode(&substream, fields, dest_struct); +    pb_close_string_substream(stream, &substream); +    return status; +} + +#ifdef PB_ENABLE_MALLOC +/* Given an oneof field, if there has already been a field inside this oneof, + * release it before overwriting with a different one. */ +static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter) +{ +    pb_size_t old_tag = *(pb_size_t*)iter->pSize; /* Previous which_ value */ +    pb_size_t new_tag = iter->pos->tag; /* New which_ value */ + +    if (old_tag == 0) +        return true; /* Ok, no old data in union */ + +    if (old_tag == new_tag) +        return true; /* Ok, old data is of same type => merge */ + +    /* Release old data. The find can fail if the message struct contains +     * invalid data. */ +    if (!pb_field_iter_find(iter, old_tag)) +        PB_RETURN_ERROR(stream, "invalid union tag"); + +    pb_release_single_field(iter); + +    /* Restore iterator to where it should be. +     * This shouldn't fail unless the pb_field_t structure is corrupted. */ +    if (!pb_field_iter_find(iter, new_tag)) +        PB_RETURN_ERROR(stream, "iterator error"); +     +    return true; +} + +static void pb_release_single_field(const pb_field_iter_t *iter) +{ +    pb_type_t type; +    type = iter->pos->type; + +    if (PB_HTYPE(type) == PB_HTYPE_ONEOF) +    { +        if (*(pb_size_t*)iter->pSize != iter->pos->tag) +            return; /* This is not the current field in the union */ +    } + +    /* Release anything contained inside an extension or submsg. +     * This has to be done even if the submsg itself is statically +     * allocated. */ +    if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) +    { +        /* Release fields from all extensions in the linked list */ +        pb_extension_t *ext = *(pb_extension_t**)iter->pData; +        while (ext != NULL) +        { +            pb_field_iter_t ext_iter; +            iter_from_extension(&ext_iter, ext); +            pb_release_single_field(&ext_iter); +            ext = ext->next; +        } +    } +    else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) +    { +        /* Release fields in submessage or submsg array */ +        void *pItem = iter->pData; +        pb_size_t count = 1; +         +        if (PB_ATYPE(type) == PB_ATYPE_POINTER) +        { +            pItem = *(void**)iter->pData; +        } +         +        if (PB_HTYPE(type) == PB_HTYPE_REPEATED) +        { +            count = *(pb_size_t*)iter->pSize; +        } +         +        if (pItem) +        { +            while (count--) +            { +                pb_release((const pb_field_t*)iter->pos->ptr, pItem); +                pItem = (char*)pItem + iter->pos->data_size; +            } +        } +    } +     +    if (PB_ATYPE(type) == PB_ATYPE_POINTER) +    { +        if (PB_HTYPE(type) == PB_HTYPE_REPEATED && +            (PB_LTYPE(type) == PB_LTYPE_STRING || +             PB_LTYPE(type) == PB_LTYPE_BYTES)) +        { +            /* Release entries in repeated string or bytes array */ +            void **pItem = *(void***)iter->pData; +            pb_size_t count = *(pb_size_t*)iter->pSize; +            while (count--) +            { +                pb_free(*pItem); +                *pItem++ = NULL; +            } +        } +         +        if (PB_HTYPE(type) == PB_HTYPE_REPEATED) +        { +            /* We are going to release the array, so set the size to 0 */ +            *(pb_size_t*)iter->pSize = 0; +        } +         +        /* Release main item */ +        pb_free(*(void**)iter->pData); +        *(void**)iter->pData = NULL; +    } +} + +void pb_release(const pb_field_t fields[], void *dest_struct) +{ +    pb_field_iter_t iter; +     +    if (!dest_struct) +        return; /* Ignore NULL pointers, similar to free() */ + +    if (!pb_field_iter_begin(&iter, fields, dest_struct)) +        return; /* Empty message type */ +     +    do +    { +        pb_release_single_field(&iter); +    } while (pb_field_iter_next(&iter)); +} +#endif + +/* Field decoders */ + +bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest) +{ +    uint64_t value; +    if (!pb_decode_varint(stream, &value)) +        return false; +     +    if (value & 1) +        *dest = (int64_t)(~(value >> 1)); +    else +        *dest = (int64_t)(value >> 1); +     +    return true; +} + +bool pb_decode_fixed32(pb_istream_t *stream, void *dest) +{ +    pb_byte_t bytes[4]; + +    if (!pb_read(stream, bytes, 4)) +        return false; +     +    *(uint32_t*)dest = ((uint32_t)bytes[0] << 0) | +                       ((uint32_t)bytes[1] << 8) | +                       ((uint32_t)bytes[2] << 16) | +                       ((uint32_t)bytes[3] << 24); +    return true; +} + +bool pb_decode_fixed64(pb_istream_t *stream, void *dest) +{ +    pb_byte_t bytes[8]; + +    if (!pb_read(stream, bytes, 8)) +        return false; +     +    *(uint64_t*)dest = ((uint64_t)bytes[0] << 0) | +                       ((uint64_t)bytes[1] << 8) | +                       ((uint64_t)bytes[2] << 16) | +                       ((uint64_t)bytes[3] << 24) | +                       ((uint64_t)bytes[4] << 32) | +                       ((uint64_t)bytes[5] << 40) | +                       ((uint64_t)bytes[6] << 48) | +                       ((uint64_t)bytes[7] << 56); +     +    return true; +} + +static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ +    uint64_t value; +    int64_t svalue; +    int64_t clamped; +    if (!pb_decode_varint(stream, &value)) +        return false; +     +    /* See issue 97: Google's C++ protobuf allows negative varint values to +     * be cast as int32_t, instead of the int64_t that should be used when +     * encoding. Previous nanopb versions had a bug in encoding. In order to +     * not break decoding of such messages, we cast <=32 bit fields to +     * int32_t first to get the sign correct. +     */ +    if (field->data_size == sizeof(int64_t)) +        svalue = (int64_t)value; +    else +        svalue = (int32_t)value; + +    /* Cast to the proper field size, while checking for overflows */ +    if (field->data_size == sizeof(int64_t)) +        clamped = *(int64_t*)dest = svalue; +    else if (field->data_size == sizeof(int32_t)) +        clamped = *(int32_t*)dest = (int32_t)svalue; +    else if (field->data_size == sizeof(int_least16_t)) +        clamped = *(int_least16_t*)dest = (int_least16_t)svalue; +    else if (field->data_size == sizeof(int_least8_t)) +        clamped = *(int_least8_t*)dest = (int_least8_t)svalue; +    else +        PB_RETURN_ERROR(stream, "invalid data_size"); + +    if (clamped != svalue) +        PB_RETURN_ERROR(stream, "integer too large"); +     +    return true; +} + +static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ +    uint64_t value, clamped; +    if (!pb_decode_varint(stream, &value)) +        return false; +     +    /* Cast to the proper field size, while checking for overflows */ +    if (field->data_size == sizeof(uint64_t)) +        clamped = *(uint64_t*)dest = value; +    else if (field->data_size == sizeof(uint32_t)) +        clamped = *(uint32_t*)dest = (uint32_t)value; +    else if (field->data_size == sizeof(uint_least16_t)) +        clamped = *(uint_least16_t*)dest = (uint_least16_t)value; +    else if (field->data_size == sizeof(uint_least8_t)) +        clamped = *(uint_least8_t*)dest = (uint_least8_t)value; +    else +        PB_RETURN_ERROR(stream, "invalid data_size"); +     +    if (clamped != value) +        PB_RETURN_ERROR(stream, "integer too large"); + +    return true; +} + +static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ +    int64_t value, clamped; +    if (!pb_decode_svarint(stream, &value)) +        return false; +     +    /* Cast to the proper field size, while checking for overflows */ +    if (field->data_size == sizeof(int64_t)) +        clamped = *(int64_t*)dest = value; +    else if (field->data_size == sizeof(int32_t)) +        clamped = *(int32_t*)dest = (int32_t)value; +    else if (field->data_size == sizeof(int_least16_t)) +        clamped = *(int_least16_t*)dest = (int_least16_t)value; +    else if (field->data_size == sizeof(int_least8_t)) +        clamped = *(int_least8_t*)dest = (int_least8_t)value; +    else +        PB_RETURN_ERROR(stream, "invalid data_size"); + +    if (clamped != value) +        PB_RETURN_ERROR(stream, "integer too large"); +     +    return true; +} + +static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ +    PB_UNUSED(field); +    return pb_decode_fixed32(stream, dest); +} + +static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ +    PB_UNUSED(field); +    return pb_decode_fixed64(stream, dest); +} + +static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ +    uint32_t size; +    size_t alloc_size; +    pb_bytes_array_t *bdest; +     +    if (!pb_decode_varint32(stream, &size)) +        return false; +     +    if (size > PB_SIZE_MAX) +        PB_RETURN_ERROR(stream, "bytes overflow"); +     +    alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); +    if (size > alloc_size) +        PB_RETURN_ERROR(stream, "size too large"); +     +    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) +    { +#ifndef PB_ENABLE_MALLOC +        PB_RETURN_ERROR(stream, "no malloc support"); +#else +        if (!allocate_field(stream, dest, alloc_size, 1)) +            return false; +        bdest = *(pb_bytes_array_t**)dest; +#endif +    } +    else +    { +        if (alloc_size > field->data_size) +            PB_RETURN_ERROR(stream, "bytes overflow"); +        bdest = (pb_bytes_array_t*)dest; +    } + +    bdest->size = (pb_size_t)size; +    return pb_read(stream, bdest->bytes, size); +} + +static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ +    uint32_t size; +    size_t alloc_size; +    bool status; +    if (!pb_decode_varint32(stream, &size)) +        return false; +     +    /* Space for null terminator */ +    alloc_size = size + 1; +     +    if (alloc_size < size) +        PB_RETURN_ERROR(stream, "size too large"); +     +    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) +    { +#ifndef PB_ENABLE_MALLOC +        PB_RETURN_ERROR(stream, "no malloc support"); +#else +        if (!allocate_field(stream, dest, alloc_size, 1)) +            return false; +        dest = *(void**)dest; +#endif +    } +    else +    { +        if (alloc_size > field->data_size) +            PB_RETURN_ERROR(stream, "string overflow"); +    } +     +    status = pb_read(stream, (pb_byte_t*)dest, size); +    *((pb_byte_t*)dest + size) = 0; +    return status; +} + +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ +    bool status; +    pb_istream_t substream; +    const pb_field_t* submsg_fields = (const pb_field_t*)field->ptr; +     +    if (!pb_make_string_substream(stream, &substream)) +        return false; +     +    if (field->ptr == NULL) +        PB_RETURN_ERROR(stream, "invalid field descriptor"); +     +    /* New array entries need to be initialized, while required and optional +     * submessages have already been initialized in the top-level pb_decode. */ +    if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED) +        status = pb_decode(&substream, submsg_fields, dest); +    else +        status = pb_decode_noinit(&substream, submsg_fields, dest); +     +    pb_close_string_substream(stream, &substream); +    return status; +} diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_decode.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_decode.h new file mode 100644 index 0000000..7ab8ce7 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_decode.h @@ -0,0 +1,152 @@ +/* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c. + * The main function is pb_decode. You also need an input stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_DECODE_H_INCLUDED +#define PB_DECODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom input streams. You will need to provide + * a callback function to read the bytes from your storage, which can be + * for example a file or a network socket. + *  + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause decoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer), + *    and rely on pb_read to verify that no-body reads past bytes_left. + * 3) Your callback may be used with substreams, in which case bytes_left + *    is different than from the main stream. Don't use bytes_left to compute + *    any pointers. + */ +struct pb_istream_s +{ +#ifdef PB_BUFFER_ONLY +    /* Callback pointer is not used in buffer-only configuration. +     * Having an int pointer here allows binary compatibility but +     * gives an error if someone tries to assign callback function. +     */ +    int *callback; +#else +    bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count); +#endif + +    void *state; /* Free field for use by callback implementation */ +    size_t bytes_left; +     +    /* Informative callback for field decoding */ +    void (* decoding_callback)(pb_istream_t *strem, uint32_t tag, pb_wire_type_t wire_type, void *iter); + +#ifndef PB_NO_ERRMSG +    const char *errmsg; +#endif +}; + +/*************************** + * Main decoding functions * + ***************************/ +  +/* Decode a single protocol buffers message from input stream into a C structure. + * Returns true on success, false on any failure. + * The actual struct pointed to by dest must match the description in fields. + * Callback fields of the destination structure must be initialized by caller. + * All other fields will be initialized by this function. + * + * Example usage: + *    MyMessage msg = {}; + *    uint8_t buffer[64]; + *    pb_istream_t stream; + *     + *    // ... read some data into buffer ... + * + *    stream = pb_istream_from_buffer(buffer, count); + *    pb_decode(&stream, MyMessage_fields, &msg); + */ +bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +/* Same as pb_decode, except does not initialize the destination structure + * to default values. This is slightly faster if you need no default values + * and just do memset(struct, 0, sizeof(struct)) yourself. + * + * This can also be used for 'merging' two messages, i.e. update only the + * fields that exist in the new message. + * + * Note: If this function returns with an error, it will not release any + * dynamically allocated fields. You will need to call pb_release() yourself. + */ +bool pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +/* Same as pb_decode, except expects the stream to start with the message size + * encoded as varint. Corresponds to parseDelimitedFrom() in Google's + * protobuf API. + */ +bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +#ifdef PB_ENABLE_MALLOC +/* Release any allocated pointer fields. If you use dynamic allocation, you should + * call this for any successfully decoded message when you are done with it. If + * pb_decode() returns with an error, the message is already released. + */ +void pb_release(const pb_field_t fields[], void *dest_struct); +#endif + + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an input stream for reading from a memory buffer. + * + * Alternatively, you can use a custom stream that reads directly from e.g. + * a file or a network socket. + */ +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize); + +/* Function to read from a pb_istream_t. You can use this if you need to + * read some custom header data, or to read data in field callbacks. + */ +bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); + + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Decode the tag for the next field in the stream. Gives the wire type and + * field tag. At end of the message, returns false and sets eof to true. */ +bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof); + +/* Skip the field payload data, given the wire type. */ +bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type); + +/* Decode an integer in the varint format. This works for bool, enum, int32, + * int64, uint32 and uint64 field types. */ +bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); + +/* Decode an integer in the zig-zagged svarint format. This works for sint32 + * and sint64. */ +bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest); + +/* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to + * a 4-byte wide C variable. */ +bool pb_decode_fixed32(pb_istream_t *stream, void *dest); + +/* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to + * a 8-byte wide C variable. */ +bool pb_decode_fixed64(pb_istream_t *stream, void *dest); + +/* Make a limited-length substream for reading a PB_WT_STRING field. */ +bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream); +void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_encode.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_encode.c new file mode 100644 index 0000000..9f91c9d --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_encode.c @@ -0,0 +1,689 @@ +/* pb_encode.c -- encode a protobuf using minimal resources + * + * 2011 Petteri Aimonen <jpa@kapsi.fi> + */ + +#include "pb.h" +#include "pb_encode.h" +#include "pb_common.h" + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) +    #define checkreturn +#else +    #define checkreturn __attribute__((warn_unused_result)) +#endif + +/************************************** + * Declarations internal to this file * + **************************************/ +typedef bool (*pb_encoder_t)(pb_ostream_t *stream, const pb_field_t *field, const void *src) checkreturn; + +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); +static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, const void *pData, size_t count, pb_encoder_t func); +static bool checkreturn encode_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData); +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 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_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_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src); + +/* --- Function pointers to field encoders --- + * Order in the array must match pb_action_t LTYPE numbering. + */ +static const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = { +    &pb_enc_varint, +    &pb_enc_uvarint, +    &pb_enc_svarint, +    &pb_enc_fixed32, +    &pb_enc_fixed64, +     +    &pb_enc_bytes, +    &pb_enc_string, +    &pb_enc_submessage, +    NULL /* extensions */ +}; + +/******************************* + * pb_ostream_t implementation * + *******************************/ + +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +{ +    pb_byte_t *dest = (pb_byte_t*)stream->state; +    stream->state = dest + count; +     +    while (count--) +        *dest++ = *buf++; +     +    return true; +} + +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize) +{ +    pb_ostream_t stream; +#ifdef PB_BUFFER_ONLY +    stream.callback = (void*)1; /* Just a marker value */ +#else +    stream.callback = &buf_write; +#endif +    stream.state = buf; +    stream.max_size = bufsize; +    stream.bytes_written = 0; +#ifndef PB_NO_ERRMSG +    stream.errmsg = NULL; +#endif +    return stream; +} + +bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +{ +    if (stream->callback != NULL) +    { +        if (stream->bytes_written + count > stream->max_size) +            PB_RETURN_ERROR(stream, "stream full"); + +#ifdef PB_BUFFER_ONLY +        if (!buf_write(stream, buf, count)) +            PB_RETURN_ERROR(stream, "io error"); +#else         +        if (!stream->callback(stream, buf, count)) +            PB_RETURN_ERROR(stream, "io error"); +#endif +    } +     +    stream->bytes_written += count; +    return true; +} + +/************************* + * Encode a single field * + *************************/ + +/* Encode a static array. Handles the size calculations and possible packing. */ +static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, +                         const void *pData, size_t count, pb_encoder_t func) +{ +    size_t i; +    const void *p; +    size_t size; +     +    if (count == 0) +        return true; + +    if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size) +        PB_RETURN_ERROR(stream, "array max size exceeded"); +     +    /* We always pack arrays if the datatype allows it. */ +    if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) +    { +        if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) +            return false; +         +        /* Determine the total size of packed array. */ +        if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32) +        { +            size = 4 * count; +        } +        else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64) +        { +            size = 8 * count; +        } +        else +        {  +            pb_ostream_t sizestream = PB_OSTREAM_SIZING; +            p = pData; +            for (i = 0; i < count; i++) +            { +                if (!func(&sizestream, field, p)) +                    return false; +                p = (const char*)p + field->data_size; +            } +            size = sizestream.bytes_written; +        } +         +        if (!pb_encode_varint(stream, (uint64_t)size)) +            return false; +         +        if (stream->callback == NULL) +            return pb_write(stream, NULL, size); /* Just sizing.. */ +         +        /* Write the data */ +        p = pData; +        for (i = 0; i < count; i++) +        { +            if (!func(stream, field, p)) +                return false; +            p = (const char*)p + field->data_size; +        } +    } +    else +    { +        p = pData; +        for (i = 0; i < count; i++) +        { +            if (!pb_encode_tag_for_field(stream, field)) +                return false; + +            /* Normally the data is stored directly in the array entries, but +             * for pointer-type string and bytes fields, the array entries are +             * actually pointers themselves also. So we have to dereference once +             * more to get to the actual data. */ +            if (PB_ATYPE(field->type) == PB_ATYPE_POINTER && +                (PB_LTYPE(field->type) == PB_LTYPE_STRING || +                 PB_LTYPE(field->type) == PB_LTYPE_BYTES)) +            { +                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; +        } +    } +     +    return true; +} + +/* Encode a field with static or pointer allocation, i.e. one whose data + * is available to the encoder directly. */ +static bool checkreturn encode_basic_field(pb_ostream_t *stream, +    const pb_field_t *field, const void *pData) +{ +    pb_encoder_t func; +    const void *pSize; +    bool implicit_has = true; +     +    func = PB_ENCODERS[PB_LTYPE(field->type)]; +     +    if (field->size_offset) +        pSize = (const char*)pData + field->size_offset; +    else +        pSize = &implicit_has; + +    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)) +    { +        case PB_HTYPE_REQUIRED: +            if (!pData) +                PB_RETURN_ERROR(stream, "missing required field"); +            if (!pb_encode_tag_for_field(stream, field)) +                return false; +            if (!func(stream, field, pData)) +                return false; +            break; +         +        case PB_HTYPE_OPTIONAL: +            if (*(const bool*)pSize) +            { +                if (!pb_encode_tag_for_field(stream, field)) +                    return false; +             +                if (!func(stream, field, pData)) +                    return false; +            } +            break; +         +        case PB_HTYPE_REPEATED: +            if (!encode_array(stream, field, pData, *(const pb_size_t*)pSize, func)) +                return false; +            break; +         +        case PB_HTYPE_ONEOF: +            if (*(const pb_size_t*)pSize == field->tag) +            { +                if (!pb_encode_tag_for_field(stream, field)) +                    return false; + +                if (!func(stream, field, pData)) +                    return false; +            } +            break; +             +        default: +            PB_RETURN_ERROR(stream, "invalid field type"); +    } +     +    return true; +} + +/* Encode a field with callback semantics. This means that a user function is + * called to provide and encode the actual data. */ +static bool checkreturn encode_callback_field(pb_ostream_t *stream, +    const pb_field_t *field, const void *pData) +{ +    const pb_callback_t *callback = (const pb_callback_t*)pData; +     +#ifdef PB_OLD_CALLBACK_STYLE +    const void *arg = callback->arg; +#else +    void * const *arg = &(callback->arg); +#endif     +     +    if (callback->funcs.encode != NULL) +    { +        if (!callback->funcs.encode(stream, field, arg)) +            PB_RETURN_ERROR(stream, "callback error"); +    } +    return true; +} + +/* Encode a single field of any callback or static type. */ +static bool checkreturn encode_field(pb_ostream_t *stream, +    const pb_field_t *field, const void *pData) +{ +    switch (PB_ATYPE(field->type)) +    { +        case PB_ATYPE_STATIC: +        case PB_ATYPE_POINTER: +            return encode_basic_field(stream, field, pData); +         +        case PB_ATYPE_CALLBACK: +            return encode_callback_field(stream, field, pData); +         +        default: +            PB_RETURN_ERROR(stream, "invalid field type"); +    } +} + +/* Default handler for extension fields. Expects to have a pb_field_t + * pointer in the extension->type->arg field. */ +static bool checkreturn default_extension_encoder(pb_ostream_t *stream, +    const pb_extension_t *extension) +{ +    const pb_field_t *field = (const pb_field_t*)extension->type->arg; +     +    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) +    { +        /* For pointer extensions, the pointer is stored directly +         * in the extension structure. This avoids having an extra +         * indirection. */ +        return encode_field(stream, field, &extension->dest); +    } +    else +    { +        return encode_field(stream, field, extension->dest); +    } +} + +/* Walk through all the registered extensions and give them a chance + * to encode themselves. */ +static bool checkreturn encode_extension_field(pb_ostream_t *stream, +    const pb_field_t *field, const void *pData) +{ +    const pb_extension_t *extension = *(const pb_extension_t* const *)pData; +    PB_UNUSED(field); +     +    while (extension) +    { +        bool status; +        if (extension->type->encode) +            status = extension->type->encode(stream, extension); +        else +            status = default_extension_encoder(stream, extension); + +        if (!status) +            return false; +         +        extension = extension->next; +    } +     +    return true; +} + +/********************* + * Encode all fields * + *********************/ + +static void *remove_const(const void *p) +{ +    /* Note: this casts away const, in order to use the common field iterator +     * logic for both encoding and decoding. */ +    union { +        void *p1; +        const void *p2; +    } t; +    t.p2 = p; +    return t.p1; +} + +bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) +{ +    pb_field_iter_t iter; +    if (!pb_field_iter_begin(&iter, fields, remove_const(src_struct))) +        return true; /* Empty message type */ +     +    do { +        if (PB_LTYPE(iter.pos->type) == PB_LTYPE_EXTENSION) +        { +            /* Special case for the extension field placeholder */ +            if (!encode_extension_field(stream, iter.pos, iter.pData)) +                return false; +        } +        else +        { +            /* Regular field */ +            if (!encode_field(stream, iter.pos, iter.pData)) +                return false; +        } +    } while (pb_field_iter_next(&iter)); +     +    return true; +} + +bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) +{ +    return pb_encode_submessage(stream, fields, src_struct); +} + +bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct) +{ +    pb_ostream_t stream = PB_OSTREAM_SIZING; +     +    if (!pb_encode(&stream, fields, src_struct)) +        return false; +     +    *size = stream.bytes_written; +    return true; +} + +/******************** + * Helper functions * + ********************/ +bool checkreturn pb_encode_varint(pb_ostream_t *stream, uint64_t value) +{ +    pb_byte_t buffer[10]; +    size_t i = 0; +     +    if (value <= 0x7F) +    { +        pb_byte_t v = (pb_byte_t)value; +        return pb_write(stream, &v, 1); +    } +     +    while (value) +    { +        buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80); +        value >>= 7; +        i++; +    } +    buffer[i-1] &= 0x7F; /* Unset top bit on last byte */ +     +    return pb_write(stream, buffer, i); +} + +bool checkreturn pb_encode_svarint(pb_ostream_t *stream, int64_t value) +{ +    uint64_t zigzagged; +    if (value < 0) +        zigzagged = ~((uint64_t)value << 1); +    else +        zigzagged = (uint64_t)value << 1; +     +    return pb_encode_varint(stream, zigzagged); +} + +bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value) +{ +    uint32_t val = *(const uint32_t*)value; +    pb_byte_t bytes[4]; +    bytes[0] = (pb_byte_t)(val & 0xFF); +    bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); +    bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); +    bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); +    return pb_write(stream, bytes, 4); +} + +bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) +{ +    uint64_t val = *(const uint64_t*)value; +    pb_byte_t bytes[8]; +    bytes[0] = (pb_byte_t)(val & 0xFF); +    bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); +    bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); +    bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); +    bytes[4] = (pb_byte_t)((val >> 32) & 0xFF); +    bytes[5] = (pb_byte_t)((val >> 40) & 0xFF); +    bytes[6] = (pb_byte_t)((val >> 48) & 0xFF); +    bytes[7] = (pb_byte_t)((val >> 56) & 0xFF); +    return pb_write(stream, bytes, 8); +} + +bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number) +{ +    uint64_t tag = ((uint64_t)field_number << 3) | wiretype; +    return pb_encode_varint(stream, tag); +} + +bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field) +{ +    pb_wire_type_t wiretype; +    switch (PB_LTYPE(field->type)) +    { +        case PB_LTYPE_VARINT: +        case PB_LTYPE_UVARINT: +        case PB_LTYPE_SVARINT: +            wiretype = PB_WT_VARINT; +            break; +         +        case PB_LTYPE_FIXED32: +            wiretype = PB_WT_32BIT; +            break; +         +        case PB_LTYPE_FIXED64: +            wiretype = PB_WT_64BIT; +            break; +         +        case PB_LTYPE_BYTES: +        case PB_LTYPE_STRING: +        case PB_LTYPE_SUBMESSAGE: +            wiretype = PB_WT_STRING; +            break; +         +        default: +            PB_RETURN_ERROR(stream, "invalid field type"); +    } +     +    return pb_encode_tag(stream, wiretype, field->tag); +} + +bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size) +{ +    if (!pb_encode_varint(stream, (uint64_t)size)) +        return false; +     +    return pb_write(stream, buffer, size); +} + +bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) +{ +    /* First calculate the message size using a non-writing substream. */ +    pb_ostream_t substream = PB_OSTREAM_SIZING; +    size_t size; +    bool status; +     +    if (!pb_encode(&substream, fields, src_struct)) +    { +#ifndef PB_NO_ERRMSG +        stream->errmsg = substream.errmsg; +#endif +        return false; +    } +     +    size = substream.bytes_written; +     +    if (!pb_encode_varint(stream, (uint64_t)size)) +        return false; +     +    if (stream->callback == NULL) +        return pb_write(stream, NULL, size); /* Just sizing */ +     +    if (stream->bytes_written + size > stream->max_size) +        PB_RETURN_ERROR(stream, "stream full"); +         +    /* Use a substream to verify that a callback doesn't write more than +     * what it did the first time. */ +    substream.callback = stream->callback; +    substream.state = stream->state; +    substream.max_size = size; +    substream.bytes_written = 0; +#ifndef PB_NO_ERRMSG +    substream.errmsg = NULL; +#endif +     +    status = pb_encode(&substream, fields, src_struct); +     +    stream->bytes_written += substream.bytes_written; +    stream->state = substream.state; +#ifndef PB_NO_ERRMSG +    stream->errmsg = substream.errmsg; +#endif +     +    if (substream.bytes_written != size) +        PB_RETURN_ERROR(stream, "submsg size changed"); +     +    return status; +} + +/* Field encoders */ + +static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ +    int64_t value = 0; +     +    if (field->data_size == sizeof(int_least8_t)) +        value = *(const int_least8_t*)src; +    else if (field->data_size == sizeof(int_least16_t)) +        value = *(const int_least16_t*)src; +    else if (field->data_size == sizeof(int32_t)) +        value = *(const int32_t*)src; +    else if (field->data_size == sizeof(int64_t)) +        value = *(const int64_t*)src; +    else +        PB_RETURN_ERROR(stream, "invalid data_size"); +     +    return pb_encode_varint(stream, (uint64_t)value); +} + +static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ +    uint64_t value = 0; +     +    if (field->data_size == sizeof(uint_least8_t)) +        value = *(const uint_least8_t*)src; +    else if (field->data_size == sizeof(uint_least16_t)) +        value = *(const uint_least16_t*)src; +    else if (field->data_size == sizeof(uint32_t)) +        value = *(const uint32_t*)src; +    else if (field->data_size == sizeof(uint64_t)) +        value = *(const uint64_t*)src; +    else +        PB_RETURN_ERROR(stream, "invalid data_size"); +     +    return pb_encode_varint(stream, value); +} + +static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ +    int64_t value = 0; +     +    if (field->data_size == sizeof(int_least8_t)) +        value = *(const int_least8_t*)src; +    else if (field->data_size == sizeof(int_least16_t)) +        value = *(const int_least16_t*)src; +    else if (field->data_size == sizeof(int32_t)) +        value = *(const int32_t*)src; +    else if (field->data_size == sizeof(int64_t)) +        value = *(const int64_t*)src; +    else +        PB_RETURN_ERROR(stream, "invalid data_size"); +     +    return pb_encode_svarint(stream, value); +} + +static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ +    PB_UNUSED(field); +    return pb_encode_fixed64(stream, src); +} + +static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ +    PB_UNUSED(field); +    return pb_encode_fixed32(stream, src); +} + +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; +     +    if (src == NULL) +    { +        /* Threat null pointer as an empty bytes field */ +        return pb_encode_string(stream, NULL, 0); +    } +     +    if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && +        PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) > field->data_size) +    { +        PB_RETURN_ERROR(stream, "bytes size exceeded"); +    } +     +    return pb_encode_string(stream, bytes->bytes, bytes->size); +} + +static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ +    size_t size = 0; +    size_t max_size = field->data_size; +    const char *p = (const char*)src; +     +    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) +        max_size = (size_t)-1; + +    if (src == NULL) +    { +        size = 0; /* Threat null pointer as an empty string */ +    } +    else +    { +        /* strnlen() is not always available, so just use a loop */ +        while (size < max_size && *p != '\0') +        { +            size++; +            p++; +        } +    } + +    return pb_encode_string(stream, (const pb_byte_t*)src, size); +} + +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ +    if (field->ptr == NULL) +        PB_RETURN_ERROR(stream, "invalid field descriptor"); +     +    return pb_encode_submessage(stream, (const pb_field_t*)field->ptr, src); +} + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_encode.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_encode.h new file mode 100644 index 0000000..d9909fb --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/nano-pb/pb_encode.h @@ -0,0 +1,154 @@ +/* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c. + * The main function is pb_encode. You also need an output stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_ENCODE_H_INCLUDED +#define PB_ENCODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom output streams. You will need to provide + * a callback function to write the bytes to your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause encoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer). + * 3) pb_write will update bytes_written after your callback runs. + * 4) Substreams will modify max_size and bytes_written. Don't use them + *    to calculate any pointers. + */ +struct pb_ostream_s +{ +#ifdef PB_BUFFER_ONLY +    /* Callback pointer is not used in buffer-only configuration. +     * Having an int pointer here allows binary compatibility but +     * gives an error if someone tries to assign callback function. +     * Also, NULL pointer marks a 'sizing stream' that does not +     * write anything. +     */ +    int *callback; +#else +    bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); +#endif +    void *state;          /* Free field for use by callback implementation. */ +    size_t max_size;      /* Limit number of output bytes written (or use SIZE_MAX). */ +    size_t bytes_written; /* Number of bytes written so far. */ +     +#ifndef PB_NO_ERRMSG +    const char *errmsg; +#endif +}; + +/*************************** + * Main encoding functions * + ***************************/ + +/* Encode a single protocol buffers message from C structure into a stream. + * Returns true on success, false on any failure. + * The actual struct pointed to by src_struct must match the description in fields. + * All required fields in the struct are assumed to have been filled in. + * + * Example usage: + *    MyMessage msg = {}; + *    uint8_t buffer[64]; + *    pb_ostream_t stream; + * + *    msg.field1 = 42; + *    stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + *    pb_encode(&stream, MyMessage_fields, &msg); + */ +bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +/* Same as pb_encode, but prepends the length of the message as a varint. + * Corresponds to writeDelimitedTo() in Google's protobuf API. + */ +bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +/* Encode the message to get the size of the encoded data, but do not store + * the data. */ +bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct); + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an output stream for writing into a memory buffer. + * The number of bytes written can be found in stream.bytes_written after + * encoding the message. + * + * Alternatively, you can use a custom stream that writes directly to e.g. + * a file or a network socket. + */ +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); + +/* Pseudo-stream for measuring the size of a message without actually storing + * the encoded data. + *  + * Example usage: + *    MyMessage msg = {}; + *    pb_ostream_t stream = PB_OSTREAM_SIZING; + *    pb_encode(&stream, MyMessage_fields, &msg); + *    printf("Message size is %d\n", stream.bytes_written); + */ +#ifndef PB_NO_ERRMSG +#define PB_OSTREAM_SIZING {0,0,0,0,0} +#else +#define PB_OSTREAM_SIZING {0,0,0,0} +#endif + +/* Function to write into a pb_ostream_t stream. You can use this if you need + * to append or prepend some custom headers to the message. + */ +bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); + + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Encode field header based on type and field number defined in the field + * structure. Call this from the callback before writing out field contents. */ +bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field); + +/* Encode field header by manually specifing wire type. You need to use this + * if you want to write out packed arrays from a callback field. */ +bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number); + +/* Encode an integer in the varint format. + * This works for bool, enum, int32, int64, uint32 and uint64 field types. */ +bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); + +/* Encode an integer in the zig-zagged svarint format. + * This works for sint32 and sint64. */ +bool pb_encode_svarint(pb_ostream_t *stream, int64_t value); + +/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */ +bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size); + +/* Encode a fixed32, sfixed32 or float value. + * You need to pass a pointer to a 4-byte wide C variable. */ +bool pb_encode_fixed32(pb_ostream_t *stream, const void *value); + +/* Encode a fixed64, sfixed64 or double value. + * You need to pass a pointer to a 8-byte wide C variable. */ +bool pb_encode_fixed64(pb_ostream_t *stream, const void *value); + +/* Encode a submessage field. + * You need to pass the pb_field_t array and pointer to struct, just like + * with pb_encode(). This internally encodes the submessage twice, first to + * calculate message size and then to actually write it out. + */ +bool pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif | 
