Serialize QFileInfo - qt

I have a list of files and I'd like to serialize the file info for every file and send it through socket.
I saw it's possible to serialize like this for example:
QByteArray ba;
QDataStream ds(&ba);
ds << my_stringlist;
QByteArray ba;
QDataStream ds(&ba);
ds >> my_stringlist;
but I couldn't find support for QFileInfo. Is it possible to serialize this Qt data type?
Is there any way to get an easy full serialization of this type or I just need to break up the data into primitive units?

There is no standard way to do that. You can define your custom QDataStream operators as showed in this answer, or you can write your own functions to convert QFileInfo to QVariant and back, and use QVariant serialization. In all these ways you need to break up the data into primitive units, yes.
However I think serializing QFileInfo is pointless. You should use QFileInfo::absoluteFilePath() to get the file's path and serialize that path instead. A new QFileInfo object can be easily constructed from that path if your receiving code is running on the same machine.
If your code is running on the other machine, you couldn't use deserialized QFileInfo even if it would be possible. It's because QFileInfo may or may not store information about file. When you run e.g. QFileInfo::isFile, it may make a request to the underlying file system.
So I think it's better to request all required data from QFileInfo add send this data instead of sending QFileInfo. Or you can just send the absolute file path.

Related

QXmlStreamWriter crashes when I try to write too many items

I am using QXmlStreamWriter to create an xml file with many items. At one point because there are too many elements probably I experience a crash.
Is there a way to perform a flush on the stream?
How else can I perform the writing so I do not experience a crash?
Found out that QByteArray doesn't support more than 2GB. That's why i had a crash. I used QXmlStreamWriter together with a QByteArray.
If I provide the file directly it works fine.
previous code:
QByteArray buffer;
QXmlStreamWriter stream(&buffer);
current code:
QFile* destFile
QXmlStreamWriter stream(destFile);

QSetting<data type> for a QList

I have a QList of some non-primitive data type, say
QList <DockWidget*> tmp;
I want to store this whole list into settings, for writing and reloading, so that i don't lose my settings on restart.
I tried
settings.setValue("reference", tmp);
but get compilation error on reading
tmp = settings.value("reference");
How should I read and write such settings?
That will not work. QSettings.setValue() operated around QVariant class, so before you can store things like
typedef QList<YouClass*> myListType;
you should implement all needed wrappers to convert myListTyoe to and from QVariant.

QSettings: Copy, modify but avoid changing underlying .ini file

I read some QSettings from an .ini file:
QSettings* settingsDocRoot=new QSettings(_settingsFile ,QSettings::IniFormat, parent);
This is passed to some object. However, I then do a copy QSettings* s2= new QSettings(settingsDocRoot); and modify one particular value s2->setValue("path", whateverNewPath);
Basically I want to pass a slightly modified QSettings object to another object. But how do I avoid that the original ini file is updated with the changed value (s2->setValue)?
One idea was, simply to set the path to "". However, according to QSettings - where is the location of the ini file? then a default location will be assumed (OK, original file will not be changed, but unnecessary file will be written).
QSettings is entirely designed for persistence. If you don't want your copy to write to disk, you'd probably be better off copying all the values into a QHash and passing that to your other object:
QHash<QString, QVariant> hash;
const QStringList keys = settings->allKeys();
Q_FOREACH(QString key, keys) {
hash[key] = settings->value(key());
}
I am currently doing the following:
QSettings* settingsWsNaviGraph = new QSettings(settingsDocRoot);
// avoid writing to file
settingsWsNaviGraph->setPath(QSettings::InvalidFormat, QSettings::UserScope, "");
This dirty hack seems to avoid writing, at least my original file remains unchanged and I do not see any unwanted file yet (will report if I do find one).
If this here does not work, I'll try to register my own format with bogus read/write methods. See here

Using QTWebKit to display a website stored in memory

Currently I have my HTML, JS, CSS, graphics, etc stored locally on hard disk and access them using QWebFrame::SetUrl( QUrl::fromLocalFile( "appFolder\html\index.html" )). At some point I am going to need to encrypt the locally stored files so I'm looking for a way to either decrypt them as they're requested or to decrypt them all into memory and access them that way.
I know I can use QWebFrame::setContent( htmlData ) to load the HTML from memory so I can load the encrypted HTML file, decrypt it in memory and then display it that way, but how would I go about the other data (JS, CSS, graphics, etc) which is currently stored in subfolders?
Alternatively, is there a way I can intercept requests for access to all the HTML, JS, CSS, etc files and decrypt them as they're loaded?
By using my own NetworkAccessManager I can intercept calls to createRequest so I can see when each file is being loaded, but I can't see how to use this to decrypt the data on the fly. I can also connect a slot function to the finished(QNetworkReply*) signal, but at that point the data has already been read - the QIODevice's current position is pointing to the end of the file.
I'd be very grateful for any advice or pointers in the right direction.
I think in your case the best solution is to inherit QNetworkReply class and use this new class in reimplemented QNetworkAccessManager::createRequest() function.
In general, you should reimplement next virtual functions of QNetworkReply:
bytesAvailable(), readData(char *data, qint64 maxSize), close(), abort().
For example, readData should be the folowing:
qint64 NetworkReplyEx::readData(char *data, qint64 maxSize)
{
return m_buffer.read(data, maxSize);
}
where m_buffer is already decrypted data.
Also you need to add all necessary logic in this class to get encrypted data, decrypt this data...
In the end you should manually emit finished() signal inside new class, so QWebView or other related class will get decrypted html.

QDataStream readSlot termination symbol

at the moment My socket conversation is text based. I end all my conversation end with a ; and some conversations are binary. now I've decided to make all my conversations binary. and I want to use QDataStream as the socket wrapper. so what measures should I take in place of ; usage.
e.g. i used to check for the ; at the end. when readyRead was emitted. now I think I'll put the buffer size at the begening of the buffer. but the problem is when I get some incomplete buffer. can I parse the size ?
Neel, I'd recommend you the following: QDataStream has convenient overloaded "operator>>" and "operator<<". What I usually do in such case is define the size of the data to be, for example, first 4 bytes of the stream. And on the other end I expect those 4 bytes to be read to determine the whole data size.
For example some pseudo code (C++ style but just gives and idea what you need rather than 100% polished and working code):
QByteArray myData = getData();
QDataStream ds(&socket);
ds << myData.size();
// Note: here your data will be encoded and be '\0' terminated
ds << myData.constData();
// so you might want to consider this call
// although since Qt doesn't guarantee exactly myData.size bytes to be written
// its your responsibility to check whether everything is written
ds.writeRawData(myData.constData(), myData.size());
Now, if you use QByteArray or any of the Qt types that can be sent through QDataStream, you can take advantage of what is already implemented in Qt and send your data as simple as:
QByteArray myData = getData();
QDataStream ds(&socket);
ds << myData;
In this case just check here http://doc.qt.nokia.com/4.7/datastreamformat.html of how Qt writes QByteArray to QDataStream. Even more: if you have QDataStream on the second end, all you need to do is just read your data as easy as you wrote it.
Hope that helps.

Resources