// 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.OFBsnLacpConvergenceStatusT;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.common.hash.PrimitiveSink;

public class OFBsnLacpConvergenceStatusTSerializerVer13 {

    public final static byte SUCCESS_VAL = (byte) 0x0;
    public final static byte TIMEDOUT_VAL = (byte) 0x1;
    public final static byte OUT_OF_SYNC_VAL = (byte) 0x2;

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

    public static void writeTo(ChannelBuffer bb, OFBsnLacpConvergenceStatusT e) {
        bb.writeByte(toWireValue(e));
    }

    public static void putTo(OFBsnLacpConvergenceStatusT e, PrimitiveSink sink) {
        sink.putByte(toWireValue(e));
    }

    public static OFBsnLacpConvergenceStatusT ofWireValue(byte val) {
        switch(val) {
            case SUCCESS_VAL:
                return OFBsnLacpConvergenceStatusT.SUCCESS;
            case TIMEDOUT_VAL:
                return OFBsnLacpConvergenceStatusT.TIMEDOUT;
            case OUT_OF_SYNC_VAL:
                return OFBsnLacpConvergenceStatusT.OUT_OF_SYNC;
            default:
                throw new IllegalArgumentException("Illegal wire value for type OFBsnLacpConvergenceStatusT in version 1.3: " + val);
        }
    }


    public static byte toWireValue(OFBsnLacpConvergenceStatusT e) {
        switch(e) {
            case SUCCESS:
                return SUCCESS_VAL;
            case TIMEDOUT:
                return TIMEDOUT_VAL;
            case OUT_OF_SYNC:
                return OUT_OF_SYNC_VAL;
            default:
                throw new IllegalArgumentException("Illegal enum value for type OFBsnLacpConvergenceStatusT in version 1.3: " + e);
        }
    }

}
