Beispiel #1
0
 def versions(self):
     return OrderedSet( JavaOFVersion(raw_version) for raw_version in of_g.target_version_list )
Beispiel #2
0
def build_protocol(version, ofinputs):
    name_frontend_classes = OrderedDict()
    name_frontend_enums = OrderedDict()

    for ofinput in ofinputs:
        for c in ofinput.classes:
            name = c.name
            if name in name_frontend_classes:
                raise RedefinedException(
                    "Error parsing {}. Class {} redefined (already defined in {})"
                    .format(ofinput.filename, name,
                            name_frontend_classes[name][1].filename))
            else:
                name_frontend_classes[name] = (c, ofinput)
        for e in ofinput.enums:
            name = e.name
            if name in name_frontend_enums:
                raise RedefinedException(
                    "Error parsing {}. Enum {} redefined (already defined in {})"
                    .format(ofinput.filename, name,
                            name_frontend_enums[name][1].filename))
            else:
                name_frontend_enums[name] = (e, ofinput)

    name_enums = {}
    for fe, _ in name_frontend_enums.values():
        entries = tuple(
            OFEnumEntry(name=e.name, value=e.value, params=e.params)
            for e in fe.entries)
        enum = OFEnum(name=fe.name, entries=entries, params=fe.params)
        for e in entries:
            e.enum = enum
        name_enums[enum.name] = enum

    name_classes = OrderedDict()
    build_touch_classes = OrderedSet()

    def convert_member_properties(props):
        return {
            name if name != "length" else "pad_length": value
            for name, value in props.items()
        }

    def build_member(of_class, fe_member, length_info):
        if isinstance(fe_member, frontend_ir.OFVersionMember):
            member = OFTypeMember(offset=length_info.offset,
                                  base_length=length_info.base_length,
                                  is_fixed_length=length_info.is_fixed_length,
                                  value=version.wire_version,
                                  **convert_member_properties(
                                      fe_member._asdict()))
        else:
            ir_class = globals()[type(fe_member).__name__]
            member = ir_class(offset=length_info.offset,
                              base_length=length_info.base_length,
                              is_fixed_length=length_info.is_fixed_length,
                              **convert_member_properties(fe_member._asdict()))
        member.of_class = of_class
        return member

    def build_class(name):
        if name in name_classes:
            return name_classes[name]
        if name in build_touch_classes:
            raise DependencyCycleException("Dependency cycle: {}".format(
                " -> ".join(list(build_touch_classes) + [name])))
        if not name in name_frontend_classes:
            raise ClassNotFoundException("Class not found: {}".format(name))

        build_touch_classes.add(name)

        fe, _ = name_frontend_classes[name]

        superclass = build_class(fe.superclass) if fe.superclass else None

        # make sure members on which we depend are built first (for calc_length)
        for m in fe.members:
            if not hasattr(m, "oftype"):
                continue
            for m_name in re.sub(r'_t$', '', m.oftype), m.oftype:
                logger.debug("Checking {}".format(m_name))
                if m_name in name_frontend_classes:
                    build_class(m_name)

        base_length, is_fixed_length, member_lengths = \
           ir_offset.calc_lengths(version, fe, name_classes, name_enums)

        members = []
        c = OFClass(name=fe.name,
                    superclass=superclass,
                    members=members,
                    virtual=fe.virtual,
                    params=fe.params,
                    is_fixed_length=is_fixed_length,
                    base_length=base_length)

        members.extend(
            build_member(c, fe_member, member_lengths[fe_member])
            for fe_member in fe.members)

        name_classes[name] = c
        build_touch_classes.remove(name)
        return c

    def build_id_class(orig_name, base_name):
        name = base_name + '_id' + orig_name[len(base_name):]
        if name in name_classes:
            return name_classes[name]
        orig_fe, _ = name_frontend_classes[orig_name]

        if orig_fe.superclass:
            superclass_name = base_name + '_id' + orig_fe.superclass[
                len(base_name):]
            superclass = build_id_class(orig_fe.superclass, base_name)
        else:
            superclass_name = None
            superclass = None

        ofc_members = []
        for m in orig_fe.members:
            if not isinstance(m, frontend_ir.OFDataMember) and not isinstance(
                    m, frontend_ir.OFPadMember):
                ofc_members.append(m)

        fe = frontend_ir.OFClass(name=name,
                                 superclass=superclass_name,
                                 members=ofc_members,
                                 virtual=orig_fe.virtual,
                                 params={})

        base_length, is_fixed_length, member_lengths = \
           ir_offset.calc_lengths(version, fe, name_classes, name_enums)
        assert fe.virtual or is_fixed_length

        members = []
        c = OFClass(name=fe.name,
                    superclass=superclass,
                    members=members,
                    virtual=fe.virtual,
                    params=fe.params,
                    is_fixed_length=is_fixed_length,
                    base_length=base_length)

        members.extend(
            build_member(c, fe_member, member_lengths[fe_member])
            for fe_member in fe.members)

        name_classes[name] = c
        return c

    id_class_roots = ["of_action", "of_instruction"]

    for name in sorted(name_frontend_classes.keys()):
        c = build_class(name)

        # Build ID classes for OF 1.3+
        if version.wire_version >= 4:
            for root in id_class_roots:
                if c.is_instanceof(root):
                    build_id_class(name, root)

    protocol = OFProtocol(version=version,
                          classes=tuple(name_classes.values()),
                          enums=tuple(name_enums.values()))
    for e in chain(protocol.classes, protocol.enums):
        e.protocol = protocol
    return protocol
 def versions(self):
     return OrderedSet(
         JavaOFVersion(ir_version)
         for ir_version in OFVersions.target_versions)