qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From acon...@apache.org
Subject svn commit: r585223 - in /incubator/qpid/trunk/qpid/cpp: rubygen/ rubygen/templates/ src/ src/qpid/broker/ src/qpid/client/ src/qpid/framing/
Date Tue, 16 Oct 2007 19:07:56 GMT
Author: aconway
Date: Tue Oct 16 12:07:54 2007
New Revision: 585223

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

	* Summary: generalized Invoker visitor to all *Operations and
	  *Handler classes, client and broker. Single template
	  free function invoke(Invocable, const AMQBody&); works for
	  all invocable handlers.
	  
	* rubygen/templates/OperationsInvoker.rb: Generates invoker
	  visitors for all Operations classes, client and server.

	* src/qpid/framing/Invoker.h: Invoker base class and
	  template invoke() function.

	* rubygen/templates/structs.rb: add generic invoke method template
	  to invoke an arbitrary object with the correct memeber function.

	* src/qpid/framing/AMQMethodBody.cpp, .h: Removed invoke(),
	  replaced by qpid::framing::invoke()

	* src/qpid/broker/SemanticHandler.cpp, ConnectionHandler.cpp:
	  Replace AMQMethodBody::invoke with invoke() free function.

	* src/qpid/framing/StructHelper.h: Avoid un-necessary alloc
	  and copy in encode/decode.

Added:
    incubator/qpid/trunk/qpid/cpp/rubygen/templates/OperationsInvoker.rb   (with props)
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Invoker.h   (with props)
Removed:
    incubator/qpid/trunk/qpid/cpp/rubygen/templates/InvocationVisitor.rb
Modified:
    incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb
    incubator/qpid/trunk/qpid/cpp/rubygen/templates/Operations.rb
    incubator/qpid/trunk/qpid/cpp/rubygen/templates/structs.rb
    incubator/qpid/trunk/qpid/cpp/src/Makefile.am
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SemanticHandler.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SessionHandler.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SessionHandler.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/client/ExecutionHandler.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/client/ExecutionHandler.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQMethodBody.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQMethodBody.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FrameDefaultVisitor.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/StructHelper.h

Modified: incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb Tue Oct 16 12:07:54 2007
@@ -202,7 +202,6 @@
   end
 
   def struct_class(type, name, bases, &block)
-    genl
     gen "#{type} #{name}"
     if (!bases.empty?)
       genl ":"

Modified: incubator/qpid/trunk/qpid/cpp/rubygen/templates/Operations.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/templates/Operations.rb?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/templates/Operations.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/templates/Operations.rb Tue Oct 16 12:07:54 2007
@@ -29,9 +29,11 @@
       handlerclass=handler_classname c
       gen <<EOS
 // ==================== class #{handlerclass} ====================
-class #{handlerclass} : public virtual Invocable {
+class #{handlerclass} {
     // Constructors and destructors
   public:
+    class Invoker;              // Declared in #{@chassis.caps}Invoker
+      
     #{handlerclass}(){};
     virtual ~#{handlerclass}() {}
     // Protocol methods
@@ -64,16 +66,10 @@
 
 class AMQMethodBody;
 
-class Invocable 
-{
-protected:
-    Invocable() {}        
-    virtual ~Invocable() {}        
-};
-
 class #{@classname} {
-
   public:
+    class Invoker;              // Declared in #{@chassis.caps}Invoker
+
     virtual ~#{@classname}() {}
 
     virtual ProtocolVersion getVersion() const = 0;

Added: incubator/qpid/trunk/qpid/cpp/rubygen/templates/OperationsInvoker.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/templates/OperationsInvoker.rb?rev=585223&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/templates/OperationsInvoker.rb (added)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/templates/OperationsInvoker.rb Tue Oct 16 12:07:54
2007
@@ -0,0 +1,92 @@
+#!/usr/bin/env ruby
+# Usage: output_directory xml_spec_file [xml_spec_file...]
+# 
+$: << '..'
+require 'cppgen'
+
+class OperationsInvokerGen < CppGen
+  def initialize(chassis, outdir, amqp)
+    super(outdir, amqp)
+    @chassis=chassis
+    @ops="AMQP_#{@chassis.caps}Operations"
+    @classname="#{@ops}::Invoker"
+    @filename="qpid/framing/#{@chassis.caps}Invoker"
+  end
+
+  def handler(c) "#{@ops}::#{c.cppname}Handler"; end
+  def getter(c) "get#{c.cppname}Handler"; end
+  def invoker(c) "#{handler(c)}::Invoker"; end
+  def visit_methods(c) c.methods_on(@chassis).select { |m| !m.content } end
+  
+  def handler_visits_cpp(c)
+    visit_methods(c).each { |m|
+      scope("void #{invoker(c)}::visit(const #{m.body_name}& body) {") {
+        if (m.result)
+          genl "this->encode(body.invoke(target), result.result);"
+        else
+          genl "body.invoke(target);"
+        end
+        genl "result.handled=true;"
+      }
+    }
+  end
+
+  def ops_visits_cpp()
+    @amqp.classes.each { |c|
+      visit_methods(c).each { |m|
+        scope("void #{@classname}::visit(const #{m.body_name}& body) {") {
+        genl "#{handler(c)}::Invoker invoker(*target.#{getter(c)}());"
+        genl "body.accept(invoker);"
+        genl "result=invoker.getResult();"
+        }
+      }
+    }
+  end
+
+  def invoker_h(invoker, target, methods)
+    return if methods.empty?
+    genl
+    cpp_class(invoker, "public qpid::framing::Invoker") {
+      genl "#{target}& target;"
+      public
+      genl("Invoker(#{target}& target_) : target(target_) {}")
+      genl "using MethodBodyDefaultVisitor::visit;"
+      methods.each { |m| genl "void visit(const #{m.body_name}& body);" }
+    }
+  end
+  
+  def generate()
+    h_file(@filename) {
+      include "qpid/framing/#{@ops}"
+      include "qpid/framing/Invoker.h"
+      namespace("qpid::framing") {
+        # AMQP_*Operations invoker.
+        methods=@amqp.classes.map { |c| visit_methods(c).to_a }.flatten
+        invoker_h(@classname, @ops, methods) 
+
+        # AMQP_*Operations::*Handler invokers.
+        @amqp.classes.each { |c|
+          invoker_h(invoker(c), handler(c), visit_methods(c))
+        }
+      }
+    }
+
+    cpp_file(@filename) {
+      include @filename
+      @amqp.classes.each { |c|
+        visit_methods(c).each { |m|
+          include "qpid/framing/#{m.body_name}"
+        }}
+      namespace("qpid::framing") {
+        ops_visits_cpp
+        @amqp.classes.each { |c|
+          next if visit_methods(c).empty?
+          handler_visits_cpp(c)
+        }
+      }
+    }
+  end
+end
+
+OperationsInvokerGen.new("client",ARGV[0], Amqp).generate()
+OperationsInvokerGen.new("server",ARGV[0], Amqp).generate()

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

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

Modified: incubator/qpid/trunk/qpid/cpp/rubygen/templates/structs.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/templates/structs.rb?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/templates/structs.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/templates/structs.rb Tue Oct 16 12:07:54 2007
@@ -191,14 +191,20 @@
 
   def methodbody_extra_defs(s)
     gen <<EOS
+    typedef #{s.result ? s.result.struct.cpptype.name : 'void'} ResultType;
+
+    template <class T> ResultType invoke(T& invocable) const {
+        return invocable.#{s.cppname}(#{s.param_names.join ", "});
+    }
+
     using  AMQMethodBody::accept;
     void accept(MethodBodyConstVisitor& v) const { v.visit(*this); }
 
-    inline ClassId amqpClassId() const { return CLASS_ID; }
-    inline MethodId amqpMethodId() const { return METHOD_ID; }
-    inline bool isContentBearing() const { return  #{s.content ? "true" : "false" }; }
-    inline bool resultExpected() const { return  #{s.result ? "true" : "false"}; }
-    inline bool responseExpected() const { return  #{s.responses().empty? ? "false" : "true"};
}
+    ClassId amqpClassId() const { return CLASS_ID; }
+    MethodId amqpMethodId() const { return METHOD_ID; }
+    bool isContentBearing() const { return  #{s.content ? "true" : "false" }; }
+    bool resultExpected() const { return  #{s.result ? "true" : "false"}; }
+    bool responseExpected() const { return  #{s.responses().empty? ? "false" : "true"}; }
 EOS
   end
 

Modified: incubator/qpid/trunk/qpid/cpp/src/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/Makefile.am?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ incubator/qpid/trunk/qpid/cpp/src/Makefile.am Tue Oct 16 12:07:54 2007
@@ -341,6 +341,7 @@
   qpid/framing/HandlerUpdater.h \
   qpid/framing/HeaderProperties.h \
   qpid/framing/InitiationHandler.h \
+  qpid/framing/Invoker.h \
   qpid/framing/InputHandler.h \
   qpid/framing/MethodContent.h \
   qpid/framing/MethodHolder.h \

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp Tue Oct 16 12:07:54
2007
@@ -23,6 +23,7 @@
 #include "ConnectionHandler.h"
 #include "Connection.h"
 #include "qpid/framing/ConnectionStartBody.h"
+#include "qpid/framing/ServerInvoker.h"
 
 using namespace qpid;
 using namespace qpid::broker;
@@ -44,7 +45,7 @@
 {
     AMQMethodBody* method=frame.getBody()->getMethod();
     try{
-        if (!method->invoke(handler.get()))
+        if (!invoke(*handler.get(), *method))
             throw ConnectionException(503, "Class can't be accessed over channel 0");
     }catch(ConnectionException& e){
         handler->client.close(e.code, e.toString(), method->amqpClassId(), method->amqpMethodId());

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SemanticHandler.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SemanticHandler.cpp?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SemanticHandler.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SemanticHandler.cpp Tue Oct 16 12:07:54
2007
@@ -28,7 +28,7 @@
 #include "Connection.h"
 #include "qpid/framing/ExecutionCompleteBody.h"
 #include "qpid/framing/ExecutionResultBody.h"
-#include "qpid/framing/InvocationVisitor.h"
+#include "qpid/framing/ServerInvoker.h"
 
 #include <boost/format.hpp>
 #include <boost/bind.hpp>
@@ -121,14 +121,13 @@
 {
     SequenceNumber id = incoming.next();
     BrokerAdapter adapter(state);
-    InvocationVisitor v(&adapter);
-    method->accept(v);
+    Invoker::Result invoker = invoke(adapter, *method);
     incoming.complete(id);                                    
     
-    if (!v.wasHandled()) {
+    if (!invoker.wasHandled()) {
         throw ConnectionException(540, "Not implemented");
-    } else if (v.hasResult()) {
-        session.getProxy().getExecution().result(id.getValue(), v.getResult());
+    } else if (invoker.hasResult()) {
+        session.getProxy().getExecution().result(id.getValue(), invoker.getResult());
     }
     if (method->isSync()) { 
         incoming.sync(id); 
@@ -139,9 +138,8 @@
 
 void SemanticHandler::handleL3(framing::AMQMethodBody* method)
 {
-    if (!method->invoke(this)) {
+    if (!invoke(*this, *method))
         throw ConnectionException(540, "Not implemented");
-    }
 }
 
 void SemanticHandler::handleContent(AMQFrame& frame)

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SessionHandler.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SessionHandler.cpp?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SessionHandler.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SessionHandler.cpp Tue Oct 16 12:07:54 2007
@@ -23,6 +23,7 @@
 #include "Connection.h"
 #include "qpid/framing/reply_exceptions.h"
 #include "qpid/framing/constants.h"
+#include "qpid/framing/ServerInvoker.h"
 #include "qpid/log/Statement.h"
 
 namespace qpid {
@@ -48,10 +49,10 @@
     // state. This is a temporary state after we have sent a channel
     // exception, where extra frames might arrive that should be
     // ignored.
-    // 
-    AMQMethodBody* m=f.getMethod();
+    //
+    AMQMethodBody* m = f.getBody()->getMethod();
     try {
-        if (m && m->invoke(this))
+        if (m && invoke(*this, *m))
             return;
         else if (session.get())
             session->in(f);

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SessionHandler.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SessionHandler.h?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SessionHandler.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/SessionHandler.h Tue Oct 16 12:07:54 2007
@@ -41,7 +41,7 @@
  * association between the channel and a session.
  */
 class SessionHandler : public framing::FrameHandler::InOutHandler,
-                       private framing::AMQP_ServerOperations::SessionHandler,
+                       public framing::AMQP_ServerOperations::SessionHandler,
                        private boost::noncopyable
 {
   public:

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/client/ExecutionHandler.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/client/ExecutionHandler.cpp?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/client/ExecutionHandler.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/client/ExecutionHandler.cpp Tue Oct 16 12:07:54
2007
@@ -25,6 +25,7 @@
 #include "qpid/framing/MessageTransferBody.h"
 #include "qpid/framing/AMQP_HighestVersion.h"
 #include "qpid/framing/all_method_bodies.h"
+#include "qpid/framing/ServerInvoker.h"
 
 using namespace qpid::client;
 using namespace qpid::framing;
@@ -49,20 +50,13 @@
     return type == HEADER_BODY || type == CONTENT_BODY || isMessageMethod(body); 
 }
 
-bool invoke(AMQBody* body, Invocable* target)
-{
-    AMQMethodBody* method=body->getMethod();
-    return method && method->invoke(target);
-}
-
 ExecutionHandler::ExecutionHandler(uint64_t _maxFrameSize) : 
     version(framing::highestProtocolVersion), maxFrameSize(_maxFrameSize) {}
 
 //incoming:
 void ExecutionHandler::handle(AMQFrame& frame)
 {
-    AMQBody* body = frame.getBody();
-    if (!invoke(body, this)) {
+    if (!invoke(*this, *frame.getBody())) {
         if (!arriving) {
             arriving = FrameSet::shared_ptr(new FrameSet(++incomingCounter));
         }

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/client/ExecutionHandler.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/client/ExecutionHandler.h?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/client/ExecutionHandler.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/client/ExecutionHandler.h Tue Oct 16 12:07:54 2007
@@ -38,9 +38,9 @@
 namespace client {
 
 class ExecutionHandler : 
-    private framing::AMQP_ServerOperations::ExecutionHandler,
-    public framing::FrameHandler,
-    public Execution
+        public framing::AMQP_ServerOperations::ExecutionHandler,
+        public framing::FrameHandler,
+        public Execution
 {
     framing::SequenceNumber incomingCounter;
     framing::AccumulatedAck incomingCompletionStatus;

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQMethodBody.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQMethodBody.cpp?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQMethodBody.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQMethodBody.cpp Tue Oct 16 12:07:54 2007
@@ -19,25 +19,10 @@
  *
  */
 #include "AMQMethodBody.h"
-#include "qpid/framing/InvocationVisitor.h"
 
 namespace qpid {
 namespace framing {
 
 AMQMethodBody::~AMQMethodBody() {}
-
-void AMQMethodBody::invoke(AMQP_ServerOperations& ops) 
-{ 
-    InvocationVisitor v(&ops);
-    accept(v);
-    assert(v.wasHandled()); 
-}
-
-bool AMQMethodBody::invoke(Invocable* invocable) 
-{ 
-    InvocationVisitor v(invocable);
-    accept(v);
-    return v.wasHandled(); 
-}
 
 }} // namespace qpid::framing

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQMethodBody.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQMethodBody.h?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQMethodBody.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQMethodBody.h Tue Oct 16 12:07:54 2007
@@ -35,7 +35,6 @@
 
 class Buffer;
 class AMQP_ServerOperations;
-class Invocable;
 class MethodBodyConstVisitor;
 
 class AMQMethodBody : public AMQBody {
@@ -52,9 +51,6 @@
     virtual bool isContentBearing() const = 0;
     virtual bool resultExpected() const = 0;    
     virtual bool responseExpected() const = 0;    
-
-    void invoke(AMQP_ServerOperations&);
-    bool invoke(Invocable*);
 
     template <class T> bool isA() const {
         return amqpClassId()==T::CLASS_ID && amqpMethodId()==T::METHOD_ID;

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FrameDefaultVisitor.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FrameDefaultVisitor.h?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FrameDefaultVisitor.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FrameDefaultVisitor.h Tue Oct 16 12:07:54
2007
@@ -43,7 +43,8 @@
  * for any non-overridden visit functions.
  *
  */
-struct FrameDefaultVisitor : public AMQBodyConstVisitor, public MethodBodyDefaultVisitor
+struct FrameDefaultVisitor : public AMQBodyConstVisitor,
+                             protected MethodBodyDefaultVisitor
 {
     virtual void defaultVisit(const AMQBody&) = 0;
 

Added: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Invoker.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Invoker.h?rev=585223&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Invoker.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Invoker.h Tue Oct 16 12:07:54 2007
@@ -0,0 +1,86 @@
+#ifndef QPID_FRAMING_INVOKER_H
+#define QPID_FRAMING_INVOKER_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.
+ *
+ */
+#include "qpid/framing/AMQMethodBody.h"
+#include "qpid/framing/MethodBodyDefaultVisitor.h"
+#include "qpid/framing/StructHelper.h"
+
+#include <boost/optional.hpp>
+
+namespace qpid {
+namespace framing {
+
+class AMQMethodBody;
+
+/**
+ * Base class for invoker visitors.
+ */ 
+class Invoker: public MethodBodyDefaultVisitor, protected StructHelper
+{
+  public:
+    struct Result {
+      public:
+        Result() : handled(false) {}
+        const std::string& getResult() const { return result; }
+        const bool hasResult() const { return !result.empty(); }
+        bool wasHandled() const { return handled; }
+        operator bool() const { return handled; }
+
+        std::string result;
+        bool handled;
+    };
+
+    void defaultVisit(const AMQMethodBody&) {}
+    Result getResult() const { return result; }
+
+  protected:
+    Result result;
+};
+
+/**
+ * Invoke on an invocable object.
+ * Invocable classes must provide a nested type Invoker.
+ */
+template <class Invocable>
+Invoker::Result invoke(Invocable& target, const AMQMethodBody& body) {
+    typename Invocable::Invoker invoker(target);
+    body.accept(invoker);
+    return invoker.getResult();
+}
+
+/**
+ * Invoke on an invocable object.
+ * Invocable classes must provide a nested type Invoker.
+ */
+template <class Invocable>
+Invoker::Result invoke(Invocable& target, const AMQBody& body) {
+    typename Invocable::Invoker invoker(target);
+    const AMQMethodBody* method = body.getMethod();
+    if (method)
+        method->accept(invoker);
+    return invoker.getResult();
+}
+
+}} // namespace qpid::framing
+
+#endif  /*!QPID_FRAMING_INVOKER_H*/

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Invoker.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/Invoker.h
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/StructHelper.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/StructHelper.h?rev=585223&r1=585222&r2=585223&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/StructHelper.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/StructHelper.h Tue Oct 16 12:07:54 2007
@@ -35,21 +35,14 @@
 
     template <class T> void encode(const T t, std::string& data) {
         uint32_t size = t.size() + 2/*type*/;
-        char* bytes = static_cast<char*>(::alloca(size));
-        Buffer wbuffer(bytes, size);
+        data.resize(size);
+        Buffer wbuffer(const_cast<char*>(data.data()), size);
         wbuffer.putShort(T::TYPE);
         t.encode(wbuffer);
-        
-        Buffer rbuffer(bytes, size);
-        rbuffer.getRawData(data, size);        
     }
 
     template <class T> void decode(T& t, const std::string& data) {
-        char* bytes = static_cast<char*>(::alloca(data.length()));
-        Buffer wbuffer(bytes, data.length());
-        wbuffer.putRawData(data);        
-
-        Buffer rbuffer(bytes, data.length());
+        Buffer rbuffer(const_cast<char*>(data.data()), data.length());
         uint16_t type = rbuffer.getShort();
         if (type == T::TYPE) {
             t.decode(rbuffer);



Mime
View raw message