tobilocker tobilocker - 18 days ago 4
C++ Question

Get the checksum of an open QIODevice

i need the checksum of a file and found this, which works perfectly fine. Now i want to change this function to take a pointer to a

QIODevice
that has been opened before with the following lines:

if (!file.open(QFile::ReadOnly | QFile::Text))
{
...
}


This is passed to read (
reader.read(&file);
) as device:

bool XmlReader::read(QIODevice* device)
{
QByteArray b = fileChecksum(device);
...
}


This is my implementation of fileChecksum. It returns a checksum, but i am caught in a loop forever and i am getting an xml parse error. What am i doing wrong here?

QByteArray XmlReader::fileChecksum(QIODevice* device)
{
if (device->isOpen())
{
QCryptographicHash hash(QCryptographicHash::Sha256);
if (hash.addData(device)) {
return hash.result();
}

}
return QByteArray();
}


EDIT

right after
QByteArray b = fileChecksum(device);
i do:

qDebug() << "Checksum: " << b.toHex();


whick keeps printing and printing and printing...

The parse error is:
premature end of document
which is rubbish.

Hope this helps.

Answer

Since the lines of code that eventually caused the error are not in view I can only speculate about what happened.

The function fileChecksum called hash.addData(device) which read the QIODevice until the end and kept the cursor position there.

Most likely you tried to read from the QIODevice afterwards which would explain the premature end of documen message.

As a fast workaround you can just try to reset the position afterwards with

auto pos = device->pos();
QByteArray b = fileChecksum(device);
device->seek(pos);

But you should only read the data once if you can (to support non random-access QIODevices too). For example you can store the result in a QBuffer and use that as a QIODevice. Like this:

bool XmlReader::read(QIODevice* device)
{
    QByteArray contents = device->readAll();
    QBuffer buffer(&contents);
    device = &buffer;//you can also just use &buffer from here on out instead of overwriting the pointer
    QByteArray b = fileChecksum(device);
    device->reset();
    /* ... further reads from device here */
}
Comments