&{${CLASS}${METHOD}Body.h}
/*
 *
 * 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.
 *
 */

/*
 * This file is auto-generated by ${GENERATOR} - do not modify.
 * Supported AMQP versions:
%{VLIST} *   ${major}-${minor}
 */

#ifndef qpid_framing_${CLASS}${METHOD}Body__
#define qpid_framing_${CLASS}${METHOD}Body__

#include <string>
#include <sstream>

#include <amqp_types.h>
#include <AMQMethodBody.h>
#include <Buffer.h>
#include <FieldTable.h>

namespace qpid
{
namespace framing
{
${version_namespace_start}
 
class ${CLASS}${METHOD}Body : public AMQMethodBody
{
	// Method field declarations

%{FLIST} ${mb_field_declaration}
     

public:
    typedef boost::shared_ptr<${CLASS}${METHOD}Body> shared_ptr;

	// Constructors and destructors

${mb_constructor_with_initializers}

    inline ${CLASS}${METHOD}Body(u_int8_t major, u_int8_t minor): AMQMethodBody(major, minor) {}
    inline ${CLASS}${METHOD}Body(ProtocolVersion& version): AMQMethodBody(version) {}
    virtual ~${CLASS}${METHOD}Body() {}
    
    // Attribute get methods

%{FLIST} ${mb_field_get_method}

    // Helper methods
    
    inline void print(std::ostream& out) const
    {
	    out << "${CLASS}${METHOD}: ";
%{FLIST} ${mb_field_print}
    }

    inline u_int16_t amqpClassId() const
    {
    	return ${CLASS_ID_INIT};
    }
    
    inline u_int16_t amqpMethodId() const
    {
    	return ${METHOD_ID_INIT};
    }

    inline u_int32_t bodySize() const
    {
		u_int32_t size = 0;        
%{FLIST} ${mb_body_size}
        return size;
    }

    inline void encodeContent(Buffer&${mb_buffer_param}) const
    {
%{FLIST} ${mb_encode}
    }

    inline void decodeContent(Buffer&${mb_buffer_param})
    {
%{FLIST} ${mb_decode}
    }       

${mb_server_operation_invoke}

}; // class ${CLASS}${METHOD}Body

${version_namespace_end}
} // namespace framing
} // namespace qpid

#endif

