dynamic compression support
This commit is contained in:
parent
cc795a2dd7
commit
d892d320ea
9 changed files with 85 additions and 13 deletions
|
@ -21,12 +21,13 @@ private:
|
||||||
ResponseCode cmdBanFromServer(Command_BanFromServer * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
ResponseCode cmdBanFromServer(Command_BanFromServer * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
||||||
ResponseCode cmdShutdownServer(Command_ShutdownServer * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
ResponseCode cmdShutdownServer(Command_ShutdownServer * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
||||||
ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
||||||
|
protected:
|
||||||
|
bool getCompressionSupport() const { return false; }
|
||||||
public:
|
public:
|
||||||
LocalServerInterface(LocalServer *_server);
|
LocalServerInterface(LocalServer *_server);
|
||||||
~LocalServerInterface();
|
~LocalServerInterface();
|
||||||
|
|
||||||
void sendProtocolItem(ProtocolItem *item, bool deleteItem = true);
|
void sendProtocolItem(ProtocolItem *item, bool deleteItem = true);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void itemToClient(ProtocolItem *item);
|
void itemToClient(ProtocolItem *item);
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -83,6 +83,7 @@ void RemoteClient::readData()
|
||||||
xmlWriter->writeStartDocument();
|
xmlWriter->writeStartDocument();
|
||||||
xmlWriter->writeStartElement("cockatrice_client_stream");
|
xmlWriter->writeStartElement("cockatrice_client_stream");
|
||||||
xmlWriter->writeAttribute("version", QString::number(ProtocolItem::protocolVersion));
|
xmlWriter->writeAttribute("version", QString::number(ProtocolItem::protocolVersion));
|
||||||
|
xmlWriter->writeAttribute("comp", "1");
|
||||||
|
|
||||||
topLevelItem = new TopLevelProtocolItem;
|
topLevelItem = new TopLevelProtocolItem;
|
||||||
connect(topLevelItem, SIGNAL(protocolItemReceived(ProtocolItem *)), this, SLOT(processProtocolItem(ProtocolItem *)));
|
connect(topLevelItem, SIGNAL(protocolItemReceived(ProtocolItem *)), this, SLOT(processProtocolItem(ProtocolItem *)));
|
||||||
|
|
|
@ -74,7 +74,7 @@ TopLevelProtocolItem::TopLevelProtocolItem()
|
||||||
bool TopLevelProtocolItem::readCurrentItem(QXmlStreamReader *xml)
|
bool TopLevelProtocolItem::readCurrentItem(QXmlStreamReader *xml)
|
||||||
{
|
{
|
||||||
if (currentItem) {
|
if (currentItem) {
|
||||||
if (currentItem->readElement(xml)) {
|
if (currentItem->read(xml)) {
|
||||||
emit protocolItemReceived(currentItem);
|
emit protocolItemReceived(currentItem);
|
||||||
currentItem = 0;
|
currentItem = 0;
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,8 @@ bool TopLevelProtocolItem::readElement(QXmlStreamReader *xml)
|
||||||
currentItem = dynamic_cast<ProtocolItem *>(getNewItem(childName + childSubType));
|
currentItem = dynamic_cast<ProtocolItem *>(getNewItem(childName + childSubType));
|
||||||
if (!currentItem)
|
if (!currentItem)
|
||||||
currentItem = new ProtocolItem_Invalid;
|
currentItem = new ProtocolItem_Invalid;
|
||||||
|
if (xml->attributes().value("comp").toString().toInt() == 1)
|
||||||
|
currentItem->setCompressed(true);
|
||||||
|
|
||||||
readCurrentItem(xml);
|
readCurrentItem(xml);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#include "serializable_item.h"
|
#include "serializable_item.h"
|
||||||
#include <QXmlStreamReader>
|
#include <QXmlStreamReader>
|
||||||
#include <QXmlStreamWriter>
|
#include <QXmlStreamWriter>
|
||||||
#include <QDebug>
|
#include <QBuffer>
|
||||||
|
|
||||||
QHash<QString, SerializableItem::NewItemFunction> SerializableItem::itemNameHash;
|
QHash<QString, SerializableItem::NewItemFunction> SerializableItem::itemNameHash;
|
||||||
|
|
||||||
SerializableItem *SerializableItem::getNewItem(const QString &name)
|
SerializableItem *SerializableItem::getNewItem(const QString &name)
|
||||||
|
@ -16,6 +17,32 @@ void SerializableItem::registerSerializableItem(const QString &name, NewItemFunc
|
||||||
itemNameHash.insert(name, func);
|
itemNameHash.insert(name, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SerializableItem::read(QXmlStreamReader *xml)
|
||||||
|
{
|
||||||
|
if (!compressed)
|
||||||
|
return readElement(xml);
|
||||||
|
if (xml->isEndElement() && (xml->name() == itemType)) {
|
||||||
|
QByteArray uncompressedData = "<d>" + qUncompress(QByteArray::fromBase64(compressedData)) + "</d>";
|
||||||
|
compressedData.clear();
|
||||||
|
QBuffer compressedBuffer(&uncompressedData);
|
||||||
|
compressedBuffer.open(QIODevice::ReadOnly);
|
||||||
|
QXmlStreamReader *xml2 = new QXmlStreamReader(&compressedBuffer);
|
||||||
|
while (!xml2->atEnd()) {
|
||||||
|
xml2->readNext();
|
||||||
|
if (xml2->name() == "d")
|
||||||
|
continue;
|
||||||
|
readElement(xml2);
|
||||||
|
}
|
||||||
|
delete xml2;
|
||||||
|
compressedBuffer.close();
|
||||||
|
|
||||||
|
return readElement(xml);
|
||||||
|
} else {
|
||||||
|
compressedData.append(xml->text().toString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SerializableItem::readElement(QXmlStreamReader *xml)
|
bool SerializableItem::readElement(QXmlStreamReader *xml)
|
||||||
{
|
{
|
||||||
if (xml->isEndElement() && (xml->name() == itemType))
|
if (xml->isEndElement() && (xml->name() == itemType))
|
||||||
|
@ -31,7 +58,19 @@ void SerializableItem::write(QXmlStreamWriter *xml)
|
||||||
xml->writeStartElement(itemType);
|
xml->writeStartElement(itemType);
|
||||||
if (!itemSubType.isEmpty())
|
if (!itemSubType.isEmpty())
|
||||||
xml->writeAttribute("type", itemSubType);
|
xml->writeAttribute("type", itemSubType);
|
||||||
writeElement(xml);
|
if (compressed) {
|
||||||
|
xml->writeAttribute("comp", "1");
|
||||||
|
|
||||||
|
QBuffer compressBuffer;
|
||||||
|
compressBuffer.open(QIODevice::WriteOnly);
|
||||||
|
QXmlStreamWriter *xml2 = new QXmlStreamWriter(&compressBuffer);
|
||||||
|
writeElement(xml2);
|
||||||
|
delete xml2;
|
||||||
|
compressBuffer.close();
|
||||||
|
|
||||||
|
xml->writeCharacters(qCompress(compressBuffer.data()).toBase64());
|
||||||
|
} else
|
||||||
|
writeElement(xml);
|
||||||
xml->writeEndElement();
|
xml->writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +86,7 @@ SerializableItem_Map::~SerializableItem_Map()
|
||||||
bool SerializableItem_Map::readElement(QXmlStreamReader *xml)
|
bool SerializableItem_Map::readElement(QXmlStreamReader *xml)
|
||||||
{
|
{
|
||||||
if (currentItem) {
|
if (currentItem) {
|
||||||
if (currentItem->readElement(xml))
|
if (currentItem->read(xml))
|
||||||
currentItem = 0;
|
currentItem = 0;
|
||||||
return false;
|
return false;
|
||||||
} else if (firstItem)
|
} else if (firstItem)
|
||||||
|
@ -57,6 +96,7 @@ bool SerializableItem_Map::readElement(QXmlStreamReader *xml)
|
||||||
else if (xml->isStartElement()) {
|
else if (xml->isStartElement()) {
|
||||||
QString childName = xml->name().toString();
|
QString childName = xml->name().toString();
|
||||||
QString childSubType = xml->attributes().value("type").toString();
|
QString childSubType = xml->attributes().value("type").toString();
|
||||||
|
bool childCompressed = xml->attributes().value("comp").toString().toInt() == 1;
|
||||||
currentItem = itemMap.value(childName);
|
currentItem = itemMap.value(childName);
|
||||||
if (!currentItem) {
|
if (!currentItem) {
|
||||||
currentItem = getNewItem(childName + childSubType);
|
currentItem = getNewItem(childName + childSubType);
|
||||||
|
@ -64,7 +104,8 @@ bool SerializableItem_Map::readElement(QXmlStreamReader *xml)
|
||||||
if (!currentItem)
|
if (!currentItem)
|
||||||
currentItem = new SerializableItem_Invalid(childName);
|
currentItem = new SerializableItem_Invalid(childName);
|
||||||
}
|
}
|
||||||
if (currentItem->readElement(xml))
|
currentItem->setCompressed(childCompressed);
|
||||||
|
if (currentItem->read(xml))
|
||||||
currentItem = 0;
|
currentItem = 0;
|
||||||
}
|
}
|
||||||
return SerializableItem::readElement(xml);
|
return SerializableItem::readElement(xml);
|
||||||
|
|
|
@ -15,6 +15,10 @@ class QXmlStreamWriter;
|
||||||
|
|
||||||
class SerializableItem : public QObject {
|
class SerializableItem : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
bool compressed;
|
||||||
|
QByteArray compressedData;
|
||||||
|
QXmlStreamReader *compressedReader;
|
||||||
protected:
|
protected:
|
||||||
typedef SerializableItem *(*NewItemFunction)();
|
typedef SerializableItem *(*NewItemFunction)();
|
||||||
static QHash<QString, NewItemFunction> itemNameHash;
|
static QHash<QString, NewItemFunction> itemNameHash;
|
||||||
|
@ -23,7 +27,7 @@ protected:
|
||||||
bool firstItem;
|
bool firstItem;
|
||||||
public:
|
public:
|
||||||
SerializableItem(const QString &_itemType, const QString &_itemSubType = QString())
|
SerializableItem(const QString &_itemType, const QString &_itemSubType = QString())
|
||||||
: QObject(), itemType(_itemType), itemSubType(_itemSubType), firstItem(true) { }
|
: QObject(), compressed(false), itemType(_itemType), itemSubType(_itemSubType), firstItem(true) { }
|
||||||
static void registerSerializableItem(const QString &name, NewItemFunction func);
|
static void registerSerializableItem(const QString &name, NewItemFunction func);
|
||||||
static SerializableItem *getNewItem(const QString &name);
|
static SerializableItem *getNewItem(const QString &name);
|
||||||
const QString &getItemType() const { return itemType; }
|
const QString &getItemType() const { return itemType; }
|
||||||
|
@ -31,6 +35,8 @@ public:
|
||||||
virtual bool readElement(QXmlStreamReader *xml);
|
virtual bool readElement(QXmlStreamReader *xml);
|
||||||
virtual void writeElement(QXmlStreamWriter *xml) = 0;
|
virtual void writeElement(QXmlStreamWriter *xml) = 0;
|
||||||
virtual bool isEmpty() const = 0;
|
virtual bool isEmpty() const = 0;
|
||||||
|
void setCompressed(bool _compressed) { compressed = _compressed; }
|
||||||
|
bool read(QXmlStreamReader *xml);
|
||||||
void write(QXmlStreamWriter *xml);
|
void write(QXmlStreamWriter *xml);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,10 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain
|
||||||
if (authState == WouldOverwriteOldSession)
|
if (authState == WouldOverwriteOldSession)
|
||||||
return RespWouldOverwriteOldSession;
|
return RespWouldOverwriteOldSession;
|
||||||
|
|
||||||
enqueueProtocolItem(new Event_ServerMessage(server->getLoginMessage()));
|
ProtocolItem *serverMessage = new Event_ServerMessage(server->getLoginMessage());
|
||||||
|
if (getCompressionSupport())
|
||||||
|
serverMessage->setCompressed(true);
|
||||||
|
enqueueProtocolItem(serverMessage);
|
||||||
|
|
||||||
QList<ServerInfo_User *> _buddyList, _ignoreList;
|
QList<ServerInfo_User *> _buddyList, _ignoreList;
|
||||||
if (authState == PasswordRight) {
|
if (authState == PasswordRight) {
|
||||||
|
@ -303,7 +306,10 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain
|
||||||
_ignoreList.append(new ServerInfo_User(ignoreIterator.next().value()));
|
_ignoreList.append(new ServerInfo_User(ignoreIterator.next().value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
cont->setResponse(new Response_Login(cont->getCmdId(), RespOk, new ServerInfo_User(userInfo, true), _buddyList, _ignoreList));
|
ProtocolResponse *resp = new Response_Login(cont->getCmdId(), RespOk, new ServerInfo_User(userInfo, true), _buddyList, _ignoreList);
|
||||||
|
if (getCompressionSupport())
|
||||||
|
resp->setCompressed(true);
|
||||||
|
cont->setResponse(resp);
|
||||||
return RespNothing;
|
return RespNothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,7 +401,10 @@ ResponseCode Server_ProtocolHandler::cmdJoinRoom(Command_JoinRoom *cmd, CommandC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cont->setResponse(new Response_JoinRoom(cont->getCmdId(), RespOk, r->getInfo(true)));
|
ServerInfo_Room *info = r->getInfo(true);
|
||||||
|
if (getCompressionSupport())
|
||||||
|
info->setCompressed(true);
|
||||||
|
cont->setResponse(new Response_JoinRoom(cont->getCmdId(), RespOk, info));
|
||||||
return RespNothing;
|
return RespNothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +453,10 @@ ResponseCode Server_ProtocolHandler::cmdListUsers(Command_ListUsers * /*cmd*/, C
|
||||||
|
|
||||||
acceptsUserListChanges = true;
|
acceptsUserListChanges = true;
|
||||||
|
|
||||||
cont->setResponse(new Response_ListUsers(cont->getCmdId(), RespOk, resultList));
|
ProtocolResponse *resp = new Response_ListUsers(cont->getCmdId(), RespOk, resultList);
|
||||||
|
if (getCompressionSupport())
|
||||||
|
resp->setCompressed(true);
|
||||||
|
cont->setResponse(resp);
|
||||||
return RespNothing;
|
return RespNothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ protected:
|
||||||
QMap<QString, ServerInfo_User *> buddyList, ignoreList;
|
QMap<QString, ServerInfo_User *> buddyList, ignoreList;
|
||||||
|
|
||||||
void prepareDestroy();
|
void prepareDestroy();
|
||||||
|
virtual bool getCompressionSupport() const = 0;
|
||||||
private:
|
private:
|
||||||
QList<ProtocolItem *> itemQueue;
|
QList<ProtocolItem *> itemQueue;
|
||||||
QList<int> messageSizeOverTime, messageCountOverTime;
|
QList<int> messageSizeOverTime, messageCountOverTime;
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "server_logger.h"
|
#include "server_logger.h"
|
||||||
|
|
||||||
ServerSocketInterface::ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent)
|
ServerSocketInterface::ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent)
|
||||||
: Server_ProtocolHandler(_server, parent), servatrice(_server), socket(_socket), topLevelItem(0)
|
: Server_ProtocolHandler(_server, parent), servatrice(_server), socket(_socket), topLevelItem(0), compressionSupport(false)
|
||||||
{
|
{
|
||||||
xmlWriter = new QXmlStreamWriter(&xmlBuffer);
|
xmlWriter = new QXmlStreamWriter(&xmlBuffer);
|
||||||
xmlReader = new QXmlStreamReader;
|
xmlReader = new QXmlStreamReader;
|
||||||
|
@ -101,6 +101,8 @@ void ServerSocketInterface::readClient()
|
||||||
if (topLevelItem)
|
if (topLevelItem)
|
||||||
topLevelItem->readElement(xmlReader);
|
topLevelItem->readElement(xmlReader);
|
||||||
else if (xmlReader->isStartElement() && (xmlReader->name().toString() == "cockatrice_client_stream")) {
|
else if (xmlReader->isStartElement() && (xmlReader->name().toString() == "cockatrice_client_stream")) {
|
||||||
|
if (xmlReader->attributes().value("comp").toString().toInt() == 1)
|
||||||
|
compressionSupport = true;
|
||||||
topLevelItem = new TopLevelProtocolItem;
|
topLevelItem = new TopLevelProtocolItem;
|
||||||
connect(topLevelItem, SIGNAL(protocolItemReceived(ProtocolItem *)), this, SLOT(processProtocolItem(ProtocolItem *)));
|
connect(topLevelItem, SIGNAL(protocolItemReceived(ProtocolItem *)), this, SLOT(processProtocolItem(ProtocolItem *)));
|
||||||
}
|
}
|
||||||
|
@ -295,7 +297,10 @@ ResponseCode ServerSocketInterface::cmdDeckList(Command_DeckList * /*cmd*/, Comm
|
||||||
if (!deckListHelper(root))
|
if (!deckListHelper(root))
|
||||||
return RespContextError;
|
return RespContextError;
|
||||||
|
|
||||||
cont->setResponse(new Response_DeckList(cont->getCmdId(), RespOk, root));
|
ProtocolResponse *resp = new Response_DeckList(cont->getCmdId(), RespOk, root);
|
||||||
|
if (getCompressionSupport())
|
||||||
|
resp->setCompressed(true);
|
||||||
|
cont->setResponse(resp);
|
||||||
|
|
||||||
return RespNothing;
|
return RespNothing;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ private:
|
||||||
QXmlStreamReader *xmlReader;
|
QXmlStreamReader *xmlReader;
|
||||||
QString xmlBuffer;
|
QString xmlBuffer;
|
||||||
TopLevelProtocolItem *topLevelItem;
|
TopLevelProtocolItem *topLevelItem;
|
||||||
|
bool compressionSupport;
|
||||||
int getUserIdInDB(const QString &name) const;
|
int getUserIdInDB(const QString &name) const;
|
||||||
|
|
||||||
ResponseCode cmdAddToList(Command_AddToList *cmd, CommandContainer *cont);
|
ResponseCode cmdAddToList(Command_AddToList *cmd, CommandContainer *cont);
|
||||||
|
@ -69,6 +70,8 @@ private:
|
||||||
ResponseCode cmdBanFromServer(Command_BanFromServer *cmd, CommandContainer *cont);
|
ResponseCode cmdBanFromServer(Command_BanFromServer *cmd, CommandContainer *cont);
|
||||||
ResponseCode cmdShutdownServer(Command_ShutdownServer *cmd, CommandContainer *cont);
|
ResponseCode cmdShutdownServer(Command_ShutdownServer *cmd, CommandContainer *cont);
|
||||||
ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage *cmd, CommandContainer *cont);
|
ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage *cmd, CommandContainer *cont);
|
||||||
|
protected:
|
||||||
|
bool getCompressionSupport() const { return compressionSupport; }
|
||||||
public:
|
public:
|
||||||
ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent = 0);
|
ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent = 0);
|
||||||
~ServerSocketInterface();
|
~ServerSocketInterface();
|
||||||
|
|
Loading…
Reference in a new issue