Fizes#24. Manually merge with fixes maked by @qnective

This commit is contained in:
Alexey Shcherbakov 2013-04-02 20:24:20 +06:00
parent e3327dbf6d
commit 1958be950d
14 changed files with 183 additions and 99 deletions

View File

@ -49,7 +49,8 @@ ClientPrivate::~ClientPrivate()
void ClientPrivate::init(QObject * parent) void ClientPrivate::init(QObject * parent)
{ {
pq_func()->setParent(parent); pq_func()->setParent(parent);
if(!network_){ if(!network_)
{
network_ = new QAMQP::Network(pq_func()); network_ = new QAMQP::Network(pq_func());
} }
@ -58,10 +59,9 @@ void ClientPrivate::init(QObject * parent)
connection_ = new QAMQP::Connection(pq_func()); connection_ = new QAMQP::Connection(pq_func());
} }
setAuth(new AMQPlainAuthenticator(QString::fromLatin1(AMQPLOGIN), QString::fromLatin1(AMQPPSWD))); network_->setMethodHandlerConnection(connection_);
QObject::connect(network_, SIGNAL(method(const QAMQP::Frame::Method &)), setAuth(new AMQPlainAuthenticator(QString::fromLatin1(AMQPLOGIN), QString::fromLatin1(AMQPPSWD)));
connection_, SLOT(_q_method(const QAMQP::Frame::Method &)));
QObject::connect(connection_, SIGNAL(connected()), pq_func(), SIGNAL(connected())); QObject::connect(connection_, SIGNAL(connected()), pq_func(), SIGNAL(connected()));
QObject::connect(connection_, SIGNAL(disconnected()), pq_func(), SIGNAL(disconnected())); QObject::connect(connection_, SIGNAL(disconnected()), pq_func(), SIGNAL(disconnected()));
@ -134,32 +134,30 @@ void ClientPrivate::login()
Exchange * ClientPrivate::createExchange(int channelNumber, const QString &name ) Exchange * ClientPrivate::createExchange(int channelNumber, const QString &name )
{ {
Exchange * exchange_ = new Exchange(channelNumber, pq_func()); Exchange * exchange_ = new Exchange(channelNumber, pq_func());
QObject::connect(network_, SIGNAL(method(const QAMQP::Frame::Method &)),
exchange_, SLOT(_q_method(const QAMQP::Frame::Method &))); network_->addMethodHandlerForChannel(exchange_->channelNumber(), exchange_);
QObject::connect(connection_, SIGNAL(connected()), exchange_, SLOT(_q_open())); QObject::connect(connection_, SIGNAL(connected()), exchange_, SLOT(_q_open()));
exchange_->pd_func()->open(); exchange_->pd_func()->open();
QObject::connect(pq_func(), SIGNAL(disconnected()), exchange_, SLOT(_q_disconnected())); QObject::connect(pq_func(), SIGNAL(disconnected()), exchange_, SLOT(_q_disconnected()));
exchange_->setName(name); exchange_->setName(name);
return exchange_; return exchange_;
} }
Queue * ClientPrivate::createQueue(int channelNumber, const QString &name ) Queue * ClientPrivate::createQueue(int channelNumber, const QString &name )
{ {
Queue * queue_ = new Queue(channelNumber, pq_func()); Queue * queue_ = new Queue(channelNumber, pq_func());
QObject::connect(network_, SIGNAL(method(const QAMQP::Frame::Method &)),
queue_, SLOT(_q_method(const QAMQP::Frame::Method &)));
QObject::connect(network_, SIGNAL(content(const QAMQP::Frame::Content &)), network_->addMethodHandlerForChannel(queue_->channelNumber(), queue_);
queue_, SLOT(_q_content(const QAMQP::Frame::Content &))); network_->addContentHandlerForChannel(queue_->channelNumber(), queue_);
network_->addContentBodyHandlerForChannel(queue_->channelNumber(), queue_);
QObject::connect(network_, SIGNAL(body(int, const QByteArray &)),
queue_, SLOT(_q_body(int, const QByteArray &)));
QObject::connect(connection_, SIGNAL(connected()), queue_, SLOT(_q_open())); QObject::connect(connection_, SIGNAL(connected()), queue_, SLOT(_q_open()));
queue_->pd_func()->open(); queue_->pd_func()->open();
QObject::connect(pq_func(), SIGNAL(disconnected()), queue_, SLOT(_q_disconnected())); QObject::connect(pq_func(), SIGNAL(disconnected()), queue_, SLOT(_q_disconnected()));
queue_->setName(name); queue_->setName(name);
return queue_; return queue_;
} }

View File

@ -109,6 +109,11 @@ void QAMQP::Channel::stateChanged( int state )
} }
} }
void QAMQP::Channel::_q_method(const Frame::Method &frame)
{
pd_func()->_q_method(frame);
}
bool QAMQP::Channel::isOpened() const bool QAMQP::Channel::isOpened() const
{ {
return pd_func()->opened; return pd_func()->opened;
@ -156,6 +161,7 @@ void ChannelPrivate::init(int channelNumber, Client * parent)
bool ChannelPrivate::_q_method( const QAMQP::Frame::Method & frame ) bool ChannelPrivate::_q_method( const QAMQP::Frame::Method & frame )
{ {
Q_ASSERT(frame.channel() == number);
if(frame.channel() != number ) if(frame.channel() != number )
return true; return true;

View File

@ -9,7 +9,7 @@ namespace QAMQP
{ {
class ChannelPrivate; class ChannelPrivate;
class Client; class Client;
class Channel : public QObject class Channel : public QObject, public Frame::MethodHandler
{ {
Q_OBJECT Q_OBJECT
@ -47,8 +47,9 @@ namespace QAMQP
private: private:
void stateChanged(int state); void stateChanged(int state);
friend class ClientPrivate; friend class ClientPrivate;
void _q_method(const QAMQP::Frame::Method & frame);
Q_PRIVATE_SLOT(pd_func(), void _q_open()) Q_PRIVATE_SLOT(pd_func(), void _q_open())
Q_PRIVATE_SLOT(pd_func(), void _q_method(const QAMQP::Frame::Method & frame))
Q_PRIVATE_SLOT(pd_func(), void _q_disconnected()) Q_PRIVATE_SLOT(pd_func(), void _q_disconnected())
}; };
} }
@ -56,4 +57,4 @@ namespace QAMQP
#ifdef QAMQP_P_INCLUDE #ifdef QAMQP_P_INCLUDE
# include "amqp_channel_p.h" # include "amqp_channel_p.h"
#endif #endif
#endif // amqp_channel_h__ #endif // amqp_channel_h__

View File

@ -260,6 +260,7 @@ void ConnectionPrivate::setQOS( qint32 prefetchSize, quint16 prefetchCount, int
bool ConnectionPrivate::_q_method( const QAMQP::Frame::Method & frame ) bool ConnectionPrivate::_q_method( const QAMQP::Frame::Method & frame )
{ {
Q_ASSERT(frame.methodClass() == QAMQP::Frame::fcConnection);
if(frame.methodClass() != QAMQP::Frame::fcConnection) if(frame.methodClass() != QAMQP::Frame::fcConnection)
return true; return true;
@ -364,6 +365,11 @@ void Connection::openOk()
emit connected(); emit connected();
} }
void Connection::_q_method(const QAMQP::Frame::Method & frame)
{
pd_func()->_q_method(frame);
}
bool Connection::isConnected() const bool Connection::isConnected() const
{ {
return pd_func()->connected; return pd_func()->connected;

View File

@ -11,7 +11,7 @@ namespace QAMQP
class ChannelPrivate; class ChannelPrivate;
class ClientPrivate; class ClientPrivate;
class Client; class Client;
class Connection : public QObject class Connection : public QObject, public Frame::MethodHandler
{ {
Q_OBJECT Q_OBJECT
P_DECLARE_PRIVATE(QAMQP::Connection) P_DECLARE_PRIVATE(QAMQP::Connection)
@ -45,8 +45,9 @@ namespace QAMQP
void openOk(); void openOk();
friend class ClientPrivate; friend class ClientPrivate;
friend class ChannelPrivate; friend class ChannelPrivate;
Q_PRIVATE_SLOT(pd_func(), void _q_method(const QAMQP::Frame::Method & frame))
Q_PRIVATE_SLOT(pd_func(), void _q_heartbeat()) void _q_method(const QAMQP::Frame::Method & frame);
Q_PRIVATE_SLOT(pd_func(), void _q_heartbeat());
}; };
} }
@ -55,4 +56,4 @@ namespace QAMQP
# include "amqp_connection_p.h" # include "amqp_connection_p.h"
#endif #endif
#endif // amqp_connection_h__ #endif // amqp_connection_h__

View File

@ -61,4 +61,4 @@ namespace QAMQP
}; };
} }
Q_DECLARE_OPERATORS_FOR_FLAGS(QAMQP::Exchange::ExchangeOptions) Q_DECLARE_OPERATORS_FOR_FLAGS(QAMQP::Exchange::ExchangeOptions)
#endif // amqp_exchange_h__ #endif // amqp_exchange_h__

View File

@ -1,5 +1,4 @@
#include "amqp_frame.h" #include "amqp_frame.h"
#define AMQP_FRAME_END 0xCE
#include <QDateTime> #include <QDateTime>
#include <QList> #include <QList>
@ -47,7 +46,7 @@ void QAMQP::Frame::Base::writeHeader( QDataStream & stream ) const
void QAMQP::Frame::Base::writeEnd( QDataStream & stream ) const void QAMQP::Frame::Base::writeEnd( QDataStream & stream ) const
{ {
stream << qint8(AMQP_FRAME_END); stream << qint8(FRAME_END);
} }
void QAMQP::Frame::Base::writePayload( QDataStream & ) const{} void QAMQP::Frame::Base::writePayload( QDataStream & ) const{}
@ -64,7 +63,7 @@ void QAMQP::Frame::Base::readEnd( QDataStream & stream )
{ {
unsigned char end_ = 0; unsigned char end_ = 0;
stream.readRawData(reinterpret_cast<char*>(&end_), sizeof(end_)); stream.readRawData(reinterpret_cast<char*>(&end_), sizeof(end_));
if(end_ != AMQP_FRAME_END ) if(end_ != FRAME_END )
{ {
qWarning("Wrong end of frame"); qWarning("Wrong end of frame");
} }
@ -711,6 +710,6 @@ qint32 QAMQP::Frame::ContentBody::size() const
QAMQP::Frame::Heartbeat::Heartbeat() : Base(ftHeartbeat) {} QAMQP::Frame::Heartbeat::Heartbeat() : Base(ftHeartbeat) {}
void QAMQP::Frame::Heartbeat::readPayload(QDataStream & stream) {} void QAMQP::Frame::Heartbeat::readPayload(QDataStream & ) {}
void QAMQP::Frame::Heartbeat::writePayload(QDataStream & stream) const {} void QAMQP::Frame::Heartbeat::writePayload(QDataStream & ) const {}

View File

@ -33,6 +33,21 @@ namespace QAMQP
*/ */
namespace Frame namespace Frame
{ {
typedef quint16 channel_t;
/*!
@brief Header size in bytes
*/
static const qint64 HEADER_SIZE = 7;
/*!
@brief Frame end indicator size in bytes
*/
static const qint64 FRAME_END_SIZE = 1;
/*!
@brief Frame end marker
*/
static const quint8 FRAME_END = 0xCE;
/*! /*!
@brief Frame type @brief Frame type
*/ */
@ -85,9 +100,9 @@ namespace QAMQP
All frames start with a 7-octet header composed of a type field (octet), a channel field (short integer) and a All frames start with a 7-octet header composed of a type field (octet), a channel field (short integer) and a
size field (long integer): size field (long integer):
@code Frame struct @code Frame struct
0 1 3 7 size+7 size+8 0 1 3 7 size+7 size+8
+------+---------+---------+ +-------------+ +-----------+ +------+---------+---------+ +-------------+ +-----------+
| type | channel | size | | payload | | frame-end | | type | channel | size | | payload | | frame-end |
+------+---------+---------+ +-------------+ +-----------+ +------+---------+---------+ +-------------+ +-----------+
@endcode @endcode
octet short long 'size' octets octet octet short long 'size' octets octet
@ -167,11 +182,11 @@ namespace QAMQP
Method frame bodies consist of an invariant list of data fields, called "arguments". All method bodies start Method frame bodies consist of an invariant list of data fields, called "arguments". All method bodies start
with identifier numbers for the class and method: with identifier numbers for the class and method:
@code Frame struct @code Frame struct
0 2 4 0 2 4
+----------+-----------+-------------- - - +----------+-----------+-------------- - -
| class-id | method-id | arguments... | class-id | method-id | arguments...
+----------+-----------+-------------- - - +----------+-----------+-------------- - -
short short ... short short ...
@endcode @endcode
*/ */
class Method : public Base class Method : public Base
@ -239,7 +254,7 @@ namespace QAMQP
+----------+--------+-----------+----------------+------------- - - +----------+--------+-----------+----------------+------------- - -
| class-id | weight | body size | property flags | property list... | class-id | weight | body size | property flags | property list...
+----------+--------+-----------+----------------+------------- - - +----------+--------+-----------+----------------+------------- - -
short short long long short remainder... short short long long short remainder...
@endcode @endcode
| Property | Description | | Property | Description |
@ -379,6 +394,24 @@ namespace QAMQP
void writePayload(QDataStream & stream) const; void writePayload(QDataStream & stream) const;
void readPayload(QDataStream & stream); void readPayload(QDataStream & stream);
}; };
class MethodHandler
{
public:
virtual void _q_method(const QAMQP::Frame::Method & frame) = 0;
};
class ContentHandler
{
public:
virtual void _q_content(const QAMQP::Frame::Content & frame) = 0;
};
class ContentBodyHandler
{
public:
virtual void _q_body(const QAMQP::Frame::ContentBody & frame) = 0;
};
} }
} }

View File

@ -13,7 +13,7 @@
#define AMQPPSWD "guest" #define AMQPPSWD "guest"
#define FRAME_MAX 131072 #define FRAME_MAX 131072
#define QAMQP_VERSION "0.1.2" #define QAMQP_VERSION "0.2.0"

View File

@ -1,20 +1,16 @@
#include "amqp_network.h" #include "amqp_network.h"
#include <QDebug> #include <QDebug>
#include <QTimer> #include <QTimer>
#include <QtEndian>
QAMQP::Network::Network( QObject * parent /*= 0*/ ):QObject(parent) QAMQP::Network::Network( QObject * parent /*= 0*/ ):QObject(parent)
{ {
qRegisterMetaType<QAMQP::Frame::Method>("QAMQP::Frame::Method"); qRegisterMetaType<QAMQP::Frame::Method>("QAMQP::Frame::Method");
buffer_.reserve(Frame::HEADER_SIZE);
buffer_ = new QBuffer(this);
offsetBuf = 0;
leftSize = 0;
timeOut_ = 1000; timeOut_ = 1000;
connect_ = false; connect_ = false;
buffer_->open(QIODevice::ReadWrite);
initSocket(false); initSocket(false);
} }
@ -97,54 +93,59 @@ void QAMQP::Network::error( QAbstractSocket::SocketError socketError )
void QAMQP::Network::readyRead() void QAMQP::Network::readyRead()
{ {
QDataStream streamA(socket_); while(socket_->bytesAvailable() >= Frame::HEADER_SIZE)
QDataStream streamB(buffer_);
while(!socket_->atEnd())
{ {
if(leftSize == 0) char* headerData = buffer_.data();
socket_->peek(headerData, Frame::HEADER_SIZE);
const quint32 payloadSize = qFromBigEndian<quint32>(*(quint32*)&headerData[3]);
const qint64 readSize = Frame::HEADER_SIZE+payloadSize+Frame::FRAME_END_SIZE;
if(socket_->bytesAvailable() >= readSize)
{ {
lastType_ = 0; buffer_.resize(readSize);
qint16 channel_ = 0; socket_->read(buffer_.data(), readSize);
leftSize = 0; const char* bufferData = buffer_.constData();
offsetBuf = 0; const quint8 type = *(quint8*)&bufferData[0];
const quint8 magic = *(quint8*)&bufferData[Frame::HEADER_SIZE+payloadSize];
if(magic != QAMQP::Frame::FRAME_END)
{
qWarning() << "Wrong end frame";
}
streamA >> lastType_; QDataStream streamB(&buffer_, QIODevice::ReadOnly);
streamB << lastType_; switch(QAMQP::Frame::Type(type))
streamA >> channel_;
streamB << channel_;
streamA >> leftSize;
streamB << leftSize;
leftSize++;
}
QByteArray data_;
data_.resize(leftSize);
offsetBuf = streamA.readRawData(data_.data(), data_.size());
leftSize -= offsetBuf;
streamB.writeRawData(data_.data(), offsetBuf);
if(leftSize == 0)
{
buffer_->reset();
switch(QAMQP::Frame::Type(lastType_))
{ {
case QAMQP::Frame::ftMethod: case QAMQP::Frame::ftMethod:
{ {
QAMQP::Frame::Method frame(streamB); QAMQP::Frame::Method frame(streamB);
emit method(frame); if(frame.methodClass() == QAMQP::Frame::fcConnection)
{
m_pMethodHandlerConnection->_q_method(frame);
}
else
{
foreach(Frame::MethodHandler* pMethodHandler, m_methodHandlersByChannel[frame.channel()])
{
pMethodHandler->_q_method(frame);
}
}
} }
break; break;
case QAMQP::Frame::ftHeader: case QAMQP::Frame::ftHeader:
{ {
QAMQP::Frame::Content frame(streamB); QAMQP::Frame::Content frame(streamB);
emit content(frame); foreach(Frame::ContentHandler* pMethodHandler, m_contentHandlerByChannel[frame.channel()])
{
pMethodHandler->_q_content(frame);
}
} }
break; break;
case QAMQP::Frame::ftBody: case QAMQP::Frame::ftBody:
{ {
QAMQP::Frame::ContentBody frame(streamB); QAMQP::Frame::ContentBody frame(streamB);
emit body(frame.channel(), frame.body()); foreach(Frame::ContentBodyHandler* pMethodHandler, m_bodyHandlersByChannel[frame.channel()])
{
pMethodHandler->_q_body(frame);
}
} }
break; break;
case QAMQP::Frame::ftHeartbeat: case QAMQP::Frame::ftHeartbeat:
@ -153,9 +154,12 @@ void QAMQP::Network::readyRead()
} }
break; break;
default: default:
qWarning("AMQP: Unknown frame type"); qWarning() << "AMQP: Unknown frame type: " << type;
} }
buffer_->reset(); }
else
{
break;
} }
} }
} }
@ -194,8 +198,7 @@ void QAMQP::Network::initSocket( bool ssl /*= false*/ )
socket_ = new QSslSocket(this); socket_ = new QSslSocket(this);
QSslSocket * ssl_= static_cast<QSslSocket*> (socket_.data()); QSslSocket * ssl_= static_cast<QSslSocket*> (socket_.data());
ssl_->setProtocol(QSsl::AnyProtocol); ssl_->setProtocol(QSsl::AnyProtocol);
connect(socket_, SIGNAL(sslErrors(const QList<QSslError> &)), connect(socket_, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors()));
this, SLOT(sslErrors()));
connect(socket_, SIGNAL(connected()), this, SLOT(conectionReady())); connect(socket_, SIGNAL(connected()), this, SLOT(conectionReady()));
#else #else
@ -251,3 +254,23 @@ QAbstractSocket::SocketState QAMQP::Network::state() const
} }
} }
void QAMQP::Network::setMethodHandlerConnection(Frame::MethodHandler* pMethodHandlerConnection)
{
m_pMethodHandlerConnection = pMethodHandlerConnection;
}
void QAMQP::Network::addMethodHandlerForChannel(Channel channel, Frame::MethodHandler* pHandler)
{
m_methodHandlersByChannel[channel].append(pHandler);
}
void QAMQP::Network::addContentHandlerForChannel(Channel channel, Frame::ContentHandler* pHandler)
{
m_contentHandlerByChannel[channel].append(pHandler);
}
void QAMQP::Network::addContentBodyHandlerForChannel(Channel channel, Frame::ContentBodyHandler* pHandler)
{
m_bodyHandlersByChannel[channel].append(pHandler);
}

View File

@ -18,6 +18,8 @@ namespace QAMQP
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY(Network) Q_DISABLE_COPY(Network)
public: public:
typedef qint16 Channel;
Network(QObject * parent = 0); Network(QObject * parent = 0);
~Network(); ~Network();
@ -34,6 +36,11 @@ namespace QAMQP
QAbstractSocket::SocketState state() const; QAbstractSocket::SocketState state() const;
void setMethodHandlerConnection(Frame::MethodHandler* pMethodHandlerConnection);
void addMethodHandlerForChannel(Channel channel, Frame::MethodHandler* pHandler);
void addContentHandlerForChannel(Channel channel, Frame::ContentHandler* pHandler);
void addContentBodyHandlerForChannel(Channel channel, Frame::ContentBodyHandler* pHandler);
public slots: public slots:
void connectTo(const QString & host = QString(), quint32 port = 0); void connectTo(const QString & host = QString(), quint32 port = 0);
void error( QAbstractSocket::SocketError socketError ); void error( QAbstractSocket::SocketError socketError );
@ -41,9 +48,6 @@ namespace QAMQP
signals: signals:
void connected(); void connected();
void disconnected(); void disconnected();
void method(const QAMQP::Frame::Method & method);
void content(const QAMQP::Frame::Content & content);
void body(int channeNumber, const QByteArray & body);
private slots: private slots:
void readyRead(); void readyRead();
@ -56,16 +60,18 @@ namespace QAMQP
private: private:
void initSocket(bool ssl = false); void initSocket(bool ssl = false);
QPointer<QTcpSocket> socket_; QPointer<QTcpSocket> socket_;
QPointer<QBuffer> buffer_; QByteArray buffer_;
QString lastHost_; QString lastHost_;
int lastPort_; int lastPort_;
int offsetBuf;
int leftSize;
qint8 lastType_;
bool autoReconnect_; bool autoReconnect_;
int timeOut_; int timeOut_;
bool connect_; bool connect_;
Frame::MethodHandler* m_pMethodHandlerConnection;
QHash<Channel, QList<Frame::MethodHandler*> > m_methodHandlersByChannel;
QHash<Channel, QList<Frame::ContentHandler*> > m_contentHandlerByChannel;
QHash<Channel, QList<Frame::ContentBodyHandler*> > m_bodyHandlersByChannel;
}; };
} }
#endif // amqp_network_h__ #endif // amqp_network_h__

View File

@ -54,10 +54,10 @@ void Queue::onOpen()
} }
if(!d->delayedBindings.isEmpty()) if(!d->delayedBindings.isEmpty())
{ {
QMap<QString, QString>::iterator i; typedef QPair<QString, QString> BindingPair;
for(i = d->delayedBindings.begin(); i!= d->delayedBindings.end(); ++i ) foreach(BindingPair binding, d->delayedBindings)
{ {
d->bind(i.value(), i.key()); d->bind(binding.first, binding.second);
} }
d->delayedBindings.clear(); d->delayedBindings.clear();
} }
@ -129,6 +129,15 @@ void Queue::unbind( Exchange * exchange, const QString & key )
pd_func()->unbind(exchange->name(), key); pd_func()->unbind(exchange->name(), key);
} }
void Queue::_q_content(const Content &frame)
{
pd_func()->_q_content(frame);
}
void Queue::_q_body(const ContentBody &frame)
{
pd_func()->_q_body(frame);
}
QAMQP::MessagePtr Queue::getMessage() QAMQP::MessagePtr Queue::getMessage()
{ {
@ -365,7 +374,7 @@ void QueuePrivate::bind( const QString & exchangeName, const QString & key )
{ {
if(!opened) if(!opened)
{ {
delayedBindings[exchangeName] = key; delayedBindings.append(QPair<QString,QString>(exchangeName, key));
return; return;
} }
@ -530,6 +539,7 @@ void QueuePrivate::deliver( const QAMQP::Frame::Method & frame )
void QueuePrivate::_q_content( const QAMQP::Frame::Content & frame ) void QueuePrivate::_q_content( const QAMQP::Frame::Content & frame )
{ {
Q_ASSERT(frame.channel() == number);
if(frame.channel() != number) if(frame.channel() != number)
return; return;
if(messages_.isEmpty()) if(messages_.isEmpty())
@ -537,7 +547,7 @@ void QueuePrivate::_q_content( const QAMQP::Frame::Content & frame )
qErrnoWarning("Received content-header without method frame before"); qErrnoWarning("Received content-header without method frame before");
return; return;
} }
MessagePtr &message = messages_.head(); MessagePtr &message = messages_.last();
message->leftSize = frame.bodySize(); message->leftSize = frame.bodySize();
QHash<int, QVariant>::ConstIterator i; QHash<int, QVariant>::ConstIterator i;
for (i = frame.properties_.begin(); i != frame.properties_.end(); ++i) for (i = frame.properties_.begin(); i != frame.properties_.end(); ++i)
@ -546,9 +556,10 @@ void QueuePrivate::_q_content( const QAMQP::Frame::Content & frame )
} }
} }
void QueuePrivate::_q_body( int channeNumber, const QByteArray & body ) void QueuePrivate::_q_body(const QAMQP::Frame::ContentBody & frame)
{ {
if(channeNumber!= number) Q_ASSERT(frame.channel() == number);
if(frame.channel() != number)
return; return;
if(messages_.isEmpty()) if(messages_.isEmpty())
@ -556,12 +567,12 @@ void QueuePrivate::_q_body( int channeNumber, const QByteArray & body )
qErrnoWarning("Received content-body without method frame before"); qErrnoWarning("Received content-body without method frame before");
return; return;
} }
MessagePtr &message = messages_.head(); MessagePtr &message = messages_.last();
message->payload.append(body); message->payload.append(frame.body());
message->leftSize -= body.size(); message->leftSize -= frame.body().size();
if(message->leftSize == 0 && messages_.size() == 1) if(message->leftSize == 0 && messages_.size() == 1)
{ {
QMetaObject::invokeMethod(pq_func(), "messageReceived"); emit pq_func()->messageReceived(pq_func());
} }
} }

View File

@ -10,7 +10,7 @@ namespace QAMQP
class ClientPrivate; class ClientPrivate;
class Exchange; class Exchange;
class QueuePrivate; class QueuePrivate;
class Queue : public Channel class Queue : public Channel, public Frame::ContentHandler, public Frame::ContentBodyHandler
{ {
Q_OBJECT Q_OBJECT
Queue(int channelNumber = -1, Client * parent = 0); Queue(int channelNumber = -1, Client * parent = 0);
@ -77,12 +77,12 @@ namespace QAMQP
void declared(); void declared();
void binded(bool); void binded(bool);
void removed(); void removed();
void messageReceived(); void messageReceived(QAMQP::Queue* pQueue);
void empty(); void empty();
private: private:
Q_PRIVATE_SLOT(pd_func(), void _q_content(const QAMQP::Frame::Content & frame)) void _q_content(const QAMQP::Frame::Content & frame);
Q_PRIVATE_SLOT(pd_func(), void _q_body(int channeNumber, const QByteArray & body)) void _q_body(const QAMQP::Frame::ContentBody & frame);
}; };
} }
#ifdef QAMQP_P_INCLUDE #ifdef QAMQP_P_INCLUDE

View File

@ -58,13 +58,13 @@ namespace QAMQP
bool noAck; bool noAck;
QString consumerTag; QString consumerTag;
QMap<QString, QString> delayedBindings; QQueue<QPair<QString, QString> > delayedBindings;
QQueue<QAMQP::MessagePtr> messages_; QQueue<QAMQP::MessagePtr> messages_;
bool recievingMessage; bool recievingMessage;
void _q_content(const QAMQP::Frame::Content & frame); void _q_content(const QAMQP::Frame::Content & frame);
void _q_body(int channeNumber, const QByteArray & body); void _q_body(const QAMQP::Frame::ContentBody & frame);
}; };
} }
#endif // amqp_queue_p_h__ #endif // amqp_queue_p_h__