# Path: coolamqp/framing/base.py
# class AMQPFrame(object):  # base class for framing
#     __slots__ = ('channel', )
#     FRAME_TYPE = None  # override me!
# 
#     def __init__(self, channel):  # type: (int) -> None
#         self.channel = channel
# 
#     def write_to(self, buf):  # type: (io.BinaryIO) -> None
#         """
#         Write a complete frame to buffer
# 
#         This writes type and channel ID.
#         """
#         # DO NOT UNCOMMENT buf.write(struct.pack('!BH', self.FRAME_TYPE, self.channel))
#         raise NotImplementedError(
#             'Please write the frame type and channel in child classes, its faster that way ')
# 
#     @staticmethod
#     def unserialize(channel, payload_as_buffer):
#         """
#         Unserialize from a buffer.
#         Buffer starts at frame's own payload - type, channel and size was already obtained.
#         Payload does not contain FRAME_EMD.
#         AMQPHeartbeatFrame does not have to implement this.
#         """
#         raise NotImplementedError('Override me')
# 
#     def get_size(self):  # type: () -> int
#         """
#         Return size of this frame, in bytes, from frame type to frame_end
#         :return: int
#         """
#         raise NotImplementedError('Override me')
# 
#     def __str__(self):  # type: () -> str
#         return 'AMQPFrame(%s)' % (self.channel,)
# 
# Path: coolamqp/framing/definitions.py
# FRAME_METHOD = 1
# 
# FRAME_HEARTBEAT = 8
# 
# FRAME_BODY = 3
# 
# FRAME_HEADER = 2
# 
# FRAME_END = 206
# 
# IDENT_TO_METHOD = {
#     (10, 60): ConnectionBlocked,
#     (10, 50): ConnectionClose,
#     (10, 51): ConnectionCloseOk,
#     (10, 40): ConnectionOpen,
#     (10, 41): ConnectionOpenOk,
#     (10, 10): ConnectionStart,
#     (10, 20): ConnectionSecure,
#     (10, 11): ConnectionStartOk,
#     (10, 21): ConnectionSecureOk,
#     (10, 30): ConnectionTune,
#     (10, 31): ConnectionTuneOk,
#     (10, 61): ConnectionUnblocked,
#     (20, 40): ChannelClose,
#     (20, 41): ChannelCloseOk,
#     (20, 20): ChannelFlow,
#     (20, 21): ChannelFlowOk,
#     (20, 10): ChannelOpen,
#     (20, 11): ChannelOpenOk,
#     (40, 30): ExchangeBind,
#     (40, 31): ExchangeBindOk,
#     (40, 10): ExchangeDeclare,
#     (40, 20): ExchangeDelete,
#     (40, 11): ExchangeDeclareOk,
#     (40, 21): ExchangeDeleteOk,
#     (40, 40): ExchangeUnbind,
#     (40, 51): ExchangeUnbindOk,
#     (50, 20): QueueBind,
#     (50, 21): QueueBindOk,
#     (50, 10): QueueDeclare,
#     (50, 40): QueueDelete,
#     (50, 11): QueueDeclareOk,
#     (50, 41): QueueDeleteOk,
#     (50, 30): QueuePurge,
#     (50, 31): QueuePurgeOk,
#     (50, 50): QueueUnbind,
#     (50, 51): QueueUnbindOk,
#     (60, 80): BasicAck,
#     (60, 20): BasicConsume,
#     (60, 30): BasicCancel,
#     (60, 21): BasicConsumeOk,
#     (60, 31): BasicCancelOk,
#     (60, 60): BasicDeliver,
#     (60, 70): BasicGet,
#     (60, 71): BasicGetOk,
#     (60, 72): BasicGetEmpty,
#     (60, 120): BasicNack,
#     (60, 40): BasicPublish,
#     (60, 10): BasicQos,
#     (60, 11): BasicQosOk,
#     (60, 50): BasicReturn,
#     (60, 90): BasicReject,
#     (60, 100): BasicRecoverAsync,
#     (60, 110): BasicRecover,
#     (60, 111): BasicRecoverOk,
#     (90, 20): TxCommit,
#     (90, 21): TxCommitOk,
#     (90, 30): TxRollback,
#     (90, 31): TxRollbackOk,
#     (90, 10): TxSelect,
#     (90, 11): TxSelectOk,
#     (85, 10): ConfirmSelect,
#     (85, 11): ConfirmSelectOk,
# }
# 
# CLASS_ID_TO_CONTENT_PROPERTY_LIST = {
#     60: BasicContentPropertyList,
# }
# 
# FRAME_END_BYTE = b'\xce'


import struct
import six
from coolamqp.framing.base import AMQPFrame
from coolamqp.framing.definitions import FRAME_METHOD, FRAME_HEARTBEAT, \
    FRAME_BODY, FRAME_HEADER, FRAME_END, \
    IDENT_TO_METHOD, CLASS_ID_TO_CONTENT_PROPERTY_LIST, FRAME_END_BYTE
    def get_size(self):  # type: () -> int
        # frame header is always 7, frame end is 1, content header is 12 + props
        return 20 + self.properties.get_size()

    def __str__(self):  # type: () -> str
        return 'AMQPHeaderFrame(%s, %s, %s, %s, %s)' % (self.channel, self.class_id, self.weight,
                                                        self.body_size, self.properties)


class AMQPBodyFrame(AMQPFrame):
    """
    A frame containing message body

    :param channel: Channel ID
    :type channel: int
    :param data: body (or a piece of it) of a message
    :type data: binary
    """
    __slots__ = ('data', )
    FRAME_TYPE = FRAME_BODY

    FRAME_SIZE_WITHOUT_PAYLOAD = 8

    def __init__(self, channel, data):  # type: (int, bytes) -> None
        AMQPFrame.__init__(self, channel)
        assert isinstance(data, (six.binary_type, memoryview))
        self.data = data

    def write_to(self, buf):
        buf.write(

# Path: coolamqp/framing/base.py
# class AMQPFrame(object):  # base class for framing
#     __slots__ = ('channel', )
#     FRAME_TYPE = None  # override me!
# 
#     def __init__(self, channel):  # type: (int) -> None
#         self.channel = channel
# 
#     def write_to(self, buf):  # type: (io.BinaryIO) -> None
#         """
#         Write a complete frame to buffer
# 
#         This writes type and channel ID.
#         """
#         # DO NOT UNCOMMENT buf.write(struct.pack('!BH', self.FRAME_TYPE, self.channel))
#         raise NotImplementedError(
#             'Please write the frame type and channel in child classes, its faster that way ')
# 
#     @staticmethod
#     def unserialize(channel, payload_as_buffer):
#         """
#         Unserialize from a buffer.
#         Buffer starts at frame's own payload - type, channel and size was already obtained.
#         Payload does not contain FRAME_EMD.
#         AMQPHeartbeatFrame does not have to implement this.
#         """
#         raise NotImplementedError('Override me')
# 
#     def get_size(self):  # type: () -> int
#         """
#         Return size of this frame, in bytes, from frame type to frame_end
#         :return: int
#         """
#         raise NotImplementedError('Override me')
# 
#     def __str__(self):  # type: () -> str
#         return 'AMQPFrame(%s)' % (self.channel,)
# 
# Path: coolamqp/framing/definitions.py
# FRAME_METHOD = 1
# 
# FRAME_HEARTBEAT = 8
# 
# FRAME_BODY = 3
# 
# FRAME_HEADER = 2
# 
# FRAME_END = 206
# 
# IDENT_TO_METHOD = {
#     (10, 60): ConnectionBlocked,
#     (10, 50): ConnectionClose,
#     (10, 51): ConnectionCloseOk,
#     (10, 40): ConnectionOpen,
#     (10, 41): ConnectionOpenOk,
#     (10, 10): ConnectionStart,
#     (10, 20): ConnectionSecure,
#     (10, 11): ConnectionStartOk,
#     (10, 21): ConnectionSecureOk,
#     (10, 30): ConnectionTune,
#     (10, 31): ConnectionTuneOk,
#     (10, 61): ConnectionUnblocked,
#     (20, 40): ChannelClose,
#     (20, 41): ChannelCloseOk,
#     (20, 20): ChannelFlow,
#     (20, 21): ChannelFlowOk,
#     (20, 10): ChannelOpen,
#     (20, 11): ChannelOpenOk,
#     (40, 30): ExchangeBind,
#     (40, 31): ExchangeBindOk,
#     (40, 10): ExchangeDeclare,
#     (40, 20): ExchangeDelete,
#     (40, 11): ExchangeDeclareOk,
#     (40, 21): ExchangeDeleteOk,
#     (40, 40): ExchangeUnbind,
#     (40, 51): ExchangeUnbindOk,
#     (50, 20): QueueBind,
#     (50, 21): QueueBindOk,
#     (50, 10): QueueDeclare,
#     (50, 40): QueueDelete,
#     (50, 11): QueueDeclareOk,
#     (50, 41): QueueDeleteOk,
#     (50, 30): QueuePurge,
#     (50, 31): QueuePurgeOk,
#     (50, 50): QueueUnbind,
#     (50, 51): QueueUnbindOk,
#     (60, 80): BasicAck,
#     (60, 20): BasicConsume,
#     (60, 30): BasicCancel,
#     (60, 21): BasicConsumeOk,
#     (60, 31): BasicCancelOk,
#     (60, 60): BasicDeliver,
#     (60, 70): BasicGet,
#     (60, 71): BasicGetOk,
#     (60, 72): BasicGetEmpty,
#     (60, 120): BasicNack,
#     (60, 40): BasicPublish,
#     (60, 10): BasicQos,
#     (60, 11): BasicQosOk,
#     (60, 50): BasicReturn,
#     (60, 90): BasicReject,
#     (60, 100): BasicRecoverAsync,
#     (60, 110): BasicRecover,
#     (60, 111): BasicRecoverOk,
#     (90, 20): TxCommit,
#     (90, 21): TxCommitOk,
#     (90, 30): TxRollback,
#     (90, 31): TxRollbackOk,
#     (90, 10): TxSelect,
#     (90, 11): TxSelectOk,
#     (85, 10): ConfirmSelect,
#     (85, 11): ConfirmSelectOk,
# }
# 
# CLASS_ID_TO_CONTENT_PROPERTY_LIST = {
#     60: BasicContentPropertyList,
# }
# 
# FRAME_END_BYTE = b'\xce'


# Path: coolamqp/framing/frames.py
import struct
import six
from coolamqp.framing.base import AMQPFrame
from coolamqp.framing.definitions import FRAME_METHOD, FRAME_HEARTBEAT, \
    FRAME_BODY, FRAME_HEADER, FRAME_END, \
    IDENT_TO_METHOD, CLASS_ID_TO_CONTENT_PROPERTY_LIST, FRAME_END_BYTE

    def get_size(self):  # type: () -> int
        # frame header is always 7, frame end is 1, content header is 12 + props
        return 20 + self.properties.get_size()

    def __str__(self):  # type: () -> str
        return 'AMQPHeaderFrame(%s, %s, %s, %s, %s)' % (self.channel, self.class_id, self.weight,
                                                        self.body_size, self.properties)


class AMQPBodyFrame(AMQPFrame):
    """
    A frame containing message body

    :param channel: Channel ID
    :type channel: int
    :param data: body (or a piece of it) of a message
    :type data: binary
    """
    __slots__ = ('data', )
    FRAME_TYPE = FRAME_BODY

    FRAME_SIZE_WITHOUT_PAYLOAD = 8

    def __init__(self, channel, data):  # type: (int, bytes) -> None
        AMQPFrame.__init__(self, channel)
        assert isinstance(data, (six.binary_type, memoryview))
        self.data = data

    def write_to(self, buf):
        buf.write(

            STRUCT_BHL.pack(FRAME_BODY, self.channel, len(self.data)))