Author: aconway
Date: Thu Aug  9 15:31:59 2007
New Revision: 564409

URL: http://svn.apache.org/viewvc?view=rev&rev=564409
Log:

        * 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.

Added:
    incubator/qpid/trunk/qpid/cpp/rubygen/templates/MethodHolder.rb   (with 
props)
Modified:
    incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb
    incubator/qpid/trunk/qpid/cpp/src/Makefile.am
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Blob.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/MethodHolder.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/MethodHolder.h

Modified: incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb?view=diff&rev=564409&r1=564408&r2=564409
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb Thu Aug  9 15:31:59 2007
@@ -136,7 +136,9 @@
   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 @@
     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

Added: incubator/qpid/trunk/qpid/cpp/rubygen/templates/MethodHolder.rb
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/templates/MethodHolder.rb?view=auto&rev=564409
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/templates/MethodHolder.rb (added)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/templates/MethodHolder.rb Thu Aug  9 
15:31:59 2007
@@ -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("[EMAIL PROTECTED]") {
+      @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("[EMAIL PROTECTED]");
+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 [EMAIL PROTECTED]::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();
+

Propchange: incubator/qpid/trunk/qpid/cpp/rubygen/templates/MethodHolder.rb
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/rubygen/templates/MethodHolder.rb
------------------------------------------------------------------------------
    svn:executable = *

Modified: incubator/qpid/trunk/qpid/cpp/src/Makefile.am
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/Makefile.am?view=diff&rev=564409&r1=564408&r2=564409
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ incubator/qpid/trunk/qpid/cpp/src/Makefile.am Thu Aug  9 15:31:59 2007
@@ -45,7 +45,7 @@
 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 @@
        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 @@
   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 \

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Blob.h
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Blob.h?view=diff&rev=564409&r1=564408&r2=564409
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Blob.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Blob.h Thu Aug  9 15:31:59 
2007
@@ -55,7 +55,7 @@
 
 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

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/MethodHolder.cpp
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/MethodHolder.cpp?view=diff&rev=564409&r1=564408&r2=564409
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/MethodHolder.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/MethodHolder.cpp Thu Aug  9 
15:31:59 2007
@@ -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

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/MethodHolder.h
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/MethodHolder.h?view=diff&rev=564409&r1=564408&r2=564409
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/MethodHolder.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/MethodHolder.h Thu Aug  9 
15:31:59 2007
@@ -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 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) {}
+    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 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;
+    /** 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*/


Reply via email to