// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
// Copyright (c) 2011, 2012 Open Networking Foundation
// Copyright (c) 2012, 2013 Big Switch Networks, Inc.
// This library was generated by the LoxiGen Compiler.
// See the file LICENSE.txt which should have been included in the source distribution

// Automatically generated by LOXI from template of_virtual_class.java
// Do not modify

package org.projectfloodlight.openflow.protocol.ver12;

import org.projectfloodlight.openflow.protocol.*;
import org.projectfloodlight.openflow.protocol.action.*;
import org.projectfloodlight.openflow.protocol.actionid.*;
import org.projectfloodlight.openflow.protocol.bsntlv.*;
import org.projectfloodlight.openflow.protocol.errormsg.*;
import org.projectfloodlight.openflow.protocol.meterband.*;
import org.projectfloodlight.openflow.protocol.instruction.*;
import org.projectfloodlight.openflow.protocol.instructionid.*;
import org.projectfloodlight.openflow.protocol.match.*;
import org.projectfloodlight.openflow.protocol.oxm.*;
import org.projectfloodlight.openflow.protocol.queueprop.*;
import org.projectfloodlight.openflow.types.*;
import org.projectfloodlight.openflow.util.*;
import org.projectfloodlight.openflow.exceptions.*;
import org.jboss.netty.buffer.ChannelBuffer;
import java.util.Set;

abstract class OFMessageVer12 {
    // version: 1.2
    final static byte WIRE_VERSION = 3;
    final static int MINIMUM_LENGTH = 8;


    public final static OFMessageVer12.Reader READER = new Reader();

    static class Reader implements OFMessageReader<OFMessage> {
        @Override
        public OFMessage readFrom(ChannelBuffer bb) throws OFParseError {
            if(bb.readableBytes() < MINIMUM_LENGTH)
                return null;
            int start = bb.readerIndex();
            // fixed value property version == 3
            byte version = bb.readByte();
            if(version != (byte) 0x3)
                throw new OFParseError("Wrong version: Expected=OFVersion.OF_12(3), got="+version);
            byte type = bb.readByte();
            bb.readerIndex(start);
            switch(type) {
               case (byte) 0x13:
                   // discriminator value OFType.STATS_REPLY=19 for class OFStatsReplyVer12
                   return OFStatsReplyVer12.READER.readFrom(bb);
               case (byte) 0x12:
                   // discriminator value OFType.STATS_REQUEST=18 for class OFStatsRequestVer12
                   return OFStatsRequestVer12.READER.readFrom(bb);
               case (byte) 0x1:
                   // discriminator value OFType.ERROR=1 for class OFErrorMsgVer12
                   return OFErrorMsgVer12.READER.readFrom(bb);
               case (byte) 0x15:
                   // discriminator value OFType.BARRIER_REPLY=21 for class OFBarrierReplyVer12
                   return OFBarrierReplyVer12.READER.readFrom(bb);
               case (byte) 0x14:
                   // discriminator value OFType.BARRIER_REQUEST=20 for class OFBarrierRequestVer12
                   return OFBarrierRequestVer12.READER.readFrom(bb);
               case (byte) 0x4:
                   // discriminator value OFType.EXPERIMENTER=4 for class OFExperimenterVer12
                   return OFExperimenterVer12.READER.readFrom(bb);
               case (byte) 0x3:
                   // discriminator value OFType.ECHO_REPLY=3 for class OFEchoReplyVer12
                   return OFEchoReplyVer12.READER.readFrom(bb);
               case (byte) 0x2:
                   // discriminator value OFType.ECHO_REQUEST=2 for class OFEchoRequestVer12
                   return OFEchoRequestVer12.READER.readFrom(bb);
               case (byte) 0x6:
                   // discriminator value OFType.FEATURES_REPLY=6 for class OFFeaturesReplyVer12
                   return OFFeaturesReplyVer12.READER.readFrom(bb);
               case (byte) 0x5:
                   // discriminator value OFType.FEATURES_REQUEST=5 for class OFFeaturesRequestVer12
                   return OFFeaturesRequestVer12.READER.readFrom(bb);
               case (byte) 0xe:
                   // discriminator value OFType.FLOW_MOD=14 for class OFFlowModVer12
                   return OFFlowModVer12.READER.readFrom(bb);
               case (byte) 0xb:
                   // discriminator value OFType.FLOW_REMOVED=11 for class OFFlowRemovedVer12
                   return OFFlowRemovedVer12.READER.readFrom(bb);
               case (byte) 0x8:
                   // discriminator value OFType.GET_CONFIG_REPLY=8 for class OFGetConfigReplyVer12
                   return OFGetConfigReplyVer12.READER.readFrom(bb);
               case (byte) 0x7:
                   // discriminator value OFType.GET_CONFIG_REQUEST=7 for class OFGetConfigRequestVer12
                   return OFGetConfigRequestVer12.READER.readFrom(bb);
               case (byte) 0x0:
                   // discriminator value OFType.HELLO=0 for class OFHelloVer12
                   return OFHelloVer12.READER.readFrom(bb);
               case (byte) 0xa:
                   // discriminator value OFType.PACKET_IN=10 for class OFPacketInVer12
                   return OFPacketInVer12.READER.readFrom(bb);
               case (byte) 0xd:
                   // discriminator value OFType.PACKET_OUT=13 for class OFPacketOutVer12
                   return OFPacketOutVer12.READER.readFrom(bb);
               case (byte) 0x10:
                   // discriminator value OFType.PORT_MOD=16 for class OFPortModVer12
                   return OFPortModVer12.READER.readFrom(bb);
               case (byte) 0xc:
                   // discriminator value OFType.PORT_STATUS=12 for class OFPortStatusVer12
                   return OFPortStatusVer12.READER.readFrom(bb);
               case (byte) 0x17:
                   // discriminator value OFType.QUEUE_GET_CONFIG_REPLY=23 for class OFQueueGetConfigReplyVer12
                   return OFQueueGetConfigReplyVer12.READER.readFrom(bb);
               case (byte) 0x16:
                   // discriminator value OFType.QUEUE_GET_CONFIG_REQUEST=22 for class OFQueueGetConfigRequestVer12
                   return OFQueueGetConfigRequestVer12.READER.readFrom(bb);
               case (byte) 0x9:
                   // discriminator value OFType.SET_CONFIG=9 for class OFSetConfigVer12
                   return OFSetConfigVer12.READER.readFrom(bb);
               case (byte) 0x11:
                   // discriminator value OFType.TABLE_MOD=17 for class OFTableModVer12
                   return OFTableModVer12.READER.readFrom(bb);
               case (byte) 0xf:
                   // discriminator value OFType.GROUP_MOD=15 for class OFGroupModVer12
                   return OFGroupModVer12.READER.readFrom(bb);
               case (byte) 0x19:
                   // discriminator value OFType.ROLE_REPLY=25 for class OFRoleReplyVer12
                   return OFRoleReplyVer12.READER.readFrom(bb);
               case (byte) 0x18:
                   // discriminator value OFType.ROLE_REQUEST=24 for class OFRoleRequestVer12
                   return OFRoleRequestVer12.READER.readFrom(bb);
               default:
                   throw new OFParseError("Unknown value for discriminator type of class OFMessageVer12: " + type);
            }
        }
    }
}
