sigNames.insert(methodId, fn);
}
// ====================
-// END SIGNALRELAY
+// /SIGNALRELAY
// ====================
detachObject(sender);
// close peer connections
- foreach(QIODevice *device, _peerByteCount.keys()) {
+ foreach(QIODevice *device, _peers.keys()) {
device->close();
delete device;
}
}
void SignalProxy::setProxyMode(ProxyMode mode) {
- foreach(QIODevice* peer, _peerByteCount.keys()) {
+ foreach(QIODevice* peer, _peers.keys()) {
if(peer->isOpen()) {
qWarning() << "SignalProxy: Cannot change proxy mode while connected";
return;
if(!iodev)
return false;
- if(_peerByteCount.contains(iodev))
+ if(_peers.contains(iodev))
return true;
- if(proxyMode() == Client && !_peerByteCount.isEmpty()) {
+ if(proxyMode() == Client && !_peers.isEmpty()) {
qWarning("SignalProxy: only one peer allowed in client mode!");
return false;
}
connect(sock, SIGNAL(disconnected()), this, SLOT(removePeerBySender()));
}
- _peerByteCount[iodev] = 0;
+ _peers[iodev] = peerInfo();
+ if(iodev->property("UseCompression").toBool())
+ _peers[iodev].usesCompression = true;
- if(_peerByteCount.count() == 1)
+ if(_peers.count() == 1)
emit connected();
return true;
}
void SignalProxy::removePeer(QIODevice* iodev) {
- if(_peerByteCount.isEmpty()) {
+ if(_peers.isEmpty()) {
qWarning() << "SignalProxy::removePeer(): No peers in use!";
return;
}
if(proxyMode() == Server && !iodev) {
// disconnect all
- QList<QIODevice *> peers = _peerByteCount.keys();
+ QList<QIODevice *> peers = _peers.keys();
foreach(QIODevice *peer, peers)
removePeer(peer);
}
if(proxyMode() != Server && !iodev)
- iodev = _peerByteCount.keys().first();
+ iodev = _peers.keys().first();
Q_ASSERT(iodev);
- if(!_peerByteCount.contains(iodev)) {
+ if(!_peers.contains(iodev)) {
qWarning() << "SignalProxy: unknown QIODevice" << iodev;
return;
}
- _peerByteCount.remove(iodev);
+ _peers.remove(iodev);
disconnect(iodev, 0, this, 0);
emit peerRemoved(iodev);
- if(_peerByteCount.isEmpty())
+ if(_peers.isEmpty())
emit disconnected();
}
}
void SignalProxy::dispatchSignal(QIODevice *receiver, const RequestType &requestType, const QVariantList ¶ms) {
+ Q_ASSERT(_peers.contains(receiver));
QVariantList packedFunc;
packedFunc << (qint16)requestType;
packedFunc << params;
- writeDataToDevice(receiver, QVariant(packedFunc));
+ writeDataToDevice(receiver, QVariant(packedFunc), _peers[receiver].usesCompression);
}
void SignalProxy::dispatchSignal(const RequestType &requestType, const QVariantList ¶ms) {
QVariantList packedFunc;
packedFunc << (qint16)requestType;
packedFunc << params;
- foreach(QIODevice* dev, _peerByteCount.keys())
- writeDataToDevice(dev, QVariant(packedFunc));
+ foreach(QIODevice* dev, _peers.keys()) {
+ Q_ASSERT(_peers.contains(dev));
+ writeDataToDevice(dev, QVariant(packedFunc), _peers[dev].usesCompression);
+ }
}
void SignalProxy::receivePeerSignal(QIODevice *sender, const QVariant &packedFunc) {
void SignalProxy::dataAvailable() {
// yet again. it's a private slot. no need for checks.
QIODevice* ioDev = qobject_cast<QIODevice* >(sender());
+ Q_ASSERT(_peers.contains(ioDev));
QVariant var;
- while(readDataFromDevice(ioDev, _peerByteCount[ioDev], var))
+ while(readDataFromDevice(ioDev, _peers[ioDev].byteCount, var, _peers[ioDev].usesCompression))
receivePeerSignal(ioDev, var);
}
-void SignalProxy::writeDataToDevice(QIODevice *dev, const QVariant &item) {
+void SignalProxy::writeDataToDevice(QIODevice *dev, const QVariant &item, bool compressed) {
QAbstractSocket* sock = qobject_cast<QAbstractSocket*>(dev);
if(!dev->isOpen() || (sock && sock->state()!=QAbstractSocket::ConnectedState)) {
qWarning("SignalProxy: Can't call on a closed device");
return;
}
+
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_2);
- out << (quint32)0 << item;
- out.device()->seek(0);
- out << (quint32)(block.size() - sizeof(quint32));
+
+ if(compressed) {
+ QByteArray rawItem;
+ QDataStream itemStream(&rawItem, QIODevice::WriteOnly);
+
+ itemStream.setVersion(QDataStream::Qt_4_2);
+ itemStream << item;
+
+ rawItem = qCompress(rawItem);
+
+ out << (quint32)rawItem.size() << rawItem;
+ } else {
+ out << (quint32)0 << item;
+ out.device()->seek(0);
+ out << (quint32)(block.size() - sizeof(quint32));
+ }
+
dev->write(block);
}
-bool SignalProxy::readDataFromDevice(QIODevice *dev, quint32 &blockSize, QVariant &item) {
+bool SignalProxy::readDataFromDevice(QIODevice *dev, quint32 &blockSize, QVariant &item, bool compressed) {
QDataStream in(dev);
in.setVersion(QDataStream::Qt_4_2);
if(dev->bytesAvailable() < blockSize)
return false;
- in >> item;
+
+ if(compressed) {
+ QByteArray rawItem;
+ in >> rawItem;
+ rawItem = qUncompress(rawItem);
+
+ QDataStream itemStream(&rawItem, QIODevice::ReadOnly);
+ itemStream.setVersion(QDataStream::Qt_4_2);
+ itemStream >> item;
+ } else {
+ in >> item;
+ }
+
blockSize = 0;
+
return true;
}
* so the corresponding function readDataFromDevice() can check if enough data is available
* at the device to reread the item.
*/
- static void writeDataToDevice(QIODevice *dev, const QVariant &item);
+ static void writeDataToDevice(QIODevice *dev, const QVariant &item, bool compressed = false);
//! Reads a data item from a device that has been written by writeDataToDevice().
/** If not enough data bytes are available, the function returns false and the QVariant reference
* remains untouched.
*/
- static bool readDataFromDevice(QIODevice *dev, quint32 &blockSize, QVariant &item);
+ static bool readDataFromDevice(QIODevice *dev, quint32 &blockSize, QVariant &item, bool compressed = false);
static QString methodBaseName(const QMetaMethod &method);
private:
// Hash of used QIODevices
- QHash<QIODevice*, quint32> _peerByteCount;
+ struct peerInfo {
+ quint32 byteCount;
+ bool usesCompression;
+ peerInfo() : byteCount(0), usesCompression(false) {};
+ };
+ //QHash<QIODevice*, peerInfo> _peerByteCount;
+ QHash<QIODevice*, peerInfo> _peers;
// containg a list of argtypes for fast access
QHash<const QMetaObject *, ClassInfo*> _classInfo;
#else
bool supportSsl = false;
#endif
+
+#ifndef QT_NO_COMPRESS
+ bool supportsCompression = true;
+#else
+ bool supportsCompression = false;
+#endif
reply["SupportSsl"] = supportSsl;
- // switch to ssl after client has been informed about our capabilities (see below)
+ reply["SupportsCompression"] = supportsCompression;
+ // switch to ssl/compression after client has been informed about our capabilities (see below)
reply["LoginEnabled"] = true;
#ifndef QT_NO_OPENSSL
// after we told the client that we are ssl capable we switch to ssl mode
if(supportSsl && msg["UseSsl"].toBool()) {
- qDebug() << "Starting TLS for Client:" << qPrintable(socket->peerAddress().toString());
+ qDebug() << "Starting TLS for Client:" << qPrintable(socket->peerAddress().toString());
connect(sslSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &)));
sslSocket->startServerEncryption();
}
#endif
+#ifndef QT_NO_COMPRESS
+ if(supportsCompression && msg["UseCompression"].toBool()) {
+ socket->setProperty("UseCompression", true);
+ qDebug() << "Using compression for Client:" << qPrintable(socket->peerAddress().toString());
+ }
+#endif
+
} else {
// for the rest, we need an initialized connection
if(!clientInfo.contains(socket)) {