Esempio n. 1
0
        def DecodeField(buffer, pos, end, message, field_dict):
            """Decode serialized repeated enum to its value and a new position.

      Args:
        buffer: memoryview of the serialized bytes.
        pos: int, position in the memory view to start at.
        end: int, end position of serialized data
        message: Message object to store unknown fields in
        field_dict: Map[Descriptor, Any] to store decoded values in.

      Returns:
        int, new position in serialized data.
      """
            value_start_pos = pos
            (enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
            if pos > end:
                raise _DecodeError('Truncated message.')
            # pylint: disable=protected-access
            if enum_value in enum_type.values_by_number:
                field_dict[key] = enum_value
            else:
                if not message._unknown_fields:
                    message._unknown_fields = []
                tag_bytes = encoder.TagBytes(field_number,
                                             wire_format.WIRETYPE_VARINT)
                message._unknown_fields.append(
                    (tag_bytes, buffer[value_start_pos:pos].tobytes()))
                if message._unknown_field_set is None:
                    message._unknown_field_set = containers.UnknownFieldSet()
                message._unknown_field_set._add(field_number,
                                                wire_format.WIRETYPE_VARINT,
                                                enum_value)
                # pylint: enable=protected-access
            return pos
Esempio n. 2
0
        def DecodePackedField(buffer, pos, end, message, field_dict):
            """Decode serialized packed enum to its value and a new position.

      Args:
        buffer: memoryview of the serialized bytes.
        pos: int, position in the memory view to start at.
        end: int, end position of serialized data
        message: Message object to store unknown fields in
        field_dict: Map[Descriptor, Any] to store decoded values in.

      Returns:
        int, new position in serialized data.
      """
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            (endpoint, pos) = local_DecodeVarint(buffer, pos)
            endpoint += pos
            if endpoint > end:
                raise _DecodeError('Truncated message.')
            while pos < endpoint:
                value_start_pos = pos
                (element, pos) = _DecodeSignedVarint32(buffer, pos)
                # pylint: disable=protected-access
                if element in enum_type.values_by_number:
                    value.append(element)
                else:
                    if not message._unknown_fields:
                        message._unknown_fields = []
                    tag_bytes = encoder.TagBytes(field_number,
                                                 wire_format.WIRETYPE_VARINT)

                    message._unknown_fields.append(
                        (tag_bytes, buffer[value_start_pos:pos].tobytes()))
                    if message._unknown_field_set is None:
                        message._unknown_field_set = containers.UnknownFieldSet(
                        )
                    message._unknown_field_set._add(
                        field_number, wire_format.WIRETYPE_VARINT, element)
                    # pylint: enable=protected-access
            if pos > endpoint:
                if element in enum_type.values_by_number:
                    del value[-1]  # Discard corrupt value.
                else:
                    del message._unknown_fields[-1]
                    # pylint: disable=protected-access
                    del message._unknown_field_set._values[-1]
                    # pylint: enable=protected-access
                raise _DecodeError('Packed element was truncated.')
            return pos
Esempio n. 3
0
def _DecodeUnknownFieldSet(buffer, pos, end_pos=None):
    """Decode UnknownFieldSet.  Returns the UnknownFieldSet and new position."""

    unknown_field_set = containers.UnknownFieldSet()
    while end_pos is None or pos < end_pos:
        (tag_bytes, pos) = ReadTag(buffer, pos)
        (tag, _) = _DecodeVarint(tag_bytes, 0)
        field_number, wire_type = wire_format.UnpackTag(tag)
        if wire_type == wire_format.WIRETYPE_END_GROUP:
            break
        (data, pos) = _DecodeUnknownField(buffer, pos, wire_type)
        # pylint: disable=protected-access
        unknown_field_set._add(field_number, wire_type, data)

    return (unknown_field_set, pos)
Esempio n. 4
0
        def DecodeRepeatedField(buffer, pos, end, message, field_dict):
            """Decode serialized repeated enum to its value and a new position.

      Args:
        buffer: memoryview of the serialized bytes.
        pos: int, position in the memory view to start at.
        end: int, end position of serialized data
        message: Message object to store unknown fields in
        field_dict: Map[Descriptor, Any] to store decoded values in.

      Returns:
        int, new position in serialized data.
      """
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            while 1:
                (element, new_pos) = _DecodeSignedVarint32(buffer, pos)
                # pylint: disable=protected-access
                if element in enum_type.values_by_number:
                    value.append(element)
                else:
                    if not message._unknown_fields:
                        message._unknown_fields = []
                    message._unknown_fields.append(
                        (tag_bytes, buffer[pos:new_pos].tobytes()))
                    if message._unknown_field_set is None:
                        message._unknown_field_set = containers.UnknownFieldSet(
                        )
                    message._unknown_field_set._add(
                        field_number, wire_format.WIRETYPE_VARINT, element)
                # pylint: enable=protected-access
                # Predict that the next tag is another copy of the same repeated
                # field.
                pos = new_pos + tag_len
                if buffer[new_pos:pos] != tag_bytes or new_pos >= end:
                    # Prediction failed.  Return.
                    if new_pos > end:
                        raise _DecodeError('Truncated message.')
                    return new_pos
Esempio n. 5
0
    def DecodeItem(buffer, pos, end, message, field_dict):
        """Decode serialized message set to its value and new position.

    Args:
      buffer: memoryview of the serialized bytes.
      pos: int, position in the memory view to start at.
      end: int, end position of serialized data
      message: Message object to store unknown fields in
      field_dict: Map[Descriptor, Any] to store decoded values in.

    Returns:
      int, new position in serialized data.
    """
        message_set_item_start = pos
        type_id = -1
        message_start = -1
        message_end = -1

        # Technically, type_id and message can appear in any order, so we need
        # a little loop here.
        while 1:
            (tag_bytes, pos) = local_ReadTag(buffer, pos)
            if tag_bytes == type_id_tag_bytes:
                (type_id, pos) = local_DecodeVarint(buffer, pos)
            elif tag_bytes == message_tag_bytes:
                (size, message_start) = local_DecodeVarint(buffer, pos)
                pos = message_end = message_start + size
            elif tag_bytes == item_end_tag_bytes:
                break
            else:
                pos = SkipField(buffer, pos, end, tag_bytes)
                if pos == -1:
                    raise _DecodeError('Missing group end tag.')

        if pos > end:
            raise _DecodeError('Truncated message.')

        if type_id == -1:
            raise _DecodeError('MessageSet item missing type_id.')
        if message_start == -1:
            raise _DecodeError('MessageSet item missing message.')

        extension = message.Extensions._FindExtensionByNumber(type_id)
        # pylint: disable=protected-access
        if extension is not None:
            value = field_dict.get(extension)
            if value is None:
                value = field_dict.setdefault(
                    extension, extension.message_type._concrete_class())
            if value._InternalParse(buffer, message_start,
                                    message_end) != message_end:
                # The only reason _InternalParse would return early is if it encountered
                # an end-group tag.
                raise _DecodeError('Unexpected end-group tag.')
        else:
            if not message._unknown_fields:
                message._unknown_fields = []
            message._unknown_fields.append(
                (MESSAGE_SET_ITEM_TAG,
                 buffer[message_set_item_start:pos].tobytes()))
            if message._unknown_field_set is None:
                message._unknown_field_set = containers.UnknownFieldSet()
            message._unknown_field_set._add(
                type_id, wire_format.WIRETYPE_LENGTH_DELIMITED,
                buffer[message_start:message_end].tobytes())
            # pylint: enable=protected-access

        return pos