def generate_encoded_size(self):
        result = ""
        msize = self.get_encoded_size()
        if msize is not None:
            submessage_exist = any(
                isinstance(x.data_type, MessageProtoType) for x in self.fields)
            if submessage_exist:
                msize = EncodedSize()
                for field in self.fields:
                    fieldsize = field.get_encoded_size()
                    if isinstance(field.data_type, MessageProtoType):
                        msize += field.data_type.message.struct_name + "_size"
                        msize += Support.varint_max_size(field.id << 3)
                        msize += Support.varint_max_size(
                            fieldsize.upperlimit())
                    else:
                        msize += fieldsize

            identifier = f"{self.struct_name}_size"

            extra = " + PB_VARINT_MAX_ENCODED_SIZE" if submessage_exist else ""
            result += f"#define {identifier:<80} ({msize}{extra})\n"
            # PB_VARINT_MAX_ENCODED_SIZE is added since we shift the result when writing a message to
            # be able to go back and add the size
        else:
            identifier = f"{self.struct_name}_static_size"
            result += f"/* {identifier} depends on runtime parameters */\n"
            result += (
                f"#define {identifier:<80} {self.get_encoded_size_static_only()}\n"
            )
        return result
    def pb_field_t(self, prev_field_name, union_index=None):
        """Return the pb_field_t initializer to use in the constant array.
        prev_field_name is the name of the previous field or None.
        """

        tag = get_prototype_tag(self.data_type)

        result = "    PB_FIELD("
        result += f"{self.id:>3}, "
        result += f"{tag:<5}, "
        result += "{size:<5}, ".format(size=Support.varint_max_size(tag))
        result += "{type:<8}, ".format(type=self.get_type(self.data_type))
        result += "{}, ".format("REPEATED" if isinstance(
            self.data_type, ArrayProtoType) else "OPTIONAL")
        result += "{:<8}, ".format("STATIC" if self.data_type.allocation ==
                                   Allocation.STATIC else "POINTER")

        if prev_field_name is None:
            result += "FIRST, "
        else:
            result += "OTHER, "

        result += f"{self.parent.struct_name}, "
        result += f"{self.entry_name}, "
        result += "{}, ".format(prev_field_name or self.entry_name)

        if isinstance(self.data_type, MessageProtoType):
            result += "&{name}_fields)".format(
                name=self.data_type.message.get_full_name().to_string("_"))
        else:
            result += "0)"

        return result
Exemple #3
0
    def html_table_row(self, enc_size_str):
        resolution, min_str, max_str = HtmlField.get_resolution_min_max(
            self.data_type)

        if self.unit != "":
            min_str = f"{min_str} {self.unit}"
            max_str = f"{max_str} {self.unit}"

        type_with_link = self.data_type.get_name()
        data_type = self.data_type
        if isinstance(data_type, ArrayProtoType):
            type_with_link += f"[{self.data_type.max_count}]"
            data_type = self.data_type.data_type

        # TODO: Think about adding link for external dependencies
        if isinstance(data_type, MessageProtoType) or isinstance(
                data_type, EnumProtoType):
            type_with_link = '<a href="#{name}">{type_name}</a>'.format(
                name=self.data_type.get_name(), type_name=type_with_link)

        return "<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>\n".format(
            self.name,
            type_with_link,
            min_str,
            max_str,
            resolution,
            self.unit,
            enc_size_str,
            Support.varint_max_size(self.id << 3),
            self.description,
        )
Exemple #4
0
    def __init__(
        self,
        name: str,
        descriptor: descriptor.EnumDescriptorProto,
        parent: SppParentGuarantees,
        enum_options: descriptor.EnumOptions,
    ):
        self.name = name
        self.parent = parent
        self.description = None
        if enum_options.description != "":
            self.description = enum_options.description

        values_dict = {}
        for x in descriptor.value:
            values_dict[x.number] = self.create_enum_value(x.number, x.name)

        self.values = [values_dict[x] for x in sorted(values_dict)]
        self.encoded_size = EncodedSize(
            max([
                Support.varint_max_size(enum_value.number)
                for enum_value in self.values
            ]))
        self.min_value = min([enum_value.number for enum_value in self.values])
        self.max_value = max([enum_value.number for enum_value in self.values])
Exemple #5
0
    def _calculate_encoded_size(self, raw_min, raw_max):
        min_encoded = Support.varint_max_size(raw_min)
        max_encoded = Support.varint_max_size(raw_max)

        self.encoded_size = EncodedSize(max(min_encoded, max_encoded))

        int_min = self.int_min
        int_max = self.int_max
        if self.numeric_type.name.startswith("S"):
            int_min = Support.svarint_convert(int_min)
            int_max = Support.svarint_convert(int_max)

        min_size = Support.varint_max_size(int_min)
        max_size = Support.varint_max_size(int_max)

        self.encoded_size.add_reduction(self.encoded_size.value -
                                        max(min_size, max_size))
Exemple #6
0
 def __init__(
     self,
     field_options: so.SystemFieldOptions,
     identifier: int,
     allow_pointer: bool,
     require_max_size: bool,
 ):
     super().__init__(field_options, identifier, allow_pointer, 2)
     self.name = None
     self.max_size = None
     if field_options.max_size != 0:
         self.max_size = field_options.max_size
         self.encoded_size = EncodedSize(
             Support.varint_max_size(self.max_size) + self.max_size)
     elif require_max_size and self.allocation == Allocation.STATIC:
         raise Exception(f"Missing max_size {self.id} {self.allocation}")
Exemple #7
0
    def html(self, proto_file):
        type_name = self.get_full_name().remove_from_beginning(
            self.get_package())
        result = '<h2 id="{full_name}">{type_name} ({full_name})</h2>\n'.format(
            full_name=self.get_full_name(),
            type_name=type_name,
        )
        if self.source:
            result += "Source: {name} ({source})\n<br>\n".format(
                name=ds._DATASOURCE.values_by_number[self.source].name,
                source=self.source,
            )
        if self.identifier:
            result += f"Identifier: {self.identifier} ({self.identifier:0x})\n<br>\n"
        if self.version:
            result += f"Version: {self.version}\n<br>\n"
        if self.description:
            result += self.description + "\n<br>\n"
        result += '<table class="property-table">\n'
        result += HtmlField.html_table_header()
        total_enc_size = EncodedSize()
        total_tag_sizes = 0
        for field in self.fields:
            enc_size_str = ""
            encsize = field.get_encoded_size()
            if encsize is not None:
                if isinstance(encsize, EncodedSize):
                    enc_size_str = encsize.string_with_reduction()
                else:
                    raise Exception("TODO: Fix it")  # TODO: Remove
                total_enc_size += encsize
            total_tag_sizes += Support.varint_max_size(field.id << 3)
            default = field.html_table_row(enc_size_str)
            if default is not None:
                result += default
        total_enc_size_str = ""
        if total_enc_size is not None:
            if isinstance(total_enc_size, EncodedSize):
                total_enc_size_str = total_enc_size.string_with_reduction()
            else:
                total_enc_size_str = str(total_enc_size)
        result += HtmlField.html_table_summary(total_enc_size_str,
                                               total_tag_sizes)

        result += "</table>\n"
        return result
Exemple #8
0
    def handle_dependencies(self, dependencies):
        if not self.dependencies_handled:
            if self.message_type in dependencies:
                self.message = dependencies[self.message_type]
                self.message.handle_dependencies(dependencies)
                self.encoded_size = self.message.get_encoded_size()

                if self.encoded_size is not None:
                    # Include submessage length prefix
                    self.encoded_size += Support.varint_max_size(
                        self.encoded_size.upperlimit())
                else:
                    # 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.
                    self.encoded_size = EncodedSize(self.message.type_name +
                                                    "size")
                    # We will have to make a conservative assumption on the length
                    # prefix size, though.
                    self.encoded_size += 5
            self.dependencies_handled = True
Exemple #9
0
 def get_tag_size(self):
     return Support.varint_max_size(self.id << 3)