PDA

View Full Version : Is it possible to serialize QVariant into a QString?



MachinTrucChose
27th October 2012, 02:04
I'm writing a client-side class, and a server-side class, who are meant to communicate data with one another. In the middle I have to use a network client whose API's "Send" function takes a QString. That Send function encapsulates my data within a larger string, which is then sent over the network, decapsulated at the other end, and then the body is given to my other class.

I have no control over the encapsulation: basically whatever I need to send, has to be stored within a QString. I'd rather avoid annoying manual serializing/deserializing stuff in XML or somesuch. My data is a collection of native Qt types that can fit in a QVariant (bool, ASCII-only QStrings, and qint32). With this in mind, is there a way I can serialize QVariant/QVariantList into a QString?

QTextStream does not seem to serialize QVariant, only QDataStream does, and from what I saw there's no combination of QDataStream, QBuffer, and QByteArray which will allow me to use QString as a container. I'm asking here with the hopes that I am wrong. Please oh please tell me that I'm wrong :)

ChrisW67
27th October 2012, 07:53
Well, apart from fixing the broken assumption that everything fits into a string, you can serialise to binary any way that works and then base-64 or hex encode the binary blob to go through th string pathway.

wysota
27th October 2012, 07:58
bools, strings and ints can be converted to text using QVariant::toString().

MachinTrucChose
27th October 2012, 22:08
Well, apart from fixing the broken assumption that everything fits into a string, you can serialise to binary any way that works and then base-64 or hex encode the binary blob to go through th string pathway.

Thanks Chris, I should have been looking at QByteArray closer. I got it working.

Full example in case anyone finds this by googling:



QList<QVariant> CreateData();
QString SerializeDataToB64String(const QList<QVariant>& listToSerialize);
QList<QVariant> DeserializeB64String(const QString& serializedList);

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QList<QVariant> dataToWrite = CreateData();
QString container = SerializeDataToB64String(dataToWrite);
qDebug() << "b64 string container contents:" << container;
QList<QVariant> dataRead = DeserializeB64String(container);

Q_ASSERT(dataToWrite.size() == dataRead.size());
for (int i = 0; i < dataToWrite.size(); i++)
{
Q_ASSERT(dataToWrite[i] == dataRead[i]);
qDebug() << dataToWrite[i];
}

return 0;
}


QList<QVariant> CreateData()
{
QList<QVariant> vars;

vars.append("a string");
vars.append((qint32) 123);
vars.append(false);

return vars;
}

QString SerializeDataToB64String(const QList<QVariant>& listToSerialize)
{
QByteArray byteArray;
QBuffer writeBuffer(&byteArray);
writeBuffer.open(QIODevice::WriteOnly);
QDataStream out(&writeBuffer);

out << listToSerialize;

writeBuffer.close();

QString s = QString(byteArray.toBase64());

qDebug() << "array size when written:" << byteArray.size();

return s;
}

QList<QVariant> DeserializeB64String(const QString& serializedList)
{
QByteArray readArr = QByteArray::fromBase64(serializedList.toAscii());
QBuffer readBuffer(&readArr);
readBuffer.open(QIODevice::ReadOnly);
QDataStream in(&readBuffer);

QList<QVariant> readVars;

in >> readVars;

qDebug() << "array size when read:" << readArr.size();

return readVars;
}