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 cmdShutdownServer(Command_ShutdownServer * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
||||
ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
||||
protected:
|
||||
bool getCompressionSupport() const { return false; }
|
||||
public:
|
||||
LocalServerInterface(LocalServer *_server);
|
||||
~LocalServerInterface();
|
||||
|
||||
void sendProtocolItem(ProtocolItem *item, bool deleteItem = true);
|
||||
|
||||
signals:
|
||||
void itemToClient(ProtocolItem *item);
|
||||
public slots:
|
||||
|
|
|
@ -83,6 +83,7 @@ void RemoteClient::readData()
|
|||
xmlWriter->writeStartDocument();
|
||||
xmlWriter->writeStartElement("cockatrice_client_stream");
|
||||
xmlWriter->writeAttribute("version", QString::number(ProtocolItem::protocolVersion));
|
||||
xmlWriter->writeAttribute("comp", "1");
|
||||
|
||||
topLevelItem = new TopLevelProtocolItem;
|
||||
connect(topLevelItem, SIGNAL(protocolItemReceived(ProtocolItem *)), this, SLOT(processProtocolItem(ProtocolItem *)));
|
||||
|
|
|
@ -74,7 +74,7 @@ TopLevelProtocolItem::TopLevelProtocolItem()
|
|||
bool TopLevelProtocolItem::readCurrentItem(QXmlStreamReader *xml)
|
||||
{
|
||||
if (currentItem) {
|
||||
if (currentItem->readElement(xml)) {
|
||||
if (currentItem->read(xml)) {
|
||||
emit protocolItemReceived(currentItem);
|
||||
currentItem = 0;
|
||||
}
|
||||
|
@ -92,6 +92,8 @@ bool TopLevelProtocolItem::readElement(QXmlStreamReader *xml)
|
|||
currentItem = dynamic_cast<ProtocolItem *>(getNewItem(childName + childSubType));
|
||||
if (!currentItem)
|
||||
currentItem = new ProtocolItem_Invalid;
|
||||
if (xml->attributes().value("comp").toString().toInt() == 1)
|
||||
currentItem->setCompressed(true);
|
||||
|
||||
readCurrentItem(xml);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "serializable_item.h"
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QDebug>
|
||||
#include <QBuffer>
|
||||
|
||||
QHash<QString, SerializableItem::NewItemFunction> SerializableItem::itemNameHash;
|
||||
|
||||
SerializableItem *SerializableItem::getNewItem(const QString &name)
|
||||
|
@ -16,6 +17,32 @@ void SerializableItem::registerSerializableItem(const QString &name, NewItemFunc
|
|||
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)
|
||||
{
|
||||
if (xml->isEndElement() && (xml->name() == itemType))
|
||||
|
@ -31,7 +58,19 @@ void SerializableItem::write(QXmlStreamWriter *xml)
|
|||
xml->writeStartElement(itemType);
|
||||
if (!itemSubType.isEmpty())
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -47,7 +86,7 @@ SerializableItem_Map::~SerializableItem_Map()
|
|||
bool SerializableItem_Map::readElement(QXmlStreamReader *xml)
|
||||
{
|
||||
if (currentItem) {
|
||||
if (currentItem->readElement(xml))
|
||||
if (currentItem->read(xml))
|
||||
currentItem = 0;
|
||||
return false;
|
||||
} else if (firstItem)
|
||||
|
@ -57,6 +96,7 @@ bool SerializableItem_Map::readElement(QXmlStreamReader *xml)
|
|||
else if (xml->isStartElement()) {
|
||||
QString childName = xml->name().toString();
|
||||
QString childSubType = xml->attributes().value("type").toString();
|
||||
bool childCompressed = xml->attributes().value("comp").toString().toInt() == 1;
|
||||
currentItem = itemMap.value(childName);
|
||||
if (!currentItem) {
|
||||
currentItem = getNewItem(childName + childSubType);
|
||||
|
@ -64,7 +104,8 @@ bool SerializableItem_Map::readElement(QXmlStreamReader *xml)
|
|||
if (!currentItem)
|
||||
currentItem = new SerializableItem_Invalid(childName);
|
||||
}
|
||||
if (currentItem->readElement(xml))
|
||||
currentItem->setCompressed(childCompressed);
|
||||
if (currentItem->read(xml))
|
||||
currentItem = 0;
|
||||
}
|
||||
return SerializableItem::readElement(xml);
|
||||
|
|
|
@ -15,6 +15,10 @@ class QXmlStreamWriter;
|
|||
|
||||
class SerializableItem : public QObject {
|
||||
Q_OBJECT
|
||||
private:
|
||||
bool compressed;
|
||||
QByteArray compressedData;
|
||||
QXmlStreamReader *compressedReader;
|
||||
protected:
|
||||
typedef SerializableItem *(*NewItemFunction)();
|
||||
static QHash<QString, NewItemFunction> itemNameHash;
|
||||
|
@ -23,7 +27,7 @@ protected:
|
|||
bool firstItem;
|
||||
public:
|
||||
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 SerializableItem *getNewItem(const QString &name);
|
||||
const QString &getItemType() const { return itemType; }
|
||||
|
@ -31,6 +35,8 @@ public:
|
|||
virtual bool readElement(QXmlStreamReader *xml);
|
||||
virtual void writeElement(QXmlStreamWriter *xml) = 0;
|
||||
virtual bool isEmpty() const = 0;
|
||||
void setCompressed(bool _compressed) { compressed = _compressed; }
|
||||
bool read(QXmlStreamReader *xml);
|
||||
void write(QXmlStreamWriter *xml);
|
||||
};
|
||||
|
||||
|
|
|
@ -286,7 +286,10 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain
|
|||
if (authState == WouldOverwriteOldSession)
|
||||
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;
|
||||
if (authState == PasswordRight) {
|
||||
|
@ -303,7 +306,10 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain
|
|||
_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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -444,7 +453,10 @@ ResponseCode Server_ProtocolHandler::cmdListUsers(Command_ListUsers * /*cmd*/, C
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ protected:
|
|||
QMap<QString, ServerInfo_User *> buddyList, ignoreList;
|
||||
|
||||
void prepareDestroy();
|
||||
virtual bool getCompressionSupport() const = 0;
|
||||
private:
|
||||
QList<ProtocolItem *> itemQueue;
|
||||
QList<int> messageSizeOverTime, messageCountOverTime;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "server_logger.h"
|
||||
|
||||
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);
|
||||
xmlReader = new QXmlStreamReader;
|
||||
|
@ -101,6 +101,8 @@ void ServerSocketInterface::readClient()
|
|||
if (topLevelItem)
|
||||
topLevelItem->readElement(xmlReader);
|
||||
else if (xmlReader->isStartElement() && (xmlReader->name().toString() == "cockatrice_client_stream")) {
|
||||
if (xmlReader->attributes().value("comp").toString().toInt() == 1)
|
||||
compressionSupport = true;
|
||||
topLevelItem = new TopLevelProtocolItem;
|
||||
connect(topLevelItem, SIGNAL(protocolItemReceived(ProtocolItem *)), this, SLOT(processProtocolItem(ProtocolItem *)));
|
||||
}
|
||||
|
@ -295,7 +297,10 @@ ResponseCode ServerSocketInterface::cmdDeckList(Command_DeckList * /*cmd*/, Comm
|
|||
if (!deckListHelper(root))
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ private:
|
|||
QXmlStreamReader *xmlReader;
|
||||
QString xmlBuffer;
|
||||
TopLevelProtocolItem *topLevelItem;
|
||||
bool compressionSupport;
|
||||
int getUserIdInDB(const QString &name) const;
|
||||
|
||||
ResponseCode cmdAddToList(Command_AddToList *cmd, CommandContainer *cont);
|
||||
|
@ -69,6 +70,8 @@ private:
|
|||
ResponseCode cmdBanFromServer(Command_BanFromServer *cmd, CommandContainer *cont);
|
||||
ResponseCode cmdShutdownServer(Command_ShutdownServer *cmd, CommandContainer *cont);
|
||||
ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage *cmd, CommandContainer *cont);
|
||||
protected:
|
||||
bool getCompressionSupport() const { return compressionSupport; }
|
||||
public:
|
||||
ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent = 0);
|
||||
~ServerSocketInterface();
|
||||
|
|
Loading…
Reference in a new issue