text:
"""
Decoder/Encoder implementations of OpenFlow 1.0.
"""

import struct
import binascii
import six

from ryu.ofproto.ofproto_parser import StringifyMixin, MsgBase, msg_str_attr
from ryu.lib import addrconv
from ryu.lib import mac
from ryu.lib.pack_utils import msg_pack_into
from . import ofproto_common
from . import ofproto_parser
from . import ofproto_v1_0 as ofproto
from . import nx_match
from ryu import utils

import logging
LOG = logging.getLogger('ryu.ofproto.ofproto_v1_0_parser')

_MSG_PARSERS = {}

def _set_msg_type(msg_type):
    '''Annotate corresponding OFP message type'''
    def _set_cls_msg_type(cls):
        cls.cls_msg_type = msg_type
        return cls
    return _set_cls_msg_type

def _register_parser(cls):
    '''class decorator to register msg parser'''
    assert cls.cls_msg_type is not None
    assert cls.cls_msg_type not in _MSG_PARSERS
    _MSG_PARSERS[cls.cls_msg_type] = cls.parser
    return cls

@ofproto_parser.register_msg_parser(ofproto.OFP_VERSION)
def msg_parser(datapath, version, msg_type, msg_len, xid, buf):
    parser = _MSG_PARSERS.get(msg_type)
    return parser(datapath, version, msg_type, msg_len, xid, buf)

# OFP_MSG_REPLY = {
#     OFPFeaturesRequest: OFPSwitchFeatures,
#     OFPBarrierRequest: OFPBarrierReply,
#     OFPQueueGetConfigRequest: OFPQueueGetConfigReply,
#
#     # ofp_stats_request -> ofp_stats_reply
#     OFPDescStatsRequest: OFPDescStatsReply,
#     OFPFlowStatsRequest: OFPFlowStatsReply,
#     OFPAggregateStatsRequest: OFPAggregateStatsReply,
#     OFPTableStatsRequest: OFPTableStatsReply,
#     OFPPortStatsRequest: OFPPortStatsReply,
#     OFPQueueStatsRequest: OFPQueueStatsReply,
#     OFPVendorStatsRequest: OFPVendorStatsReply,
#     }
def _set_msg_reply(msg_reply):
    '''Annotate OFP reply message class'''
    def _set_cls_msg_reply(cls):
        cls.cls_msg_reply = msg_reply
        return cls
    return _set_cls_msg_reply

#
# common structures
#

class OFPPhyPort(ofproto_parser.namedtuple('OFPPhyPort', (
        'port_no', 'hw_addr', 'name', 'config', 'state', 'curr', 'advertised',
        'supported', 'peer'))):

    _TYPE = {
        'ascii': [
            'hw_addr',
        ],
        'utf-8': [
            # OF spec is unclear about the encoding of name.
            # we assumes UTF-8, which is used by OVS.
            'name',
        ]
    }

    @classmethod
    def parser(cls, buf, offset):
        port = struct.unpack_from(ofproto.OFP_PHY_PORT_PACK_STR,
                                  buf, offset)
        port = list(port)
        i = cls._fields.index('hw_addr')
        port[i] = addrconv.mac.bin_to_text(port[i])
        i = cls._fields.index('name')
        port[i] = port[i].rstrip(b'\0')
        return cls(*port)

class OFPMatch(StringifyMixin):
    def __init__(self, wildcards=None, in_port=None, dl_src=None, dl_dst=None,
                 dl_vlan=None, dl_vlan_pcp=None, dl_type=None, nw_tos=None,
                 nw_proto=None, nw_src=None, nw_dst=None,
                 tp_src=None, tp_dst=None, nw_src_mask=32, nw_dst_mask=32):
        super(OFPMatch, self).__init__()
        wc = ofproto.OFPFW_ALL
        if in_port is None:
            self.in_port = 0
        else:
            wc &= ~ofproto.OFPFW_IN_PORT
            self.in_port = in_port

        if dl_src is None:
            self.dl_src = mac.DONTCARE
        else:
            wc &= ~ofproto.OFPFW_DL_SRC
            if dl_src == 0:
                self.dl_src = mac.DONTCARE
            else:
                self.dl_src = dl_src

        if dl_dst is None:
            self.dl_dst = mac.DONTCARE
        else:
            wc &= ~ofproto.OFPFW_DL_DST
            if dl_dst == 0:
                self.dl_dst = mac.DONTCARE
            else:
                self.dl_dst = dl_dst

        if dl_vlan is None:
            self.dl_vlan = 0
        else:
            wc &= ~ofproto.OFPFW_DL_VLAN
            self.dl_vlan = dl_vlan

        if dl_vlan_pcp is None:
            self.dl_vlan_pcp = 0
        else:
            wc &= ~ofproto.OFPFW_DL_VLAN_PCP
            self.dl_vlan_pcp = dl_vlan_pcp

        if dl_type is None:
            self.dl_type = 0
        else:
            wc &= ~ofproto.OFPFW_DL_TYPE
            self.dl_type = dl_type

        if nw_tos is None:
            self.nw_tos = 0
        else:
            wc &= ~ofproto.OFPFW_NW_TOS
            self.nw_tos = nw_tos

        if nw_proto is None:
            self.nw_proto = 0
        else:
            wc &= ~ofproto.OFPFW_NW_PROTO
            self.nw_proto = nw_proto

        if nw_src is None:
            self.nw_src = 0
        else:
            wc &= (32 - nw_src_mask) << ofproto.OFPFW_NW_SRC_SHIFT \
                | ~ofproto.OFPFW_NW_SRC_MASK
            self.nw_src = nw_src

        if nw_dst is None:
            self.nw_dst = 0
        else:
            wc &= (32 - nw_dst_mask) << ofproto.OFPFW_NW_DST_SHIFT \
                | ~ofproto.OFPFW_NW_DST_MASK
            self.nw_dst = nw_dst

        if tp_src is None:
            self.tp_src = 0
        else:
            wc &= ~ofproto.OFPFW_TP_SRC
            self.tp_src = tp_src

        if tp_dst is None:
            self.tp_dst = 0
        else:
            wc &= ~ofproto.OFPFW_TP_DST
            self.tp_dst = tp_dst

        if wildcards is None:
            self.wildcards = wc
        else:
            self.wildcards = wildcards

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.OFP_MATCH_PACK_STR, buf, offset,
                      self.wildcards, self.in_port, self.dl_src,
                      self.dl_dst, self.dl_vlan, self.dl_vlan_pcp,
                      self.dl_type, self.nw_tos, self.nw_proto,
                      self.nw_src, self.nw_dst, self.tp_src, self.tp_dst)

    @classmethod
    def parse(cls, buf, offset):
        match = struct.unpack_from(ofproto.OFP_MATCH_PACK_STR,
                                   buf, offset)
        return cls(*match)

class OFPActionHeader(StringifyMixin):
    _base_attributes = ['type', 'len']

    def __init__(self, type_, len_):
        self.type = type_
        self.len = len_

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.OFP_ACTION_HEADER_PACK_STR,
                      buf, offset, self.type, self.len)

class OFPAction(OFPActionHeader):
    _ACTION_TYPES = {}

    @staticmethod
    def register_action_type(type_, len_):
        def _register_action_type(cls):
            cls.cls_action_type = type_
            cls.cls_action_len = len_
            OFPAction._ACTION_TYPES[cls.cls_action_type] = cls
            return cls
        return _register_action_type

    def __init__(self):
        cls = self.__class__
        super(OFPAction, self).__init__(cls.cls_action_type,
                                        cls.cls_action_len)

    @classmethod
    def parser(cls, buf, offset):
        type_, len_ = struct.unpack_from(
            ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset)
        cls_ = cls._ACTION_TYPES.get(type_)
        assert cls_ is not None
        return cls_.parser(buf, offset)

@OFPAction.register_action_type(ofproto.OFPAT_OUTPUT,
                                ofproto.OFP_ACTION_OUTPUT_SIZE)
class OFPActionOutput(OFPAction):
    # NOTE: The reason of this magic number (0xffe5)
    #       is because there is no good constant in of1.0.
    #       The same value as OFPCML_MAX of of1.2 and of1.3 is used.
    def __init__(self, port, max_len=0xffe5):
        super(OFPActionOutput, self).__init__()
        self.port = port
        self.max_len = max_len

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, port, max_len = struct.unpack_from(
            ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset)
        assert type_ == ofproto.OFPAT_OUTPUT
        assert len_ == ofproto.OFP_ACTION_OUTPUT_SIZE
        return cls(port, max_len)

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf,
                      offset, self.type, self.len, self.port, self.max_len)

@OFPAction.register_action_type(ofproto.OFPAT_SET_VLAN_VID,
                                ofproto.OFP_ACTION_VLAN_VID_SIZE)
class OFPActionVlanVid(OFPAction):
    def __init__(self, vlan_vid):
        super(OFPActionVlanVid, self).__init__()
        self.vlan_vid = vlan_vid

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, vlan_vid = struct.unpack_from(
            ofproto.OFP_ACTION_VLAN_VID_PACK_STR, buf, offset)
        assert type_ == ofproto.OFPAT_SET_VLAN_VID
        assert len_ == ofproto.OFP_ACTION_VLAN_VID_SIZE
        return cls(vlan_vid)

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.OFP_ACTION_VLAN_VID_PACK_STR,
                      buf, offset, self.type, self.len, self.vlan_vid)

@OFPAction.register_action_type(ofproto.OFPAT_SET_VLAN_PCP,
                                ofproto.OFP_ACTION_VLAN_PCP_SIZE)
class OFPActionVlanPcp(OFPAction):
    def __init__(self, vlan_pcp):
        super(OFPActionVlanPcp, self).__init__()
        self.vlan_pcp = vlan_pcp

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, vlan_pcp = struct.unpack_from(
            ofproto.OFP_ACTION_VLAN_PCP_PACK_STR, buf, offset)
        assert type_ == ofproto.OFPAT_SET_VLAN_PCP
        assert len_ == ofproto.OFP_ACTION_VLAN_PCP_SIZE
        return cls(vlan_pcp)

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.OFP_ACTION_VLAN_PCP_PACK_STR,
                      buf, offset, self.type, self.len, self.vlan_pcp)

@OFPAction.register_action_type(ofproto.OFPAT_STRIP_VLAN,
                                ofproto.OFP_ACTION_HEADER_SIZE)
class OFPActionStripVlan(OFPAction):
    def __init__(self):
        super(OFPActionStripVlan, self).__init__()

    @classmethod
    def parser(cls, buf, offset):
        type_, len_ = struct.unpack_from(
            ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset)
        assert type_ == ofproto.OFPAT_STRIP_VLAN
        assert len_ == ofproto.OFP_ACTION_HEADER_SIZE
        return cls()

class OFPActionDlAddr(OFPAction):
    def __init__(self, dl_addr):
        super(OFPActionDlAddr, self).__init__()
        self.dl_addr = dl_addr

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, dl_addr = struct.unpack_from(
            ofproto.OFP_ACTION_DL_ADDR_PACK_STR, buf, offset)
        assert type_ in (ofproto.OFPAT_SET_DL_SRC,
                         ofproto.OFPAT_SET_DL_DST)
        assert len_ == ofproto.OFP_ACTION_DL_ADDR_SIZE
        return cls(dl_addr)

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.OFP_ACTION_DL_ADDR_PACK_STR,
                      buf, offset, self.type, self.len, self.dl_addr)

@OFPAction.register_action_type(ofproto.OFPAT_SET_DL_SRC,
                                ofproto.OFP_ACTION_DL_ADDR_SIZE)
class OFPActionSetDlSrc(OFPActionDlAddr):
    def __init__(self, dl_addr):
        super(OFPActionSetDlSrc, self).__init__(dl_addr)

@OFPAction.register_action_type(ofproto.OFPAT_SET_DL_DST,
                                ofproto.OFP_ACTION_DL_ADDR_SIZE)
class OFPActionSetDlDst(OFPActionDlAddr):
    def __init__(self, dl_addr):
        super(OFPActionSetDlDst, self).__init__(dl_addr)

class OFPActionNwAddr(OFPAction):
    def __init__(self, nw_addr):
        super(OFPActionNwAddr, self).__init__()
        self.nw_addr = nw_addr

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, nw_addr = struct.unpack_from(
            ofproto.OFP_ACTION_NW_ADDR_PACK_STR, buf, offset)
        assert type_ in (ofproto.OFPAT_SET_NW_SRC,
                         ofproto.OFPAT_SET_NW_DST)
        assert len_ == ofproto.OFP_ACTION_NW_ADDR_SIZE
        return cls(nw_addr)

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.OFP_ACTION_NW_ADDR_PACK_STR,
                      buf, offset, self.type, self.len, self.nw_addr)

@OFPAction.register_action_type(ofproto.OFPAT_SET_NW_SRC,
                                ofproto.OFP_ACTION_NW_ADDR_SIZE)
class OFPActionSetNwSrc(OFPActionNwAddr):
    def __init__(self, nw_addr):
        super(OFPActionSetNwSrc, self).__init__(nw_addr)

@OFPAction.register_action_type(ofproto.OFPAT_SET_NW_DST,
                                ofproto.OFP_ACTION_NW_ADDR_SIZE)
class OFPActionSetNwDst(OFPActionNwAddr):
    def __init__(self, nw_addr):
        super(OFPActionSetNwDst, self).__init__(nw_addr)

@OFPAction.register_action_type(ofproto.OFPAT_SET_NW_TOS,
                                ofproto.OFP_ACTION_NW_TOS_SIZE)
class OFPActionSetNwTos(OFPAction):
    def __init__(self, tos):
        super(OFPActionSetNwTos, self).__init__()
        self.tos = tos

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, tos = struct.unpack_from(
            ofproto.OFP_ACTION_NW_TOS_PACK_STR, buf, offset)
        assert type_ == ofproto.OFPAT_SET_NW_TOS
        assert len_ == ofproto.OFP_ACTION_NW_TOS_SIZE
        return cls(tos)

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.OFP_ACTION_NW_TOS_PACK_STR,
                      buf, offset, self.type, self.len, self.tos)

class OFPActionTpPort(OFPAction):
    def __init__(self, tp):
        super(OFPActionTpPort, self).__init__()
        self.tp = tp

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, tp = struct.unpack_from(
            ofproto.OFP_ACTION_TP_PORT_PACK_STR, buf, offset)
        assert type_ in (ofproto.OFPAT_SET_TP_SRC,
                         ofproto.OFPAT_SET_TP_DST)
        assert len_ == ofproto.OFP_ACTION_TP_PORT_SIZE
        return cls(tp)

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.OFP_ACTION_TP_PORT_PACK_STR,
                      buf, offset, self.type, self.len, self.tp)

@OFPAction.register_action_type(ofproto.OFPAT_SET_TP_SRC,
                                ofproto.OFP_ACTION_TP_PORT_SIZE)
class OFPActionSetTpSrc(OFPActionTpPort):
    def __init__(self, tp):
        super(OFPActionSetTpSrc, self).__init__(tp)

@OFPAction.register_action_type(ofproto.OFPAT_SET_TP_DST,
                                ofproto.OFP_ACTION_TP_PORT_SIZE)
class OFPActionSetTpDst(OFPActionTpPort):
    def __init__(self, tp):
        super(OFPActionSetTpDst, self).__init__(tp)

@OFPAction.register_action_type(ofproto.OFPAT_ENQUEUE,
                                ofproto.OFP_ACTION_ENQUEUE_SIZE)
class OFPActionEnqueue(OFPAction):
    def __init__(self, port, queue_id):
        super(OFPActionEnqueue, self).__init__()
        self.port = port
        self.queue_id = queue_id

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, port, queue_id = struct.unpack_from(
            ofproto.OFP_ACTION_ENQUEUE_PACK_STR, buf, offset)
        assert type_ == ofproto.OFPAT_ENQUEUE
        assert len_ == ofproto.OFP_ACTION_ENQUEUE_SIZE
        return cls(port, queue_id)

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.OFP_ACTION_ENQUEUE_PACK_STR, buf, offset,
                      self.type, self.len, self.port, self.queue_id)

@OFPAction.register_action_type(ofproto.OFPAT_VENDOR, 0)
class OFPActionVendor(OFPAction):
    _ACTION_VENDORS = {}

    @staticmethod
    def register_action_vendor(vendor):
        def _register_action_vendor(cls):
            cls.cls_vendor = vendor
            OFPActionVendor._ACTION_VENDORS[cls.cls_vendor] = cls
            return cls
        return _register_action_vendor

    def __init__(self):
        super(OFPActionVendor, self).__init__()
        self.vendor = self.cls_vendor

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, vendor = struct.unpack_from(
            ofproto.OFP_ACTION_VENDOR_HEADER_PACK_STR, buf, offset)
        cls_ = cls._ACTION_VENDORS.get(vendor)
        return cls_.parser(buf, offset)

@OFPActionVendor.register_action_vendor(ofproto_common.NX_EXPERIMENTER_ID)
class NXActionHeader(OFPActionVendor):
    _NX_ACTION_SUBTYPES = {}

    @staticmethod
    def register_nx_action_subtype(subtype, len_):
        def _register_nx_action_subtype(cls):
            cls.cls_action_len = len_
            cls.cls_subtype = subtype
            NXActionHeader._NX_ACTION_SUBTYPES[cls.cls_subtype] = cls
            return cls
        return _register_nx_action_subtype

    def __init__(self):
        super(NXActionHeader, self).__init__()
        self.subtype = self.cls_subtype

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.OFP_ACTION_HEADER_PACK_STR,
                      buf, offset, self.type, self.len)

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, vendor, subtype = struct.unpack_from(
            ofproto.NX_ACTION_HEADER_PACK_STR, buf, offset)
        cls_ = cls._NX_ACTION_SUBTYPES.get(subtype)
        return cls_.parser(buf, offset)

class NXActionResubmitBase(NXActionHeader):
    def __init__(self, in_port, table):
        super(NXActionResubmitBase, self).__init__()
        assert self.subtype in (ofproto.NXAST_RESUBMIT,
                                ofproto.NXAST_RESUBMIT_TABLE)
        self.in_port = in_port
        self.table = table

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_RESUBMIT_PACK_STR, buf, offset,
                      self.type, self.len, self.vendor, self.subtype,
                      self.in_port, self.table)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_RESUBMIT, ofproto.NX_ACTION_RESUBMIT_SIZE)
class NXActionResubmit(NXActionResubmitBase):
    def __init__(self, in_port=ofproto.OFPP_IN_PORT):
        super(NXActionResubmit, self).__init__(in_port, 0)

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, vendor, subtype, in_port, table = struct.unpack_from(
            ofproto.NX_ACTION_RESUBMIT_PACK_STR, buf, offset)
        return cls(in_port)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_RESUBMIT_TABLE, ofproto.NX_ACTION_RESUBMIT_SIZE)
class NXActionResubmitTable(NXActionResubmitBase):
    def __init__(self, in_port=ofproto.OFPP_IN_PORT, table=0xff):
        super(NXActionResubmitTable, self).__init__(in_port, table)

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, vendor, subtype, in_port, table = struct.unpack_from(
            ofproto.NX_ACTION_RESUBMIT_PACK_STR, buf, offset)
        return cls(in_port, table)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_SET_TUNNEL, ofproto.NX_ACTION_SET_TUNNEL_SIZE)
class NXActionSetTunnel(NXActionHeader):
    def __init__(self, tun_id):
        super(NXActionSetTunnel, self).__init__()
        self.tun_id = tun_id

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_SET_TUNNEL_PACK_STR, buf,
                      offset, self.type, self.len, self.vendor, self.subtype,
                      self.tun_id)

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, vendor, subtype, tun_id = struct.unpack_from(
            ofproto.NX_ACTION_SET_TUNNEL_PACK_STR, buf, offset)
        return cls(tun_id)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_SET_QUEUE, ofproto.NX_ACTION_SET_QUEUE_SIZE)
class NXActionSetQueue(NXActionHeader):
    def __init__(self, queue_id):
        super(NXActionSetQueue, self).__init__()
        self.queue_id = queue_id

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_SET_QUEUE_PACK_STR, buf,
                      offset, self.type, self.len, self.vendor,
                      self.subtype, self.queue_id)

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype, queue_id) = struct.unpack_from(
            ofproto.NX_ACTION_SET_QUEUE_PACK_STR, buf, offset)
        return cls(queue_id)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_POP_QUEUE, ofproto.NX_ACTION_POP_QUEUE_SIZE)
class NXActionPopQueue(NXActionHeader):
    def __init__(self):
        super(NXActionPopQueue, self).__init__()

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_POP_QUEUE_PACK_STR, buf,
                      offset, self.type, self.len, self.vendor,
                      self.subtype)

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype) = struct.unpack_from(
            ofproto.NX_ACTION_POP_QUEUE_PACK_STR, buf, offset)
        return cls()

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_REG_MOVE, ofproto.NX_ACTION_REG_MOVE_SIZE)
class NXActionRegMove(NXActionHeader):
    def __init__(self, n_bits, src_ofs, dst_ofs, src, dst):
        super(NXActionRegMove, self).__init__()
        self.n_bits = n_bits
        self.src_ofs = src_ofs
        self.dst_ofs = dst_ofs
        self.src = src
        self.dst = dst

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_REG_MOVE_PACK_STR, buf,
                      offset, self.type, self.len, self.vendor,
                      self.subtype, self.n_bits, self.src_ofs, self.dst_ofs,
                      self.src, self.dst)

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype, n_bits, src_ofs, dst_ofs,
            src, dst) = struct.unpack_from(
            ofproto.NX_ACTION_REG_MOVE_PACK_STR, buf, offset)
        return cls(n_bits, src_ofs, dst_ofs, src, dst)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_REG_LOAD, ofproto.NX_ACTION_REG_LOAD_SIZE)
class NXActionRegLoad(NXActionHeader):
    def __init__(self, ofs_nbits, dst, value):
        super(NXActionRegLoad, self).__init__()
        self.ofs_nbits = ofs_nbits
        self.dst = dst
        self.value = value

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_REG_LOAD_PACK_STR, buf,
                      offset, self.type, self.len, self.vendor,
                      self.subtype, self.ofs_nbits, self.dst, self.value)

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype, ofs_nbits, dst,
            value) = struct.unpack_from(
            ofproto.NX_ACTION_REG_LOAD_PACK_STR, buf, offset)
        return cls(ofs_nbits, dst, value)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_SET_TUNNEL64, ofproto.NX_ACTION_SET_TUNNEL64_SIZE)
class NXActionSetTunnel64(NXActionHeader):
    def __init__(self, tun_id):
        super(NXActionSetTunnel64, self).__init__()
        self.tun_id = tun_id

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_SET_TUNNEL64_PACK_STR, buf,
                      offset, self.type, self.len, self.vendor, self.subtype,
                      self.tun_id)

    @classmethod
    def parser(cls, buf, offset):
        type_, len_, vendor, subtype, tun_id = struct.unpack_from(
            ofproto.NX_ACTION_SET_TUNNEL64_PACK_STR, buf, offset)
        return cls(tun_id)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_MULTIPATH, ofproto.NX_ACTION_MULTIPATH_SIZE)
class NXActionMultipath(NXActionHeader):
    def __init__(self, fields, basis, algorithm, max_link, arg,
                 ofs_nbits, dst):
        super(NXActionMultipath, self).__init__()
        self.fields = fields
        self.basis = basis
        self.algorithm = algorithm
        self.max_link = max_link
        self.arg = arg
        self.ofs_nbits = ofs_nbits
        self.dst = dst

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_MULTIPATH_PACK_STR, buf,
                      offset, self.type, self.len, self.vendor, self.subtype,
                      self.fields, self.basis, self.algorithm, self.max_link,
                      self.arg, self.ofs_nbits, self.dst)

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype, fields, basis, algorithm,
            max_link, arg, ofs_nbits, dst) = struct.unpack_from(
            ofproto.NX_ACTION_MULTIPATH_PACK_STR, buf, offset)
        return cls(fields, basis, algorithm, max_link, arg, ofs_nbits,
                   dst)

@NXActionHeader.register_nx_action_subtype(ofproto.NXAST_NOTE, 0)
class NXActionNote(NXActionHeader):
    def __init__(self, note):
        super(NXActionNote, self).__init__()
        # should check here if the note is valid (only hex values)
        pad = (len(note) + 10) % 8
        if pad:
            note += [0x0 for i in range(8 - pad)]
        self.note = note
        self.len = len(note) + 10

    def serialize(self, buf, offset):
        note = self.note
        extra = None
        extra_len = len(self.note) - 6
        if extra_len > 0:
            extra = note[6:]
        note = note[0:6]
        msg_pack_into(ofproto.NX_ACTION_NOTE_PACK_STR, buf,
                      offset, self.type, self.len, self.vendor, self.subtype,
                      *note)
        if extra_len > 0:
            msg_pack_into('B' * extra_len, buf,
                          offset + ofproto.NX_ACTION_NOTE_SIZE,
                          *extra)

    @classmethod
    def parser(cls, buf, offset):
        note = struct.unpack_from(
            ofproto.NX_ACTION_NOTE_PACK_STR, buf, offset)
        (type_, len_, vendor, subtype) = note[0:4]
        note = [i for i in note[4:]]
        if len_ > ofproto.NX_ACTION_NOTE_SIZE:
            note_start = offset + ofproto.NX_ACTION_NOTE_SIZE
            note_end = note_start + len_ - ofproto.NX_ACTION_NOTE_SIZE
            note += [int(binascii.b2a_hex(i), 16) for i
                     in buf[note_start:note_end]]
        return cls(note)

class NXActionBundleBase(NXActionHeader):
    def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
                 ofs_nbits, dst, slaves):
        super(NXActionBundleBase, self).__init__()
        _len = ofproto.NX_ACTION_BUNDLE_SIZE + len(slaves) * 2
        _len += (_len % 8)
        self.len = _len

        self.algorithm = algorithm
        self.fields = fields
        self.basis = basis
        self.slave_type = slave_type
        self.n_slaves = n_slaves
        self.ofs_nbits = ofs_nbits
        self.dst = dst
        self.slaves = slaves

    def serialize(self, buf, offset):
        slave_offset = offset + ofproto.NX_ACTION_BUNDLE_SIZE

        for s in self.slaves:
            msg_pack_into('!H', buf, slave_offset, s)
            slave_offset += 2

        pad_len = (len(self.slaves) * 2 +
                   ofproto.NX_ACTION_BUNDLE_SIZE) % 8

        if pad_len != 0:
            msg_pack_into('%dx' % pad_len, buf, slave_offset)

        msg_pack_into(ofproto.NX_ACTION_BUNDLE_PACK_STR, buf,
                      offset, self.type, self.len, self.vendor, self.subtype,
                      self.algorithm, self.fields, self.basis,
                      self.slave_type, self.n_slaves,
                      self.ofs_nbits, self.dst)

    @classmethod
    def parser(cls, action_cls, buf, offset):
        (type_, len_, vendor, subtype, algorithm, fields, basis,
            slave_type, n_slaves, ofs_nbits, dst) = struct.unpack_from(
            ofproto.NX_ACTION_BUNDLE_PACK_STR, buf, offset)
        slave_offset = offset + ofproto.NX_ACTION_BUNDLE_SIZE

        slaves = []
        for i in range(0, n_slaves):
            s = struct.unpack_from('!H', buf, slave_offset)
            slaves.append(s[0])
            slave_offset += 2

        return action_cls(algorithm, fields, basis, slave_type,
                          n_slaves, ofs_nbits, dst, slaves)

@NXActionHeader.register_nx_action_subtype(ofproto.NXAST_BUNDLE, 0)
class NXActionBundle(NXActionBundleBase):
    def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
                 ofs_nbits, dst, slaves):
        super(NXActionBundle, self).__init__(
            algorithm, fields, basis, slave_type, n_slaves,
            ofs_nbits, dst, slaves)

    @classmethod
    def parser(cls, buf, offset):
        return NXActionBundleBase.parser(NXActionBundle, buf, offset)

@NXActionHeader.register_nx_action_subtype(ofproto.NXAST_BUNDLE_LOAD, 0)
class NXActionBundleLoad(NXActionBundleBase):
    def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
                 ofs_nbits, dst, slaves):
        super(NXActionBundleLoad, self).__init__(
            algorithm, fields, basis, slave_type, n_slaves,
            ofs_nbits, dst, slaves)

    @classmethod
    def parser(cls, buf, offset):
        return NXActionBundleBase.parser(NXActionBundleLoad, buf, offset)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_AUTOPATH, ofproto.NX_ACTION_AUTOPATH_SIZE)
class NXActionAutopath(NXActionHeader):
    def __init__(self, ofs_nbits, dst, id_):
        super(NXActionAutopath, self).__init__()
        self.ofs_nbits = ofs_nbits
        self.dst = dst
        self.id = id_

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_AUTOPATH_PACK_STR, buf, offset,
                      self.type, self.len, self.vendor, self.subtype,
                      self.ofs_nbits, self.dst, self.id)

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype, ofs_nbits, dst,
            id_) = struct.unpack_from(
            ofproto.NX_ACTION_AUTOPATH_PACK_STR, buf, offset)
        return cls(ofs_nbits, dst, id_)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_OUTPUT_REG, ofproto.NX_ACTION_OUTPUT_REG_SIZE)
class NXActionOutputReg(NXActionHeader):
    def __init__(self, ofs_nbits, src, max_len):
        super(NXActionOutputReg, self).__init__()
        self.ofs_nbits = ofs_nbits
        self.src = src
        self.max_len = max_len

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_OUTPUT_REG_PACK_STR, buf, offset,
                      self.type, self.len, self.vendor, self.subtype,
                      self.ofs_nbits, self.src, self.max_len)

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype, ofs_nbits, src,
            max_len) = struct.unpack_from(
            ofproto.NX_ACTION_OUTPUT_REG_PACK_STR, buf, offset)
        return cls(ofs_nbits, src, max_len)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_EXIT, ofproto.NX_ACTION_HEADER_SIZE)
class NXActionExit(NXActionHeader):
    def __init__(self):
        super(NXActionExit, self).__init__()

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_HEADER_PACK_STR, buf, offset,
                      self.type, self.len, self.vendor, self.subtype)

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype) = struct.unpack_from(
            ofproto.NX_ACTION_HEADER_PACK_STR, buf, offset)
        return cls()

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_DEC_TTL, ofproto.NX_ACTION_HEADER_SIZE)
class NXActionDecTtl(NXActionHeader):
    def __init__(self):
        super(NXActionDecTtl, self).__init__()

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_HEADER_PACK_STR, buf, offset,
                      self.type, self.len, self.vendor, self.subtype)

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype) = struct.unpack_from(
            ofproto.NX_ACTION_HEADER_PACK_STR, buf, offset)
        return cls()

@NXActionHeader.register_nx_action_subtype(ofproto.NXAST_LEARN, 0)
class NXActionLearn(NXActionHeader):
    def __init__(self, idle_timeout, hard_timeout, priority, cookie, flags,
                 table_id, fin_idle_timeout, fin_hard_timeout, spec):
        super(NXActionLearn, self).__init__()
        len_ = len(spec) + ofproto.NX_ACTION_LEARN_SIZE
        pad_len = 8 - (len_ % 8)
        self.len = len_ + pad_len

        self.idle_timeout = idle_timeout
        self.hard_timeout = hard_timeout
        self.priority = priority
        self.cookie = cookie
        self.flags = flags
        self.table_id = table_id
        self.fin_idle_timeout = fin_idle_timeout
        self.fin_hard_timeout = fin_hard_timeout
        self.spec = spec + bytearray(b'\x00' * pad_len)

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_LEARN_PACK_STR, buf, offset,
                      self.type, self.len, self.vendor, self.subtype,
                      self.idle_timeout, self.hard_timeout, self.priority,
                      self.cookie, self.flags, self.table_id,
                      self.fin_idle_timeout, self.fin_hard_timeout)
        buf += self.spec

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype, idle_timeout, hard_timeout, priority,
            cookie, flags, table_id, fin_idle_timeout,
            fin_hard_timeout) = struct.unpack_from(
            ofproto.NX_ACTION_LEARN_PACK_STR, buf, offset)
        spec = buf[offset + ofproto.NX_ACTION_LEARN_SIZE:]
        return cls(idle_timeout, hard_timeout, priority,
                   cookie, flags, table_id, fin_idle_timeout,
                   fin_hard_timeout, spec)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_CONTROLLER, ofproto.NX_ACTION_CONTROLLER_SIZE)
class NXActionController(NXActionHeader):
    def __init__(self, max_len, controller_id, reason):
        super(NXActionController, self).__init__()
        self.max_len = max_len
        self.controller_id = controller_id
        self.reason = reason

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_CONTROLLER_PACK_STR, buf, offset,
                      self.type, self.len, self.vendor, self.subtype,
                      self.max_len, self.controller_id, self.reason, 0)

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype, max_len, controller_id, reason,
            _zero) = struct.unpack_from(
            ofproto.NX_ACTION_CONTROLLER_PACK_STR, buf, offset)
        return cls(max_len, controller_id, reason)

@NXActionHeader.register_nx_action_subtype(
    ofproto.NXAST_FIN_TIMEOUT, ofproto.NX_ACTION_FIN_TIMEOUT_SIZE)
class NXActionFinTimeout(NXActionHeader):
    def __init__(self, fin_idle_timeout, fin_hard_timeout):
        super(NXActionFinTimeout, self).__init__()
        self.fin_idle_timeout = fin_idle_timeout
        self.fin_hard_timeout = fin_hard_timeout

    def serialize(self, buf, offset):
        msg_pack_into(ofproto.NX_ACTION_FIN_TIMEOUT_PACK_STR, buf, offset,
                      self.type, self.len, self.vendor, self.subtype,
                      self.fin_idle_timeout, self.fin_hard_timeout)

    @classmethod
    def parser(cls, buf, offset):
        (type_, len_, vendor, subtype, fin_idle_timeout,
            fin_hard_timeout) = struct.unpack_from(
            ofproto.NX_ACTION_FIN_TIMEOUT_PACK_STR, buf, offset)
        return cls(fin_idle_timeout, fin_hard_timeout)

class OFPDescStats(ofproto_parser.namedtuple('OFPDescStats', (
        'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc'))):

    _TYPE = {
        'ascii': [
            'mfr_desc',
            'hw_desc',
            'sw_desc',
            'serial_num',
            'dp_desc',
        ]
    }

    @classmethod
    def parser(cls, buf, offset):
        desc = struct.unpack_from(ofproto.OFP_DESC_STATS_PACK_STR,
                                  buf, offset)
        desc = list(desc)
        desc = [x.rstrip(b'\0') for x in desc]
        stats = cls(*desc)
        stats.length = ofproto.OFP_DESC_STATS_SIZE
        return stats

class OFPFlowStats(StringifyMixin):
    def __init__(self):
        super(OFPFlowStats, self).__init__()
        self.length = None
        self.table_id = None
        self.match = None
        self.duration_sec = None
        self.duration_nsec = None
        self.priority = None
        self.idle_timeout = None
        self.hard_timeout = None
        self.cookie = None
        self.packet_count = None
        self.byte_count = None
        self.actions = None

    @classmethod
    def parser(cls, buf, offset):
        flow_stats = cls()

        flow_stats.length, flow_stats.table_id = struct.unpack_from(
            ofproto.OFP_FLOW_STATS_0_PACK_STR, buf, offset)
        offset += ofproto.OFP_FLOW_STATS_0_SIZE

        flow_stats.match = OFPMatch.parse(buf, offset)
        offset += ofproto.OFP_MATCH_SIZE

        (flow_stats.duration_sec,
         flow_stats.duration_nsec,
         flow_stats.priority,
         flow_stats.idle_timeout,
         flow_stats.hard_timeout,
         flow_stats.cookie,
         flow_stats.packet_count,
         flow_stats.byte_count) = struct.unpack_from(
            ofproto.OFP_FLOW_STATS_1_PACK_STR, buf, offset)
        offset += ofproto.OFP_FLOW_STATS_1_SIZE

        flow_stats.actions = []
        length = ofproto.OFP_FLOW_STATS_SIZE
        while length < flow_stats.length:
            action = OFPAction.parser(buf, offset)
            flow_stats.actions.append(action)

            offset += action.len
            length += action.len

        return flow_stats

class OFPAggregateStats(ofproto_parser.namedtuple('OFPAggregateStats', (
        'packet_count', 'byte_count', 'flow_count'))):
    @classmethod
    def parser(cls, buf, offset):
        agg = struct.unpack_from(
            ofproto.OFP_AGGREGATE_STATS_REPLY_PACK_STR, buf, offset)
        stats = cls(*agg)
        stats.length = ofproto.OFP_AGGREGATE_STATS_REPLY_SIZE
        return stats

class OFPTableStats(ofproto_parser.namedtuple('OFPTableStats', (
        'table_id', 'name', 'wildcards', 'max_entries', 'active_count',
        'lookup_count', 'matched_count'))):

    _TYPE = {
        'utf-8': [
            # OF spec is unclear about the encoding of name.
            # we assumes UTF-8.
            'name',
        ]
    }

    @classmethod
    def parser(cls, buf, offset):
        tbl = struct.unpack_from(ofproto.OFP_TABLE_STATS_PACK_STR,
                                 buf, offset)
        tbl = list(tbl)
        i = cls._fields.index('name')
        tbl[i] = tbl[i].rstrip(b'\0')
        stats = cls(*tbl)
        stats.length = ofproto.OFP_TABLE_STATS_SIZE
        return stats

class OFPPortStats(ofproto_parser.namedtuple('OFPPortStats', (
        'port_no', 'rx_packets', 'tx_packets', 'rx_bytes', 'tx_bytes',
        'rx_dropped', 'tx_dropped', 'rx_errors', 'tx_errors',
        'rx_frame_err', 'rx_over_err', 'rx_crc_err', 'collisions'))):
    @classmethod
    def parser(cls, buf, offset):
        port = struct.unpack_from(ofproto.OFP_PORT_STATS_PACK_STR,
                                  buf, offset)
        stats = cls(*port)
        stats.length = ofproto.OFP_PORT_STATS_SIZE
        return stats

class OFPQueueStats(ofproto_parser.namedtuple('OFPQueueStats', (
        'port_no', 'queue_id', 'tx_bytes', 'tx_packets', 'tx_errors'))):
    @classmethod
    def parser(cls, buf, offset):
        queue = struct.unpack_from(ofproto.OFP_QUEUE_STATS_PACK_STR,
                                   buf, offset)
        stats = cls(*queue)
        stats.length = ofproto.OFP_QUEUE_STATS_SIZE
        return stats

class OFPVendorStats(ofproto_parser.namedtuple('OFPVendorStats',
                                               ('specific_data'))):
    @classmethod
    def parser(cls, buf, offset):
        stats = cls(buf[offset:])
        stats.length = len(stats.specific_data)
        return stats

class NXFlowStats(StringifyMixin):
    def __init__(self):
        super(NXFlowStats, self).__init__()
        self.length = None
        self.table_id = None
        self.duration_sec = None
        self.duration_nsec = None
        self.priority = None
        self.idle_timeout = None
        self.hard_timeout = None
        self.match_len = None
        self.idle_age = None
        self.hard_age = None
        self.cookie = None
        self.packet_count = None
        self.byte_count = None

    @classmethod
    def parser(cls, buf, offset):
        original_offset = offset
        nxflow_stats = cls()
        (nxflow_stats.length, nxflow_stats.table_id,
         nxflow_stats.duration_sec, nxflow_stats.duration_nsec,
         nxflow_stats.priority, nxflow_stats.idle_timeout,
         nxflow_stats.hard_timeout, nxflow_stats.match_len,
         nxflow_stats.idle_age, nxflow_stats.hard_age,
         nxflow_stats.cookie, nxflow_stats.packet_count,
         nxflow_stats.byte_count) = struct.unpack_from(
            ofproto.NX_FLOW_STATS_PACK_STR, buf, offset)
        offset += ofproto.NX_FLOW_STATS_SIZE

        fields = []
        match_len = nxflow_stats.match_len
        match_len -= 4
        while match_len > 0:
            field = nx_match.MFField.parser(buf, offset)
            offset += field.length
            match_len -= field.length
            fields.append(field)
        nxflow_stats.fields = fields

        actions = []
        total_len = original_offset + nxflow_stats.length
        match_len = nxflow_stats.match_len
        offset += utils.round_up(match_len, 8) - match_len
        while offset < total_len:
            action = OFPAction.parser(buf, offset)
            actions.append(action)
            offset += action.len
        nxflow_stats.actions = actions

        return nxflow_stats

class NXAggregateStats(ofproto_parser.namedtuple('NXAggregateStats', (
        'packet_count', 'byte_count', 'flow_count'))):
    @classmethod
    def parser(cls, buf, offset):
        agg = struct.unpack_from(
            ofproto.NX_AGGREGATE_STATS_REPLY_PACK_STR, buf, offset)
        stats = cls(*agg)
        stats.length = ofproto.NX_AGGREGATE_STATS_REPLY_SIZE

        return stats

class OFPQueuePropHeader(StringifyMixin):
    _QUEUE_PROPERTIES = {}

    @staticmethod
    def register_queue_property(prop_type, prop_len):
        def _register_queue_propery(cls):
            cls.cls_prop_type = prop_type
            cls.cls_prop_len = prop_len
            OFPQueuePropHeader._QUEUE_PROPERTIES[prop_type] = cls
            return cls
        return _register_queue_propery

    def __init__(self):
        self.property = self.cls_prop_type
        self.len = self.cls_prop_len

    @classmethod
    def parser(cls, buf, offset):
        property_, len_ = struct.unpack_from(
            ofproto.OFP_QUEUE_PROP_HEADER_PACK_STR, buf, offset)
        prop_cls = cls._QUEUE_PROPERTIES[property_]
        assert property_ == prop_cls.cls_prop_type
        assert len_ == prop_cls.cls_prop_len

        offset += ofproto.OFP_QUEUE_PROP_HEADER_SIZE
        return prop_cls.parser(buf, offset)

@OFPQueuePropHeader.register_queue_property(
    ofproto.OFPQT_NONE, ofproto.OFP_QUEUE_PROP_HEADER_SIZE)
class OFPQueuePropNone(OFPQueuePropHeader):
    def __init__(self):
        super(OFPQueuePropNone, self).__init__()

    @classmethod
    def parser(cls, buf, offset):
        return cls()

@OFPQueuePropHeader.register_queue_property(
    ofproto.OFPQT_MIN_RATE, ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE)
class OFPQueuePropMinRate(OFPQueuePropHeader):
    def __init__(self, rate):
        super(OFPQueuePropMinRate, self).__init__()
        self.rate = rate

    @classmethod
    def parser(cls, buf, offset):
        (rate,) = struct.unpack_from(
            ofproto.OFP_QUEUE_PROP_MIN_RATE_PACK_STR,
            buf, offset)
        return cls(rate)

class OFPPacketQueue(StringifyMixin):
    def __init__(self, queue_id, len_):
        self.queue_id = queue_id
        self.len = len_
        self.properties = None

    @classmethod
    def parser(cls, buf, offset):
        queue_id, len_ = struct.unpack_from(
            ofproto.OFP_PACKET_QUEUE_PQCK_STR, buf, offset)
        packet_queue = cls(queue_id, len_)

        packet_queue.properties = []
        cur_len = ofproto.OFP_PACKET_QUEUE_SIZE
        offset += ofproto.OFP_PACKET_QUEUE_SIZE
        while (cur_len + ofproto.OFP_QUEUE_PROP_HEADER_SIZE <=
               packet_queue.len):
            prop = OFPQueuePropHeader.parser(buf, offset)
            packet_queue.properties.append(prop)

            cur_len += prop.len
            offset += prop.len

        return packet_queue

#
# Symmetric messages
# parser + serializer
#

@_register_parser
@_set_msg_type(ofproto.OFPT_HELLO)
class OFPHello(MsgBase):
    def __init__(self, datapath):
        super(OFPHello, self).__init__(datapath)

@_register_parser
@_set_msg_type(ofproto.OFPT_ERROR)
class OFPErrorMsg(MsgBase):
    def __init__(self, datapath, type_=None, code=None, data=None):
        super(OFPErrorMsg, self).__init__(datapath)
        self.type = type_
        self.code = code
        self.data = data

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
        msg = super(OFPErrorMsg, cls).parser(datapath, version, msg_type,
                                             msg_len, xid, buf)
        msg.type, msg.code = struct.unpack_from(
            ofproto.OFP_ERROR_MSG_PACK_STR, msg.buf,
            ofproto.OFP_HEADER_SIZE)
        msg.data = msg.buf[ofproto.OFP_ERROR_MSG_SIZE:]
        return msg

    def _serialize_body(self):
        assert self.data is not None
        msg_pack_into(ofproto.OFP_ERROR_MSG_PACK_STR, self.buf,
                      ofproto.OFP_HEADER_SIZE, self.type, self.code)
        self.buf += self.data

@_register_parser
@_set_msg_type(ofproto.OFPT_ECHO_REQUEST)
class OFPEchoRequest(MsgBase):
    def __init__(self, datapath, data=None):
        super(OFPEchoRequest, self).__init__(datapath)
        self.data = data

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
        msg = super(OFPEchoRequest, cls).parser(datapath, version, msg_type,
                                                msg_len, xid, buf)
        msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:]
        return msg

    def _serialize_body(self):
        if self.data is not None:
            self.buf += self.data

@_register_parser
@_set_msg_type(ofproto.OFPT_ECHO_REPLY)
class OFPEchoReply(MsgBase):
    def __init__(self, datapath, data=None):
        super(OFPEchoReply, self).__init__(datapath)
        self.data = data

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
        msg = super(OFPEchoReply, cls).parser(datapath, version, msg_type,
                                              msg_len, xid, buf)
        msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:]
        return msg

    def _serialize_body(self):
        assert self.data is not None
        self.buf += self.data

@_register_parser
@_set_msg_type(ofproto.OFPT_VENDOR)
class OFPVendor(MsgBase):
    _VENDORS = {}

    @staticmethod
    def register_vendor(id_):
        def _register_vendor(cls):
            OFPVendor._VENDORS[id_] = cls
            return cls
        return _register_vendor

    def __init__(self, datapath):
        super(OFPVendor, self).__init__(datapath)
        self.data = None
        self.vendor = None

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
        msg = super(OFPVendor, cls).parser(datapath, version, msg_type,
                                           msg_len, xid, buf)
        (msg.vendor,) = struct.unpack_from(
            ofproto.OFP_VENDOR_HEADER_PACK_STR, msg.buf,
            ofproto.OFP_HEADER_SIZE)

        cls_ = cls._VENDORS.get(msg.vendor)
        if cls_:
            msg.data = cls_.parser(datapath, msg.buf, 0)
        else:
            msg.data = msg.buf[ofproto.OFP_VENDOR_HEADER_SIZE:]

        return msg

    def serialize_header(self):
        msg_pack_into(ofproto.OFP_VENDOR_HEADER_PACK_STR,
                      self.buf, ofproto.OFP_HEADER_SIZE, self.vendor)

    def _serialize_body(self):
        assert self.data is not None
        self.serialize_header()
        self.buf += self.data

@OFPVendor.register_vendor(ofproto_common.NX_EXPERIMENTER_ID)
class NiciraHeader(OFPVendor):
    _NX_SUBTYPES = {}

    @staticmethod
    def register_nx_subtype(subtype):
        def _register_nx_subtype(cls):
            cls.cls_subtype = subtype
            NiciraHeader._NX_SUBTYPES[cls.cls_subtype] = cls
            return cls
        return _register_nx_subtype

    def __init__(self, datapath, subtype):
        super(NiciraHeader, self).__init__(datapath)
        self.vendor = ofproto_common.NX_EXPERIMENTER_ID
        self.subtype = subtype

    def serialize_header(self):
        super(NiciraHeader, self).serialize_header()
        msg_pack_into(ofproto.NICIRA_HEADER_PACK_STR,
                      self.buf, ofproto.OFP_HEADER_SIZE,
                      self.vendor, self.subtype)

    @classmethod
    def parser(cls, datapath, buf, offset):
        vendor, subtype = struct.unpack_from(
            ofproto.NICIRA_HEADER_PACK_STR, buf,
            offset + ofproto.OFP_HEADER_SIZE)
        cls_ = cls._NX_SUBTYPES.get(subtype)
        return cls_.parser(datapath, buf,
                           offset + ofproto.NICIRA_HEADER_SIZE)

class NXTSetFlowFormat(NiciraHeader):
    def __init__(self, datapath, flow_format):
        super(NXTSetFlowFormat, self).__init__(
            datapath, ofproto.NXT_SET_FLOW_FORMAT)
        self.format = flow_format

    def _serialize_body(self):
        self.serialize_header()
        msg_pack_into(ofproto.NX_SET_FLOW_FORMAT_PACK_STR,
                      self.buf, ofproto.NICIRA_HEADER_SIZE, self.format)

class NXTFlowMod(NiciraHeader):
    def __init__(self, datapath, cookie, command,
                 idle_timeout=0, hard_timeout=0,
                 priority=ofproto.OFP_DEFAULT_PRIORITY,
                 buffer_id=0xffffffff, out_port=ofproto.OFPP_NONE,
                 flags=0, rule=None, actions=None):

        # the argument, rule, is positioned at the one before the last due
        # to the layout struct nxt_flow_mod.
        # Although rule must be given, default argument to rule, None,
        # is given to allow other default value of argument before rule.
        assert rule is not None

        if actions is None:
            actions = []
        super(NXTFlowMod, self).__init__(datapath, ofproto.NXT_FLOW_MOD)
        self.cookie = cookie
        self.command = command
        self.idle_timeout = idle_timeout
        self.hard_timeout = hard_timeout
        self.priority = priority
        self.buffer_id = buffer_id
        self.out_port = out_port
        self.flags = flags
        self.rule = rule
        self.actions = actions

    def _serialize_body(self):
        self.serialize_header()

        offset = ofproto.NX_FLOW_MOD_SIZE
        match_len = nx_match.serialize_nxm_match(self.rule, self.buf, offset)
        offset += nx_match.round_up(match_len)

        msg_pack_into(ofproto.NX_FLOW_MOD_PACK_STR,
                      self.buf, ofproto.NICIRA_HEADER_SIZE,
                      self.cookie, self.command, self.idle_timeout,
                      self.hard_timeout, self.priority, self.buffer_id,
                      self.out_port, self.flags, match_len)

        if self.actions is not None:
            for a in self.actions:
                a.serialize(self.buf, offset)
                offset += a.len

class NXTRoleRequest(NiciraHeader):
    def __init__(self, datapath, role):
        super(NXTRoleRequest, self).__init__(
            datapath, ofproto.NXT_ROLE_REQUEST)
        self.role = role

    def _serialize_body(self):
        self.serialize_header()
        msg_pack_into(ofproto.NX_ROLE_PACK_STR,
                      self.buf, ofproto.NICIRA_HEADER_SIZE, self.role)

@NiciraHeader.register_nx_subtype(ofproto.NXT_ROLE_REPLY)
class NXTRoleReply(NiciraHeader):
    def __init__(self, datapath, role):
        super(NXTRoleReply, self).__init__(
            datapath, ofproto.NXT_ROLE_REPLY)
        self.role = role

    @classmethod
    def parser(cls, datapath, buf, offset):
        (role,) = struct.unpack_from(
            ofproto.NX_ROLE_PACK_STR, buf, offset)
        return cls(datapath, role)

class NXTFlowModTableId(NiciraHeader):
    def __init__(self, datapath, set_):
        super(NXTFlowModTableId, self).__init__(
            datapath, ofproto.NXT_FLOW_MOD_TABLE_ID)
        self.set = set_

    def _serialize_body(self):
        self.serialize_header()
        msg_pack_into(ofproto.NX_FLOW_MOD_TABLE_ID_PACK_STR,
                      self.buf, ofproto.NICIRA_HEADER_SIZE,
                      self.set)

@NiciraHeader.register_nx_subtype(ofproto.NXT_FLOW_REMOVED)
class NXTFlowRemoved(NiciraHeader):
    def __init__(self, datapath, cookie, priority, reason,
                 duration_sec, duration_nsec, idle_timeout, match_len,
                 packet_count, byte_count, match):
        super(NXTFlowRemoved, self).__init__(
            datapath, ofproto.NXT_FLOW_REMOVED)
        self.cookie = cookie
        self.priority = priority
        self.reason = reason
        self.duration_sec = duration_sec
        self.duration_nsec = duration_nsec
        self.idle_timeout = idle_timeout
        self.match_len = match_len
        self.packet_count = packet_count
        self.byte_count = byte_count
        self.match = match

    @classmethod
    def parser(cls, datapath, buf, offset):
        (cookie, priority, reason, duration_sec, duration_nsec,
         idle_timeout, match_len,
         packet_count, byte_count) = struct.unpack_from(
            ofproto.NX_FLOW_REMOVED_PACK_STR, buf, offset)
        offset += (ofproto.NX_FLOW_REMOVED_SIZE
                   - ofproto.NICIRA_HEADER_SIZE)
        match = nx_match.NXMatch.parser(buf, offset, match_len)
        return cls(datapath, cookie, priority, reason, duration_sec,
                   duration_nsec, idle_timeout, match_len, packet_count,
                   byte_count, match)

class NXTSetPacketInFormat(NiciraHeader):
    def __init__(self, datapath, packet_in_format):
        super(NXTSetPacketInFormat, self).__init__(
            datapath, ofproto.NXT_SET_PACKET_IN_FORMAT)
        self.format = packet_in_format

    def _serialize_body(self):
        self.serialize_header()
        msg_pack_into(ofproto.NX_SET_PACKET_IN_FORMAT_PACK_STR,
                      self.buf, ofproto.NICIRA_HEADER_SIZE,
                      self.format)

@NiciraHeader.register_nx_subtype(ofproto.NXT_PACKET_IN)
class NXTPacketIn(NiciraHeader):
    def __init__(self, datapath, buffer_id, total_len, reason, table_id,
                 cookie, match_len, match, frame):
        super(NXTPacketIn, self).__init__(
            datapath, ofproto.NXT_PACKET_IN)
        self.buffer_id = buffer_id
        self.total_len = total_len
        self.reason = reason
        self.table_id = table_id
        self.cookie = cookie
        self.match_len = match_len
        self.match = match
        self.frame = frame

    @classmethod
    def parser(cls, datapath, buf, offset):
        (buffer_id, total_len, reason, table_id,
         cookie, match_len) = struct.unpack_from(
            ofproto.NX_PACKET_IN_PACK_STR, buf, offset)

        offset += (ofproto.NX_PACKET_IN_SIZE
                   - ofproto.NICIRA_HEADER_SIZE)

        match = nx_match.NXMatch.parser(buf, offset, match_len)
        offset += (match_len + 7) // 8 * 8
        frame = buf[offset:]
        if total_len < len(frame):
            frame = frame[:total_len]
        return cls(datapath, buffer_id, total_len, reason, table_id,
                   cookie, match_len, match, frame)

class NXTFlowAge(NiciraHeader):
    def __init__(self, datapath):
        super(NXTFlowAge, self).__init__(
            datapath, ofproto.NXT_FLOW_AGE)

    def _serialize_body(self):
        self.serialize_header()

class NXTSetAsyncConfig(NiciraHeader):
    def __init__(self, datapath, packet_in_mask, port_status_mask,
                 flow_removed_mask):
        super(NXTSetAsyncConfig, self).__init__(
            datapath, ofproto.NXT_SET_ASYNC_CONFIG)
        self.packet_in_mask = packet_in_mask
        self.port_status_mask = port_status_mask
        self.flow_removed_mask = flow_removed_mask

    def _serialize_body(self):
        self.serialize_header()
        msg_pack_into(ofproto.NX_ASYNC_CONFIG_PACK_STR,
                      self.buf, ofproto.NICIRA_HEADER_SIZE,
                      self.packet_in_mask[0], self.packet_in_mask[1],
                      self.port_status_mask[0], self.port_status_mask[1],
                      self.flow_removed_mask[0], self.flow_removed_mask[1])

class NXTSetControllerId(NiciraHeader):
    def __init__(self, datapath, controller_id):
        super(NXTSetControllerId, self).__init__(
            datapath, ofproto.NXT_SET_CONTROLLER_ID)
        self.controller_id = controller_id

    def _serialize_body(self):
        self.serialize_header()
        msg_pack_into(ofproto.NX_CONTROLLER_ID_PACK_STR,
                      self.buf, ofproto.NICIRA_HEADER_SIZE,
                      self.controller_id)

#
# asymmetric message (datapath -> controller)
# parser only
#

@_register_parser
@_set_msg_type(ofproto.OFPT_FEATURES_REPLY)
class OFPSwitchFeatures(MsgBase):
    def __init__(self, datapath, datapath_id=None, n_buffers=None,
                 n_tables=None, capabilities=None, actions=None, ports=None):
        super(OFPSwitchFeatures, self).__init__(datapath)
        self.datapath_id = datapath_id
        self.n_buffers = n_buffers
        self.n_tables = n_tables
        self.capabilities = capabilities
        self.actions = actions
        self.ports = ports

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
        msg = super(OFPSwitchFeatures, cls).parser(datapath, version, msg_type,
                                                   msg_len, xid, buf)
        (msg.datapath_id,
         msg.n_buffers,
         msg.n_tables,
         msg.capabilities,
         msg.actions) = struct.unpack_from(
            ofproto.OFP_SWITCH_FEATURES_PACK_STR, msg.buf,
            ofproto.OFP_HEADER_SIZE)

        msg.ports = {}
        n_ports = ((msg_len - ofproto.OFP_SWITCH_FEATURES_SIZE) //
                   ofproto.OFP_PHY_PORT_SIZE)
        offset = ofproto.OFP_SWITCH_FEATURES_SIZE
        for _i in range(n_ports):
            port = OFPPhyPort.parser(msg.buf, offset)
            # print 'port = %s' % str(port)
            msg.ports[port.port_no] = port
            offset += ofproto.OFP_PHY_PORT_SIZE

        return msg

@_register_parser
@_set_msg_type(ofproto.OFPT_PORT_STATUS)
class OFPPortStatus(MsgBase):
    def __init__(self, datapath, reason=None, desc=None):
        super(OFPPortStatus, self).__init__(datapath)
        self.reason = reason
        self.desc = desc

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
        msg = super(OFPPortStatus, cls).parser(datapath, version, msg_type,
                                               msg_len, xid, buf)
        msg.reason = struct.unpack_from(
            ofproto.OFP_PORT_STATUS_PACK_STR,
            msg.buf, ofproto.OFP_HEADER_SIZE)[0]
        msg.desc = OFPPhyPort.parser(msg.buf,
                                     ofproto.OFP_PORT_STATUS_DESC_OFFSET)
        return msg

@_register_parser
@_set_msg_type(ofproto.OFPT_PACKET_IN)
class OFPPacketIn(MsgBase):
    def __init__(self, datapath, buffer_id=None, total_len=None, in_port=None,
                 reason=None, data=None):
        super(OFPPacketIn, self).__init__(datapath)
        self.buffer_id = buffer_id
        self.total_len = total_len
        self.in_port = in_port
        self.reason = reason
        self.data = data

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
        msg = super(OFPPacketIn, cls).parser(datapath, version, msg_type,
                                             msg_len, xid, buf)
        (msg.buffer_id,
         msg.total_len,
         msg.in_port,
         msg.reason) = struct.unpack_from(
            ofproto.OFP_PACKET_IN_PACK_STR,
            msg.buf, ofproto.OFP_HEADER_SIZE)
        msg.data = msg.buf[ofproto.OFP_PACKET_IN_SIZE:]
        if msg.total_len < len(msg.data):
            # discard padding for 8-byte alignment of OFP packet
            msg.data = msg.data[:msg.total_len]
        return msg

@_register_parser
@_set_msg_type(ofproto.OFPT_GET_CONFIG_REPLY)
class OFPGetConfigReply(MsgBase):
    def __init__(self, datapath):
        super(OFPGetConfigReply, self).__init__(datapath)

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
        msg = super(OFPGetConfigReply, cls).parser(datapath, version, msg_type,
                                                   msg_len, xid, buf)
        (msg.flags, msg.miss_send_len) = struct.unpack_from(
            ofproto.OFP_SWITCH_CONFIG_PACK_STR,
            msg.buf, ofproto.OFP_HEADER_SIZE)
        return msg

@_register_parser
@_set_msg_type(ofproto.OFPT_BARRIER_REPLY)
class OFPBarrierReply(MsgBase):
    def __init__(self, datapath):
        super(OFPBarrierReply, self).__init__(datapath)

@_register_parser
@_set_msg_type(ofproto.OFPT_FLOW_REMOVED)
class OFPFlowRemoved(MsgBase):
    def __init__(self, datapath):
        super(OFPFlowRemoved, self).__init__(datapath)

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
        msg = super(OFPFlowRemoved, cls).parser(datapath, version, msg_type,
                                                msg_len, xid, buf)

        msg.match = OFPMatch.parse(msg.buf, ofproto.OFP_HEADER_SIZE)

        (msg.cookie,
         msg.priority,
         msg.reason,
         msg.duration_sec,
         msg.duration_nsec,
         msg.idle_timeout,
         msg.packet_count,
         msg.byte_count) = struct.unpack_from(
            ofproto.OFP_FLOW_REMOVED_PACK_STR0, msg.buf,
            ofproto.OFP_HEADER_SIZE + ofproto.OFP_MATCH_SIZE)

        return msg

@_register_parser
@_set_msg_type(ofproto.OFPT_QUEUE_GET_CONFIG_REPLY)
class OFPQueueGetConfigReply(MsgBase):
    def __init__(self, datapath):
        super(OFPQueueGetConfigReply, self).__init__(datapath)

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
        msg = super(OFPQueueGetConfigReply, cls).parser(
            datapath, version, msg_type, msg_len, xid, buf)

        offset = ofproto.OFP_HEADER_SIZE
        (msg.port,) = struct.unpack_from(
            ofproto.OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR, msg.buf, offset)

        msg.queues = []
        offset = ofproto.OFP_QUEUE_GET_CONFIG_REPLY_SIZE
        while offset + ofproto.OFP_PACKET_QUEUE_SIZE <= msg_len:
            queue = OFPPacketQueue.parser(msg.buf, offset)
            msg.queues.append(queue)

            offset += queue.len

        return msg

def _set_stats_type(stats_type, stats_body_cls):
    def _set_cls_stats_type(cls):
        cls.cls_stats_type = stats_type
        cls.cls_stats_body_cls = stats_body_cls
        return cls
    return _set_cls_stats_type

@_register_parser
@_set_msg_type(ofproto.OFPT_STATS_REPLY)
class OFPStatsReply(MsgBase):
    _STATS_MSG_TYPES = {}

    @staticmethod
    def register_stats_type(body_single_struct=False):
        def _register_stats_type(cls):
            assert cls.cls_stats_type is not None
            assert cls.cls_stats_type not in OFPStatsReply._STATS_MSG_TYPES
            assert cls.cls_stats_body_cls is not None
            cls.cls_body_single_struct = body_single_struct
            OFPStatsReply._STATS_MSG_TYPES[cls.cls_stats_type] = cls
            return cls
        return _register_stats_type

    def __init__(self, datapath):
        super(OFPStatsReply, self).__init__(datapath)
        self.type = None
        self.flags = None
        self.body = None

    @classmethod
    def parser_stats_body(cls, buf, msg_len, offset):
        body_cls = cls.cls_stats_body_cls
        body = []
        while offset < msg_len:
            entry = body_cls.parser(buf, offset)
            body.append(entry)
            offset += entry.length

        if cls.cls_body_single_struct:
            return body[0]
        return body

    @classmethod
    def parser_stats(cls, datapath, version, msg_type, msg_len, xid, buf):
        # call MsgBase::parser, not OFPStatsReply::parser
        msg = MsgBase.parser.__func__(
            cls, datapath, version, msg_type, msg_len, xid, buf)
        msg.body = msg.parser_stats_body(msg.buf, msg.msg_len,
                                         ofproto.OFP_STATS_MSG_SIZE)
        return msg

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
        type_, flags = struct.unpack_from(ofproto.OFP_STATS_MSG_PACK_STR,
                                          six.binary_type(buf),
                                          ofproto.OFP_HEADER_SIZE)
        stats_type_cls = cls._STATS_MSG_TYPES.get(type_)
        msg = stats_type_cls.parser_stats(
            datapath, version, msg_type, msg_len, xid, buf)
        msg.type = type_
        msg.flags = flags
        return msg

@OFPStatsReply.register_stats_type(body_single_struct=True)
@_set_stats_type(ofproto.OFPST_DESC, OFPDescStats)
@_set_msg_type(ofproto.OFPT_STATS_REPLY)
class OFPDescStatsReply(OFPStatsReply):
    def __init__(self, datapath):
        super(OFPDescStatsReply, self).__init__(datapath)

@OFPStatsReply.register_stats_type()
@_set_stats_type(ofproto.OFPST_FLOW, OFPFlowStats)
@_set_msg_type(ofproto.OFPT_STATS_REPLY)
class OFPFlowStatsReply(OFPStatsReply):
    def __init__(self, datapath):
        super(OFPFlowStatsReply, self).__init__(datapath)

@OFPStatsReply.register_stats_type()
@_set_stats_type(ofproto.OFPST_AGGREGATE, OFPAggregateStats)
@_set_msg_type(ofproto.OFPT_STATS_REPLY)
class OFPAggregateStatsReply(OFPStatsReply):
    def __init__(self, datapath):
        super(OFPAggregateStatsReply, self).__init__(datapath)

@OFPStatsReply.register_stats_type()
@_set_stats_type(ofproto.OFPST_TABLE, OFPTableStats)
@_set_msg_type(ofproto.OFPT_STATS_REPLY)
class OFPTableStatsReply(OFPStatsReply):
    def __init__(self, datapath):
        super(OFPTableStatsReply, self).__init__(datapath)

@OFPStatsReply.register_stats_type()
@_set_stats_type(ofproto.OFPST_PORT, OFPPortStats)
@_set_msg_type(ofproto.OFPT_STATS_REPLY)
class OFPPortStatsReply(OFPStatsReply):
    def __init__(self, datapath):
        super(OFPPortStatsReply, self).__init__(datapath)

@OFPStatsReply.register_stats_type()
@_set_stats_type(ofproto.OFPST_QUEUE, OFPQueueStats)
@_set_msg_type(ofproto.OFPT_STATS_REPLY)
class OFPQueueStatsReply(OFPStatsReply):
    def __init__(self, datapath):
        super(OFPQueueStatsReply, self).__init__(datapath)

@OFPStatsReply.register_stats_type()
@_set_stats_type(ofproto.OFPST_VENDOR, OFPVendorStats)
@_set_msg_type(ofproto.OFPT_STATS_REPLY)
class OFPVendorStatsReply(OFPStatsReply):
    _STATS_VENDORS = {}

    @staticmethod
    def register_stats_vendor(vendor):
        def _register_stats_vendor(cls):
            cls.cls_vendor = vendor
            OFPVendorStatsReply._STATS_VENDORS[cls.cls_vendor] = cls
            return cls
        return _register_stats_vendor

    def __init__(self, datapath):
        super(OFPVendorStatsReply, self).__init__(datapath)

    @classmethod
    def parser_stats(cls, datapath, version, msg_type, msg_len, xid,
                     buf):
        (type_,) = struct.unpack_from(
            ofproto.OFP_VENDOR_STATS_MSG_PACK_STR, six.binary_type(buf),
            ofproto.OFP_STATS_MSG_SIZE)

        cls_ = cls._STATS_VENDORS.get(type_)

        if cls_ is None:
            msg = MsgBase.parser.__func__(
                cls, datapath, version, msg_type, msg_len, xid, buf)
            body_cls = cls.cls_stats_body_cls
            body = body_cls.parser(buf,
                                   ofproto.OFP_STATS_MSG_SIZE)
            msg.body = body
            return msg

        return cls_.parser(
            datapath, version, msg_type, msg_len, xid, buf,
            ofproto.OFP_VENDOR_STATS_MSG_SIZE)

@OFPVendorStatsReply.register_stats_vendor(ofproto_common.NX_EXPERIMENTER_ID)
class NXStatsReply(OFPStatsReply):
    _NX_STATS_TYPES = {}

    @staticmethod
    def register_nx_stats_type(body_single_struct=False):
        def _register_nx_stats_type(cls):
            assert cls.cls_stats_type is not None
            assert cls.cls_stats_type not in \
                NXStatsReply._NX_STATS_TYPES
            assert cls.cls_stats_body_cls is not None
            cls.cls_body_single_struct = body_single_struct
            NXStatsReply._NX_STATS_TYPES[cls.cls_stats_type] = cls
            return cls
        return _register_nx_stats_type

    @classmethod
    def parser_stats_body(cls, buf, msg_len, offset):
        body_cls = cls.cls_stats_body_cls
        body = []
        while offset < msg_len:
            entry = body_cls.parser(buf, offset)
            body.append(entry)
            offset += entry.length

        if cls.cls_body_single_struct:
            return body[0]
        return body

    @classmethod
    def parser_stats(cls, datapath, version, msg_type, msg_len, xid,
                     buf, offset):
        msg = MsgBase.parser.__func__(
            cls, datapath, version, msg_type, msg_len, xid, buf)
        msg.body = msg.parser_stats_body(msg.buf, msg.msg_len, offset)

        return msg

    @classmethod
    def parser(cls, datapath, version, msg_type, msg_len, xid, buf,
               offset):
        (type_,) = struct.unpack_from(
            ofproto.NX_STATS_MSG_PACK_STR, six.binary_type(buf), offset)
        offset += ofproto.NX_STATS_MSG0_SIZE

        cls_ = cls._NX_STATS_TYPES.get(type_)

        msg = cls_.parser_stats(
            datapath, version, msg_type, msg_len, xid, buf, offset)

        return msg

@NXStatsReply.register_nx_stats_type()
@_set_stats_type(ofproto.NXST_FLOW, NXFlowStats)
class NXFlowStatsReply(NXStatsReply):
    def __init__(self, datapath):
        super(NXFlowStatsReply, self).__init__(datapath)

@NXStatsReply.register_nx_stats_type()
@_set_stats_type(ofproto.NXST_AGGREGATE, NXAggregateStats)
class NXAggregateStatsReply(NXStatsReply):
    def __init__(self, datapath):
        super(NXAggregateStatsReply, self).__init__(datapath)

#
# controller-to-switch message
# serializer only
#

@_set_msg_reply(OFPSwitchFeatures)
@_set_msg_type(ofproto.OFPT_FEATURES_REQUEST)
class OFPFeaturesRequest(MsgBase):
    def __init__(self, datapath):
        super(OFPFeaturesRequest, self).__init__(datapath)

@_set_msg_type(ofproto.OFPT_GET_CONFIG_REQUEST)
class OFPGetConfigRequest(MsgBase):
    def __init__(self, datapath):
        super(OFPGetConfigRequest, self).__init__(datapath)

@_set_msg_type(ofproto.OFPT_SET_CONFIG)
class OFPSetConfig(MsgBase):
    def __init__(self, datapath, flags=None, miss_send_len=None):
        super(OFPSetConfig, self).__init__(datapath)
        self.flags = flags
        self.miss_send_len = miss_send_len

    def _serialize_body(self):
        assert self.flags is not None
        assert self.miss_send_len is not None
        msg_pack_into(ofproto.OFP_SWITCH_CONFIG_PACK_STR,
                      self.buf, ofproto.OFP_HEADER_SIZE,
                      self.flags, self.miss_send_len)

@_set_msg_type(ofproto.OFPT_PACKET_OUT)
class OFPPacketOut(MsgBase):
    def __init__(self, datapath, buffer_id=None, in_port=None, actions=None,
                 data=None):
        super(OFPPacketOut, self).__init__(datapath)
        self.buffer_id = buffer_id
        self.in_port = in_port
        self._actions_len = None
        self.actions = actions
        self.data = data

    def _serialize_body(self):
        assert self.buffer_id is not None
        assert self.in_port is not None
        assert self.actions is not None

        self._actions_len = 0
        offset = ofproto.OFP_PACKET_OUT_SIZE
        for a in self.actions:
            a.serialize(self.buf, offset)
            offset += a.len
            self._actions_len += a.len

        if self.data is not None:
            assert self.buffer_id == 0xffffffff
            self.buf += self.data

        msg_pack_into(ofproto.OFP_PACKET_OUT_PACK_STR,
                      self.buf, ofproto.OFP_HEADER_SIZE,
                      self.buffer_id, self.in_port, self._actions_len)

@_set_msg_type(ofproto.OFPT_FLOW_MOD)
class OFPFlowMod(MsgBase):
    def __init__(self, datapath, match, cookie, command,
                 idle_timeout=0, hard_timeout=0,
                 priority=ofproto.OFP_DEFAULT_PRIORITY,
                 buffer_id=0xffffffff, out_port=ofproto.OFPP_NONE,
                 flags=0, actions=None):
        if actions is None:
            actions = []
        super(OFPFlowMod, self).__init__(datapath)
        self.match = match
        self.cookie = cookie
        self.command = command
        self.idle_timeout = idle_timeout
        self.hard_timeout = hard_timeout
        self.priority = priority
        self.buffer_id = buffer_id
        self.out_port = out_port
        self.flags = flags
        self.actions = actions

    def _serialize_body(self):
        offset = ofproto.OFP_HEADER_SIZE
        self.match.serialize(self.buf, offset)

        offset += ofproto.OFP_MATCH_SIZE
        msg_pack_into(ofproto.OFP_FLOW_MOD_PACK_STR0, self.buf, offset,
                      self.cookie, self.command,
                      self.idle_timeout, self.hard_timeout,
                      self.priority, self.buffer_id, self.out_port,
                      self.flags)

        offset = ofproto.OFP_FLOW_MOD_SIZE
        if self.actions is not None:
            for a in self.actions:
                a.serialize(self.buf, offset)
                offset += a.len

@_set_msg_type(ofproto.OFPT_PORT_MOD)
class OFPPortMod(MsgBase):

    _TYPE = {
        'ascii': [
            'hw_addr',
        ]
    }

    def __init__(self, datapath, port_no=0, hw_addr='00:00:00:00:00:00',
                 config=0, mask=0, advertise=0):
        super(OFPPortMod, self).__init__(datapath)
        self.port_no = port_no
        self.hw_addr = hw_addr
        self.config = config
        self.mask = mask
        self.advertise = advertise

    def _serialize_body(self):
        msg_pack_into(ofproto.OFP_PORT_MOD_PACK_STR,
                      self.buf, ofproto.OFP_HEADER_SIZE,
                      self.port_no, addrconv.mac.text_to_bin(self.hw_addr),
                      self.config, self.mask, self.advertise)

@_set_msg_reply(OFPBarrierReply)
@_set_msg_type(ofproto.OFPT_BARRIER_REQUEST)
class OFPBarrierRequest(MsgBase):
    def __init__(self, datapath):
        super(OFPBarrierRequest, self).__init__(datapath)

@_set_msg_reply(OFPQueueGetConfigReply)
@_set_msg_type(ofproto.OFPT_QUEUE_GET_CONFIG_REQUEST)
class OFPQueueGetConfigRequest(MsgBase):
    def __init__(self, datapath, port):
        super(OFPQueueGetConfigRequest, self).__init__(datapath)
        self.port = port

    def _serialize_body(self):
        msg_pack_into(ofproto.OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR,
                      self.buf, ofproto.OFP_HEADER_SIZE, self.port)

class OFPStatsRequest(MsgBase):
    def __init__(self, datapath, flags):
        assert flags == 0       # none yet defined

        super(OFPStatsRequest, self).__init__(datapath)
        self.type = self.__class__.cls_stats_type
        self.flags = flags

    def _serialize_stats_body(self):
        pass

    def _serialize_body(self):
        msg_pack_into(ofproto.OFP_STATS_MSG_PACK_STR,
                      self.buf, ofproto.OFP_HEADER_SIZE,
                      self.type, self.flags)
        self._serialize_stats_body()

@_set_msg_reply(OFPDescStatsReply)
@_set_stats_type(ofproto.OFPST_DESC, OFPDescStats)
@_set_msg_type(ofproto.OFPT_STATS_REQUEST)
class OFPDescStatsRequest(OFPStatsRequest):
    def __init__(self, datapath, flags):
        super(OFPDescStatsRequest, self).__init__(datapath, flags)

class OFPFlowStatsRequestBase(OFPStatsRequest):
    def __init__(self, datapath, flags, match, table_id, out_port):
        super(OFPFlowStatsRequestBase, self).__init__(datapath, flags)
        self.match = match
        self.table_id = table_id
        self.out_port = out_port

    def _serialize_stats_body(self):
        offset = ofproto.OFP_STATS_MSG_SIZE
        self.match.serialize(self.buf, offset)

        offset += ofproto.OFP_MATCH_SIZE
        msg_pack_into(ofproto.OFP_FLOW_STATS_REQUEST_ID_PORT_STR,
                      self.buf, offset, self.table_id, self.out_port)

@_set_msg_reply(OFPFlowStatsReply)
@_set_stats_type(ofproto.OFPST_FLOW, OFPFlowStats)
@_set_msg_type(ofproto.OFPT_STATS_REQUEST)
class OFPFlowStatsRequest(OFPFlowStatsRequestBase):
    def __init__(self, datapath, flags, match, table_id, out_port):
        super(OFPFlowStatsRequest, self).__init__(
            datapath, flags, match, table_id, out_port)

@_set_msg_reply(OFPAggregateStatsReply)
@_set_stats_type(ofproto.OFPST_AGGREGATE, OFPAggregateStats)
@_set_msg_type(ofproto.OFPT_STATS_REQUEST)
class OFPAggregateStatsRequest(OFPFlowStatsRequestBase):
    def __init__(self, datapath, flags, match, table_id, out_port):
        super(OFPAggregateStatsRequest, self).__init__(
            datapath, flags, match, table_id, out_port)

@_set_msg_reply(OFPTableStatsReply)
@_set_stats_type(ofproto.OFPST_TABLE, OFPTableStats)
@_set_msg_type(ofproto.OFPT_STATS_REQUEST)
class OFPTableStatsRequest(OFPStatsRequest):
    def __init__(self, datapath, flags):
        super(OFPTableStatsRequest, self).__init__(datapath, flags)

@_set_msg_reply(OFPPortStatsReply)
@_set_stats_type(ofproto.OFPST_PORT, OFPPortStats)
@_set_msg_type(ofproto.OFPT_STATS_REQUEST)
class OFPPortStatsRequest(OFPStatsRequest):
    def __init__(self, datapath, flags, port_no):
        super(OFPPortStatsRequest, self).__init__(datapath, flags)
        self.port_no = port_no

    def _serialize_stats_body(self):
        msg_pack_into(ofproto.OFP_PORT_STATS_REQUEST_PACK_STR,
                      self.buf, ofproto.OFP_STATS_MSG_SIZE, self.port_no)

@_set_msg_reply(OFPQueueStatsReply)
@_set_stats_type(ofproto.OFPST_QUEUE, OFPQueueStats)
@_set_msg_type(ofproto.OFPT_STATS_REQUEST)
class OFPQueueStatsRequest(OFPStatsRequest):
    def __init__(self, datapath, flags, port_no, queue_id):
        super(OFPQueueStatsRequest, self).__init__(datapath, flags)
        self.port_no = port_no
        self.queue_id = queue_id

    def _serialize_stats_body(self):
        msg_pack_into(ofproto.OFP_QUEUE_STATS_REQUEST_PACK_STR,
                      self.buf, ofproto.OFP_STATS_MSG_SIZE,
                      self.port_no, self.queue_id)

@_set_msg_reply(OFPVendorStatsReply)
@_set_stats_type(ofproto.OFPST_VENDOR, OFPVendorStats)
@_set_msg_type(ofproto.OFPT_STATS_REQUEST)
class OFPVendorStatsRequest(OFPStatsRequest):
    def __init__(self, datapath, flags, vendor, specific_data=None):
        super(OFPVendorStatsRequest, self).__init__(datapath, flags)
        self.vendor = vendor
        self.specific_data = specific_data

    def _serialize_vendor_stats(self):
        self.buf += self.specific_data

    def _serialize_stats_body(self):
        msg_pack_into(ofproto.OFP_VENDOR_STATS_MSG_PACK_STR,
                      self.buf, ofproto.OFP_STATS_MSG_SIZE,
                      self.vendor)
        self._serialize_vendor_stats()

class NXStatsRequest(OFPVendorStatsRequest):
    def __init__(self, datapath, flags, subtype):
        super(NXStatsRequest, self).__init__(datapath, flags,
                                             ofproto_common.NX_EXPERIMENTER_ID)
        self.subtype = subtype

    def _serialize_vendor_stats_body(self):
        pass

    def _serialize_vendor_stats(self):
        msg_pack_into(ofproto.NX_STATS_MSG_PACK_STR, self.buf,
                      ofproto.OFP_VENDOR_STATS_MSG_SIZE,
                      self.subtype)
        self._serialize_vendor_stats_body()

class NXFlowStatsRequest(NXStatsRequest):
    def __init__(self, datapath, flags, out_port, table_id, rule=None):
        super(NXFlowStatsRequest, self).__init__(datapath, flags,
                                                 ofproto.NXST_FLOW)
        self.out_port = out_port
        self.table_id = table_id
        self.rule = rule
        self.match_len = 0

    def _serialize_vendor_stats_body(self):
        if self.rule is not None:
            offset = ofproto.NX_STATS_MSG_SIZE + \
                ofproto.NX_FLOW_STATS_REQUEST_SIZE
            self.match_len = nx_match.serialize_nxm_match(
                self.rule, self.buf, offset)

        msg_pack_into(
            ofproto.NX_FLOW_STATS_REQUEST_PACK_STR,
            self.buf, ofproto.NX_STATS_MSG_SIZE, self.out_port,
            self.match_len, self.table_id)

class NXAggregateStatsRequest(NXStatsRequest):
    def __init__(self, datapath, flags, out_port, table_id, rule=None):
        super(NXAggregateStatsRequest, self).__init__(
            datapath, flags, ofproto.NXST_AGGREGATE)
        self.out_port = out_port
        self.table_id = table_id
        self.rule = rule
        self.match_len = 0

    def _serialize_vendor_stats_body(self):
        if self.rule is not None:
            offset = ofproto.NX_STATS_MSG_SIZE + \
                ofproto.NX_AGGREGATE_STATS_REQUEST_SIZE
            self.match_len = nx_match.serialize_nxm_match(
                self.rule, self.buf, offset)

        msg_pack_into(
            ofproto.NX_AGGREGATE_STATS_REQUEST_PACK_STR,
            self.buf, ofproto.NX_STATS_MSG_SIZE, self.out_port,
            self.match_len, self.table_id)

redpajama_set_name: RedPajamaGithub


text:
require 'spec_helper'

describe 'regexpescape' do
  describe 'signature validation' do
    it { is_expected.not_to eq(nil) }
    it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) }
    it {
      pending('Current implementation ignores parameters after the first.')
      is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i)
    }
    it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) }
    it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) }
    it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) }
  end

  describe 'handling normal strings' do
    it 'calls ruby\'s Regexp.escape function' do
      Regexp.expects(:escape).with('regexp_string').returns('escaped_regexp_string').once
      is_expected.to run.with_params('regexp_string').and_return('escaped_regexp_string')
    end
  end

  describe 'handling classes derived from String' do
    it 'calls ruby\'s Regexp.escape function' do
      regexp_string = AlsoString.new('regexp_string')
      Regexp.expects(:escape).with(regexp_string).returns('escaped_regexp_string').once
      is_expected.to run.with_params(regexp_string).and_return('escaped_regexp_string')
    end
  end

  describe 'strings in arrays handling' do
    it { is_expected.to run.with_params([]).and_return([]) }
    it { is_expected.to run.with_params(['one*', 'two']).and_return(['one\*', 'two']) }
    it { is_expected.to run.with_params(['one*', 1, true, {}, 'two']).and_return(['one\*', 1, true, {}, 'two']) }

    context 'with UTF8 and double byte characters' do
      it { is_expected.to run.with_params(['ŏ'nε*']).and_return(['ŏ'nε\*']) }
      it { is_expected.to run.with_params(['インターネット*']).and_return(['インターネット\*']) }
    end
  end
end


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="generator" content="rustdoc">
    <meta name="description" content="API documentation for the Rust `One` trait in crate `num`.">
    <meta name="keywords" content="rust, rustlang, rust-lang, One">

    <title>num::traits::One - Rust</title>

    <link rel="stylesheet" type="text/css" href="../../main.css">

    <link rel="shortcut icon" href="http://www.rust-lang.org/favicon.ico">

num::<wbr>traits

        <form class="search-form js-only">

                <input class="search-input" name="search"
                       autocomplete="off"
                       placeholder="Click or press 'S' to search, '?' for more options..."
                       type="search">

        </form>

Trait num::<wbr>traits::<wbr>One

                [−]

        [src]

pub trait One: Mul<Self, Output=Self> {
    fn one() -> Self;
}

Defines a multiplicative identity element for Self.

Required Methods

fn one() -> Self

Returns the multiplicative identity element of Self, 1.

Laws

a * 1 = a       ∀ a ∈ Self
1 * a = a       ∀ a ∈ Self

Purity

This function should return the same result at all times regardless of
external mutable state, for example values stored in TLS or in
static muts.

Implementors

impl One for BigUint

impl One for BigInt

impl<T: Clone + Num> One for Complex<T>

impl One for usize

impl One for u8

impl One for u16

impl One for u32

impl One for u64

impl One for isize

impl One for i8

impl One for i16

impl One for i32

impl One for i64

impl One for f32

impl One for f64

impl<T: Clone + Integer + PartialOrd> One for Ratio<T>

Keyboard shortcuts

?

Show this help dialog

S

Focus the search field

⇤

Move up in search results

⇥

Move down in search results

⏎

Go to active search result

Search tricks

                Prefix searches with a type followed by a colon (e.g.
                fn:) to restrict the search to a given type.

                Accepted types are: fn, mod,
                struct, enum,
                trait, typedef (or
                tdef).

                Search functions by type signature (e.g.
                vec -> usize)


text:
import re
import csv
import datetime

from quickbooksR import QBRosetta

class HoffmannAndBaron(QBRosetta):

    lawFirmName = 'Hoffmann & Baron'
    pattern_lawFirmCase = re.compile(r'OUR DOCKET: (.*)')
    pattern_parentheses = re.compile(r'\(.*\)')

    def load_expenses(self, csvPath):
        csvReader = csv.reader(open(csvPath))
        lawFirmExpenseByInvoiceNumber = {}
        lawFirm = self.lawFirmByName[self.lawFirmName.lower()]
        lawFirmID = lawFirm['id']
        for row in csvReader:
            if not row:
                continue
            if row[0].startswith('LEDES1998B'):
                continue
            if '\t' in row[0]:
                row = row[0].split('\t')
            if 'INVOICE_AMOUNT' in row:
                indexByKey = dict((key.strip(), index) for index, key in enumerate(row))
                continue
            lawFirmCase = self.pattern_lawFirmCase.match(row[indexByKey['LAW_FIRM_REFERENCE_NUMBER']]).group(1)
            lawFirmCase = self.pattern_parentheses.sub('', lawFirmCase).strip()
            invoiceDate = datetime.datetime.strptime(row[indexByKey['INVOICE_DATE']], '%Y%m%d').date()
            invoiceNumber = row[indexByKey['INVOICE_NUMBER']].strip()
            invoiceAmount = float(row[indexByKey['INVOICE_AMOUNT']])
            description = row[indexByKey['DESCRIPTION_OF_EXPENSES']].strip('" ')
            if invoiceNumber not in lawFirmExpenseByInvoiceNumber:
                lawFirmExpenseByInvoiceNumber[invoiceNumber] = {
                    'lawFirmID': lawFirmID,
                    'lawFirmCase': lawFirmCase,
                    'invoiceDate': invoiceDate,
                    'invoiceNumber': invoiceNumber,
                    'invoiceAmount': invoiceAmount,
                    'description': description,
                }
            elif len(description) > len(lawFirmExpenseByInvoiceNumber[invoiceNumber]['description']):
                # Store the longer description
                lawFirmExpenseByInvoiceNumber[invoiceNumber]['description'] = description
        return lawFirmExpenseByInvoiceNumber.values()

modules = [
    HoffmannAndBaron,
]


text:
package com.communote.server.web.api.service.post.convert.v1_0_1;

import java.util.ArrayList;

import com.communote.server.api.core.attachment.AttachmentData;
import com.communote.server.api.core.note.NoteData;
import com.communote.server.api.core.note.NoteRenderContext;
import com.communote.server.api.core.tag.TagData;
import com.communote.server.core.filter.listitems.SimpleNoteListItem;
import com.communote.server.core.tag.TagParser;
import com.communote.server.core.tag.TagParserFactory;
import com.communote.server.core.vo.query.QueryResultConverter;
import com.communote.server.core.vo.query.note.SimpleNoteListItemToNoteDataQueryResultConverter;
import com.communote.server.web.api.to.listitem.DiscussionListItem;
import com.communote.server.web.api.to.listitem.v1_0_1.DetailPostListItem;

/**
 * ApiDetailNoteConverter to convert the temporary object into a DetailPostListItem (v1_0_1)
 *
 * Note: this converter is not thread-safe
 *
 * @author Communote GmbH - http://www.communote.com/
 *
 * @param <T>
 *            type of the source objects
 * @param <O>
 *            type of the target objects
 *
 * @deprecated Use new generated API.
 */
@Deprecated
public class ApiDetailNoteConverter<T extends SimpleNoteListItem, O extends DetailPostListItem>
        extends QueryResultConverter<T, O> {

    private static final TagParser DEFAULT_TAG_PARSER = TagParserFactory.instance()
            .getDefaultTagParser();

    private final SimpleNoteListItemToNoteDataQueryResultConverter<NoteData> noteListDataConverter;

    /**
     * Constructs a new converter
     *
     * @param renderContext
     *            the render context to be used
     */
    public ApiDetailNoteConverter(NoteRenderContext renderContext) {
        noteListDataConverter = new SimpleNoteListItemToNoteDataQueryResultConverter<NoteData>(
                NoteData.class, renderContext);
    }

    @Override
    public boolean convert(T queryResult, O finalResult) {
        NoteData tempResult = noteListDataConverter.create();
        if (noteListDataConverter.convert(queryResult, tempResult)) {
            fillingResultItem(tempResult, finalResult);
            return true;
        }
        return false;
    }

    @Override
    public O create() {
        return (O) new DetailPostListItem();
    }

    /**
     * Filling the DetailPostListItem
     *
     * @param note
     *            The note object
     * @param detailItem
     *            The DetailPostListitem
     */
    private void fillingResultItem(NoteData note, O detailItem) {

        detailItem.setBlogId(note.getBlog().getId());

        if (note.getParent() != null) {
            detailItem.setParentUserId(note.getParent().getUser().getId());
            detailItem.setParentPostId(note.getParent().getId());
        }

        // TODO setCanEdit - or better not, who knows what will happen with clients when they
        // encounter a true here
        // detailItem.setCanEdit(canEdit);
        detailItem.setNumberOfComments(note.getNumberOfComments());

        detailItem.setDiscussion(new DiscussionListItem());
        detailItem.getDiscussion().setDiscussionId(note.getDiscussionId());

        detailItem.setCreationDate(note.getCreationDate());
        detailItem.setLastModificationDate(note.getLastModificationDate());

        detailItem.setPostId(note.getId());

        detailItem.setText(note.getContent());
        detailItem.setUserId(note.getUser().getId());

        detailItem.setDirect(note.isDirect());
        detailItem.setFavorite(note.isFavorite());

        if (note.getTags() != null) {
            String[] tags = new String[note.getTags().size()];

            int i = 0;
            for (TagData tag : note.getTags()) {
                tags[i++] = tag.getName();
            }
            detailItem.setTags(DEFAULT_TAG_PARSER.buildTagString(tags));

        }
        if (note.getAttachments() == null) {
            detailItem.setAttachments(new ArrayList<AttachmentData>());
        } else {
            detailItem.setAttachments(note.getAttachments());
        }
    }

}


text:
package org.revapi.base;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Nonnull;

import org.revapi.Report;

/**
 * This is a simple helper class that can be used by the users to collect all the reports from Revapi.
 *
 * The extension ID is {@code test.collecting-reporter}.
 */
public class CollectingReporter extends BaseReporter {

    private final List<Report> reports = new ArrayList<>();

    @Override
    public void report(@Nonnull Report report) {
        reports.add(report);
    }

    public List<Report> getReports() {
        return reports;
    }

    @Override
    public String getExtensionId() {
        return "test.collecting-reporter";
    }
}


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Acta Bot. Bohem. 8:61. 1929

#### Original name
null

### Remarks
null


text:
package org.nightcode.common.base;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * An object that divides CharSequence into a map of key/value pairs.
 */
public final class Splitter {

  private interface Matcher {
    boolean matches(char c);
  }

  private static final class CharMatcher implements Matcher {

    private final char c;

    private CharMatcher(char c) {
      this.c = c;
    }

    public boolean matches(char c) {
      return this.c == c;
    }
  }

  private static final class CharsMatcher implements Matcher {

    private final char[] chars;

    private CharsMatcher(char[] chars) {
      this.chars = chars;
    }

    @Override public boolean matches(char c) {
      return Arrays.binarySearch(chars, c) >= 0;
    }
  }

  private static final Matcher NONE = c -> false;

  /**
   * Returns a splitter that uses the given fixed
   * string as a separator of key/value pair.
   *
   * @param pairSeparator separator of key/value pair
   * @return a splitter with the desired configuration
   */
  public static Splitter on(String pairSeparator) {
    return new Splitter(pairSeparator, "=", NONE, NONE);
  }

  private final String keyValueSeparator;
  private final String pairSeparator;
  private final Matcher keyTrimMatcher;
  private final Matcher valueTrimMatcher;

  private Splitter(String pairSeparator, String keyValueSeparator, Matcher keyTrimMatcher,
      Matcher valueTrimMatcher) {
    this.pairSeparator = pairSeparator;
    this.keyValueSeparator = keyValueSeparator;
    this.keyTrimMatcher = keyTrimMatcher;
    this.valueTrimMatcher = valueTrimMatcher;
  }

  /**
   * Splits the CharSequence passed in parameter.
   *
   * @param source the sequence of characters to split
   * @return a map of key/value pairs
   */
  public Map<String, String> split(final CharSequence source) {
    java.util.Objects.requireNonNull(source, "source");
    Map<String, String> parameters = new HashMap<>();
    Iterator<String> i = new StringIterator(source, pairSeparator);
    while (i.hasNext()) {
      String keyValue = i.next();

      int keyValueSeparatorPosition = keyValueSeparatorStart(keyValue);
      if (keyValueSeparatorPosition == 0 || keyValue.length() == 0) {
        continue;
      }
      if (keyValueSeparatorPosition < 0) {
        parameters.put(keyValue, null);
        continue;
      }
      int keyStart = 0;
      int keyEnd = keyValueSeparatorPosition;

      while (keyStart < keyEnd && keyTrimMatcher.matches(keyValue.charAt(keyStart))) {
        keyStart++;
      }
      while (keyStart < keyEnd && keyTrimMatcher.matches(keyValue.charAt(keyEnd - 1))) {
        keyEnd--;
      }

      int valueStart = keyValueSeparatorPosition + keyValueSeparator.length();
      int valueEnd = keyValue.length();

      while (valueStart < valueEnd && valueTrimMatcher.matches(keyValue.charAt(valueStart))) {
        valueStart++;
      }
      while (valueStart < valueEnd && valueTrimMatcher.matches(keyValue.charAt(valueEnd - 1))) {
        valueEnd--;
      }

      String key = keyValue.substring(keyStart, keyEnd);
      String value = keyValue.substring(valueStart, valueEnd);
      parameters.put(key, value);
    }
    return parameters;
  }

  /**
   * Returns a splitter that removes all leading or trailing characters
   * matching the given character from each returned key and value.
   *
   * @param c character
   * @return a splitter with the desired configuration
   */
  public Splitter trim(char c) {
    Matcher matcher = new CharMatcher(c);
    return new Splitter(pairSeparator, keyValueSeparator, matcher, matcher);
  }

  /**
   * Returns a splitter that removes all leading or trailing characters
   * matching the given characters from each returned key and value.
   *
   * @param chars characters
   * @return a splitter with the desired configuration
   */
  public Splitter trim(char[] chars) {
    Matcher matcher = new CharsMatcher(chars);
    return new Splitter(pairSeparator, keyValueSeparator, matcher, matcher);
  }

  /**
   * Returns a splitter that removes all leading or trailing characters
   * matching the given character from each returned key.
   *
   * @param c character
   * @return a splitter with the desired configuration
   */
  public Splitter trimKeys(char c) {
    return new Splitter(pairSeparator, keyValueSeparator, new CharMatcher(c), valueTrimMatcher);
  }

  /**
   * Returns a splitter that removes all leading or trailing characters
   * matching the given characters from each returned key.
   *
   * @param chars characters
   * @return a splitter with the desired configuration
   */
  public Splitter trimKeys(char[] chars) {
    return new Splitter(pairSeparator, keyValueSeparator, new CharsMatcher(chars)
        , valueTrimMatcher);
  }

  /**
   * Returns a splitter that removes all leading or trailing characters
   * matching the given character from each returned value.
   *
   * @param c character
   * @return a splitter with the desired configuration
   */
  public Splitter trimValues(char c) {
    return new Splitter(pairSeparator, keyValueSeparator, keyTrimMatcher, new CharMatcher(c));
  }

  /**
   * Returns a splitter that removes all leading or trailing characters
   * matching the given characters from each returned value.
   *
   * @param chars characters
   * @return a splitter with the desired configuration
   */
  public Splitter trimValues(char[] chars) {
    return new Splitter(pairSeparator, keyValueSeparator, keyTrimMatcher, new CharsMatcher(chars));
  }

  /**
   * Returns a splitter that behaves equivalently to this
   * splitter, but uses the given fixed string as a key/value separator.
   *
   * @param keyValueSeparator key/value separator
   * @return a splitter with the desired configuration
   */
  public Splitter withKeyValueSeparator(String keyValueSeparator) {
    return new Splitter(pairSeparator, keyValueSeparator, keyTrimMatcher, valueTrimMatcher);
  }

  private boolean isKeyValueSeparator(String source, int position) {
    for (int i = 1; i < keyValueSeparator.length(); i++) {
      if (source.charAt(i + position) != keyValueSeparator.charAt(i)) {
        return false;
      }
    }
    return true;
  }

  private int keyValueSeparatorStart(String source) {
    for (int i = 0, j = source.length() - keyValueSeparator.length(); i <= j; i++) {
      if (source.charAt(i) == keyValueSeparator.charAt(0) && isKeyValueSeparator(source, i)) {
        return i;
      }
    }
    return -1;
  }
}


text:
function Tile(position, value) {
    this.x = position.x;
    this.y = position.y;
    this.value = value || 2;
    this.previousPosition = null;
    this.mergedFrom = null;
};

Tile.prototype.savePosition = function() {
    this.previousPosition = {
        x: this.x,
        y: this.y
    };
};

Tile.prototype.updatePosition = function(position) {
    this.x = position.x;
    this.y = position.y;
};

Tile.prototype.serialize = function() {
    return {
        position: {
            x: this.x,
            y: this.y
        },
        value: this.value
    };
};