/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 *
 *  Marshaler code for OpenWire format for ConsumerControl
 *
 *  NOTE!: This file is auto generated - do not modify!
 *         if you need to make a change, please see the Java Classes
 *         in the nms-activemq-openwire-generator module
 *
 */

using System;
using System.IO;

using Apache.NMS.ActiveMQ.Commands;

namespace Apache.NMS.ActiveMQ.OpenWire.V4
{
    /// <summary>
    ///  Marshalling code for Open Wire Format for ConsumerControl
    /// </summary>
    class ConsumerControlMarshaller : BaseCommandMarshaller
    {
        /// <summery>
        ///  Creates an instance of the Object that this marshaller handles.
        /// </summery>
        public override DataStructure CreateObject() 
        {
            return new ConsumerControl();
        }

        /// <summery>
        ///  Returns the type code for the Object that this Marshaller handles..
        /// </summery>
        public override byte GetDataStructureType() 
        {
            return ConsumerControl.ID_CONSUMERCONTROL;
        }

        // 
        // Un-marshal an object instance from the data input stream
        // 
        public override void TightUnmarshal(OpenWireFormat wireFormat, Object o, BinaryReader dataIn, BooleanStream bs) 
        {
            base.TightUnmarshal(wireFormat, o, dataIn, bs);

            ConsumerControl info = (ConsumerControl)o;
            info.Close = bs.ReadBoolean();
            info.ConsumerId = (ConsumerId) TightUnmarshalNestedObject(wireFormat, dataIn, bs);
            info.Prefetch = dataIn.ReadInt32();
            info.Flush = bs.ReadBoolean();
            info.Start = bs.ReadBoolean();
            info.Stop = bs.ReadBoolean();
        }

        //
        // Write the booleans that this object uses to a BooleanStream
        //
        public override int TightMarshal1(OpenWireFormat wireFormat, Object o, BooleanStream bs)
        {
            ConsumerControl info = (ConsumerControl)o;

            int rc = base.TightMarshal1(wireFormat, o, bs);
            bs.WriteBoolean(info.Close);
        rc += TightMarshalNestedObject1(wireFormat, (DataStructure)info.ConsumerId, bs);
            bs.WriteBoolean(info.Flush);
            bs.WriteBoolean(info.Start);
            bs.WriteBoolean(info.Stop);

            return rc + 4;
        }

        // 
        // Write a object instance to data output stream
        //
        public override void TightMarshal2(OpenWireFormat wireFormat, Object o, BinaryWriter dataOut, BooleanStream bs)
        {
            base.TightMarshal2(wireFormat, o, dataOut, bs);

            ConsumerControl info = (ConsumerControl)o;
            bs.ReadBoolean();
            TightMarshalNestedObject2(wireFormat, (DataStructure)info.ConsumerId, dataOut, bs);
            dataOut.Write(info.Prefetch);
            bs.ReadBoolean();
            bs.ReadBoolean();
            bs.ReadBoolean();
        }

        // 
        // Un-marshal an object instance from the data input stream
        // 
        public override void LooseUnmarshal(OpenWireFormat wireFormat, Object o, BinaryReader dataIn) 
        {
            base.LooseUnmarshal(wireFormat, o, dataIn);

            ConsumerControl info = (ConsumerControl)o;
            info.Close = dataIn.ReadBoolean();
            info.ConsumerId = (ConsumerId) LooseUnmarshalNestedObject(wireFormat, dataIn);
            info.Prefetch = dataIn.ReadInt32();
            info.Flush = dataIn.ReadBoolean();
            info.Start = dataIn.ReadBoolean();
            info.Stop = dataIn.ReadBoolean();
        }

        // 
        // Write a object instance to data output stream
        //
        public override void LooseMarshal(OpenWireFormat wireFormat, Object o, BinaryWriter dataOut)
        {

            ConsumerControl info = (ConsumerControl)o;

            base.LooseMarshal(wireFormat, o, dataOut);
            dataOut.Write(info.Close);
            LooseMarshalNestedObject(wireFormat, (DataStructure)info.ConsumerId, dataOut);
            dataOut.Write(info.Prefetch);
            dataOut.Write(info.Flush);
            dataOut.Write(info.Start);
            dataOut.Write(info.Stop);
        }
    }
}
