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
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
def getfield(self, name): field_descriptor = self.descriptor.fields_by_name[name] wire_type = type_checkers.field_type_to_wire_type[field_descriptor.type] field_tag = encoder.tagbytes(field_descriptor.number, wire_type) for tag_bytes, value in self.unknown_fields: if tag_bytes == field_tag: decoder = unittest_pb2.testalltypes._decoders_by_tag[tag_bytes] result_dict = {} decoder(value, 0, len(value), self.all_fields, result_dict) return result_dict[field_descriptor]
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: 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.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
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
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
(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 # -------------------------------------------------------------------- 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; } } """
def adddecoder(wiretype, is_packed): tag_bytes = encoder.tagbytes(field_descriptor.number, wiretype) cls._decoders_by_tag[tag_bytes] = ( type_checkers.type_to_decoder[field_descriptor.type]( field_descriptor.number, is_repeated, is_packed, field_descriptor, field_descriptor._default_constructor))