diff options
author | Alan Conway <aconway@apache.org> | 2007-08-09 22:31:59 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2007-08-09 22:31:59 +0000 |
commit | f82c2029963a67ee6586ab03c7f5ef3f2a728c0b (patch) | |
tree | fcf9f7b95c9b99e9a7542a27324ebb793201b3be /cpp | |
parent | 17f7af3557b1a4db846d0521f3652a297a1ef3aa (diff) | |
download | qpid-python-f82c2029963a67ee6586ab03c7f5ef3f2a728c0b.tar.gz |
* src/qpid/framing/MethodHolder.h, .cpp:
Replace boost::variant with Blob.
* rubygen/templates/MethodHolder.rb:
Generate support files for Blob-based MethodHolder.
* src/Makefile.am: generate MethodHolder suppport files.
* rubygen/cppgen.rb: Minor fixes/enhancements.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@564409 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp')
-rwxr-xr-x | cpp/rubygen/cppgen.rb | 8 | ||||
-rwxr-xr-x | cpp/rubygen/templates/MethodHolder.rb | 67 | ||||
-rw-r--r-- | cpp/src/Makefile.am | 11 | ||||
-rw-r--r-- | cpp/src/qpid/framing/Blob.h | 2 | ||||
-rw-r--r-- | cpp/src/qpid/framing/MethodHolder.cpp | 59 | ||||
-rw-r--r-- | cpp/src/qpid/framing/MethodHolder.h | 76 |
6 files changed, 135 insertions, 88 deletions
diff --git a/cpp/rubygen/cppgen.rb b/cpp/rubygen/cppgen.rb index 8feaeb9ba5..64987e763f 100755 --- a/cpp/rubygen/cppgen.rb +++ b/cpp/rubygen/cppgen.rb @@ -136,7 +136,9 @@ class CppGen < Generator end def include(header) - genl /<.*>/.match(header) ? "#include #{header}" : "#include \"#{header}\"" + header+=".h" unless /(\.h|[">])$/===header + header="\"#{header}\"" unless /(^<.*>$)|(^".*"$)/===header + genl "#include #{header}" end def scope(open="{",close="}", &block) @@ -154,11 +156,11 @@ class CppGen < Generator genl end - def struct_class(type, name, *bases, &block) + def struct_class(type, name, bases, &block) genl gen "#{type} #{name}" gen ": #{bases.join(', ')}" unless bases.empty? - scope(" {","};", &block) + scope(" {","};") { yield } end def struct(name, *bases, &block) struct_class("struct", name, bases, &block); end diff --git a/cpp/rubygen/templates/MethodHolder.rb b/cpp/rubygen/templates/MethodHolder.rb new file mode 100755 index 0000000000..a99270055f --- /dev/null +++ b/cpp/rubygen/templates/MethodHolder.rb @@ -0,0 +1,67 @@ +#!/usr/bin/env ruby +$: << ".." # Include .. in load path +require 'cppgen' + +class MethodHolderGen < CppGen + + def initialize(outdir, amqp) + super(outdir, amqp) + @namespace="qpid::framing" + @classname="MethodHolder" + @filename="qpid/framing/MethodHolder" + end + + def gen_max_size() + # Generate program to generate MaxSize.h + cpp_file("generate_#{@classname}MaxSize_h") { + @amqp.amqp_methods.each { |m| include "qpid/framing/#{m.body_name}" } + genl + include "<algorithm>" + include "<fstream>" + genl + genl "using namespace std;" + genl "using namespace qpid::framing;" + genl + scope("int main(int argc, char** argv) {") { + genl "size_t maxSize=0;" + @amqp.amqp_methods.each { |m| + genl "maxSize=max(maxSize, sizeof(#{m.body_name}));" } + gen <<EOS +ofstream out("#{@filename}MaxSize.h"); +out << "// GENERATED CODE: generated by " << argv[0] << endl; +out << "namespace qpid{ namespace framing { " << endl; +out << "const size_t MAX_METHODBODY_SIZE=" << maxSize << ";" << endl; +out << "}}" << endl; +EOS + } + } + end + + def gen_construct + cpp_file(@filename+"_construct") { + include @filename + @amqp.amqp_methods.each { |m| include "qpid/framing/#{m.body_name}" } + genl + namespace(@namespace) { + scope("void #{@classname}::construct(const Id& newId) {") { + scope("switch (newId.first) {") { + @amqp.amqp_classes.each { |c| + scope("case #{c.index}: switch(newId.second) {") { + c.amqp_methods.each { |m| + genl "case #{m.index}: blob.construct(in_place<#{m.body_name}>()); break;" + }} + genl "break;" + }} + genl "id=newId;"; + }}} + end + + + def generate + gen_max_size + gen_construct + end +end + +MethodHolderGen.new(Outdir, Amqp).generate(); + diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am index d59a3a11ea..70e3be7539 100644 --- a/cpp/src/Makefile.am +++ b/cpp/src/Makefile.am @@ -45,7 +45,7 @@ rgen_dir=$(top_srcdir)/rubygen rgen_tdir=$(rgen_dir)/templates rgen_cmd=ruby -I $(rgen_dir) $(rgen_dir)/generate -rgen_templates=$(rgen_tdir)/method_variants.rb \ +rgen_templates=$(rgen_tdir)/MethodHolder.rb \ $(rgen_tdir)/frame_body_lists.rb \ $(rgen_tdir)/Session.rb \ $(rgen_tdir)/Proxy.rb @@ -69,6 +69,12 @@ rubygen.mk: cp $(srcdir)/$@ $@ endif # GENERATE +# Code generated by C++ +noinst_PROGRAMS=generate_MethodHolderMaxSize_h +generate_MethodHolderMaxSize_h_SOURCES=generate_MethodHolderMaxSize_h.cpp +qpid/framing/MethodHolderMaxSize.h: generate_MethodHolderMaxSize_h + ./generate_MethodHolderMaxSize_h + ## Compiler flags AM_CXXFLAGS = $(WARNING_CFLAGS) @@ -160,6 +166,9 @@ libqpidcommon_la_SOURCES = \ qpid/framing/AMQP_ServerProxy.cpp \ gen/qpid/framing/AMQP_HighestVersion.h \ gen/qpid/framing/AMQP_MethodVersionMap.cpp \ + qpid/framing/MethodHolder.h qpid/framing/MethodHolder.cpp \ + qpid/framing/MethodHolderMaxSize.h \ + qpid/framing/MethodHolder_construct.cpp \ qpid/Exception.cpp \ qpid/Plugin.h \ qpid/Plugin.cpp \ diff --git a/cpp/src/qpid/framing/Blob.h b/cpp/src/qpid/framing/Blob.h index 5f1fec14bb..1754e851e5 100644 --- a/cpp/src/qpid/framing/Blob.h +++ b/cpp/src/qpid/framing/Blob.h @@ -55,7 +55,7 @@ using boost::in_place; template <class T> void destroyT(void* ptr) { static_cast<T*>(ptr)->~T(); } -void nullDestroy(void*) {} +inline void nullDestroy(void*) {} /** * A "blob" is a chunk of memory which can contain a single object at diff --git a/cpp/src/qpid/framing/MethodHolder.cpp b/cpp/src/qpid/framing/MethodHolder.cpp index 27046af43c..cc0800a1e8 100644 --- a/cpp/src/qpid/framing/MethodHolder.cpp +++ b/cpp/src/qpid/framing/MethodHolder.cpp @@ -20,74 +20,37 @@ */ #include "MethodHolder.h" -#include "amqp_types.h" +#include "qpid/framing/AMQMethodBody.h" #include "qpid/framing/Buffer.h" #include "qpid/framing/variant.h" +// Note: MethodHolder::construct is in a separate generated file +// MethodHolder_construct.cpp + using namespace boost; namespace qpid { namespace framing { -struct SetVariantVisitor : public NoBlankVisitor<> { - QPID_USING_NOBLANK(); - MethodId id; - SetVariantVisitor(MethodId m) : id(m) {} - template <class T> void operator()(T& t) const { setVariant(t, id); } -}; - -inline void setVariant(MethodVariant& var, ClassId c, MethodId m) { - setVariant(var,c); - boost::apply_visitor(SetVariantVisitor(m), var); -} - -void MethodHolder::setMethod(ClassId c, MethodId m) { - setVariant(method, c, m); -} - -MethodHolder::MethodHolder(ClassId c, MethodId m) { - setMethod(c,m); -} - -struct GetClassId : public NoBlankVisitor<ClassId> { - QPID_USING_NOBLANK(ClassId); - template <class T> ClassId operator()(const T&) const { - return T::CLASS_ID; - } -}; - -struct GetMethodId : public NoBlankVisitor<MethodId> { - QPID_USING_NOBLANK(ClassId); - template <class T> MethodId operator()(const T&) const { - return T::METHOD_ID; - } -}; - void MethodHolder::encode(Buffer& b) const { - const AMQMethodBody* body = getMethod(); + const AMQMethodBody* body = get(); b.putShort(body->amqpClassId()); b.putShort(body->amqpMethodId()); body->encodeContent(b); } void MethodHolder::decode(Buffer& b) { - ClassId classId = b.getShort(); - ClassId methodId = b.getShort(); - setVariant(method, classId, methodId); - getMethod()->decodeContent(b); + construct(std::make_pair(b.getShort(), b.getShort())); + get()->decodeContent(b); } uint32_t MethodHolder::size() const { - return sizeof(ClassId)+sizeof(MethodId)+getMethod()->size(); -} - - -AMQMethodBody* MethodHolder::getMethod() { - return applyApplyVisitor(AddressVisitor<AMQMethodBody*>(), method); + return sizeof(Id)+get()->size(); } -const AMQMethodBody* MethodHolder::getMethod() const { - return const_cast<MethodHolder*>(this)->getMethod(); +std::ostream& operator<<(std::ostream& out, const MethodHolder& h) { + h.get()->print(out); + return out; } }} // namespace qpid::framing diff --git a/cpp/src/qpid/framing/MethodHolder.h b/cpp/src/qpid/framing/MethodHolder.h index b93c6b83b1..fa14db2f79 100644 --- a/cpp/src/qpid/framing/MethodHolder.h +++ b/cpp/src/qpid/framing/MethodHolder.h @@ -1,5 +1,5 @@ -#ifndef QPID_FRAMING_METHODBODYHOLDER_H -#define QPID_FRAMING_METHODBODYHOLDER_H +#ifndef QPID_FRAMING_METHODHOLDER_H +#define QPID_FRAMING_METHODHOLDER_H /* * @@ -22,14 +22,17 @@ * */ -#include "qpid/framing/method_variants.h" +#include "qpid/framing/amqp_types.h" +#include "qpid/framing/Blob.h" +#include "qpid/framing/MethodHolderMaxSize.h" // Generated file. -#include <boost/type_traits/has_nothrow_copy.hpp> +#include <utility> namespace qpid { namespace framing { class AMQMethodBody; +class Buffer; /** * Holder for arbitrary method body. @@ -37,44 +40,47 @@ class AMQMethodBody; class MethodHolder { public: + typedef std::pair<ClassId, MethodId> Id; + + template <class T>static Id idOf() { + return std::make_pair(T::CLASS_ID, T::METHOD_ID); } + MethodHolder() {} - MethodHolder(const MethodVariant& mv) : method(mv) {} - - /** Construct from a concrete method body type. - * ClassVariant<T>::value is the containing class variant. - */ - template <class T> - MethodHolder(const T& t) - : method(typename ClassVariant<T>::value(t)) {} - - /** Construct from class/method ID, set the method accordingly. */ - MethodHolder(ClassId, MethodId); - - /** Set the method to the type corresponding to ClassId, MethodId */ - void setMethod(ClassId, MethodId); - - AMQMethodBody* getMethod(); - const AMQMethodBody* getMethod() const; - - MethodVariant method; + MethodHolder(const Id& id) { construct(id); } + MethodHolder(ClassId& c, MethodId& m) { construct(std::make_pair(c,m)); } + + template <class M> + MethodHolder(const M& m) : blob(m), id(idOf<M>()) {} + + template <class M> + MethodHolder& operator=(const M& m) { blob=m; id=idOf<M>(); return *this; } + + /** Construct the method body corresponding to Id */ + void construct(const Id&); void encode(Buffer&) const; void decode(Buffer&); uint32_t size() const; + + AMQMethodBody* get() { + return static_cast<AMQMethodBody*>(blob.get()); + } + const AMQMethodBody* get() const { + return static_cast<const AMQMethodBody*>(blob.get()); + } + + AMQMethodBody* operator* () { return get(); } + const AMQMethodBody* operator*() const { return get(); } + AMQMethodBody* operator-> () { return get(); } + const AMQMethodBody* operator->() const { return get(); } + + private: + Blob<MAX_METHODBODY_SIZE> blob; + Id id; }; -inline std::ostream& operator<<(std::ostream& out, const MethodHolder& h) { - return out << h.method; -} - +std::ostream& operator<<(std::ostream& out, const MethodHolder& h); }} // namespace qpid::framing -namespace boost { -template<> struct has_nothrow_copy<qpid::framing::MethodHolder> - : public boost::true_type {}; -} - - - -#endif /*!QPID_FRAMING_METHODBODYHOLDER_H*/ +#endif /*!QPID_FRAMING_METHODHOLDER_H*/ |