def _unmarshal_method_frame(frame_data): """Attempt to unmarshal a method frame :param bytes frame_data: Raw frame data to assign to our method frame :return tuple: Amount of data consumed and the frame object """ # Get the Method Index from the class data bytes_used, method_index = decode.long_int(frame_data[0:4]) # Create an instance of the method object we're going to unmarshal try: method = specification.INDEX_MAPPING[method_index]() except KeyError: raise exceptions.UnmarshalingException( 'Unknown', 'Unknown method index: {}'.format(str(method_index))) # Unmarshal the data try: method.unmarshal(frame_data[bytes_used:]) except struct.error as error: raise exceptions.UnmarshalingException(method, error) # Unmarshal the data in the object and return it return method
def unmarshal(data_in): """Takes in binary data and maps builds the appropriate frame type, returning a frame object. :param bytes data_in: Raw byte stream data :rtype: tuple of bytes consumed, channel, and a frame object :raises: specification.FrameError """ # Look to see if it's a protocol header frame try: frame_value = _unmarshal_protocol_header_frame(data_in) if frame_value: return 8, 0, frame_value except ValueError as error: raise exceptions.UnmarshalingException(header.ProtocolHeader, error) # Decode the low level frame and break it into parts frame_type, channel_id, frame_size = frame_parts(data_in) # Heartbeats do not have frame length indicators if frame_type == specification.FRAME_HEARTBEAT and frame_size == 0: return 8, channel_id, heartbeat.Heartbeat() if not frame_size: raise exceptions.UnmarshalingException('Unknown', 'No frame size') byte_count = FRAME_HEADER_SIZE + frame_size + 1 if byte_count > len(data_in): raise exceptions.UnmarshalingException('Unknown', 'Not all data received') if data_in[byte_count - 1] != DECODE_FRAME_END_CHAR: raise exceptions.UnmarshalingException('Unknown', 'Last byte error') frame_data = data_in[FRAME_HEADER_SIZE:byte_count - 1] # Decode a method frame if frame_type == specification.FRAME_METHOD: return byte_count, channel_id, _unmarshal_method_frame(frame_data) # Decode a header frame elif frame_type == specification.FRAME_HEADER: return byte_count, channel_id, _unmarshal_header_frame(frame_data) # Decode a body frame elif frame_type == specification.FRAME_BODY: return byte_count, channel_id, _unmarshal_body_frame(frame_data) raise exceptions.UnmarshalingException( 'Unknown', 'Unknown frame type: {}'.format(frame_type))
def _unmarshal_method_frame(frame_data: bytes) -> base.Frame: """Attempt to unmarshal a method frame :raises: pamqp.exceptions.UnmarshalingException """ bytes_used, method_index = decode.long_int(frame_data[0:4]) try: method = commands.INDEX_MAPPING[method_index]() except KeyError: raise exceptions.UnmarshalingException( 'Unknown', 'Unknown method index: {}'.format(str(method_index))) try: method.unmarshal(frame_data[bytes_used:]) except struct.error as error: raise exceptions.UnmarshalingException(method, error) return method
def unmarshal(data_in: bytes) -> typing.Tuple[int, int, FrameTypes]: """Takes in binary data and maps builds the appropriate frame type, returning a frame object. :returns: tuple of bytes consumed, channel, and a frame object :raises: exceptions.UnmarshalingException """ try: # Look to see if it's a protocol header frame value = _unmarshal_protocol_header_frame(data_in) except ValueError as error: raise exceptions.UnmarshalingException(header.ProtocolHeader, error) else: if value: return 8, 0, value frame_type, channel_id, frame_size = _frame_parts(data_in) # Heartbeats do not have frame length indicators if frame_type == constants.FRAME_HEARTBEAT and frame_size == 0: return 8, channel_id, heartbeat.Heartbeat() if not frame_size: raise exceptions.UnmarshalingException('Unknown', 'No frame size') byte_count = constants.FRAME_HEADER_SIZE + frame_size + 1 if byte_count > len(data_in): raise exceptions.UnmarshalingException('Unknown', 'Not all data received') if data_in[byte_count - 1] != constants.FRAME_END: raise exceptions.UnmarshalingException('Unknown', 'Last byte error') frame_data = data_in[constants.FRAME_HEADER_SIZE:byte_count - 1] if frame_type == constants.FRAME_METHOD: return byte_count, channel_id, _unmarshal_method_frame(frame_data) elif frame_type == constants.FRAME_HEADER: return byte_count, channel_id, _unmarshal_header_frame(frame_data) elif frame_type == constants.FRAME_BODY: return byte_count, channel_id, _unmarshal_body_frame(frame_data) raise exceptions.UnmarshalingException( 'Unknown', 'Unknown frame type: {}'.format(frame_type))
def _unmarshal_header_frame(frame_data: bytes) -> header.ContentHeader: """Attempt to unmarshal a header frame :raises: pamqp.exceptions.UnmarshalingException """ content_header = header.ContentHeader() try: content_header.unmarshal(frame_data) except struct.error as error: raise exceptions.UnmarshalingException('ContentHeader', error) return content_header
def _unmarshal_header_frame(frame_data): """Attempt to unmarshal a header frame :param bytes frame_data: Raw frame data to assign to our header frame :return tuple: Amount of data consumed and the frame object """ content_header = header.ContentHeader() try: content_header.unmarshal(frame_data) except struct.error as error: raise exceptions.UnmarshalingException('ContentHeader', error) return content_header