Example #1
0
def GroupDecoder(field_number, is_repeated, is_packed, key, new_default):
    """Returns a decoder for a group field."""

    end_tag_bytes = encoder.TagBytes(field_number,
                                     wire_format.WIRETYPE_END_GROUP)
    end_tag_len = len(end_tag_bytes)

    assert not is_packed
    if is_repeated:
        tag_bytes = encoder.TagBytes(field_number,
                                     wire_format.WIRETYPE_START_GROUP)
        tag_len = len(tag_bytes)

        def DecodeRepeatedField(buffer, pos, end, message, field_dict):
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            while 1:
                value = field_dict.get(key)
                if value is None:
                    value = field_dict.setdefault(key, new_default(message))
                # Read sub-message.
                pos = value.add()._InternalParse(buffer, pos, end)
                # Read end tag.
                new_pos = pos + end_tag_len
                if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
                    raise _DecodeError('Missing group end tag.')
                # 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.
                    return new_pos

        return DecodeRepeatedField
    else:

        def DecodeField(buffer, pos, end, message, field_dict):
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            # Read sub-message.
            pos = value._InternalParse(buffer, pos, end)
            # Read end tag.
            new_pos = pos + end_tag_len
            if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
                raise _DecodeError('Missing group end tag.')
            return new_pos

        return DecodeField
Example #2
0
def _MapDecoder(field_descriptor, new_default, is_message_map):
	Origin_DecodeMap = Origin_MapDecoder(field_descriptor, new_default, is_message_map)
	if not is_message_map:
		return Origin_DecodeMap
	key = field_descriptor
	tag_bytes = encoder.TagBytes(field_descriptor.number, wire_format.WIRETYPE_LENGTH_DELIMITED)
	tag_len = len(tag_bytes)
	local_DecodeVarint = decoder._DecodeVarint
	message_type = field_descriptor.message_type
	def _DecodeMap(buffer, pos, end, message, field_dict):
		submsg = message_type._concrete_class()
		value = field_dict.get(key)
		if value is None:
			value = field_dict.setdefault(key, new_default(message))
		while 1:
			(size, pos) = local_DecodeVarint(buffer, pos)
			new_pos = pos + size
			if new_pos > end:
				raise decoder._DecodeError('Truncated message.')
			submsg.Clear()
			if submsg._InternalParse(buffer, pos, new_pos) != new_pos:
				raise decoder._DecodeError('Unexpected end-group tag.')

			if submsg.value is None:
				value.__setitem__(submsg.key, None)
			elif getattr(value, '_nestingList', None) or getattr(value, '_nestingDict', None):
				value.__getitem__(submsg.key).MergeFrom(submsg.value)
			elif isinstance(value._message_descriptor, PythonDescriptor):
				value.__setitem__(submsg.key, submsg.value)
			else:
				super(_MessageMap, value).__getitem__(submsg.key).MergeFrom(submsg.value)
			pos = new_pos + tag_len
			if buffer[new_pos:pos] != tag_bytes or new_pos == end:
				return new_pos
	return _DecodeMap
Example #3
0
 def DecodePackedField(buffer, pos, end, message, field_dict):
     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)
         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]))
     if pos > endpoint:
         if element in enum_type.values_by_number:
             del value[-1]  # Discard corrupt value.
         else:
             del message._unknown_fields[-1]
         raise _DecodeError('Packed element was truncated.')
     return pos
Example #4
0
def _AttachFixedPointHelpers(cls, field, precision, floor):
	is_repeated = (field.label == FieldDescriptor.LABEL_REPEATED)
	is_packed = (is_repeated and wire_format.IsTypePackable(FieldDescriptor.TYPE_INT64))
	sizer = FixedPointSizer(encoder._SignedVarintSize, precision, floor, is_repeated)
	field._encoder = encoder._SimpleEncoder(wire_format.WIRETYPE_VARINT, EncodeFixedPoint(encoder._EncodeSignedVarint, precision, floor, is_repeated), sizer)(field.number, is_repeated, is_packed)
	field._sizer = encoder._SimpleSizer(sizer)(field.number, is_repeated, is_packed)
	oneof_descriptor = None if field.containing_oneof is None else field
	tag_bytes = encoder.TagBytes(field.number, type_checkers.FIELD_TYPE_TO_WIRE_TYPE[FieldDescriptor.TYPE_INT64])
	field_decoder = decoder._SimpleDecoder(wire_format.WIRETYPE_VARINT, DecodeFixedPoint(decoder._DecodeSignedVarint, precision, floor))(field.number, is_repeated, is_packed, field, field._default_constructor)
	cls._decoders_by_tag[tag_bytes] = (field_decoder, oneof_descriptor)
	if hasattr(cls, 'fields_by_tag'):
		cls.field_tag[field] = tag_bytes
		cls.fields_by_tag[tag_bytes] = field
		cls.fields_by_tag.pop(encoder.TagBytes(field.number, type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field.type]))
	if is_packed:
		tag_bytes = encoder.TagBytes(field.number, wire_format.WIRETYPE_LENGTH_DELIMITED)
		cls._decoders_by_tag[tag_bytes] = (field_decoder, oneof_descriptor)
		if hasattr(cls, 'fields_by_tag'):
			cls.field_tag[field] = tag_bytes
			cls.fields_by_tag[tag_bytes] = field
Example #5
0
    def SpecificDecoder(field_number, is_repeated, is_packed, key,
                        new_default):
        if is_packed:
            local_DecodeVarint = _DecodeVarint

            def DecodePackedField(buffer, pos, end, message, field_dict):
                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:
                    (element, pos) = decode_value(buffer, pos)
                    value.append(element)
                if pos > endpoint:
                    del value[-1]  # Discard corrupt value.
                    raise _DecodeError('Packed element was truncated.')
                return pos

            return DecodePackedField
        elif is_repeated:
            tag_bytes = encoder.TagBytes(field_number, wire_type)
            tag_len = len(tag_bytes)

            def DecodeRepeatedField(buffer, pos, end, message, field_dict):
                value = field_dict.get(key)
                if value is None:
                    value = field_dict.setdefault(key, new_default(message))
                while 1:
                    (element, new_pos) = decode_value(buffer, pos)
                    value.append(element)
                    # 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

            return DecodeRepeatedField
        else:

            def DecodeField(buffer, pos, end, message, field_dict):
                (field_dict[key], pos) = decode_value(buffer, pos)
                if pos > end:
                    del field_dict[key]  # Discard corrupt value.
                    raise _DecodeError('Truncated message.')
                return pos

            return DecodeField
Example #6
0
def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
    """Returns a decoder for a message field."""

    local_DecodeVarint = _DecodeVarint

    assert not is_packed
    if is_repeated:
        tag_bytes = encoder.TagBytes(field_number,
                                     wire_format.WIRETYPE_LENGTH_DELIMITED)
        tag_len = len(tag_bytes)

        def DecodeRepeatedField(buffer, pos, end, message, field_dict):
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            while 1:
                # Read length.
                (size, pos) = local_DecodeVarint(buffer, pos)
                new_pos = pos + size
                if new_pos > end:
                    raise _DecodeError('Truncated message.')
                # Read sub-message.
                if value.add()._InternalParse(buffer, pos, new_pos) != new_pos:
                    # The only reason _InternalParse would return early is if it
                    # encountered an end-group tag.
                    raise _DecodeError('Unexpected end-group tag.')
                # 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.
                    return new_pos

        return DecodeRepeatedField
    else:

        def DecodeField(buffer, pos, end, message, field_dict):
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            # Read length.
            (size, pos) = local_DecodeVarint(buffer, pos)
            new_pos = pos + size
            if new_pos > end:
                raise _DecodeError('Truncated message.')
            # Read sub-message.
            if value._InternalParse(buffer, pos, new_pos) != new_pos:
                # The only reason _InternalParse would return early is if it encountered
                # an end-group tag.
                raise _DecodeError('Unexpected end-group tag.')
            return new_pos

        return DecodeField
Example #7
0
def _AttachSymbolHelpers(cls, field):
	is_packed = False
	is_repeated = (field.label == FieldDescriptor.LABEL_REPEATED)
	sizer = SymbolSizer(encoder._VarintSize, is_repeated)
	field._encoder = encoder._SimpleEncoder(wire_format.WIRETYPE_LENGTH_DELIMITED, SymbolEncoder(encoder._EncodeVarint, is_repeated), sizer)(field.number, is_repeated, is_packed)
	field._sizer = encoder._SimpleSizer(sizer)(field.number, is_repeated, is_packed)
	oneof_descriptor = None if field.containing_oneof is None else field
	field_decoder = decoder._SimpleDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, SymbolDecoder(decoder._DecodeVarint))(field.number, is_repeated, is_packed, field, field._default_constructor)
	tag_bytes = encoder.TagBytes(field.number, wire_format.WIRETYPE_LENGTH_DELIMITED)
	cls._decoders_by_tag[tag_bytes] = (field_decoder, oneof_descriptor)
	if hasattr(cls, 'fields_by_tag'):
		cls.field_tag[field] = tag_bytes
		cls.fields_by_tag[tag_bytes] = field
Example #8
0
 def __init__(cls, clsname, bases, attrs):
     super(MetaObject, cls).__init__(clsname, bases, attrs)
     from typy.google.protobuf.internal import encoder
     from typy.google.protobuf.internal import type_checkers
     from typy.google.protobuf.internal import wire_format
     cls.fields_by_tag = {}
     cls.field_tag = {}
     for field in attrs[reflection.GeneratedProtocolMessageType.
                        _DESCRIPTOR_KEY].fields:
         tag = encoder.TagBytes(
             field.number,
             type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field.type])
         cls.fields_by_tag[tag] = field
         cls.field_tag[field] = tag
         if field.label == descriptor.FieldDescriptor.LABEL_REPEATED and wire_format.IsTypePackable(
                 field.type):
             tag = encoder.TagBytes(
                 field.number, wire_format.WIRETYPE_LENGTH_DELIMITED)
             cls.fields_by_tag[tag] = field
             cls.field_tag[field] = tag
     Hacker.initObjectClass(cls, clsname, bases, attrs)
     cls.__repr__ = cls.__str__ = lambda s: repr(s.Json())
Example #9
0
 def DecodeField(buffer, pos, end, message, field_dict):
     value_start_pos = pos
     (enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
     if pos > end:
         raise _DecodeError('Truncated message.')
     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]))
     return pos
Example #10
0
def StringDecoder(field_number, is_repeated, is_packed, key, new_default):
    """Returns a decoder for a string field."""

    local_DecodeVarint = _DecodeVarint
    local_unicode = six.text_type

    def _ConvertToUnicode(byte_str):
        try:
            return local_unicode(byte_str, 'utf-8')
        except UnicodeDecodeError as e:
            # add more information to the error message and re-raise it.
            e.reason = '%s in field: %s' % (e, key.full_name)
            raise

    assert not is_packed
    if is_repeated:
        tag_bytes = encoder.TagBytes(field_number,
                                     wire_format.WIRETYPE_LENGTH_DELIMITED)
        tag_len = len(tag_bytes)

        def DecodeRepeatedField(buffer, pos, end, message, field_dict):
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            while 1:
                (size, pos) = local_DecodeVarint(buffer, pos)
                new_pos = pos + size
                if new_pos > end:
                    raise _DecodeError('Truncated string.')
                value.append(_ConvertToUnicode(buffer[pos:new_pos]))
                # 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.
                    return new_pos

        return DecodeRepeatedField
    else:

        def DecodeField(buffer, pos, end, message, field_dict):
            (size, pos) = local_DecodeVarint(buffer, pos)
            new_pos = pos + size
            if new_pos > end:
                raise _DecodeError('Truncated string.')
            field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos])
            return new_pos

        return DecodeField
Example #11
0
def MapDecoder(field_descriptor, new_default, is_message_map):
    """Returns a decoder for a map field."""

    key = field_descriptor
    tag_bytes = encoder.TagBytes(field_descriptor.number,
                                 wire_format.WIRETYPE_LENGTH_DELIMITED)
    tag_len = len(tag_bytes)
    local_DecodeVarint = _DecodeVarint
    # Can't read _concrete_class yet; might not be initialized.
    message_type = field_descriptor.message_type

    def DecodeMap(buffer, pos, end, message, field_dict):
        submsg = message_type._concrete_class()
        value = field_dict.get(key)
        if value is None:
            value = field_dict.setdefault(key, new_default(message))
        while 1:
            # Read length.
            (size, pos) = local_DecodeVarint(buffer, pos)
            new_pos = pos + size
            if new_pos > end:
                raise _DecodeError('Truncated message.')
            # Read sub-message.
            submsg.Clear()
            if submsg._InternalParse(buffer, pos, new_pos) != new_pos:
                # The only reason _InternalParse would return early is if it
                # encountered an end-group tag.
                raise _DecodeError('Unexpected end-group tag.')

            if is_message_map:
                value[submsg.key].MergeFrom(submsg.value)
            else:
                value[submsg.key] = submsg.value

            # 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.
                return new_pos

    return DecodeMap
Example #12
0
def _MessageEncoder(field_number, is_repeated, is_packed):
	if is_repeated:
		tag = encoder.TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
		def EncodeRepeatedField(write, value):
			isPythonMessage = isinstance(value._message_descriptor, PythonDescriptor)
			if value._message_descriptor.oneofs:
				value = value._values
			for element in value:
				write(tag)
				if element is None:
					encoder._EncodeVarint(write, 0)
				else:
					if isPythonMessage:
						encoder._EncodeVarint(write, PythonMessage.Static_ByteSize(element))
						PythonMessage.Static_InternalSerialize(element, write)
					else:
						encoder._EncodeVarint(write, element.ByteSize())
						element._InternalSerialize(write)
		return EncodeRepeatedField
	else:
		return Origin_MessageEncoder(field_number, is_repeated, is_packed)
Example #13
0
def BytesDecoder(field_number, is_repeated, is_packed, key, new_default):
    """Returns a decoder for a bytes field."""

    local_DecodeVarint = _DecodeVarint

    assert not is_packed
    if is_repeated:
        tag_bytes = encoder.TagBytes(field_number,
                                     wire_format.WIRETYPE_LENGTH_DELIMITED)
        tag_len = len(tag_bytes)

        def DecodeRepeatedField(buffer, pos, end, message, field_dict):
            value = field_dict.get(key)
            if value is None:
                value = field_dict.setdefault(key, new_default(message))
            while 1:
                (size, pos) = local_DecodeVarint(buffer, pos)
                new_pos = pos + size
                if new_pos > end:
                    raise _DecodeError('Truncated string.')
                value.append(buffer[pos:new_pos])
                # 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.
                    return new_pos

        return DecodeRepeatedField
    else:

        def DecodeField(buffer, pos, end, message, field_dict):
            (size, pos) = local_DecodeVarint(buffer, pos)
            new_pos = pos + size
            if new_pos > end:
                raise _DecodeError('Truncated string.')
            field_dict[key] = buffer[pos:new_pos]
            return new_pos

        return DecodeField
Example #14
0
def MessageSetItemDecoder(extensions_by_number):
    """Returns a decoder for a MessageSet item.

  The parameter is the _extensions_by_number map for the message class.

  The message set message looks like this:
    message MessageSet {
      repeated group Item = 1 {
        required int32 type_id = 2;
        required string message = 3;
      }
    }
  """

    type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT)
    message_tag_bytes = encoder.TagBytes(3,
                                         wire_format.WIRETYPE_LENGTH_DELIMITED)
    item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP)

    local_ReadTag = ReadTag
    local_DecodeVarint = _DecodeVarint
    local_SkipField = SkipField

    def DecodeItem(buffer, pos, end, message, field_dict):
        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 = extensions_by_number.get(type_id)
        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]))

        return pos

    return DecodeItem
Example #15
0
def EnumDecoder(field_number, is_repeated, is_packed, key, new_default):
    enum_type = key.enum_type
    if is_packed:
        local_DecodeVarint = _DecodeVarint

        def DecodePackedField(buffer, pos, end, message, field_dict):
            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)
                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]))
            if pos > endpoint:
                if element in enum_type.values_by_number:
                    del value[-1]  # Discard corrupt value.
                else:
                    del message._unknown_fields[-1]
                raise _DecodeError('Packed element was truncated.')
            return pos

        return DecodePackedField
    elif is_repeated:
        tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT)
        tag_len = len(tag_bytes)

        def DecodeRepeatedField(buffer, pos, end, message, field_dict):
            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)
                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]))
                # 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

        return DecodeRepeatedField
    else:

        def DecodeField(buffer, pos, end, message, field_dict):
            value_start_pos = pos
            (enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
            if pos > end:
                raise _DecodeError('Truncated message.')
            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]))
            return pos

        return DecodeField
Example #16
0
            new_pos = pos + size
            if new_pos > end:
                raise _DecodeError('Truncated message.')
            # Read sub-message.
            if value._InternalParse(buffer, pos, new_pos) != new_pos:
                # The only reason _InternalParse would return early is if it encountered
                # an end-group tag.
                raise _DecodeError('Unexpected end-group tag.')
            return new_pos

        return DecodeField


# --------------------------------------------------------------------

MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP)


def MessageSetItemDecoder(extensions_by_number):
    """Returns a decoder for a MessageSet item.

  The parameter is the _extensions_by_number map for the message class.

  The message set message looks like this:
    message MessageSet {
      repeated group Item = 1 {
        required int32 type_id = 2;
        required string message = 3;
      }
    }
  """