Beispiel #1
0
    def set_length(self, buf):
        """Set the length of the variable-width encoding."""
        self.length = compat.from_bytes(buf.read(self.width), "big")
        buf.seek(self.length, os.SEEK_CUR)

        # Update the offset with the length indicator.
        self.offset += self.width
Beispiel #2
0
def decode_constructor(read):
    """Decodes the constructor of an AMQP-encoded value at the beginning
    of the datastream in file-like object `buf`. Return a tuple indicating
    the format code, width, length, symbolic and numeric decriptor.

    Args:
        read: a callable that accepts an integer as its argument, indicating
            the number of octets to be read from the stream, and returns
            a :class:`bytes` object of equal length to the input value.

    Returns:
        Constructor

    Raises:
        EOFError: may be raised by invoking `read()`.
    """
    symbolic = None
    numeric = None
    raw_format_code = read(1)
    if not raw_format_code:
        raise EOFError("End of AMQP-encoded datastream")

    # The first octet indicates the format code type; 0 for described
    # format codes, non-zero for codec.
    format_code = compat.from_bytes(raw_format_code, ENDIAN)
    if format_code == 0x00:
        # If the value has a described format code, its descriptor is
        # either an unsigned long integer, or a symbol.
        format_code = compat.from_bytes(read(1), ENDIAN)
        if format_code in (ULONG, SMALLULONG):
            numeric =\
                compat.from_bytes(read_stream(format_code, read), ENDIAN)
        elif format_code in (SYM8, SYM32):
            #: Symbol is encoded as ASCII (OASIS 2012: 25).
            symbolic = read_stream(format_code, read)\
                .decode('ascii')
        else:
            raise ValueError(
                "Invalid format code for descriptor: " + str(format_code)
            )

        # Right after the descriptor comes the actual primitive type
        # of the encoded value.
        format_code = compat.from_bytes(read(1), ENDIAN)

    return Constructor(format_code, symbolic, numeric)
Beispiel #3
0
    def set_members(self, buf):
        """Read the size and count indicator from the buffer."""
        self.member_size = compat.from_bytes(buf.read(self.width), "big")
        self.member_count = compat.from_bytes(buf.read(self.width), "big")

        start = buf.tell() - self.width
        if self.is_array():
            self.member_ctr = decode_constructor(buf.read)

        # Set the start of the members to the current buffer position
        # minus the width of the type length, because the total length
        # includes.
        end = start + self.member_size
        while buf.tell() < end:
            node = type(self).frombuf(buf, parent=self, ctr=self.member_ctr, depth=self.depth)
            self.children.append(node)
        assert buf.tell() == end, "{0}!={1}".format(buf.tell(), end)
Beispiel #4
0
def read_variable(format_code, read):
    """Read a variable-length value from an AMQP-encoded datastream.

    Args:
        read: a callable that accepts an integer as its argument, indicating
            the number of octets to be read from the stream, and returns
            a :class:`bytes` object of equal length to the input value.
        format_code (:class:`int`): an AMQP primitive type format
            code.

    Returns:
        bytes
    """
    n = compat.from_bytes(read(get_type_length(format_code)), ENDIAN)
    return read(n)
def decode_boolean(format_code, value):
    return (format_code == const.TRUE) or (compat.from_bytes(value, "big") == 1)
def decode_integer(signed, format_code, value):
    return compat.from_bytes(value, "big", signed=signed)