From 324ae188301d46e2268462bc0d8411baed8f00b8 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Mon, 29 Feb 2016 00:23:25 +0100 Subject: [PATCH] Fix (meta) type handling in existing DCC code Obviously, this code was never tested with a non-monolithic build, and Qt didn't know how to handle our fancy enums. Also, enum classes are now a thing since C++11, and we should use them. Unfortunately, they have the same annoyances as nested classes with Qt4-style signal/slot connections... --- src/client/clienttransfer.cpp | 6 ++-- src/client/clienttransfer.h | 2 +- src/common/quassel.cpp | 2 ++ src/common/transfer.cpp | 42 +++++++++++++++++++++++--- src/common/transfer.h | 22 +++++++++----- src/core/coresessioneventprocessor.cpp | 2 +- src/core/coretransfer.cpp | 23 +++++++------- 7 files changed, 72 insertions(+), 27 deletions(-) diff --git a/src/client/clienttransfer.cpp b/src/client/clienttransfer.cpp index 83980979..4b55e930 100644 --- a/src/client/clienttransfer.cpp +++ b/src/client/clienttransfer.cpp @@ -27,7 +27,7 @@ ClientTransfer::ClientTransfer(const QUuid &uuid, QObject *parent) : Transfer(uuid, parent), _file(0) { - connect(this, SIGNAL(stateChanged(State)), SLOT(onStateChanged(State))); + connect(this, SIGNAL(stateChanged(Transfer::State)), SLOT(onStateChanged(Transfer::State))); } @@ -88,11 +88,11 @@ void ClientTransfer::dataReceived(PeerPtr, const QByteArray &data) void ClientTransfer::onStateChanged(Transfer::State state) { switch(state) { - case Completed: + case State::Completed: if (_file) _file->close(); break; - case Failed: + case State::Failed: if (_file) _file->remove(); break; diff --git a/src/client/clienttransfer.h b/src/client/clienttransfer.h index 04637c78..e7a09d11 100644 --- a/src/client/clienttransfer.h +++ b/src/client/clienttransfer.h @@ -44,7 +44,7 @@ public slots: private slots: void dataReceived(PeerPtr peer, const QByteArray &data); - void onStateChanged(State state); + void onStateChanged(Transfer::State state); private: virtual void cleanUp(); diff --git a/src/common/quassel.cpp b/src/common/quassel.cpp index c166ee64..954d91ed 100644 --- a/src/common/quassel.cpp +++ b/src/common/quassel.cpp @@ -194,7 +194,9 @@ void Quassel::registerMetaTypes() qRegisterMetaType("MsgId"); qRegisterMetaType("QHostAddress"); + qRegisterMetaTypeStreamOperators("QHostAddress"); qRegisterMetaType("QUuid"); + qRegisterMetaTypeStreamOperators("QUuid"); qRegisterMetaTypeStreamOperators("IdentityId"); qRegisterMetaTypeStreamOperators("BufferId"); diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index 460b0676..f565a0d2 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -23,8 +23,8 @@ INIT_SYNCABLE_OBJECT(Transfer) Transfer::Transfer(const QUuid &uuid, QObject *parent) : SyncableObject(parent), - _state(New), - _direction(Receive), + _state(State::New), + _direction(Direction::Receive), _port(0), _fileSize(0), _uuid(uuid) @@ -34,7 +34,7 @@ Transfer::Transfer(const QUuid &uuid, QObject *parent) Transfer::Transfer(Direction direction, const QString &nick, const QString &fileName, const QHostAddress &address, quint16 port, quint64 fileSize, QObject *parent) : SyncableObject(parent), - _state(New), + _state(State::New), _direction(direction), _fileName(fileName), _address(address), @@ -49,6 +49,15 @@ Transfer::Transfer(Direction direction, const QString &nick, const QString &file void Transfer::init() { + static auto regTypes = []() -> bool { + qRegisterMetaType("Transfer::State"); + qRegisterMetaType("Transfer::Direction"); + qRegisterMetaTypeStreamOperators("Transfer::State"); + qRegisterMetaTypeStreamOperators("Transfer::Direction"); + return true; + }(); + Q_UNUSED(regTypes); + renameObject(QString("Transfer/%1").arg(_uuid.toString())); setAllowClientUpdates(true); } @@ -177,6 +186,31 @@ void Transfer::setError(const QString &errorString) { qWarning() << Q_FUNC_INFO << errorString; emit error(errorString); - setState(Failed); + setState(State::Failed); cleanUp(); } + + +QDataStream &operator<<(QDataStream &out, Transfer::State state) { + out << static_cast(state); + return out; +} + +QDataStream &operator>>(QDataStream &in, Transfer::State &state) { + qint8 s; + in >> s; + state = static_cast(s); + return in; +} + +QDataStream &operator<<(QDataStream &out, Transfer::Direction direction) { + out << static_cast(direction); + return out; +} + +QDataStream &operator>>(QDataStream &in, Transfer::Direction &direction) { + qint8 d; + in >> d; + direction = static_cast(d); + return in; +} diff --git a/src/common/transfer.h b/src/common/transfer.h index 00948514..96a5cc75 100644 --- a/src/common/transfer.h +++ b/src/common/transfer.h @@ -33,8 +33,8 @@ class Transfer : public SyncableObject SYNCABLE_OBJECT Q_PROPERTY(QUuid uuid READ uuid); - Q_PROPERTY(State state READ state WRITE setState NOTIFY stateChanged); - Q_PROPERTY(Direction direction READ direction WRITE setDirection NOTIFY directionChanged); + Q_PROPERTY(Transfer::State state READ state WRITE setState NOTIFY stateChanged); + Q_PROPERTY(Transfer::Direction direction READ direction WRITE setDirection NOTIFY directionChanged); Q_PROPERTY(QHostAddress address READ address WRITE setAddress NOTIFY addressChanged); Q_PROPERTY(quint16 port READ port WRITE setPort NOTIFY portChanged); Q_PROPERTY(QString fileName READ fileName WRITE setFileName NOTIFY fileNameChanged); @@ -42,7 +42,7 @@ class Transfer : public SyncableObject Q_PROPERTY(QString nick READ nick WRITE setNick NOTIFY nickChanged); public: - enum State { + enum class State { New, Pending, Connecting, @@ -54,7 +54,7 @@ public: }; Q_ENUMS(State) - enum Direction { + enum class Direction { Send, Receive }; @@ -83,8 +83,8 @@ public slots: virtual void requestRejected(PeerPtr peer) { Q_UNUSED(peer); } signals: - void stateChanged(State state); - void directionChanged(Direction direction); + void stateChanged(Transfer::State state); + void directionChanged(Transfer::Direction direction); void addressChanged(const QHostAddress &address); void portChanged(quint16 port); void fileNameChanged(const QString &fileName); @@ -97,7 +97,7 @@ signals: void rejected(PeerPtr peer = 0) const; protected slots: - void setState(State state); + void setState(Transfer::State state); void setError(const QString &errorString); // called on the client side through sync calls @@ -126,4 +126,12 @@ private: QUuid _uuid; }; +Q_DECLARE_METATYPE(Transfer::State) +Q_DECLARE_METATYPE(Transfer::Direction) + +QDataStream &operator<<(QDataStream &out, Transfer::State state); +QDataStream &operator>>(QDataStream &in, Transfer::State &state); +QDataStream &operator<<(QDataStream &out, Transfer::Direction direction); +QDataStream &operator>>(QDataStream &in, Transfer::Direction &direction); + #endif diff --git a/src/core/coresessioneventprocessor.cpp b/src/core/coresessioneventprocessor.cpp index b5981dd1..0468d970 100644 --- a/src/core/coresessioneventprocessor.cpp +++ b/src/core/coresessioneventprocessor.cpp @@ -1265,7 +1265,7 @@ void CoreSessionEventProcessor::handleCtcpDcc(CtcpEvent *e) } // TODO: check if target is the right thing to use for the partner - CoreTransfer *transfer = new CoreTransfer(Transfer::Receive, e->target(), filename, address, port, size, this); + CoreTransfer *transfer = new CoreTransfer(Transfer::Direction::Receive, e->target(), filename, address, port, size, this); coreSession()->signalProxy()->synchronize(transfer); coreSession()->transferManager()->addTransfer(transfer); } diff --git a/src/core/coretransfer.cpp b/src/core/coretransfer.cpp index 3ccb5a39..766136e0 100644 --- a/src/core/coretransfer.cpp +++ b/src/core/coretransfer.cpp @@ -54,7 +54,7 @@ void CoreTransfer::cleanUp() void CoreTransfer::onSocketDisconnected() { - if (state() == Connecting || state() == Transferring) { + if (state() == State::Connecting || state() == State::Transferring) { setError(tr("Socket closed while still transferring!")); } else @@ -66,7 +66,7 @@ void CoreTransfer::onSocketError(QAbstractSocket::SocketError error) { Q_UNUSED(error) - if (state() == Connecting || state() == Transferring) { + if (state() == State::Connecting || state() == State::Transferring) { setError(tr("DCC connection error: %1").arg(_socket->errorString())); } } @@ -74,11 +74,11 @@ void CoreTransfer::onSocketError(QAbstractSocket::SocketError error) void CoreTransfer::requestAccepted(PeerPtr peer) { - if (_peer || !peer || state() != New) + if (_peer || !peer || state() != State::New) return; // transfer was already accepted _peer = peer; - setState(Pending); + setState(State::Pending); emit accepted(peer); @@ -89,11 +89,11 @@ void CoreTransfer::requestAccepted(PeerPtr peer) void CoreTransfer::requestRejected(PeerPtr peer) { - if (_peer || state() != New) + if (_peer || state() != State::New) return; _peer = peer; - setState(Rejected); + setState(State::Rejected); emit rejected(peer); } @@ -101,7 +101,7 @@ void CoreTransfer::requestRejected(PeerPtr peer) void CoreTransfer::start() { - if (!_peer || state() != Pending || direction() != Receive) + if (!_peer || state() != State::Pending || direction() != Direction::Receive) return; setupConnectionForReceive(); @@ -115,7 +115,7 @@ void CoreTransfer::setupConnectionForReceive() return; } - setState(Connecting); + setState(State::Connecting); _socket = new QTcpSocket(this); connect(_socket, SIGNAL(connected()), SLOT(startReceiving())); @@ -129,7 +129,7 @@ void CoreTransfer::setupConnectionForReceive() void CoreTransfer::startReceiving() { - setState(Transferring); + setState(State::Transferring); } @@ -162,7 +162,7 @@ void CoreTransfer::onDataReceived() else if (_pos == fileSize()) { qDebug() << "DCC Receive: Transfer finished"; if (relayData(QByteArray(), false)) // empty buffer - setState(Completed); + setState(State::Completed); } _reading = false; @@ -180,7 +180,8 @@ bool CoreTransfer::relayData(const QByteArray &data, bool requireChunkSize) // we only want to send data to the client once we have reached the chunksize if (_buffer.size() > 0 && (_buffer.size() >= chunkSize || !requireChunkSize)) { - SYNC_OTHER(dataReceived, ARG(_peer), ARG(_buffer)); + Peer *p = _peer.data(); + SYNC_OTHER(dataReceived, ARG(p), ARG(_buffer)); _buffer.clear(); } -- 2.20.1