diff --git a/src/qamqpchannelhash.cpp b/src/qamqpchannelhash.cpp new file mode 100644 index 0000000..98883ab --- /dev/null +++ b/src/qamqpchannelhash.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2012-2014 Alexey Shcherbakov + * Copyright (C) 2014-2015 Matt Broadstone + * Contact: https://github.com/mbroadst/qamqp + * + * This file is part of the QAMQP Library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +#include "qamqpqueue.h" +#include "qamqpexchange.h" +#include "qamqpchannelhash_p.h" + +/*! +* Retrieve a pointer to the named channel. +* +* A NULL string is assumed to be equivalent to "" for the purpose +* of retrieving the nameless (default) exchange. +* +* \param[in] name The name of the channel to retrieve. +* \retval NULL Channel does not exist. +*/ +QAmqpChannel* QAmqpChannelHash::get(const QString& name) const +{ + if (name.isNull()) + return channels.value(QString("")); + return channels.value(name); +} + +/*! +* Store an exchange in the hash. The nameless exchange is stored under +* the name "". +*/ +void QAmqpChannelHash::put(QAmqpExchange* exchange) +{ + if (exchange->name().isEmpty()) + put(QString(""), exchange); + else + put(exchange->name(), exchange); +} + +/*! +* Store a queue in the hash. If the queue is nameless, we hook its +* declared signal and store it when the queue receives a name from the +* broker, otherwise we store it under the name given. +*/ +void QAmqpChannelHash::put(QAmqpQueue* queue) +{ + if (queue->name().isEmpty()) + connect(queue, SIGNAL(declared()), + this, SLOT(queueDeclared())); + else + put(queue->name(), queue); +} + +/*! +* Handle destruction of a channel. Retrieve its current name and +* remove it from the list, otherwise do a full garbage collection +* run. +*/ +void QAmqpChannelHash::channelDestroyed() +{ + QAmqpChannel* ch = static_cast(sender()); + if (!channels.contains(ch->name())) + return; + if (channels[ch->name()] == ch) + channels.remove(ch->name()); +} + +/*! +* Handle a queue that has just been declared and given a new name. The +* caller is assumed to be a QAmqpQueue instance. +*/ +void QAmqpChannelHash::queueDeclared() +{ + put(static_cast(sender())); +} + +/*! +* Store a channel in the hash. The channel is assumed +* to be named at the time of storage. This hooks the 'destroyed' signal +* so the channel can be removed from our list. +*/ +void QAmqpChannelHash::put(const QString& name, QAmqpChannel* channel) +{ + connect(channel, SIGNAL(destroyed()), + this, SLOT(channelDestroyed())); + channels[name] = channel; +} + +#include "moc_qamqpchannelhash_p.cpp" +/* vim: set ts=4 sw=4 et */ diff --git a/src/qamqpchannelhash_p.h b/src/qamqpchannelhash_p.h new file mode 100644 index 0000000..6533c10 --- /dev/null +++ b/src/qamqpchannelhash_p.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012-2014 Alexey Shcherbakov + * Copyright (C) 2014-2015 Matt Broadstone + * Contact: https://github.com/mbroadst/qamqp + * + * This file is part of the QAMQP Library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +#ifndef QAMQPCHANNELHASH_P_H +#define QAMQPCHANNELHASH_P_H + +#include +#include +#include + +/* Forward declarations */ +class QAmqpChannel; +class QAmqpQueue; +class QAmqpExchange; + +/*! + * QAmqpChannelHash is a container for storing queues and exchanges for later + * retrieval. When the objects are destroyed, they are automatically removed + * from the container. + */ +class QAmqpChannelHash : public QObject +{ + Q_OBJECT +public: + /*! + * Retrieve a pointer to the named channel. + * + * A NULL string is assumed to be equivalent to "" for the purpose + * of retrieving the nameless (default) exchange. + * + * \param[in] name The name of the channel to retrieve. + * \retval NULL Channel does not exist. + */ + QAmqpChannel* get(const QString& name) const; + + /*! + * Store an exchange in the hash. The nameless exchange is stored under + * the name "". + */ + void put(QAmqpExchange* exchange); + + /*! + * Store a queue in the hash. If the queue is nameless, we hook its + * declared signal and store it when the queue receives a name from the + * broker, otherwise we store it under the name given. + */ + void put(QAmqpQueue* queue); + +private Q_SLOTS: + /*! + * Handle destruction of a channel. Retrieve its current name and + * remove it from the list, otherwise do a full garbage collection + * run. + */ + void channelDestroyed(); + + /*! + * Handle a queue that has just been declared and given a new name. The + * caller is assumed to be a QAmqpQueue instance. + */ + void queueDeclared(); + +private: + /*! + * Store a channel in the hash. This hooks the 'destroyed' signal + * so the channel can be removed from our list. + */ + void put(const QString& name, QAmqpChannel* channel); + + /*! A collection of channels. Key is the channel's "name". */ + QHash channels; +}; + +/* vim: set ts=4 sw=4 et */ +#endif diff --git a/src/src.pro b/src/src.pro index c0fc609..2a5cdd1 100644 --- a/src/src.pro +++ b/src/src.pro @@ -33,6 +33,7 @@ greaterThan(NEED_GCOV_SUPPORT, 0) { PRIVATE_HEADERS += \ qamqpchannel_p.h \ + qamqpchannelhash_p.h \ qamqpclient_p.h \ qamqpexchange_p.h \ qamqpframe_p.h \ @@ -56,6 +57,7 @@ HEADERS += \ SOURCES += \ qamqpauthenticator.cpp \ qamqpchannel.cpp \ + qamqpchannelhash.cpp \ qamqpclient.cpp \ qamqpexchange.cpp \ qamqpframe.cpp \