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 [EMAIL PROTECTED]
+
#{handlerclass}(){};
virtual ~#{handlerclass}() {}
// Protocol methods
@@ -64,16 +66,10 @@
class AMQMethodBody;
-class Invocable
-{
-protected:
- Invocable() {}
- virtual ~Invocable() {}
-};
-
class [EMAIL PROTECTED] {
-
public:
+ class Invoker; // Declared in [EMAIL PROTECTED]
+
virtual [EMAIL PROTECTED]() {}
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="[EMAIL PROTECTED]"
+ @classname="[EMAIL PROTECTED]::Invoker"
+ @filename="qpid/framing/[EMAIL PROTECTED]"
+ end
+
+ def handler(c) "[EMAIL PROTECTED]::#{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 [EMAIL PROTECTED]::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/[EMAIL PROTECTED]"
+ include "qpid/framing/Invoker.h"
+ namespace("qpid::framing") {
+ # AMQP_*Operations invoker.
+ [EMAIL PROTECTED] { |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);