Esempio n. 1
0
    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))
Esempio n. 2
0
    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
Esempio n. 3
0
 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
Esempio n. 4
0
 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
Esempio n. 5
0
 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))
Esempio n. 6
0
 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
Esempio n. 7
0
 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))
Esempio n. 8
0
 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