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
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)
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)
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)