def decode_buf(cls, buf, offset, end=None): if end is None: raise DecodeError('Strings need to be length delimited!') try: return buf[offset:end].decode('UTF-8') except UnicodeDecodeError as e: raise DecodeError(e.reason)
def read_varint(buf, offset=0, signed=True): r"""Reads a varint from buf at offset. >>> read_varint(b'\x2a') (42, 1) >>> read_varint(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01') (-1, 10) """ result = 0 shift_amount = 0 while True: byte = buf[offset] offset += 1 result |= ((byte & 0x7f) << shift_amount) if not (byte & 0x80): if signed and result >> 63: # reinterpret integer as signed result &= _MASK result = ~(result ^ _MASK) else: result &= _MASK return (result, offset) shift_amount += 7 if shift_amount >= 64: raise DecodeError('Not a valid varint')
def decode_packet(packet_type, buf): try: message_type = messages_by_id[packet_type] except KeyError: raise DecodeError('No message with ID {0}'.format(packet_type)) message = message_type() message.MergeFromString(bytes(buf)) return message
def decode_packet(packet_type, buf): handler = _packet_type_handlers.get(packet_type, None) if handler is None: import pdb pdb.set_trace() raise DecodeError('No handler for packet type {0}'.format(packet_type)) return handler.decode_buf(buf)
def decode_buf(self, buf, offset=0, end=None): if end is None: end = offset + self._n_bytes return (struct.unpack('<' + self._s, buf[offset:end])[0], end) else: length = end - offset if length % self._n_bytes != 0: raise DecodeError('Not a valid packed fixed field') n = length // self._n_bytes return list(struct.unpack('<' + str(n) + self._s, buf[offset:end]))
def decode_buf(cls, buf, offset=0, end=None): if end is None: end = len(buf) ret = cls() for k, v in cls._mfields_.items(): if v[2]: setattr(ret, v[0], []) while offset < end: a = buf[offset] field_number = a >> 3 wtype = a & 7 our = cls._mfields_.get(field_number, None) if our is None: raise DecodeError( 'No field definition for type {0!r} slot {1} wire type {2}' .format(cls.__name__, field_number, wtype)) name, typehandler, is_array = our if wtype == serialize.WTYPE_LEN_DELIM: length, offset = serialize.read_varint(buf, offset + 1) val = typehandler.decode_buf(buf, offset, end=offset + length) offset += length elif wtype == serialize.WTYPE_VARINT: val, offset = typehandler.decode_buf(buf, offset + 1) elif wtype == serialize.WTYPE_FIXED32: val, offset = typehandler.decode_buf(buf, offset + 1) elif wtype == serialize.WTYPE_FIXED64: val, offset = typehandler.decode_buf(buf, offset + 1) else: raise DecodeError('Unhandled wire type {0}'.format(wtype)) if is_array: if isinstance(val, list): getattr(ret, name).extend(val) else: getattr(ret, name).append(val) else: if hasattr(ret, name): raise DecodeError('Duplicated slot for non-array type') setattr(ret, name, val) return ret
def read_field(buf, offset): a = buf[offset] field_number = a >> 3 wire_type = a & 7 if wire_type == 0: # varint val, offset = read_varint(buf, offset+1) return ((field_number, val), offset) elif wire_type == 2: # bytes val, after = read_varint(buf, offset+1) return ((field_number, bytes(buf[after:after+val])), after+val) else: raise DecodeError('Unimplemented or wrong wire type {0}'.format(wire_type))
def read_packed_varint(buf, offset=0, end=None, signed=True): if end is None: end = len(buf) ret = [] while offset < end: var, offset = read_varint(buf, offset, signed) ret.append(var) if offset != end: raise DecodeError('Misaligned') return ret
def read_fields(buf, offset=0, end=None): if end is None: end = len(buf) fields = [] while offset < end: field, offset = read_field(buf, offset) fields.append(field) if offset != end: raise DecodeError('misaligned') return fields