# Path: oppy/cell/exceptions.py
# class BadRelayCellHeader(Exception):
#     pass
# 
# class BadPayloadData(Exception):
#     pass
# 
# Path: oppy/cell/fixedlen.py
# class FixedLenCell(Cell):
#     '''A container class for representing fixed-length cells.'''
# 
#     _subclass_map = None
# 
#     def __init__(self, header, payload=None):
#         '''Create a :class:`~oppy.cell.fixedlen.FixedLenCell` with the
#         using *header*.
# 
#         :param :class:`oppy.cell.fixedlen.FixedLenCell.Header` header: The
#             cell header information to be used.
#         :param str payload: Cell payload to be used.
#         '''
#         if not isinstance(header, FixedLenCell.Header):
#             msg = 'Expected cell header type FixedLenCell.Header, but '
#             msg += 'received header of type: {}'.format(type(header))
#             raise BadCellHeader(msg)
# 
#         self.header = header
#         self.payload = payload
# 
#     @staticmethod
#     def padCellBytes(cell_bytes, link_version=3):
#         '''Pad cell_bytes to uniform length.
# 
#         Length depends on the Link Protocol version in use.
# 
#         :param str cell_bytes: byte string to pad
#         :param int link_version: Link Protocol version in use
#         :returns: **str** cell_bytes padded to a fixed-length
#         '''
#         PAD_BYTE = '\x00'
#         if link_version <= 3:
#             pad_len = DEF.FIXED_LEN_V3_LEN
#         else:
#             pad_len = DEF.FIXED_LEN_V4_LEN
#         return cell_bytes + PAD_BYTE * (pad_len - len(cell_bytes))
# 
#     def getBytes(self, trimmed=False):
#         '''Build and return the raw bytes this cell represents.
# 
#         :param bool trimmed: ignored
#         :returns: **str** byte representation of this cell.
#         '''
#         return self.header.getBytes() + self.payload
# 
#     def payloadRange(self):
#         '''Return a two-tuple representing the (start, end) positions of this
#         cell's payload data (based on Link Protocol version in use).
# 
#         :returns: **tuple, int** (start, end) indices of payload.
#         '''
#         if 1 <= self.header.link_version <= 3:
#             return DEF.PAYLOAD_START_V3, DEF.FIXED_LEN_V3_LEN
#         elif self.header.link_version <= 4:
#             return DEF.PAYLOAD_START_V4, DEF.FIXED_LEN_V4_LEN
#         else:
#             fmt = "The cell's link version is invalid: {}"
#             raise ValueError(fmt.format(self.header.link_version))
# 
#     def _parseHeader(self, data):
#         # This check is only useful for debugging purposes. For fixed-length
#         # cells, this method actually doesn't need to do anything, because
#         # all header fields have already been parsed.
#         already_parsed = (self.header.circ_id,
#                           self.header.cmd,
#                           self.header.link_version)
#         for field in already_parsed:
#             assert field is not None
# 
#     def _parsePayload(self, data):
#         start, end = self.payloadRange()
#         self.payload = data[start:end]
# 
#     @staticmethod
#     def _initSubclassMap():
#         FixedLenCell._subclass_map = {
#             DEF.PADDING_CMD     :   PaddingCell,
#             DEF.CREATE_CMD      :   CreateCell,
#             DEF.CREATED_CMD     :   CreatedCell,
#             DEF.RELAY_CMD       :   EncryptedCell,
#             DEF.DESTROY_CMD     :   DestroyCell,
#             DEF.CREATE_FAST_CMD :   CreateFastCell,
#             DEF.CREATED_FAST_CMD:   CreatedFastCell,
#             DEF.NETINFO_CMD     :   NetInfoCell,
#             DEF.RELAY_EARLY_CMD :   EncryptedCell,
#             DEF.CREATE2_CMD     :   Create2Cell,
#             DEF.CREATED2_CMD    :   Created2Cell
#         }
# 
#     @staticmethod
#     def _extractCmd(data, header):
#         return header.cmd
# 
#     class Header(object):
#         '''A simple container class for representing the header information of
#         a fixed-length cell.'''
# 
#         def __init__(self, circ_id=None, cmd=None, link_version=3):
#             self.circ_id = circ_id
#             self.cmd = cmd
#             self.link_version = link_version
# 
#         def getBytes(self):
#             '''Return the raw bytes of this header.
# 
#             :returns: **str** byte representation of this header
#             '''
#             fmt = "!HB" if self.link_version <= 3 else "!IB"
#             return struct.pack(fmt, self.circ_id, self.cmd)
# 
#         def __repr__(self):
#             fmt = "FixedLenCell.Header(circ_id={}, cmd={}, link_version={})"
#             return fmt.format(self.circ_id, self.cmd, self.link_version)
# 
#         def __eq__(self, other):
#             if type(other) is type(self):
#                 return self.__dict__ == other.__dict__
#             return False


import struct
import oppy.cell.definitions as DEF
from oppy.cell.exceptions import BadRelayCellHeader, BadPayloadData
from oppy.cell.fixedlen import FixedLenCell
        self.rheader = rheader
        self.addr = addr
        self.flags = flags

    @staticmethod
    def make(circ_id, stream_id, request, flags=None, link_version=3):
        '''Build and return a RelayBegin cell, filling in default values
        when possible.

        Automatically create a default FixedLenCell.Header and
        RelayCell.RelayHeader.

        :param int circ_id: Circuit ID to use in this cell
        :param int stream_id: Stream ID to use in this cell
        :param oppy.util.ExitRequest request: destination this
            cell will request a connection to
        :param list, int flags: flags to use for this connection
        :param int link_version: Link Protocol version in use on this
            connection
        :returns: :class:`~cell.relay.RelayBeginCell`
        '''
        addr = str(request)

        if flags is None:
            flags = [DEF.BEGIN_FLAG_IPv6_OK]

        f = 0
        for flag in flags:
            if flag not in DEF.RELAY_BEGIN_FLAGS:
                msg = 'Unrecognized Relay Begin flag: {}'.format(flag)

# Path: oppy/cell/exceptions.py
# class BadRelayCellHeader(Exception):
#     pass
# 
# class BadPayloadData(Exception):
#     pass
# 
# Path: oppy/cell/fixedlen.py
# class FixedLenCell(Cell):
#     '''A container class for representing fixed-length cells.'''
# 
#     _subclass_map = None
# 
#     def __init__(self, header, payload=None):
#         '''Create a :class:`~oppy.cell.fixedlen.FixedLenCell` with the
#         using *header*.
# 
#         :param :class:`oppy.cell.fixedlen.FixedLenCell.Header` header: The
#             cell header information to be used.
#         :param str payload: Cell payload to be used.
#         '''
#         if not isinstance(header, FixedLenCell.Header):
#             msg = 'Expected cell header type FixedLenCell.Header, but '
#             msg += 'received header of type: {}'.format(type(header))
#             raise BadCellHeader(msg)
# 
#         self.header = header
#         self.payload = payload
# 
#     @staticmethod
#     def padCellBytes(cell_bytes, link_version=3):
#         '''Pad cell_bytes to uniform length.
# 
#         Length depends on the Link Protocol version in use.
# 
#         :param str cell_bytes: byte string to pad
#         :param int link_version: Link Protocol version in use
#         :returns: **str** cell_bytes padded to a fixed-length
#         '''
#         PAD_BYTE = '\x00'
#         if link_version <= 3:
#             pad_len = DEF.FIXED_LEN_V3_LEN
#         else:
#             pad_len = DEF.FIXED_LEN_V4_LEN
#         return cell_bytes + PAD_BYTE * (pad_len - len(cell_bytes))
# 
#     def getBytes(self, trimmed=False):
#         '''Build and return the raw bytes this cell represents.
# 
#         :param bool trimmed: ignored
#         :returns: **str** byte representation of this cell.
#         '''
#         return self.header.getBytes() + self.payload
# 
#     def payloadRange(self):
#         '''Return a two-tuple representing the (start, end) positions of this
#         cell's payload data (based on Link Protocol version in use).
# 
#         :returns: **tuple, int** (start, end) indices of payload.
#         '''
#         if 1 <= self.header.link_version <= 3:
#             return DEF.PAYLOAD_START_V3, DEF.FIXED_LEN_V3_LEN
#         elif self.header.link_version <= 4:
#             return DEF.PAYLOAD_START_V4, DEF.FIXED_LEN_V4_LEN
#         else:
#             fmt = "The cell's link version is invalid: {}"
#             raise ValueError(fmt.format(self.header.link_version))
# 
#     def _parseHeader(self, data):
#         # This check is only useful for debugging purposes. For fixed-length
#         # cells, this method actually doesn't need to do anything, because
#         # all header fields have already been parsed.
#         already_parsed = (self.header.circ_id,
#                           self.header.cmd,
#                           self.header.link_version)
#         for field in already_parsed:
#             assert field is not None
# 
#     def _parsePayload(self, data):
#         start, end = self.payloadRange()
#         self.payload = data[start:end]
# 
#     @staticmethod
#     def _initSubclassMap():
#         FixedLenCell._subclass_map = {
#             DEF.PADDING_CMD     :   PaddingCell,
#             DEF.CREATE_CMD      :   CreateCell,
#             DEF.CREATED_CMD     :   CreatedCell,
#             DEF.RELAY_CMD       :   EncryptedCell,
#             DEF.DESTROY_CMD     :   DestroyCell,
#             DEF.CREATE_FAST_CMD :   CreateFastCell,
#             DEF.CREATED_FAST_CMD:   CreatedFastCell,
#             DEF.NETINFO_CMD     :   NetInfoCell,
#             DEF.RELAY_EARLY_CMD :   EncryptedCell,
#             DEF.CREATE2_CMD     :   Create2Cell,
#             DEF.CREATED2_CMD    :   Created2Cell
#         }
# 
#     @staticmethod
#     def _extractCmd(data, header):
#         return header.cmd
# 
#     class Header(object):
#         '''A simple container class for representing the header information of
#         a fixed-length cell.'''
# 
#         def __init__(self, circ_id=None, cmd=None, link_version=3):
#             self.circ_id = circ_id
#             self.cmd = cmd
#             self.link_version = link_version
# 
#         def getBytes(self):
#             '''Return the raw bytes of this header.
# 
#             :returns: **str** byte representation of this header
#             '''
#             fmt = "!HB" if self.link_version <= 3 else "!IB"
#             return struct.pack(fmt, self.circ_id, self.cmd)
# 
#         def __repr__(self):
#             fmt = "FixedLenCell.Header(circ_id={}, cmd={}, link_version={})"
#             return fmt.format(self.circ_id, self.cmd, self.link_version)
# 
#         def __eq__(self, other):
#             if type(other) is type(self):
#                 return self.__dict__ == other.__dict__
#             return False


# Path: oppy/cell/relay.py
import struct
import oppy.cell.definitions as DEF
from oppy.cell.exceptions import BadRelayCellHeader, BadPayloadData
from oppy.cell.fixedlen import FixedLenCell

        self.rheader = rheader
        self.addr = addr
        self.flags = flags

    @staticmethod
    def make(circ_id, stream_id, request, flags=None, link_version=3):
        '''Build and return a RelayBegin cell, filling in default values
        when possible.

        Automatically create a default FixedLenCell.Header and
        RelayCell.RelayHeader.

        :param int circ_id: Circuit ID to use in this cell
        :param int stream_id: Stream ID to use in this cell
        :param oppy.util.ExitRequest request: destination this
            cell will request a connection to
        :param list, int flags: flags to use for this connection
        :param int link_version: Link Protocol version in use on this
            connection
        :returns: :class:`~cell.relay.RelayBeginCell`
        '''
        addr = str(request)

        if flags is None:
            flags = [DEF.BEGIN_FLAG_IPv6_OK]

        f = 0
        for flag in flags:
            if flag not in DEF.RELAY_BEGIN_FLAGS:
                msg = 'Unrecognized Relay Begin flag: {}'.format(flag)

                raise BadPayloadData(msg)