// 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 const_serializer.java
// Do not modify

package org.projectfloodlight.openflow.protocol.ver13;

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.projectfloodlight.openflow.protocol.OFTableFeaturePropType;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.common.hash.PrimitiveSink;

public class OFTableFeaturePropTypeSerializerVer13 {

    public final static short INSTRUCTIONS_VAL = (short) 0x0;
    public final static short INSTRUCTIONS_MISS_VAL = (short) 0x1;
    public final static short NEXT_TABLES_VAL = (short) 0x2;
    public final static short NEXT_TABLES_MISS_VAL = (short) 0x3;
    public final static short WRITE_ACTIONS_VAL = (short) 0x4;
    public final static short WRITE_ACTIONS_MISS_VAL = (short) 0x5;
    public final static short APPLY_ACTIONS_VAL = (short) 0x6;
    public final static short APPLY_ACTIONS_MISS_VAL = (short) 0x7;
    public final static short MATCH_VAL = (short) 0x8;
    public final static short WILDCARDS_VAL = (short) 0xa;
    public final static short WRITE_SETFIELD_VAL = (short) 0xc;
    public final static short WRITE_SETFIELD_MISS_VAL = (short) 0xd;
    public final static short APPLY_SETFIELD_VAL = (short) 0xe;
    public final static short APPLY_SETFIELD_MISS_VAL = (short) 0xf;
    public final static short EXPERIMENTER_VAL = (short) 0xfffe;
    public final static short EXPERIMENTER_MISS_VAL = (short) 0xffff;

    public static OFTableFeaturePropType readFrom(ChannelBuffer bb) throws OFParseError {
        try {
            return ofWireValue(bb.readShort());
        } catch (IllegalArgumentException e) {
            throw new OFParseError(e);
        }
    }

    public static void writeTo(ChannelBuffer bb, OFTableFeaturePropType e) {
        bb.writeShort(toWireValue(e));
    }

    public static void putTo(OFTableFeaturePropType e, PrimitiveSink sink) {
        sink.putShort(toWireValue(e));
    }

    public static OFTableFeaturePropType ofWireValue(short val) {
        switch(val) {
            case INSTRUCTIONS_VAL:
                return OFTableFeaturePropType.INSTRUCTIONS;
            case INSTRUCTIONS_MISS_VAL:
                return OFTableFeaturePropType.INSTRUCTIONS_MISS;
            case NEXT_TABLES_VAL:
                return OFTableFeaturePropType.NEXT_TABLES;
            case NEXT_TABLES_MISS_VAL:
                return OFTableFeaturePropType.NEXT_TABLES_MISS;
            case WRITE_ACTIONS_VAL:
                return OFTableFeaturePropType.WRITE_ACTIONS;
            case WRITE_ACTIONS_MISS_VAL:
                return OFTableFeaturePropType.WRITE_ACTIONS_MISS;
            case APPLY_ACTIONS_VAL:
                return OFTableFeaturePropType.APPLY_ACTIONS;
            case APPLY_ACTIONS_MISS_VAL:
                return OFTableFeaturePropType.APPLY_ACTIONS_MISS;
            case MATCH_VAL:
                return OFTableFeaturePropType.MATCH;
            case WILDCARDS_VAL:
                return OFTableFeaturePropType.WILDCARDS;
            case WRITE_SETFIELD_VAL:
                return OFTableFeaturePropType.WRITE_SETFIELD;
            case WRITE_SETFIELD_MISS_VAL:
                return OFTableFeaturePropType.WRITE_SETFIELD_MISS;
            case APPLY_SETFIELD_VAL:
                return OFTableFeaturePropType.APPLY_SETFIELD;
            case APPLY_SETFIELD_MISS_VAL:
                return OFTableFeaturePropType.APPLY_SETFIELD_MISS;
            case EXPERIMENTER_VAL:
                return OFTableFeaturePropType.EXPERIMENTER;
            case EXPERIMENTER_MISS_VAL:
                return OFTableFeaturePropType.EXPERIMENTER_MISS;
            default:
                throw new IllegalArgumentException("Illegal wire value for type OFTableFeaturePropType in version 1.3: " + val);
        }
    }


    public static short toWireValue(OFTableFeaturePropType e) {
        switch(e) {
            case INSTRUCTIONS:
                return INSTRUCTIONS_VAL;
            case INSTRUCTIONS_MISS:
                return INSTRUCTIONS_MISS_VAL;
            case NEXT_TABLES:
                return NEXT_TABLES_VAL;
            case NEXT_TABLES_MISS:
                return NEXT_TABLES_MISS_VAL;
            case WRITE_ACTIONS:
                return WRITE_ACTIONS_VAL;
            case WRITE_ACTIONS_MISS:
                return WRITE_ACTIONS_MISS_VAL;
            case APPLY_ACTIONS:
                return APPLY_ACTIONS_VAL;
            case APPLY_ACTIONS_MISS:
                return APPLY_ACTIONS_MISS_VAL;
            case MATCH:
                return MATCH_VAL;
            case WILDCARDS:
                return WILDCARDS_VAL;
            case WRITE_SETFIELD:
                return WRITE_SETFIELD_VAL;
            case WRITE_SETFIELD_MISS:
                return WRITE_SETFIELD_MISS_VAL;
            case APPLY_SETFIELD:
                return APPLY_SETFIELD_VAL;
            case APPLY_SETFIELD_MISS:
                return APPLY_SETFIELD_MISS_VAL;
            case EXPERIMENTER:
                return EXPERIMENTER_VAL;
            case EXPERIMENTER_MISS:
                return EXPERIMENTER_MISS_VAL;
            default:
                throw new IllegalArgumentException("Illegal enum value for type OFTableFeaturePropType in version 1.3: " + e);
        }
    }

}
