summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/framing
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/qpid/framing')
-rw-r--r--cpp/src/qpid/framing/AMQMethodBody.cpp15
-rw-r--r--cpp/src/qpid/framing/AMQMethodBody.h4
-rw-r--r--cpp/src/qpid/framing/FrameDefaultVisitor.h3
-rw-r--r--cpp/src/qpid/framing/Invoker.h86
-rw-r--r--cpp/src/qpid/framing/StructHelper.h13
5 files changed, 91 insertions, 30 deletions
diff --git a/cpp/src/qpid/framing/AMQMethodBody.cpp b/cpp/src/qpid/framing/AMQMethodBody.cpp
index 48b50763fc..924d906d43 100644
--- a/cpp/src/qpid/framing/AMQMethodBody.cpp
+++ b/cpp/src/qpid/framing/AMQMethodBody.cpp
@@ -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
diff --git a/cpp/src/qpid/framing/AMQMethodBody.h b/cpp/src/qpid/framing/AMQMethodBody.h
index 09a5ea4f00..9f64fd1690 100644
--- a/cpp/src/qpid/framing/AMQMethodBody.h
+++ b/cpp/src/qpid/framing/AMQMethodBody.h
@@ -35,7 +35,6 @@ namespace framing {
class Buffer;
class AMQP_ServerOperations;
-class Invocable;
class MethodBodyConstVisitor;
class AMQMethodBody : public AMQBody {
@@ -53,9 +52,6 @@ class AMQMethodBody : public AMQBody {
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;
}
diff --git a/cpp/src/qpid/framing/FrameDefaultVisitor.h b/cpp/src/qpid/framing/FrameDefaultVisitor.h
index a826d69b3d..93a5204308 100644
--- a/cpp/src/qpid/framing/FrameDefaultVisitor.h
+++ b/cpp/src/qpid/framing/FrameDefaultVisitor.h
@@ -43,7 +43,8 @@ class AMQHeartbeatBody;
* for any non-overridden visit functions.
*
*/
-struct FrameDefaultVisitor : public AMQBodyConstVisitor, public MethodBodyDefaultVisitor
+struct FrameDefaultVisitor : public AMQBodyConstVisitor,
+ protected MethodBodyDefaultVisitor
{
virtual void defaultVisit(const AMQBody&) = 0;
diff --git a/cpp/src/qpid/framing/Invoker.h b/cpp/src/qpid/framing/Invoker.h
new file mode 100644
index 0000000000..e6467ab3c4
--- /dev/null
+++ b/cpp/src/qpid/framing/Invoker.h
@@ -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*/
diff --git a/cpp/src/qpid/framing/StructHelper.h b/cpp/src/qpid/framing/StructHelper.h
index 6b111e1f9e..7fc1d2e22b 100644
--- a/cpp/src/qpid/framing/StructHelper.h
+++ b/cpp/src/qpid/framing/StructHelper.h
@@ -35,21 +35,14 @@ public:
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);