def buffer_to_value(self, obj, buffer, offset, default_endianness=DEFAULT_ENDIANNESS): """ Converts the bytes in ``buffer`` at ``offset`` to a native Python value. Returns that value and the number of bytes consumed to create it. :param obj: The parent :class:`.PebblePacket` of this field :type obj: .PebblePacket :param buffer: The buffer from which to extract a value. :type buffer: bytes :param offset: The offset in the buffer to start at. :type offset: int :param default_endianness: The default endianness of the value. Used if ``endianness`` was not passed to the :class:`Field` constructor. :type default_endianness: str :return: (value, length) :rtype: (:class:`object`, :any:`int`) """ try: value, length = struct.unpack_from( str(self.endianness or default_endianness) + self.struct_format, buffer, offset)[0], struct.calcsize(self.struct_format) if self._enum is not None: try: return self._enum(value), length except ValueError as e: raise PacketDecodeError("{}: {}".format(self.type, e)) else: return value, length except struct.error as e: raise PacketDecodeError("{}: {}".format(self.type, e))
def buffer_to_value(self, obj, buffer, offset, default_endianness=DEFAULT_ENDIANNESS): results = [] length = 0 max_count = None if isinstance(self.count, Field): max_count = getattr(obj, self.count._name) i = 0 while offset + length < len(buffer) and (max_count is None or i < max_count): try: item_length, = struct.unpack_from('B', buffer, offset + length) except struct.error as e: raise PacketDecodeError( "{}: couldn't parse entry length: {}".format(self.type, e)) length += 1 results.append( self.member_type.parse( buffer[offset + length:offset + length + item_length], default_endianness=default_endianness)[0]) length += item_length i += 1 return results, length
def buffer_to_value(self, obj, buffer, offset, default_endianness=DEFAULT_ENDIANNESS): end = offset if end >= len(buffer): raise PacketDecodeError("{}: No bytes available.") while buffer[end] != b'\x00'[0]: print(buffer[end]) end += 1 if end >= len(buffer): raise PacketDecodeError( "{}: Reached end of buffer without terminating.".format( self.type)) return buffer[offset:end].split(b'\x00')[0].decode( 'utf-8'), end - offset + 1
def buffer_to_value(self, obj, buffer, offset, default_endianness=DEFAULT_ENDIANNESS): try: length, = struct.unpack_from('B', buffer, offset) except struct.error as e: raise PacketDecodeError("{}: {}".format(self.type, str(e))) extra_bytes = 1 if self.null_terminated and not self.count_null_terminator: extra_bytes += 1 if len(buffer) < offset + length + extra_bytes: raise PacketDecodeError( "{}: Expected {} bytes, but only had {}".format( self.type, length + extra_bytes, len(buffer) - offset)) return buffer[offset + 1:offset + 1 + length].split(b'\x00')[0].decode( 'utf-8'), length + extra_bytes
def buffer_to_value(self, obj, buffer, offset, default_endianness=DEFAULT_ENDIANNESS): try: return uuid.UUID(bytes=buffer[offset:offset + 16]), 16 except ValueError as e: raise PacketDecodeError("{}: failed to decode UUID: {}".format( self.type, e))
def buffer_to_value(self, obj, buffer, offset, default_endianness=DEFAULT_ENDIANNESS): if isinstance(self.length, Field): length = getattr(obj, self.length._name) elif self.length is None: length = len(buffer) - offset else: length = self.length if len(buffer) - offset < length: raise PacketDecodeError( "{}: Expected more bytes (wanted {}; got {}).".format( self.type, length, len(buffer) - offset)) return buffer[offset:offset + length], length
def buffer_to_value(self, obj, buffer, offset, default_endianness=DEFAULT_ENDIANNESS): if isinstance(self.length, Field): length = getattr(obj, self.length._name) elif self.length is not None: length = self.length else: length = len(buffer) - offset try: return struct.unpack_from( '%ds' % length, buffer, offset)[0].split(b'\x00')[0].decode('utf-8'), length except struct.error: raise PacketDecodeError( "{}: string not long enough (wanted {} bytes)".format( self.type, length))
def buffer_to_value(self, obj, buffer, offset, default_endianness=DEFAULT_ENDIANNESS): if isinstance(self.length, Field): length = getattr(obj, self.length._name) else: length = len(buffer) - offset k = getattr(obj, self.determinant._name) try: return self.contents[k].parse( buffer[offset:offset + length], default_endianness=default_endianness) except KeyError: if not self.accept_missing: raise PacketDecodeError( "{}: unrecognised value for union: {}".format( self.type, k)) else: return None, length