summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2007-08-09 22:31:59 +0000
committerAlan Conway <aconway@apache.org>2007-08-09 22:31:59 +0000
commitf82c2029963a67ee6586ab03c7f5ef3f2a728c0b (patch)
treefcf9f7b95c9b99e9a7542a27324ebb793201b3be /cpp
parent17f7af3557b1a4db846d0521f3652a297a1ef3aa (diff)
downloadqpid-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-xcpp/rubygen/cppgen.rb8
-rwxr-xr-xcpp/rubygen/templates/MethodHolder.rb67
-rw-r--r--cpp/src/Makefile.am11
-rw-r--r--cpp/src/qpid/framing/Blob.h2
-rw-r--r--cpp/src/qpid/framing/MethodHolder.cpp59
-rw-r--r--cpp/src/qpid/framing/MethodHolder.h76
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*/