You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2009/05/22 23:40:58 UTC
svn commit: r777720 [2/2] - in /qpid/trunk/qpid/cpp/src: ./ qmf/
Added: qpid/trunk/qpid/cpp/src/qmf/ResilientConnection.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/ResilientConnection.cpp?rev=777720&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/ResilientConnection.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qmf/ResilientConnection.cpp Fri May 22 21:40:57 2009
@@ -0,0 +1,460 @@
+/*
+ * 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 "ResilientConnection.h"
+#include "MessageImpl.h"
+#include <qpid/client/Session.h>
+#include <qpid/client/MessageListener.h>
+#include <qpid/client/SubscriptionManager.h>
+#include <qpid/client/Message.h>
+#include <qpid/sys/Thread.h>
+#include <qpid/sys/Runnable.h>
+#include <qpid/sys/Mutex.h>
+#include <qpid/sys/Condition.h>
+#include <qpid/log/Statement.h>
+#include <qpid/RefCounted.h>
+#include <boost/bind.hpp>
+#include <string>
+#include <deque>
+#include <vector>
+#include <set>
+#include <boost/intrusive_ptr.hpp>
+
+using namespace std;
+using namespace qmf;
+using namespace qpid::client;
+using qpid::sys::Mutex;
+
+namespace qmf {
+ struct ResilientConnectionEventImpl {
+ ResilientConnectionEvent::EventKind kind;
+ void* sessionContext;
+ string errorText;
+ MessageImpl message;
+
+ ResilientConnectionEventImpl(ResilientConnectionEvent::EventKind k,
+ const MessageImpl& m = MessageImpl()) :
+ kind(k), sessionContext(0), message(m) {}
+ ResilientConnectionEvent copy();
+ };
+
+ struct RCSession : public MessageListener, public qpid::sys::Runnable, public qpid::RefCounted {
+ typedef boost::intrusive_ptr<RCSession> Ptr;
+ ResilientConnectionImpl& connImpl;
+ string name;
+ Connection& connection;
+ Session session;
+ SubscriptionManager* subscriptions;
+ void* userContext;
+ vector<string> dests;
+ qpid::sys::Thread thread;
+
+ RCSession(ResilientConnectionImpl& ci, const string& n, Connection& c, void* uc) :
+ connImpl(ci), name(n), connection(c), session(connection.newSession(name)),
+ subscriptions(new SubscriptionManager(session)), userContext(uc), thread(*this) {}
+ ~RCSession();
+ void received(qpid::client::Message& msg);
+ void run();
+ void stop();
+ };
+
+ class ResilientConnectionImpl : public qpid::sys::Runnable {
+ public:
+ ResilientConnectionImpl(ConnectionSettings& settings,
+ int dmin, int dmax, int dfactor);
+ ~ResilientConnectionImpl();
+
+ bool isConnected() const;
+ bool getEvent(ResilientConnectionEvent& event);
+ void popEvent();
+ bool createSession(const char* name, void* sessionContext, SessionHandle& handle);
+ void destroySession(SessionHandle handle);
+ void sendMessage(SessionHandle handle, qmf::Message& message);
+ void declareQueue(SessionHandle handle, char* queue);
+ void deleteQueue(SessionHandle handle, char* queue);
+ void bind(SessionHandle handle, char* exchange, char* queue, char* key);
+ void unbind(SessionHandle handle, char* exchange, char* queue, char* key);
+ void setNotifyFd(int fd);
+
+ void run();
+ void failure();
+ void sessionClosed(RCSession* sess);
+
+ void EnqueueEvent(ResilientConnectionEvent::EventKind kind,
+ void* sessionContext = 0,
+ const MessageImpl& message = MessageImpl(),
+ const string& errorText = "");
+
+ private:
+ int notifyFd;
+ bool connected;
+ bool shutdown;
+ string lastError;
+ ConnectionSettings settings;
+ Connection connection;
+ mutable qpid::sys::Mutex lock;
+ int delayMin;
+ int delayMax;
+ int delayFactor;
+ qpid::sys::Condition cond;
+ qpid::sys::Thread connThread;
+ deque<ResilientConnectionEventImpl> eventQueue;
+ set<RCSession::Ptr> sessions;
+ };
+}
+
+ResilientConnectionEvent ResilientConnectionEventImpl::copy()
+{
+ ResilientConnectionEvent item;
+
+ ::memset(&item, 0, sizeof(ResilientConnectionEvent));
+ item.kind = kind;
+ item.sessionContext = sessionContext;
+ item.message = message.copy();
+ item.errorText = const_cast<char*>(errorText.c_str());
+
+ return item;
+}
+
+RCSession::~RCSession()
+{
+ subscriptions->stop();
+ thread.join();
+ session.close();
+ delete subscriptions;
+}
+
+void RCSession::run()
+{
+ try {
+ subscriptions->run();
+ } catch (exception& e) {
+ connImpl.sessionClosed(this);
+ }
+}
+
+void RCSession::stop()
+{
+ subscriptions->stop();
+}
+
+void RCSession::received(qpid::client::Message& msg)
+{
+ qmf::MessageImpl qmsg;
+ qmsg.body = msg.getData();
+
+ qpid::framing::MessageProperties p = msg.getMessageProperties();
+ if (p.hasReplyTo()) {
+ const qpid::framing::ReplyTo& rt = p.getReplyTo();
+ qmsg.replyExchange = rt.getExchange();
+ qmsg.replyKey = rt.getRoutingKey();
+ }
+
+ if (p.hasUserId()) {
+ qmsg.userId = p.getUserId();
+ }
+
+ connImpl.EnqueueEvent(ResilientConnectionEvent::RECV, userContext, qmsg);
+}
+
+ResilientConnectionImpl::ResilientConnectionImpl(ConnectionSettings& _settings,
+ int dmin, int dmax, int dfactor) :
+ notifyFd(-1), connected(false), shutdown(false), settings(_settings),
+ delayMin(dmin), delayMax(dmax), delayFactor(dfactor), connThread(*this)
+{
+ connection.registerFailureCallback(boost::bind(&ResilientConnectionImpl::failure, this));
+}
+
+ResilientConnectionImpl::~ResilientConnectionImpl()
+{
+ shutdown = true;
+ connected = false;
+ cond.notify();
+ connThread.join();
+ connection.close();
+}
+
+bool ResilientConnectionImpl::isConnected() const
+{
+ Mutex::ScopedLock _lock(lock);
+ return connected;
+}
+
+bool ResilientConnectionImpl::getEvent(ResilientConnectionEvent& event)
+{
+ Mutex::ScopedLock _lock(lock);
+ if (eventQueue.empty())
+ return false;
+ event = eventQueue.front().copy();
+ return true;
+}
+
+void ResilientConnectionImpl::popEvent()
+{
+ Mutex::ScopedLock _lock(lock);
+ if (!eventQueue.empty())
+ eventQueue.pop_front();
+}
+
+bool ResilientConnectionImpl::createSession(const char* name, void* sessionContext,
+ SessionHandle& handle)
+{
+ Mutex::ScopedLock _lock(lock);
+ if (!connected)
+ return false;
+
+ RCSession::Ptr sess = RCSession::Ptr(new RCSession(*this, name, connection, sessionContext));
+
+ handle.handle = (void*) sess.get();
+ sessions.insert(sess);
+
+ return true;
+}
+
+void ResilientConnectionImpl::destroySession(SessionHandle handle)
+{
+ Mutex::ScopedLock _lock(lock);
+ RCSession::Ptr sess = RCSession::Ptr((RCSession*) handle.handle);
+ set<RCSession::Ptr>::iterator iter = sessions.find(sess);
+ if (iter != sessions.end()) {
+ for (vector<string>::iterator dIter = sess->dests.begin(); dIter != sess->dests.end(); dIter++)
+ sess->subscriptions->cancel(dIter->c_str());
+ sess->subscriptions->stop();
+ sess->subscriptions->wait();
+
+ sessions.erase(iter);
+ return;
+ }
+}
+
+void ResilientConnectionImpl::sendMessage(SessionHandle handle, qmf::Message& message)
+{
+ Mutex::ScopedLock _lock(lock);
+ RCSession::Ptr sess = RCSession::Ptr((RCSession*) handle.handle);
+ set<RCSession::Ptr>::iterator iter = sessions.find(sess);
+ qpid::client::Message msg;
+ string data(message.body, message.length);
+ msg.getDeliveryProperties().setRoutingKey(message.routingKey);
+ msg.getMessageProperties().setReplyTo(qpid::framing::ReplyTo(message.replyExchange, message.replyKey));
+ msg.setData(data);
+
+ try {
+ sess->session.messageTransfer(arg::content=msg, arg::destination=message.destination);
+ } catch(exception& e) {
+ QPID_LOG(error, "Session Exception during message-transfer: " << e.what());
+ sessions.erase(iter);
+ EnqueueEvent(ResilientConnectionEvent::SESSION_CLOSED, (*iter)->userContext);
+ }
+}
+
+void ResilientConnectionImpl::declareQueue(SessionHandle handle, char* queue)
+{
+ Mutex::ScopedLock _lock(lock);
+ RCSession* sess = (RCSession*) handle.handle;
+
+ sess->session.queueDeclare(arg::queue=queue, arg::autoDelete=true, arg::exclusive=true);
+ sess->subscriptions->subscribe(*sess, queue, queue);
+ sess->dests.push_back(string(queue));
+}
+
+void ResilientConnectionImpl::deleteQueue(SessionHandle handle, char* queue)
+{
+ Mutex::ScopedLock _lock(lock);
+ RCSession* sess = (RCSession*) handle.handle;
+
+ sess->session.queueDelete(arg::queue=queue);
+ for (vector<string>::iterator iter = sess->dests.begin();
+ iter != sess->dests.end(); iter++)
+ if (*iter == queue) {
+ sess->subscriptions->cancel(queue);
+ sess->dests.erase(iter);
+ break;
+ }
+}
+
+void ResilientConnectionImpl::bind(SessionHandle handle,
+ char* exchange, char* queue, char* key)
+{
+ Mutex::ScopedLock _lock(lock);
+ RCSession* sess = (RCSession*) handle.handle;
+
+ sess->session.exchangeBind(arg::exchange=exchange, arg::queue=queue, arg::bindingKey=key);
+}
+
+void ResilientConnectionImpl::unbind(SessionHandle handle,
+ char* exchange, char* queue, char* key)
+{
+ Mutex::ScopedLock _lock(lock);
+ RCSession* sess = (RCSession*) handle.handle;
+
+ sess->session.exchangeUnbind(arg::exchange=exchange, arg::queue=queue, arg::bindingKey=key);
+}
+
+void ResilientConnectionImpl::setNotifyFd(int fd)
+{
+ notifyFd = fd;
+}
+
+void ResilientConnectionImpl::run()
+{
+ int delay(delayMin);
+
+ while (true) {
+ try {
+ connection.open(settings);
+ {
+ Mutex::ScopedLock _lock(lock);
+ connected = true;
+ EnqueueEvent(ResilientConnectionEvent::CONNECTED);
+
+ while (connected)
+ cond.wait(lock);
+
+ while (!sessions.empty()) {
+ set<RCSession::Ptr>::iterator iter = sessions.begin();
+ RCSession::Ptr sess = *iter;
+ sessions.erase(iter);
+ EnqueueEvent(ResilientConnectionEvent::SESSION_CLOSED, sess->userContext);
+ Mutex::ScopedUnlock _u(lock);
+ sess->stop();
+ }
+
+ EnqueueEvent(ResilientConnectionEvent::DISCONNECTED);
+
+ if (shutdown)
+ return;
+ }
+ delay = delayMin;
+ connection.close();
+ } catch (exception &e) {
+ QPID_LOG(debug, "connection.open exception: " << e.what());
+ Mutex::ScopedLock _lock(lock);
+ lastError = e.what();
+ if (delay < delayMax)
+ delay *= delayFactor;
+ }
+
+ ::sleep(delay);
+ }
+}
+
+void ResilientConnectionImpl::failure()
+{
+ Mutex::ScopedLock _lock(lock);
+
+ connected = false;
+ lastError = "Closed by Peer";
+ cond.notify();
+}
+
+void ResilientConnectionImpl::sessionClosed(RCSession*)
+{
+ Mutex::ScopedLock _lock(lock);
+ connected = false;
+ lastError = "Closed due to Session failure";
+ cond.notify();
+}
+
+void ResilientConnectionImpl::EnqueueEvent(ResilientConnectionEvent::EventKind kind,
+ void* sessionContext,
+ const MessageImpl& message,
+ const string& errorText)
+{
+ Mutex::ScopedLock _lock(lock);
+ ResilientConnectionEventImpl event(kind, message);
+
+ event.sessionContext = sessionContext;
+ event.errorText = errorText;
+
+ eventQueue.push_back(event);
+ if (notifyFd != -1)
+ ::write(notifyFd, ".", 1);
+}
+
+
+//==================================================================
+// Wrappers
+//==================================================================
+
+ResilientConnection::ResilientConnection(ConnectionSettings& settings,
+ int delayMin, int delayMax, int delayFactor)
+{
+ impl = new ResilientConnectionImpl(settings, delayMin, delayMax, delayFactor);
+}
+
+ResilientConnection::~ResilientConnection()
+{
+ delete impl;
+}
+
+bool ResilientConnection::isConnected() const
+{
+ return impl->isConnected();
+}
+
+bool ResilientConnection::getEvent(ResilientConnectionEvent& event)
+{
+ return impl->getEvent(event);
+}
+
+void ResilientConnection::popEvent()
+{
+ impl->popEvent();
+}
+
+bool ResilientConnection::createSession(const char* name, void* sessionContext, SessionHandle& handle)
+{
+ return impl->createSession(name, sessionContext, handle);
+}
+
+void ResilientConnection::destroySession(SessionHandle handle)
+{
+ impl->destroySession(handle);
+}
+
+void ResilientConnection::sendMessage(SessionHandle handle, qmf::Message& message)
+{
+ impl->sendMessage(handle, message);
+}
+
+void ResilientConnection::declareQueue(SessionHandle handle, char* queue)
+{
+ impl->declareQueue(handle, queue);
+}
+
+void ResilientConnection::deleteQueue(SessionHandle handle, char* queue)
+{
+ impl->deleteQueue(handle, queue);
+}
+
+void ResilientConnection::bind(SessionHandle handle, char* exchange, char* queue, char* key)
+{
+ impl->bind(handle, exchange, queue, key);
+}
+
+void ResilientConnection::unbind(SessionHandle handle, char* exchange, char* queue, char* key)
+{
+ impl->unbind(handle, exchange, queue, key);
+}
+
+void ResilientConnection::setNotifyFd(int fd)
+{
+ impl->setNotifyFd(fd);
+}
+
Added: qpid/trunk/qpid/cpp/src/qmf/ResilientConnection.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/ResilientConnection.h?rev=777720&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/ResilientConnection.h (added)
+++ qpid/trunk/qpid/cpp/src/qmf/ResilientConnection.h Fri May 22 21:40:57 2009
@@ -0,0 +1,166 @@
+#ifndef _QmfResilientConnection_
+#define _QmfResilientConnection_
+
+/*
+ * 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 <qmf/Message.h>
+#include <qpid/client/Connection.h>
+#include <qpid/client/ConnectionSettings.h>
+#include <string>
+
+namespace qmf {
+
+ /**
+ * Represents events that occur, unsolicited, from ResilientConnection.
+ */
+ struct ResilientConnectionEvent {
+ enum EventKind {
+ CONNECTED = 1,
+ DISCONNECTED = 2,
+ SESSION_CLOSED = 3,
+ RECV = 4
+ };
+
+ EventKind kind;
+ void* sessionContext; // SESSION_CLOSED, RECV
+ char* errorText; // DISCONNECTED, SESSION_CLOSED
+ Message message; // RECV
+ };
+
+ struct SessionHandle {
+ void* handle;
+ };
+
+ class ResilientConnectionImpl;
+
+ /**
+ * ResilientConnection represents a Qpid connection that is resilient.
+ *
+ * Upon creation, ResilientConnection attempts to establish a connection to the
+ * messaging broker. If it fails, it will continue to retry at an interval that
+ * increases over time (to a maximum interval). If an extablished connection is
+ * dropped, a reconnect will be attempted.
+ */
+ class ResilientConnection {
+ public:
+
+ /**
+ * Create a new resilient connection.
+ *@param settings Settings that define how the connection is to be made.
+ *@param delayMin Minimum delay (in seconds) between retries.
+ *@param delayMax Maximum delay (in seconds) between retries.
+ *@param delayFactor Factor to multiply retry delay by after each failure.
+ */
+ ResilientConnection(qpid::client::ConnectionSettings& settings,
+ int delayMin = 1,
+ int delayMax = 128,
+ int delayFactor = 2);
+ ~ResilientConnection();
+
+ /**
+ * Get the connected status of the resilient connection.
+ *@return true iff the connection is established.
+ */
+ bool isConnected() const;
+
+ /**
+ * Get the next event (if present) from the connection.
+ *@param event Returned event if one is available.
+ *@return true if event is valid, false if there are no more events to handle.
+ */
+ bool getEvent(ResilientConnectionEvent& event);
+
+ /**
+ * Discard the event on the front of the queue. This should be invoked after processing
+ * the event from getEvent.
+ */
+ void popEvent();
+
+ /**
+ * Create a new AMQP session.
+ *@param name Unique name for the session.
+ *@param sessionContext Optional user-context value that will be provided in events
+ * pertaining to this session.
+ *@param handle Output handle to be stored and used in subsequent calls pertaining to
+ * this session.
+ *@return true iff the session was successfully created.
+ */
+ bool createSession(const char* name, void* sessionContext, SessionHandle& handle);
+
+ /**
+ * Destroy a created session.
+ *@param handle SessionHandle returned by createSession.
+ */
+ void destroySession(SessionHandle handle);
+
+ /**
+ * Send a message into the AMQP broker via a session.
+ *@param handle The session handle of the session to transmit through.
+ *@param message The QMF message to transmit.
+ */
+ void sendMessage(SessionHandle handle, Message& message);
+
+ /**
+ * Declare an exclusive, auto-delete queue for a session.
+ *@param handle The session handle for the owner of the queue.
+ *@param queue The name of the queue.
+ */
+ void declareQueue(SessionHandle handle, char* queue);
+
+ /**
+ * Delete a queue.
+ *@param handle The session handle for the owner of the queue.
+ *@param queue The name of the queue.
+ */
+ void deleteQueue(SessionHandle handle, char* queue);
+
+ /**
+ * Bind a queue to an exchange.
+ *@param handle The session handle of the session to use for binding.
+ *@param exchange The name of the exchange for binding.
+ *@param queue The name of the queue for binding.
+ *@param key The binding key.
+ */
+ void bind(SessionHandle handle, char* exchange, char* queue, char* key);
+
+ /**
+ * Remove a binding.
+ *@param handle The session handle of the session to use for un-binding.
+ *@param exchange The name of the exchange.
+ *@param queue The name of the queue.
+ *@param key The binding key.
+ */
+ void unbind(SessionHandle handle, char* exchange, char* queue, char* key);
+
+ /**
+ * Establish a file descriptor for event notification.
+ *@param fd A file descriptor into which the connection shall write a character each
+ * time an event is enqueued. This fd may be in a pair, the other fd of which
+ * is used in a select loop to control execution.
+ */
+ void setNotifyFd(int fd);
+
+ private:
+ ResilientConnectionImpl* impl;
+ };
+}
+
+#endif
+
Added: qpid/trunk/qpid/cpp/src/qmf/Schema.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/Schema.h?rev=777720&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/Schema.h (added)
+++ qpid/trunk/qpid/cpp/src/qmf/Schema.h Fri May 22 21:40:57 2009
@@ -0,0 +1,160 @@
+#ifndef _QmfSchema_
+#define _QmfSchema_
+
+/*
+ * 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 <qmf/Typecode.h>
+#include <stdint.h>
+
+namespace qmf {
+
+ enum Access { ACCESS_READ_CREATE = 1, ACCESS_READ_WRITE = 2, ACCESS_READ_ONLY = 3 };
+ enum Direction { DIR_IN = 1, DIR_OUT = 2, DIR_IN_OUT = 3 };
+ enum ClassKind { CLASS_OBJECT = 1, CLASS_EVENT = 2 };
+
+ class SchemaArgumentImpl;
+ class SchemaMethodImpl;
+ class SchemaPropertyImpl;
+ class SchemaStatisticImpl;
+ class SchemaObjectClassImpl;
+ class SchemaEventClassImpl;
+
+ /**
+ */
+ class SchemaArgument {
+ public:
+ SchemaArgument(const char* name, Typecode typecode);
+ SchemaArgument(SchemaArgumentImpl* impl);
+ ~SchemaArgument();
+ void setDirection(Direction dir);
+ void setUnit(const char* val);
+ void setDesc(const char* desc);
+ const char* getName() const;
+ Typecode getType() const;
+ Direction getDirection() const;
+ const char* getUnit() const;
+ const char* getDesc() const;
+
+ SchemaArgumentImpl* impl;
+ };
+
+ /**
+ */
+ class SchemaMethod {
+ public:
+ SchemaMethod(const char* name);
+ SchemaMethod(SchemaMethodImpl* impl);
+ ~SchemaMethod();
+ void addArgument(const SchemaArgument& argument);
+ void setDesc(const char* desc);
+ const char* getName() const;
+ const char* getDesc() const;
+ int getArgumentCount() const;
+ const SchemaArgument* getArgument(int idx) const;
+
+ SchemaMethodImpl* impl;
+ };
+
+ /**
+ */
+ class SchemaProperty {
+ public:
+ SchemaProperty(const char* name, Typecode typecode);
+ SchemaProperty(SchemaPropertyImpl* impl);
+ ~SchemaProperty();
+ void setAccess(Access access);
+ void setIndex(bool val);
+ void setOptional(bool val);
+ void setUnit(const char* val);
+ void setDesc(const char* desc);
+ const char* getName() const;
+ Typecode getType() const;
+ Access getAccess() const;
+ bool isIndex() const;
+ bool isOptional() const;
+ const char* getUnit() const;
+ const char* getDesc() const;
+
+ SchemaPropertyImpl* impl;
+ };
+
+ /**
+ */
+ class SchemaStatistic {
+ public:
+ SchemaStatistic(const char* name, Typecode typecode);
+ SchemaStatistic(SchemaStatisticImpl* impl);
+ ~SchemaStatistic();
+ void setUnit(const char* val);
+ void setDesc(const char* desc);
+ const char* getName() const;
+ Typecode getType() const;
+ const char* getUnit() const;
+ const char* getDesc() const;
+
+ SchemaStatisticImpl* impl;
+ };
+
+ /**
+ */
+ class SchemaObjectClass {
+ public:
+ SchemaObjectClass(const char* package, const char* name);
+ SchemaObjectClass(SchemaObjectClassImpl* impl);
+ ~SchemaObjectClass();
+ void addProperty(const SchemaProperty& property);
+ void addStatistic(const SchemaStatistic& statistic);
+ void addMethod(const SchemaMethod& method);
+
+ const char* getPackage() const;
+ const char* getName() const;
+ const uint8_t* getHash() const;
+ int getPropertyCount() const;
+ int getStatisticCount() const;
+ int getMethodCount() const;
+ const SchemaProperty* getProperty(int idx) const;
+ const SchemaStatistic* getStatistic(int idx) const;
+ const SchemaMethod* getMethod(int idx) const;
+
+ SchemaObjectClassImpl* impl;
+ };
+
+ /**
+ */
+ class SchemaEventClass {
+ public:
+ SchemaEventClass(const char* package, const char* name);
+ SchemaEventClass(SchemaEventClassImpl* impl);
+ ~SchemaEventClass();
+ void addArgument(const SchemaArgument& argument);
+ void setDesc(const char* desc);
+
+ const char* getPackage() const;
+ const char* getName() const;
+ const uint8_t* getHash() const;
+ int getArgumentCount() const;
+ const SchemaArgument* getArgument(int idx) const;
+
+ SchemaEventClassImpl* impl;
+ };
+}
+
+#endif
+
Added: qpid/trunk/qpid/cpp/src/qmf/SchemaImpl.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/SchemaImpl.cpp?rev=777720&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/SchemaImpl.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qmf/SchemaImpl.cpp Fri May 22 21:40:57 2009
@@ -0,0 +1,740 @@
+/*
+ * 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 "SchemaImpl.h"
+#include <qpid/framing/Buffer.h>
+#include <qpid/framing/FieldTable.h>
+#include <string>
+#include <vector>
+
+using namespace std;
+using namespace qmf;
+using qpid::framing::Buffer;
+using qpid::framing::FieldTable;
+
+SchemaHash::SchemaHash()
+{
+ for (int idx = 0; idx < 16; idx++)
+ hash[idx] = 0x5A;
+}
+
+void SchemaHash::encode(Buffer& buffer)
+{
+ buffer.putBin128(hash);
+}
+
+void SchemaHash::decode(Buffer& buffer)
+{
+ buffer.getBin128(hash);
+}
+
+void SchemaHash::update(uint8_t data)
+{
+ update((char*) &data, 1);
+}
+
+void SchemaHash::update(const char* data, uint32_t len)
+{
+ uint64_t* first = (uint64_t*) hash;
+ uint64_t* second = (uint64_t*) hash + 1;
+
+ for (uint32_t idx = 0; idx < len; idx++) {
+ *first = *first ^ (uint64_t) data[idx];
+ *second = *second << 1;
+ *second |= ((*first & 0x8000000000000000LL) >> 63);
+ *first = *first << 1;
+ *first = *first ^ *second;
+ }
+}
+
+SchemaArgumentImpl::SchemaArgumentImpl(Buffer& buffer) : envelope(new SchemaArgument(this))
+{
+ FieldTable map;
+ map.decode(buffer);
+
+ name = map.getAsString("name");
+ typecode = (Typecode) map.getAsInt("type");
+ unit = map.getAsString("unit");
+ description = map.getAsString("desc");
+
+ dir = DIR_IN;
+ string dstr(map.getAsString("dir"));
+ if (dstr == "O")
+ dir = DIR_OUT;
+ else if (dstr == "IO")
+ dir = DIR_IN_OUT;
+}
+
+void SchemaArgumentImpl::encode(Buffer& buffer) const
+{
+ FieldTable map;
+
+ map.setString("name", name);
+ map.setInt("type", (int) typecode);
+ if (dir == DIR_IN)
+ map.setString("dir", "I");
+ else if (dir == DIR_OUT)
+ map.setString("dir", "O");
+ else
+ map.setString("dir", "IO");
+ if (!unit.empty())
+ map.setString("unit", unit);
+ if (!description.empty())
+ map.setString("desc", description);
+
+ map.encode(buffer);
+}
+
+void SchemaArgumentImpl::updateHash(SchemaHash& hash) const
+{
+ hash.update(name);
+ hash.update(typecode);
+ hash.update(dir);
+ hash.update(unit);
+ hash.update(description);
+}
+
+SchemaMethodImpl::SchemaMethodImpl(Buffer& buffer) : envelope(new SchemaMethod(this))
+{
+ FieldTable map;
+ int argCount;
+
+ map.decode(buffer);
+ name = map.getAsString("name");
+ argCount = map.getAsInt("argCount");
+ description = map.getAsString("desc");
+
+ for (int idx = 0; idx < argCount; idx++) {
+ SchemaArgumentImpl* arg = new SchemaArgumentImpl(buffer);
+ addArgument(*arg->envelope);
+ }
+}
+
+void SchemaMethodImpl::encode(Buffer& buffer) const
+{
+ FieldTable map;
+
+ map.setString("name", name);
+ map.setInt("argCount", arguments.size());
+ if (!description.empty())
+ map.setString("desc", description);
+ map.encode(buffer);
+
+ for (vector<SchemaArgumentImpl*>::const_iterator iter = arguments.begin();
+ iter != arguments.end(); iter++)
+ (*iter)->encode(buffer);
+}
+
+void SchemaMethodImpl::addArgument(const SchemaArgument& argument)
+{
+ arguments.push_back(argument.impl);
+}
+
+const SchemaArgument* SchemaMethodImpl::getArgument(int idx) const
+{
+ int count = 0;
+ for (vector<SchemaArgumentImpl*>::const_iterator iter = arguments.begin();
+ iter != arguments.end(); iter++, count++)
+ if (idx == count)
+ return (*iter)->envelope;
+ return 0;
+}
+
+void SchemaMethodImpl::updateHash(SchemaHash& hash) const
+{
+ hash.update(name);
+ hash.update(description);
+ for (vector<SchemaArgumentImpl*>::const_iterator iter = arguments.begin();
+ iter != arguments.end(); iter++)
+ (*iter)->updateHash(hash);
+}
+
+SchemaPropertyImpl::SchemaPropertyImpl(Buffer& buffer) : envelope(new SchemaProperty(this))
+{
+ FieldTable map;
+ map.decode(buffer);
+
+ name = map.getAsString("name");
+ typecode = (Typecode) map.getAsInt("type");
+ access = (Access) map.getAsInt("access");
+ index = map.getAsInt("index") != 0;
+ optional = map.getAsInt("optional") != 0;
+ unit = map.getAsString("unit");
+ description = map.getAsString("desc");
+}
+
+void SchemaPropertyImpl::encode(Buffer& buffer) const
+{
+ FieldTable map;
+
+ map.setString("name", name);
+ map.setInt("type", (int) typecode);
+ map.setInt("access", (int) access);
+ map.setInt("index", index ? 1 : 0);
+ map.setInt("optional", optional ? 1 : 0);
+ if (!unit.empty())
+ map.setString("unit", unit);
+ if (!description.empty())
+ map.setString("desc", description);
+
+ map.encode(buffer);
+}
+
+void SchemaPropertyImpl::updateHash(SchemaHash& hash) const
+{
+ hash.update(name);
+ hash.update(typecode);
+ hash.update(access);
+ hash.update(index);
+ hash.update(optional);
+ hash.update(unit);
+ hash.update(description);
+}
+
+SchemaStatisticImpl::SchemaStatisticImpl(Buffer& buffer) : envelope(new SchemaStatistic(this))
+{
+ FieldTable map;
+ map.decode(buffer);
+
+ name = map.getAsString("name");
+ typecode = (Typecode) map.getAsInt("type");
+ unit = map.getAsString("unit");
+ description = map.getAsString("desc");
+}
+
+void SchemaStatisticImpl::encode(Buffer& buffer) const
+{
+ FieldTable map;
+
+ map.setString("name", name);
+ map.setInt("type", (int) typecode);
+ if (!unit.empty())
+ map.setString("unit", unit);
+ if (!description.empty())
+ map.setString("desc", description);
+
+ map.encode(buffer);
+}
+
+void SchemaStatisticImpl::updateHash(SchemaHash& hash) const
+{
+ hash.update(name);
+ hash.update(typecode);
+ hash.update(unit);
+ hash.update(description);
+}
+
+SchemaObjectClassImpl::SchemaObjectClassImpl(Buffer& buffer) : envelope(new SchemaObjectClass(this)), hasHash(true)
+{
+ buffer.getShortString(package);
+ buffer.getShortString(name);
+ hash.decode(buffer);
+
+ uint16_t propCount = buffer.getShort();
+ uint16_t statCount = buffer.getShort();
+ uint16_t methodCount = buffer.getShort();
+
+ for (uint16_t idx = 0; idx < propCount; idx++) {
+ SchemaPropertyImpl* property = new SchemaPropertyImpl(buffer);
+ addProperty(*property->envelope);
+ }
+
+ for (uint16_t idx = 0; idx < statCount; idx++) {
+ SchemaStatisticImpl* statistic = new SchemaStatisticImpl(buffer);
+ addStatistic(*statistic->envelope);
+ }
+
+ for (uint16_t idx = 0; idx < methodCount; idx++) {
+ SchemaMethodImpl* method = new SchemaMethodImpl(buffer);
+ addMethod(*method->envelope);
+ }
+}
+
+void SchemaObjectClassImpl::encode(Buffer& buffer) const
+{
+ buffer.putOctet((uint8_t) CLASS_OBJECT);
+ buffer.putShortString(package);
+ buffer.putShortString(name);
+ hash.encode(buffer);
+ buffer.putShort((uint16_t) properties.size());
+ buffer.putShort((uint16_t) statistics.size());
+ buffer.putShort((uint16_t) methods.size());
+
+ for (vector<SchemaPropertyImpl*>::const_iterator iter = properties.begin();
+ iter != properties.end(); iter++)
+ (*iter)->encode(buffer);
+ for (vector<SchemaStatisticImpl*>::const_iterator iter = statistics.begin();
+ iter != statistics.end(); iter++)
+ (*iter)->encode(buffer);
+ for (vector<SchemaMethodImpl*>::const_iterator iter = methods.begin();
+ iter != methods.end(); iter++)
+ (*iter)->encode(buffer);
+}
+
+const uint8_t* SchemaObjectClassImpl::getHash() const
+{
+ if (!hasHash) {
+ hasHash = true;
+ hash.update(package);
+ hash.update(name);
+ for (vector<SchemaPropertyImpl*>::const_iterator iter = properties.begin();
+ iter != properties.end(); iter++)
+ (*iter)->updateHash(hash);
+ for (vector<SchemaStatisticImpl*>::const_iterator iter = statistics.begin();
+ iter != statistics.end(); iter++)
+ (*iter)->updateHash(hash);
+ for (vector<SchemaMethodImpl*>::const_iterator iter = methods.begin();
+ iter != methods.end(); iter++)
+ (*iter)->updateHash(hash);
+ }
+
+ return hash.get();
+}
+
+void SchemaObjectClassImpl::addProperty(const SchemaProperty& property)
+{
+ properties.push_back(property.impl);
+}
+
+void SchemaObjectClassImpl::addStatistic(const SchemaStatistic& statistic)
+{
+ statistics.push_back(statistic.impl);
+}
+
+void SchemaObjectClassImpl::addMethod(const SchemaMethod& method)
+{
+ methods.push_back(method.impl);
+}
+
+const SchemaProperty* SchemaObjectClassImpl::getProperty(int idx) const
+{
+ int count = 0;
+ for (vector<SchemaPropertyImpl*>::const_iterator iter = properties.begin();
+ iter != properties.end(); iter++, count++)
+ if (idx == count)
+ return (*iter)->envelope;
+ return 0;
+}
+
+const SchemaStatistic* SchemaObjectClassImpl::getStatistic(int idx) const
+{
+ int count = 0;
+ for (vector<SchemaStatisticImpl*>::const_iterator iter = statistics.begin();
+ iter != statistics.end(); iter++, count++)
+ if (idx == count)
+ return (*iter)->envelope;
+ return 0;
+}
+
+const SchemaMethod* SchemaObjectClassImpl::getMethod(int idx) const
+{
+ int count = 0;
+ for (vector<SchemaMethodImpl*>::const_iterator iter = methods.begin();
+ iter != methods.end(); iter++, count++)
+ if (idx == count)
+ return (*iter)->envelope;
+ return 0;
+}
+
+SchemaEventClassImpl::SchemaEventClassImpl(Buffer& buffer) : envelope(new SchemaEventClass(this)), hasHash(true)
+{
+ buffer.getShortString(package);
+ buffer.getShortString(name);
+ hash.decode(buffer);
+
+ uint16_t argCount = buffer.getShort();
+
+ for (uint16_t idx = 0; idx < argCount; idx++) {
+ SchemaArgumentImpl* argument = new SchemaArgumentImpl(buffer);
+ addArgument(*argument->envelope);
+ }
+}
+
+void SchemaEventClassImpl::encode(Buffer& buffer) const
+{
+ buffer.putOctet((uint8_t) CLASS_EVENT);
+ buffer.putShortString(package);
+ buffer.putShortString(name);
+ hash.encode(buffer);
+ buffer.putShort((uint16_t) arguments.size());
+
+ for (vector<SchemaArgumentImpl*>::const_iterator iter = arguments.begin();
+ iter != arguments.end(); iter++)
+ (*iter)->encode(buffer);
+}
+
+const uint8_t* SchemaEventClassImpl::getHash() const
+{
+ if (!hasHash) {
+ hasHash = true;
+ hash.update(package);
+ hash.update(name);
+ for (vector<SchemaArgumentImpl*>::const_iterator iter = arguments.begin();
+ iter != arguments.end(); iter++)
+ (*iter)->updateHash(hash);
+ }
+ return hash.get();
+}
+
+void SchemaEventClassImpl::addArgument(const SchemaArgument& argument)
+{
+ arguments.push_back(argument.impl);
+}
+
+const SchemaArgument* SchemaEventClassImpl::getArgument(int idx) const
+{
+ int count = 0;
+ for (vector<SchemaArgumentImpl*>::const_iterator iter = arguments.begin();
+ iter != arguments.end(); iter++, count++)
+ if (idx == count)
+ return (*iter)->envelope;
+ return 0;
+}
+
+//==================================================================
+// Wrappers
+//==================================================================
+
+SchemaArgument::SchemaArgument(const char* name, Typecode typecode)
+{
+ impl = new SchemaArgumentImpl(this, name, typecode);
+}
+
+SchemaArgument::SchemaArgument(SchemaArgumentImpl* i) : impl(i) {}
+
+SchemaArgument::~SchemaArgument()
+{
+ delete impl;
+}
+
+void SchemaArgument::setDirection(Direction dir)
+{
+ impl->setDirection(dir);
+}
+
+void SchemaArgument::setUnit(const char* val)
+{
+ impl->setUnit(val);
+}
+
+void SchemaArgument::setDesc(const char* desc)
+{
+ impl->setDesc(desc);
+}
+
+const char* SchemaArgument::getName() const
+{
+ return impl->getName().c_str();
+}
+
+Typecode SchemaArgument::getType() const
+{
+ return impl->getType();
+}
+
+Direction SchemaArgument::getDirection() const
+{
+ return impl->getDirection();
+}
+
+const char* SchemaArgument::getUnit() const
+{
+ return impl->getUnit().c_str();
+}
+
+const char* SchemaArgument::getDesc() const
+{
+ return impl->getDesc().c_str();
+}
+
+SchemaMethod::SchemaMethod(const char* name)
+{
+ impl = new SchemaMethodImpl(this, name);
+}
+
+SchemaMethod::SchemaMethod(SchemaMethodImpl* i) : impl(i) {}
+
+SchemaMethod::~SchemaMethod()
+{
+ delete impl;
+}
+
+void SchemaMethod::addArgument(const SchemaArgument& argument)
+{
+ impl->addArgument(argument);
+}
+
+void SchemaMethod::setDesc(const char* desc)
+{
+ impl->setDesc(desc);
+}
+
+const char* SchemaMethod::getName() const
+{
+ return impl->getName().c_str();
+}
+
+const char* SchemaMethod::getDesc() const
+{
+ return impl->getDesc().c_str();
+}
+
+int SchemaMethod::getArgumentCount() const
+{
+ return impl->getArgumentCount();
+}
+
+const SchemaArgument* SchemaMethod::getArgument(int idx) const
+{
+ return impl->getArgument(idx);
+}
+
+SchemaProperty::SchemaProperty(const char* name, Typecode typecode)
+{
+ impl = new SchemaPropertyImpl(this, name, typecode);
+}
+
+SchemaProperty::SchemaProperty(SchemaPropertyImpl* i) : impl(i) {}
+
+SchemaProperty::~SchemaProperty()
+{
+ delete impl;
+}
+
+void SchemaProperty::setAccess(Access access)
+{
+ impl->setAccess(access);
+}
+
+void SchemaProperty::setIndex(bool val)
+{
+ impl->setIndex(val);
+}
+
+void SchemaProperty::setOptional(bool val)
+{
+ impl->setOptional(val);
+}
+
+void SchemaProperty::setUnit(const char* val)
+{
+ impl->setUnit(val);
+}
+
+void SchemaProperty::setDesc(const char* desc)
+{
+ impl->setDesc(desc);
+}
+
+const char* SchemaProperty::getName() const
+{
+ return impl->getName().c_str();
+}
+
+Typecode SchemaProperty::getType() const
+{
+ return impl->getType();
+}
+
+Access SchemaProperty::getAccess() const
+{
+ return impl->getAccess();
+}
+
+bool SchemaProperty::isIndex() const
+{
+ return impl->isIndex();
+}
+
+bool SchemaProperty::isOptional() const
+{
+ return impl->isOptional();
+}
+
+const char* SchemaProperty::getUnit() const
+{
+ return impl->getUnit().c_str();
+}
+
+const char* SchemaProperty::getDesc() const
+{
+ return impl->getDesc().c_str();
+}
+
+SchemaStatistic::SchemaStatistic(const char* name, Typecode typecode)
+{
+ impl = new SchemaStatisticImpl(this, name, typecode);
+}
+
+SchemaStatistic::SchemaStatistic(SchemaStatisticImpl* i) : impl(i) {}
+
+SchemaStatistic::~SchemaStatistic()
+{
+ delete impl;
+}
+
+void SchemaStatistic::setUnit(const char* val)
+{
+ impl->setUnit(val);
+}
+
+void SchemaStatistic::setDesc(const char* desc)
+{
+ impl->setDesc(desc);
+}
+
+const char* SchemaStatistic::getName() const
+{
+ return impl->getName().c_str();
+}
+
+Typecode SchemaStatistic::getType() const
+{
+ return impl->getType();
+}
+
+const char* SchemaStatistic::getUnit() const
+{
+ return impl->getUnit().c_str();
+}
+
+const char* SchemaStatistic::getDesc() const
+{
+ return impl->getDesc().c_str();
+}
+
+SchemaObjectClass::SchemaObjectClass(const char* package, const char* name)
+{
+ impl = new SchemaObjectClassImpl(this, package, name);
+}
+
+SchemaObjectClass::SchemaObjectClass(SchemaObjectClassImpl* i) : impl(i) {}
+
+SchemaObjectClass::~SchemaObjectClass()
+{
+ delete impl;
+}
+
+void SchemaObjectClass::addProperty(const SchemaProperty& property)
+{
+ impl->addProperty(property);
+}
+
+void SchemaObjectClass::addStatistic(const SchemaStatistic& statistic)
+{
+ impl->addStatistic(statistic);
+}
+
+void SchemaObjectClass::addMethod(const SchemaMethod& method)
+{
+ impl->addMethod(method);
+}
+
+const char* SchemaObjectClass::getPackage() const
+{
+ return impl->getPackage().c_str();
+}
+
+const char* SchemaObjectClass::getName() const
+{
+ return impl->getName().c_str();
+}
+
+const uint8_t* SchemaObjectClass::getHash() const
+{
+ return impl->getHash();
+}
+
+int SchemaObjectClass::getPropertyCount() const
+{
+ return impl->getPropertyCount();
+}
+
+int SchemaObjectClass::getStatisticCount() const
+{
+ return impl->getStatisticCount();
+}
+
+int SchemaObjectClass::getMethodCount() const
+{
+ return impl->getMethodCount();
+}
+
+const SchemaProperty* SchemaObjectClass::getProperty(int idx) const
+{
+ return impl->getProperty(idx);
+}
+
+const SchemaStatistic* SchemaObjectClass::getStatistic(int idx) const
+{
+ return impl->getStatistic(idx);
+}
+
+const SchemaMethod* SchemaObjectClass::getMethod(int idx) const
+{
+ return impl->getMethod(idx);
+}
+
+SchemaEventClass::SchemaEventClass(const char* package, const char* name)
+{
+ impl = new SchemaEventClassImpl(this, package, name);
+}
+
+SchemaEventClass::SchemaEventClass(SchemaEventClassImpl* i) : impl(i) {}
+
+SchemaEventClass::~SchemaEventClass()
+{
+ delete impl;
+}
+
+void SchemaEventClass::addArgument(const SchemaArgument& argument)
+{
+ impl->addArgument(argument);
+}
+
+void SchemaEventClass::setDesc(const char* desc)
+{
+ impl->setDesc(desc);
+}
+
+const char* SchemaEventClass::getPackage() const
+{
+ return impl->getPackage().c_str();
+}
+
+const char* SchemaEventClass::getName() const
+{
+ return impl->getName().c_str();
+}
+
+const uint8_t* SchemaEventClass::getHash() const
+{
+ return impl->getHash();
+}
+
+int SchemaEventClass::getArgumentCount() const
+{
+ return impl->getArgumentCount();
+}
+
+const SchemaArgument* SchemaEventClass::getArgument(int idx) const
+{
+ return impl->getArgument(idx);
+}
+
Added: qpid/trunk/qpid/cpp/src/qmf/SchemaImpl.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/SchemaImpl.h?rev=777720&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/SchemaImpl.h (added)
+++ qpid/trunk/qpid/cpp/src/qmf/SchemaImpl.h Fri May 22 21:40:57 2009
@@ -0,0 +1,195 @@
+#ifndef _QmfSchemaImpl_
+#define _QmfSchemaImpl_
+
+/*
+ * 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 "Schema.h"
+#include <string>
+#include <vector>
+#include <qpid/framing/Buffer.h>
+
+namespace qmf {
+
+ // TODO: Destructors for schema classes
+ // TODO: Add "frozen" attribute for schema classes so they can't be modified after
+ // they've been registered.
+
+ class SchemaHash {
+ uint8_t hash[16];
+ public:
+ SchemaHash();
+ void encode(qpid::framing::Buffer& buffer);
+ void decode(qpid::framing::Buffer& buffer);
+ void update(const char* data, uint32_t len);
+ void update(uint8_t data);
+ void update(const std::string& data) { update(data.c_str(), data.size()); }
+ void update(Typecode t) { update((uint8_t) t); }
+ void update(Direction d) { update((uint8_t) d); }
+ void update(Access a) { update((uint8_t) a); }
+ void update(bool b) { update((uint8_t) (b ? 1 : 0)); }
+ const uint8_t* get() const { return hash; }
+ };
+
+ struct SchemaArgumentImpl {
+ SchemaArgument* envelope;
+ std::string name;
+ Typecode typecode;
+ Direction dir;
+ std::string unit;
+ std::string description;
+
+ SchemaArgumentImpl(SchemaArgument* e, const char* n, Typecode t) :
+ envelope(e), name(n), typecode(t), dir(DIR_IN) {}
+ SchemaArgumentImpl(qpid::framing::Buffer& buffer);
+ void encode(qpid::framing::Buffer& buffer) const;
+ void setDirection(Direction d) { dir = d; }
+ void setUnit(const char* val) { unit = val; }
+ void setDesc(const char* desc) { description = desc; }
+ const std::string& getName() const { return name; }
+ Typecode getType() const { return typecode; }
+ Direction getDirection() const { return dir; }
+ const std::string& getUnit() const { return unit; }
+ const std::string& getDesc() const { return description; }
+ void updateHash(SchemaHash& hash) const;
+ };
+
+ struct SchemaMethodImpl {
+ SchemaMethod* envelope;
+ std::string name;
+ std::string description;
+ std::vector<SchemaArgumentImpl*> arguments;
+
+ SchemaMethodImpl(SchemaMethod* e, const char* n) : envelope(e), name(n) {}
+ SchemaMethodImpl(qpid::framing::Buffer& buffer);
+ void encode(qpid::framing::Buffer& buffer) const;
+ void addArgument(const SchemaArgument& argument);
+ void setDesc(const char* desc) { description = desc; }
+ const std::string& getName() const { return name; }
+ const std::string& getDesc() const { return description; }
+ int getArgumentCount() const { return arguments.size(); }
+ const SchemaArgument* getArgument(int idx) const;
+ void updateHash(SchemaHash& hash) const;
+ };
+
+ struct SchemaPropertyImpl {
+ SchemaProperty* envelope;
+ std::string name;
+ Typecode typecode;
+ Access access;
+ bool index;
+ bool optional;
+ std::string unit;
+ std::string description;
+
+ SchemaPropertyImpl(SchemaProperty* e, const char* n, Typecode t) :
+ envelope(e), name(n), typecode(t), access(ACCESS_READ_ONLY),
+ index(false), optional(false) {}
+ SchemaPropertyImpl(qpid::framing::Buffer& buffer);
+ void encode(qpid::framing::Buffer& buffer) const;
+ void setAccess(Access a) { access = a; }
+ void setIndex(bool val) { index = val; }
+ void setOptional(bool val) { optional = val; }
+ void setUnit(const char* val) { unit = val; }
+ void setDesc(const char* desc) { description = desc; }
+ const std::string& getName() const { return name; }
+ Typecode getType() const { return typecode; }
+ Access getAccess() const { return access; }
+ bool isIndex() const { return index; }
+ bool isOptional() const { return optional; }
+ const std::string& getUnit() const { return unit; }
+ const std::string& getDesc() const { return description; }
+ void updateHash(SchemaHash& hash) const;
+ };
+
+ struct SchemaStatisticImpl {
+ SchemaStatistic* envelope;
+ std::string name;
+ Typecode typecode;
+ std::string unit;
+ std::string description;
+
+ SchemaStatisticImpl(SchemaStatistic* e, const char* n, Typecode t) :
+ envelope(e), name(n), typecode(t) {}
+ SchemaStatisticImpl(qpid::framing::Buffer& buffer);
+ void encode(qpid::framing::Buffer& buffer) const;
+ void setUnit(const char* val) { unit = val; }
+ void setDesc(const char* desc) { description = desc; }
+ const std::string& getName() const { return name; }
+ Typecode getType() const { return typecode; }
+ const std::string& getUnit() const { return unit; }
+ const std::string& getDesc() const { return description; }
+ void updateHash(SchemaHash& hash) const;
+ };
+
+ struct SchemaObjectClassImpl {
+ SchemaObjectClass* envelope;
+ std::string package;
+ std::string name;
+ mutable SchemaHash hash;
+ mutable bool hasHash;
+ std::vector<SchemaPropertyImpl*> properties;
+ std::vector<SchemaStatisticImpl*> statistics;
+ std::vector<SchemaMethodImpl*> methods;
+
+ SchemaObjectClassImpl(SchemaObjectClass* e, const char* p, const char* n) :
+ envelope(e), package(p), name(n), hasHash(false) {}
+ SchemaObjectClassImpl(qpid::framing::Buffer& buffer);
+ void encode(qpid::framing::Buffer& buffer) const;
+ void addProperty(const SchemaProperty& property);
+ void addStatistic(const SchemaStatistic& statistic);
+ void addMethod(const SchemaMethod& method);
+
+ const std::string& getPackage() const { return package; }
+ const std::string& getName() const { return name; }
+ const uint8_t* getHash() const;
+ int getPropertyCount() const { return properties.size(); }
+ int getStatisticCount() const { return statistics.size(); }
+ int getMethodCount() const { return methods.size(); }
+ const SchemaProperty* getProperty(int idx) const;
+ const SchemaStatistic* getStatistic(int idx) const;
+ const SchemaMethod* getMethod(int idx) const;
+ };
+
+ struct SchemaEventClassImpl {
+ SchemaEventClass* envelope;
+ std::string package;
+ std::string name;
+ mutable SchemaHash hash;
+ mutable bool hasHash;
+ std::string description;
+ std::vector<SchemaArgumentImpl*> arguments;
+
+ SchemaEventClassImpl(SchemaEventClass* e, const char* p, const char* n) :
+ envelope(e), package(p), name(n), hasHash(false) {}
+ SchemaEventClassImpl(qpid::framing::Buffer& buffer);
+ void encode(qpid::framing::Buffer& buffer) const;
+ void addArgument(const SchemaArgument& argument);
+ void setDesc(const char* desc) { description = desc; }
+
+ const std::string& getPackage() const { return package; }
+ const std::string& getName() const { return name; }
+ const uint8_t* getHash() const;
+ int getArgumentCount() const { return arguments.size(); }
+ const SchemaArgument* getArgument(int idx) const;
+ };
+}
+
+#endif
+
Added: qpid/trunk/qpid/cpp/src/qmf/Typecode.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/Typecode.h?rev=777720&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/Typecode.h (added)
+++ qpid/trunk/qpid/cpp/src/qmf/Typecode.h Fri May 22 21:40:57 2009
@@ -0,0 +1,51 @@
+#ifndef _QmfTypecode_
+#define _QmfTypecode_
+
+/*
+ * 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.
+ */
+
+namespace qmf {
+
+ enum Typecode {
+ TYPE_UINT8 = 1,
+ TYPE_UINT16 = 2,
+ TYPE_UINT32 = 3,
+ TYPE_UINT64 = 4,
+ TYPE_SSTR = 6,
+ TYPE_LSTR = 7,
+ TYPE_ABSTIME = 8,
+ TYPE_DELTATIME = 9,
+ TYPE_REF = 10,
+ TYPE_BOOL = 11,
+ TYPE_FLOAT = 12,
+ TYPE_DOUBLE = 13,
+ TYPE_UUID = 14,
+ TYPE_MAP = 15,
+ TYPE_INT8 = 16,
+ TYPE_INT16 = 17,
+ TYPE_INT32 = 18,
+ TYPE_INT64 = 19,
+ TYPE_OBJECT = 20,
+ TYPE_LIST = 21,
+ TYPE_ARRAY = 22
+ };
+}
+
+#endif
+
Added: qpid/trunk/qpid/cpp/src/qmf/Value.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/Value.h?rev=777720&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/Value.h (added)
+++ qpid/trunk/qpid/cpp/src/qmf/Value.h Fri May 22 21:40:57 2009
@@ -0,0 +1,113 @@
+#ifndef _QmfValue_
+#define _QmfValue_
+
+/*
+ * 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 <qmf/ObjectId.h>
+#include <qmf/Typecode.h>
+
+namespace qmf {
+
+ class Object;
+ class ValueImpl;
+
+ class Value {
+ public:
+ Value();
+ Value(Typecode t, Typecode arrayType = TYPE_UINT8);
+ Value(ValueImpl* impl);
+ ~Value();
+
+ Typecode getType() const;
+ bool isNull() const;
+ void setNull();
+
+ bool isObjectId() const;
+ const ObjectId& asObjectId() const;
+ void setObjectId(const ObjectId& oid);
+
+ bool isUint() const;
+ uint32_t asUint() const;
+ void setUint(uint32_t val);
+
+ bool isInt() const;
+ int32_t asInt() const;
+ void setInt(int32_t val);
+
+ bool isUint64() const;
+ uint64_t asUint64() const;
+ void setUint64(uint64_t val);
+
+ bool isInt64() const;
+ int64_t asInt64() const;
+ void setInt64(int64_t val);
+
+ bool isString() const;
+ const char* asString() const;
+ void setString(const char* val);
+
+ bool isBool() const;
+ bool asBool() const;
+ void setBool(bool val);
+
+ bool isFloat() const;
+ float asFloat() const;
+ void setFloat(float val);
+
+ bool isDouble() const;
+ double asDouble() const;
+ void setDouble(double val);
+
+ bool isUuid() const;
+ const uint8_t* asUuid() const;
+ void setUuid(const uint8_t* val);
+
+ bool isObject() const;
+ Object* asObject() const;
+ void setObject(Object* val);
+
+ bool isMap() const;
+ bool keyInMap(const char* key) const;
+ Value* byKey(const char* key);
+ const Value* byKey(const char* key) const;
+ void deleteKey(const char* key);
+ void insert(const char* key, Value* val);
+ uint32_t keyCount() const;
+ const char* key(uint32_t idx) const;
+
+ bool isList() const;
+ uint32_t listItemCount() const;
+ Value* listItem(uint32_t idx);
+ void appendToList(Value* val);
+ void deleteListItem(uint32_t idx);
+
+ bool isArray() const;
+ Typecode arrayType() const;
+ uint32_t arrayItemCount() const;
+ Value* arrayItem(uint32_t idx);
+ void appendToArray(Value* val);
+ void deleteArrayItem(uint32_t idx);
+
+ ValueImpl* impl;
+ };
+}
+
+#endif
+
Added: qpid/trunk/qpid/cpp/src/qmf/ValueImpl.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/ValueImpl.cpp?rev=777720&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/ValueImpl.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qmf/ValueImpl.cpp Fri May 22 21:40:57 2009
@@ -0,0 +1,478 @@
+/*
+ * 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 "ValueImpl.h"
+#include <qpid/framing/FieldTable.h>
+
+using namespace std;
+using namespace qmf;
+using qpid::framing::Buffer;
+
+ValueImpl::ValueImpl(Typecode t, Buffer& buf) : envelope(new Value(this)), typecode(t)
+{
+ uint64_t first;
+ uint64_t second;
+ qpid::framing::FieldTable ft;
+
+ switch (typecode) {
+ case TYPE_UINT8 : value.u32 = (uint32_t) buf.getOctet(); break;
+ case TYPE_UINT16 : value.u32 = (uint32_t) buf.getShort(); break;
+ case TYPE_UINT32 : value.u32 = (uint32_t) buf.getLong(); break;
+ case TYPE_UINT64 : value.u64 = buf.getLongLong(); break;
+ case TYPE_SSTR : buf.getShortString(stringVal); break;
+ case TYPE_LSTR : buf.getMediumString(stringVal); break;
+ case TYPE_ABSTIME : value.s64 = buf.getLongLong(); break;
+ case TYPE_DELTATIME : value.u64 = buf.getLongLong(); break;
+ case TYPE_BOOL : value.boolVal = (buf.getOctet() != 0); break;
+ case TYPE_FLOAT : value.floatVal = buf.getFloat(); break;
+ case TYPE_DOUBLE : value.doubleVal = buf.getDouble(); break;
+ case TYPE_INT8 : value.s32 = (int32_t) buf.getOctet(); break;
+ case TYPE_INT16 : value.s32 = (int32_t) buf.getShort(); break;
+ case TYPE_INT32 : value.s32 = (int32_t) buf.getLong(); break;
+ case TYPE_INT64 : value.s64 = buf.getLongLong(); break;
+ case TYPE_UUID : buf.getBin128(value.uuidVal); break;
+ case TYPE_REF:
+ first = buf.getLongLong();
+ second = buf.getLongLong();
+ refVal.impl->setValue(first, second);
+ break;
+
+ case TYPE_MAP:
+ ft.decode(buf);
+ // TODO: either update to recursively use QMF types or reduce to int/string/...
+ // (maybe use another ctor with a FieldValue argument)
+ break;
+
+ case TYPE_LIST:
+ case TYPE_ARRAY:
+ case TYPE_OBJECT:
+ default:
+ break;
+ }
+}
+
+ValueImpl::ValueImpl(Typecode t) : envelope(new Value(this)), typecode(t)
+{
+ ::memset(&value, 0, sizeof(value));
+}
+
+ValueImpl::~ValueImpl()
+{
+}
+
+void ValueImpl::encode(Buffer& buf) const
+{
+ switch (typecode) {
+ case TYPE_UINT8 : buf.putOctet((uint8_t) value.u32); break;
+ case TYPE_UINT16 : buf.putShort((uint16_t) value.u32); break;
+ case TYPE_UINT32 : buf.putLong(value.u32); break;
+ case TYPE_UINT64 : buf.putLongLong(value.u64); break;
+ case TYPE_SSTR : buf.putShortString(stringVal); break;
+ case TYPE_LSTR : buf.putMediumString(stringVal); break;
+ case TYPE_ABSTIME : buf.putLongLong(value.s64); break;
+ case TYPE_DELTATIME : buf.putLongLong(value.u64); break;
+ case TYPE_BOOL : buf.putOctet(value.boolVal ? 1 : 0); break;
+ case TYPE_FLOAT : buf.putFloat(value.floatVal); break;
+ case TYPE_DOUBLE : buf.putDouble(value.doubleVal); break;
+ case TYPE_INT8 : buf.putOctet((uint8_t) value.s32); break;
+ case TYPE_INT16 : buf.putShort((uint16_t) value.s32); break;
+ case TYPE_INT32 : buf.putLong(value.s32); break;
+ case TYPE_INT64 : buf.putLongLong(value.s64); break;
+ case TYPE_UUID : buf.putBin128(value.uuidVal); break;
+ case TYPE_REF : refVal.impl->encode(buf); break;
+ case TYPE_MAP: // TODO
+ case TYPE_LIST:
+ case TYPE_ARRAY:
+ case TYPE_OBJECT:
+ default:
+ break;
+ }
+}
+
+bool ValueImpl::keyInMap(const char* key) const
+{
+ return typecode == TYPE_MAP && mapVal.count(key) > 0;
+}
+
+Value* ValueImpl::byKey(const char* key)
+{
+ if (keyInMap(key)) {
+ map<std::string, VPtr>::iterator iter = mapVal.find(key);
+ if (iter != mapVal.end())
+ return iter->second.get();
+ }
+ return 0;
+}
+
+const Value* ValueImpl::byKey(const char* key) const
+{
+ if (keyInMap(key)) {
+ map<std::string, VPtr>::const_iterator iter = mapVal.find(key);
+ if (iter != mapVal.end())
+ return iter->second.get();
+ }
+ return 0;
+}
+
+void ValueImpl::deleteKey(const char* key)
+{
+ mapVal.erase(key);
+}
+
+void ValueImpl::insert(const char* key, Value* val)
+{
+ mapVal[key] = VPtr(val);
+}
+
+const char* ValueImpl::key(uint32_t idx) const
+{
+ map<std::string, VPtr>::const_iterator iter = mapVal.begin();
+ for (uint32_t i = 0; i < idx; i++) {
+ if (iter == mapVal.end())
+ break;
+ iter++;
+ }
+
+ if (iter == mapVal.end())
+ return 0;
+ else
+ return iter->first.c_str();
+}
+
+Value* ValueImpl::listItem(uint32_t)
+{
+ return 0;
+}
+
+void ValueImpl::appendToList(Value*)
+{
+}
+
+void ValueImpl::deleteListItem(uint32_t)
+{
+}
+
+Value* ValueImpl::arrayItem(uint32_t)
+{
+ return 0;
+}
+
+void ValueImpl::appendToArray(Value*)
+{
+}
+
+void ValueImpl::deleteArrayItem(uint32_t)
+{
+}
+
+
+//==================================================================
+// Wrappers
+//==================================================================
+
+Value::Value(Typecode t, Typecode at)
+{
+ impl = new ValueImpl(this, t, at);
+}
+
+Value::Value(ValueImpl* i)
+{
+ impl = i;
+}
+
+Value::~Value()
+{
+ delete impl;
+}
+
+Typecode Value::getType() const
+{
+ return impl->getType();
+}
+
+bool Value::isNull() const
+{
+ return impl->isNull();
+}
+
+void Value::setNull()
+{
+ impl->setNull();
+}
+
+bool Value::isObjectId() const
+{
+ return impl->isObjectId();
+}
+
+const ObjectId& Value::asObjectId() const
+{
+ return impl->asObjectId();
+}
+
+void Value::setObjectId(const ObjectId& oid)
+{
+ impl->setObjectId(oid);
+}
+
+bool Value::isUint() const
+{
+ return impl->isUint();
+}
+
+uint32_t Value::asUint() const
+{
+ return impl->asUint();
+}
+
+void Value::setUint(uint32_t val)
+{
+ impl->setUint(val);
+}
+
+bool Value::isInt() const
+{
+ return impl->isInt();
+}
+
+int32_t Value::asInt() const
+{
+ return impl->asInt();
+}
+
+void Value::setInt(int32_t val)
+{
+ impl->setInt(val);
+}
+
+bool Value::isUint64() const
+{
+ return impl->isUint64();
+}
+
+uint64_t Value::asUint64() const
+{
+ return impl->asUint64();
+}
+
+void Value::setUint64(uint64_t val)
+{
+ impl->setUint64(val);
+}
+
+bool Value::isInt64() const
+{
+ return impl->isInt64();
+}
+
+int64_t Value::asInt64() const
+{
+ return impl->asInt64();
+}
+
+void Value::setInt64(int64_t val)
+{
+ impl->setInt64(val);
+}
+
+bool Value::isString() const
+{
+ return impl->isString();
+}
+
+const char* Value::asString() const
+{
+ return impl->asString();
+}
+
+void Value::setString(const char* val)
+{
+ impl->setString(val);
+}
+
+bool Value::isBool() const
+{
+ return impl->isBool();
+}
+
+bool Value::asBool() const
+{
+ return impl->asBool();
+}
+
+void Value::setBool(bool val)
+{
+ impl->setBool(val);
+}
+
+bool Value::isFloat() const
+{
+ return impl->isFloat();
+}
+
+float Value::asFloat() const
+{
+ return impl->asFloat();
+}
+
+void Value::setFloat(float val)
+{
+ impl->setFloat(val);
+}
+
+bool Value::isDouble() const
+{
+ return impl->isDouble();
+}
+
+double Value::asDouble() const
+{
+ return impl->asDouble();
+}
+
+void Value::setDouble(double val)
+{
+ impl->setDouble(val);
+}
+
+bool Value::isUuid() const
+{
+ return impl->isUuid();
+}
+
+const uint8_t* Value::asUuid() const
+{
+ return impl->asUuid();
+}
+
+void Value::setUuid(const uint8_t* val)
+{
+ impl->setUuid(val);
+}
+
+bool Value::isObject() const
+{
+ return impl->isObject();
+}
+
+Object* Value::asObject() const
+{
+ return impl->asObject();
+}
+
+void Value::setObject(Object* val)
+{
+ impl->setObject(val);
+}
+
+bool Value::isMap() const
+{
+ return impl->isMap();
+}
+
+bool Value::keyInMap(const char* key) const
+{
+ return impl->keyInMap(key);
+}
+
+Value* Value::byKey(const char* key)
+{
+ return impl->byKey(key);
+}
+
+const Value* Value::byKey(const char* key) const
+{
+ return impl->byKey(key);
+}
+
+void Value::deleteKey(const char* key)
+{
+ impl->deleteKey(key);
+}
+
+void Value::insert(const char* key, Value* val)
+{
+ impl->insert(key, val);
+}
+
+uint32_t Value::keyCount() const
+{
+ return impl->keyCount();
+}
+
+const char* Value::key(uint32_t idx) const
+{
+ return impl->key(idx);
+}
+
+bool Value::isList() const
+{
+ return impl->isList();
+}
+
+uint32_t Value::listItemCount() const
+{
+ return impl->listItemCount();
+}
+
+Value* Value::listItem(uint32_t idx)
+{
+ return impl->listItem(idx);
+}
+
+void Value::appendToList(Value* val)
+{
+ impl->appendToList(val);
+}
+
+void Value::deleteListItem(uint32_t idx)
+{
+ impl->deleteListItem(idx);
+}
+
+bool Value::isArray() const
+{
+ return impl->isArray();
+}
+
+Typecode Value::arrayType() const
+{
+ return impl->arrayType();
+}
+
+uint32_t Value::arrayItemCount() const
+{
+ return impl->arrayItemCount();
+}
+
+Value* Value::arrayItem(uint32_t idx)
+{
+ return impl->arrayItem(idx);
+}
+
+void Value::appendToArray(Value* val)
+{
+ impl->appendToArray(val);
+}
+
+void Value::deleteArrayItem(uint32_t idx)
+{
+ impl->deleteArrayItem(idx);
+}
+
Added: qpid/trunk/qpid/cpp/src/qmf/ValueImpl.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/ValueImpl.h?rev=777720&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/ValueImpl.h (added)
+++ qpid/trunk/qpid/cpp/src/qmf/ValueImpl.h Fri May 22 21:40:57 2009
@@ -0,0 +1,144 @@
+#ifndef _QmfValueImpl_
+#define _QmfValueImpl_
+
+/*
+ * 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 <qmf/Value.h>
+#include <qmf/ObjectIdImpl.h>
+#include <qmf/Object.h>
+#include <qpid/framing/Buffer.h>
+#include <string>
+#include <string.h>
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+namespace qmf {
+
+ // TODO: set valid flag on all value settors
+ // TODO: add a modified flag and accessors
+
+ struct ValueImpl {
+ typedef boost::shared_ptr<Value> VPtr;
+ typedef boost::shared_ptr<Object> OPtr;
+ Value* envelope;
+ const Typecode typecode;
+ bool valid;
+
+ ObjectId refVal;
+ std::string stringVal;
+ OPtr objectVal;
+ std::map<std::string, VPtr> mapVal;
+ std::vector<VPtr> vectorVal;
+ Typecode arrayTypecode;
+
+ union {
+ uint32_t u32;
+ uint64_t u64;
+ int32_t s32;
+ int64_t s64;
+ bool boolVal;
+ float floatVal;
+ double doubleVal;
+ uint8_t uuidVal[16];
+ } value;
+
+ ValueImpl(Value* e, Typecode t, Typecode at) :
+ envelope(e), typecode(t), valid(false), arrayTypecode(at) {}
+ ValueImpl(Typecode t, qpid::framing::Buffer& b);
+ ValueImpl(Typecode t);
+ ~ValueImpl();
+
+ void encode(qpid::framing::Buffer& b) const;
+
+ Typecode getType() const { return typecode; }
+ bool isNull() const { return !valid; }
+ void setNull() { valid = false; }
+
+ bool isObjectId() const { return typecode == TYPE_REF; }
+ const ObjectId& asObjectId() const { return refVal; }
+ void setObjectId(const ObjectId& o) { refVal = o; } // TODO
+
+ bool isUint() const { return typecode >= TYPE_UINT8 && typecode <= TYPE_UINT32; }
+ uint32_t asUint() const { return value.u32; }
+ void setUint(uint32_t val) { value.u32 = val; }
+
+ bool isInt() const { return typecode >= TYPE_INT8 && typecode <= TYPE_INT32; }
+ int32_t asInt() const { return value.s32; }
+ void setInt(int32_t val) { value.s32 = val; }
+
+ bool isUint64() const { return typecode == TYPE_UINT64 || typecode == TYPE_DELTATIME; }
+ uint64_t asUint64() const { return value.u64; }
+ void setUint64(uint64_t val) { value.u64 = val; }
+
+ bool isInt64() const { return typecode == TYPE_INT64 || typecode == TYPE_ABSTIME; }
+ int64_t asInt64() const { return value.s64; }
+ void setInt64(int64_t val) { value.s64 = val; }
+
+ bool isString() const { return typecode == TYPE_SSTR || typecode == TYPE_LSTR; }
+ const char* asString() const { return stringVal.c_str(); }
+ void setString(const char* val) { stringVal = val; }
+
+ bool isBool() const { return typecode == TYPE_BOOL; }
+ bool asBool() const { return value.boolVal; }
+ void setBool(bool val) { value.boolVal = val; }
+
+ bool isFloat() const { return typecode == TYPE_FLOAT; }
+ float asFloat() const { return value.floatVal; }
+ void setFloat(float val) { value.floatVal = val; }
+
+ bool isDouble() const { return typecode == TYPE_DOUBLE; }
+ double asDouble() const { return value.doubleVal; }
+ void setDouble(double val) { value.doubleVal = val; }
+
+ bool isUuid() const { return typecode == TYPE_UUID; }
+ const uint8_t* asUuid() const { return value.uuidVal; }
+ void setUuid(const uint8_t* val) { ::memcpy(value.uuidVal, val, 16); }
+
+ bool isObject() const { return typecode == TYPE_OBJECT; }
+ Object* asObject() const { return objectVal.get(); }
+ void setObject(Object* val) { objectVal.reset(val); }
+
+ bool isMap() const { return typecode == TYPE_MAP; }
+ bool keyInMap(const char* key) const;
+ Value* byKey(const char* key);
+ const Value* byKey(const char* key) const;
+ void deleteKey(const char* key);
+ void insert(const char* key, Value* val);
+ uint32_t keyCount() const { return mapVal.size(); }
+ const char* key(uint32_t idx) const;
+
+ bool isList() const { return typecode == TYPE_LIST; }
+ uint32_t listItemCount() const { return vectorVal.size(); }
+ Value* listItem(uint32_t idx);
+ void appendToList(Value* val);
+ void deleteListItem(uint32_t idx);
+
+ bool isArray() const { return typecode == TYPE_ARRAY; }
+ Typecode arrayType() const { return arrayTypecode; }
+ uint32_t arrayItemCount() const { return vectorVal.size(); }
+ Value* arrayItem(uint32_t idx);
+ void appendToArray(Value* val);
+ void deleteArrayItem(uint32_t idx);
+ };
+}
+
+#endif
+
---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project: http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org