Exemple #1
0
//----------------------------------------------------------------------------------
void tst_QIODevice::constructing_QFile()
{
    QFile file;
    QIODevice *device = &file;

    QVERIFY(!device->isOpen());

    file.setFileName(SRCDIR "tst_qiodevice.cpp");
    QVERIFY(file.open(QFile::ReadOnly));
    QVERIFY(device->isOpen());
    QCOMPARE((int) device->openMode(), (int) QFile::ReadOnly);

    char buf[1024];
    memset(buf, 0, sizeof(buf));
    qlonglong lineLength = device->readLine(buf, sizeof(buf));
    QVERIFY(lineLength > 0);
    QCOMPARE(file.pos(), lineLength);

    file.seek(0);
    char buf2[1024];
    memset(buf2, 0, sizeof(buf2));
    QCOMPARE(file.readLine(buf2, sizeof(buf2)), lineLength);

    char *c1 = buf;
    char *c2 = buf2;
    while (*c1 && *c2) {
        QCOMPARE(*c1, *c2);
        ++c1;
        ++c2;
    }
    QCOMPARE(*c1, *c2);
}
Exemple #2
0
/**
 * @brief Flushes output stream and closes stream if requested.
 * @param Whether to close the current stream. Defaults to true.
 */
void Logger::closeLogger(bool closeStream)
{
    if (outputStream)
    {
        outputStream->flush();

        if (closeStream && outputStream->device() != 0)
        {
            QIODevice *device = outputStream->device();
            if (device->isOpen())
            {
                device->close();
            }
        }
    }

    if (errorStream)
    {
        errorStream->flush();

        if (closeStream && errorStream->device() != 0)
        {
            QIODevice *device = errorStream->device();
            if (device->isOpen())
            {
                device->close();
            }
        }
    }

    instance->pendingTimer.stop();
    instance = 0;
}
Exemple #3
0
voidpf ZCALLBACK qiodevice_open_file_func (
   voidpf opaque,
   voidpf file,
   int mode)
{
    QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
    QIODevice *iodevice = reinterpret_cast<QIODevice*>(file);
    QIODevice::OpenMode desiredMode;
    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
        desiredMode = QIODevice::ReadOnly;
    else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
        desiredMode = QIODevice::ReadWrite;
    else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
        desiredMode = QIODevice::WriteOnly;
    if (iodevice->isOpen()) {
        if ((iodevice->openMode() & desiredMode) == desiredMode) {
            if (desiredMode != QIODevice::WriteOnly
                    && iodevice->isSequential()) {
                // We can use sequential devices only for writing.
                delete d;
                return NULL;
            } else {
                if ((desiredMode & QIODevice::WriteOnly) != 0) {
                    // open for writing, need to seek existing device
                    if (!iodevice->isSequential()) {
                        iodevice->seek(0);
                    } else {
                        d->pos = iodevice->pos();
                    }
                }
            }
            return iodevice;
        } else {
            delete d;
            return NULL;
        }
    }
    iodevice->open(desiredMode);
    if (iodevice->isOpen()) {
        if (desiredMode != QIODevice::WriteOnly && iodevice->isSequential()) {
            // We can use sequential devices only for writing.
            iodevice->close();
            delete d;
            return NULL;
        } else {
            return iodevice;
        }
    } else {
        delete d;
        return NULL;
    }
}
Exemple #4
0
bool Bundle::fileExists(enum Bundle::File file) const
{
    QIODevice *dev = openFile(file);
    bool exists = dev && dev->isOpen();
    delete dev;
    return exists;
}
bool QIODeviceProto::isOpen() const
{
  QIODevice *item = qscriptvalue_cast<QIODevice*>(thisObject());
  if (item)
    return item->isOpen();
  return false;
}
Exemple #6
0
bool XmlLookupTable::readFile(QIODevice &file)
{
    if (!file.isOpen())
        return false;
    int depth = 0;
    QXmlStreamReader reader(&file);
    QStringList path;

    m_data.clear();
    while (!reader.atEnd() && !reader.hasError()) {
        QXmlStreamReader::TokenType token = reader.readNext();
        if (token == QXmlStreamReader::StartElement) {
            path.push_back(reader.name().toString());
            Entry& entry = m_data[path.join("/")];
            QXmlStreamAttributes attributes = reader.attributes();
            entry.attributes.clear();
            foreach (QXmlStreamAttribute attr, attributes)
                entry.attributes[attr.name().toString()]
                        = attr.value().toString();
            ++depth;
        } else if (token == QXmlStreamReader::Characters) {
            Entry& entry = m_data[path.join("/")];
            entry.data += reader.text().toString().trimmed();
        } else if (token == QXmlStreamReader::EndElement) {
            if (depth <= 0)
                return false; // malformed xml
            --depth;
            path.pop_back();
        }
    }

    return !reader.hasError();
}
Exemple #7
0
const QByteArray& QxtMailAttachment::rawData() const
{
    if (qxt_d->content == 0)
    {
        qWarning("QxtMailAttachment::rawData(): Content not set!");
        static QByteArray defaultRv;
        return defaultRv;
    }
    if (qobject_cast<QBuffer *>(qxt_d->content.data()) == 0)
    {
        // content isn't hold in a buffer but in another kind of QIODevice
        // (probably a QFile...). Read the data and cache it into a buffer
        static QByteArray empty;
        QIODevice* c = content();
        if (!c->isOpen() && !c->open(QIODevice::ReadOnly))
        {
            qWarning() << "QxtMailAttachment::rawData(): Cannot open content for reading";
            return empty;
        }
        QBuffer* cache = new QBuffer();
        cache->open(QIODevice::WriteOnly);
        char buf[1024];
        while (!c->atEnd())
        {
            cache->write(buf, c->read(buf, 1024));
        }
        if (qxt_d->deleteContent && qxt_d->content)
        qxt_d->content->deleteLater();
        qxt_d->content = cache;
        qxt_d->deleteContent = true;
    }
    return qobject_cast<QBuffer *>(qxt_d->content.data())->data();
}
Exemple #8
0
voidpf ZCALLBACK qiodevice_open_file_func (
   voidpf opaque UNUSED,
   voidpf file,
   int mode)
{
    QIODevice *iodevice = reinterpret_cast<QIODevice*>(file);
    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
        iodevice->open(QIODevice::ReadOnly);
    else
    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
        iodevice->open(QIODevice::ReadWrite);
    else
    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
        iodevice->open(QIODevice::WriteOnly);

    if (iodevice->isOpen()) {
        if (iodevice->isSequential()) {
            iodevice->close();
            return NULL;
        } else {
            return iodevice;
        }
    } else
        return NULL;
}
Exemple #9
0
/*!
    \internal
*/
bool QImageReaderPrivate::initHandler()
{
    // check some preconditions
    if (!device || (!deleteDevice && !device->isOpen() && !device->open(QIODevice::ReadOnly))) {
        imageReaderError = QImageReader::DeviceError;
        errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Invalid device"));
        return false;
    }

    // probe the file extension
    if (deleteDevice && !device->isOpen() && !device->open(QIODevice::ReadOnly) && autoDetectImageFormat) {
        QList<QByteArray> extensions = QImageReader::supportedImageFormats();
        if (!format.isEmpty()) {
            // Try the most probable extension first
            int currentFormatIndex = extensions.indexOf(format.toLower());
            if (currentFormatIndex > 0)
                extensions.swap(0, currentFormatIndex);
        }

        int currentExtension = 0;

        QFile *file = static_cast<QFile *>(device);
        QString fileName = file->fileName();

        do {
            file->setFileName(fileName + QLatin1Char('.')
                    + QString::fromLatin1(extensions.at(currentExtension++).constData()));
            file->open(QIODevice::ReadOnly);
        } while (!file->isOpen() && currentExtension < extensions.size());

        if (!device->isOpen()) {
            imageReaderError = QImageReader::FileNotFoundError;
            errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "File not found"));
            file->setFileName(fileName); // restore the old file name
            return false;
        }
    }

    // assign a handler
    if (!handler && (handler = createReadHandlerHelper(device, format, autoDetectImageFormat, ignoresFormatAndExtension)) == 0) {
        imageReaderError = QImageReader::UnsupportedFormatError;
        errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unsupported image format"));
        return false;
    }
    return true;
}
Exemple #10
0
//----------------------------------------------------------------------------------
void tst_QIODevice::constructing_QTcpSocket()
{
#if defined(Q_OS_WINCE) && defined(WINCE_EMULATOR_TEST)
    QSKIP("Networking tests in a WinCE emulator are unstable", SkipAll);
#endif
    QTcpSocket socket;
    QIODevice *device = &socket;

    QVERIFY(!device->isOpen());

    socket.connectToHost(QtNetworkSettings::serverName(), 143);
    QVERIFY(socket.waitForConnected(5000));
    QVERIFY(device->isOpen());

    while (!device->canReadLine())
        QVERIFY(device->waitForReadyRead(5000));

    char buf[1024];
    memset(buf, 0, sizeof(buf));
    qlonglong lineLength = device->readLine(buf, sizeof(buf));
    QVERIFY(lineLength > 0);
    QCOMPARE(socket.pos(), qlonglong(0));

    socket.close();
    socket.connectToHost(QtNetworkSettings::serverName(), 143);
    QVERIFY(socket.waitForConnected(5000));
    QVERIFY(device->isOpen());

    while (!device->canReadLine())
        QVERIFY(device->waitForReadyRead(5000));

    char buf2[1024];
    memset(buf2, 0, sizeof(buf2));
    QCOMPARE(socket.readLine(buf2, sizeof(buf2)), lineLength);

    char *c1 = buf;
    char *c2 = buf2;
    while (*c1 && *c2) {
        QCOMPARE(*c1, *c2);
        ++c1;
        ++c2;
    }
    QCOMPARE(*c1, *c2);
}
Exemple #11
0
voidpf ZCALLBACK qiodevice_open_file_func (
   voidpf /*opaque UNUSED*/,
   voidpf file,
   int mode)
{
    QIODevice *iodevice = reinterpret_cast<QIODevice*>(file);
    QIODevice::OpenMode desiredMode;
    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
        desiredMode = QIODevice::ReadOnly;
    else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
        desiredMode = QIODevice::ReadWrite;
    else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
        desiredMode = QIODevice::WriteOnly;
    if (iodevice->isOpen()) {
        if ((iodevice->openMode() & desiredMode) == desiredMode) {
            if (iodevice->isSequential()) {
                return NULL;
            } else {
                if ((desiredMode & QIODevice::WriteOnly) != 0) {
                    // open for writing, need to seek existing device
                    iodevice->seek(0);
                }
            }
            return iodevice;
        } else {
            return NULL;
        }
    }
    iodevice->open(desiredMode);
    if (iodevice->isOpen()) {
        if (iodevice->isSequential()) {
            iodevice->close();
            return NULL;
        } else {
            return iodevice;
        }
    } else
        return NULL;
}
Exemple #12
0
QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart)
{
    // copy the request, we probably need to add some headers
    QNetworkRequest newRequest(request);

    // add Content-Type header if not there already
    if (!request.header(QNetworkRequest::ContentTypeHeader).isValid()) {
        QByteArray contentType;
        contentType.reserve(34 + multiPart->d_func()->boundary.count());
        contentType += "multipart/";
        switch (multiPart->d_func()->contentType) {
        case QHttpMultiPart::RelatedType:
            contentType += "related";
            break;
        case QHttpMultiPart::FormDataType:
            contentType += "form-data";
            break;
        case QHttpMultiPart::AlternativeType:
            contentType += "alternative";
            break;
        default:
            contentType += "mixed";
            break;
        }
        // putting the boundary into quotes, recommended in RFC 2046 section 5.1.1
        contentType += "; boundary=\"" + multiPart->d_func()->boundary + "\"";
        newRequest.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType));
    }

    // add MIME-Version header if not there already (we must include the header
    // if the message conforms to RFC 2045, see section 4 of that RFC)
    QByteArray mimeHeader("MIME-Version");
    if (!request.hasRawHeader(mimeHeader))
        newRequest.setRawHeader(mimeHeader, QByteArray("1.0"));

    QIODevice *device = multiPart->d_func()->device;
    if (!device->isReadable()) {
        if (!device->isOpen()) {
            if (!device->open(QIODevice::ReadOnly))
                qWarning("could not open device for reading");
        } else {
            qWarning("device is not readable");
        }
    }

    return newRequest;
}
Exemple #13
0
bool RkCommand::waitAnAnswer(Request &req, QIODevice &io)
{
    if(io.isOpen()){
        QByteArray answer;
        if(io.waitForReadyRead(100)){
            int cnt=0;
            answer+=io.readAll();
            while(io.waitForReadyRead(10)) {
                answer+=io.readAll();
                cnt++;if(cnt>=maxCnt) break;
            }
        }
        req.updateRdData(answer);
        if(answer.count()) {return true;}
    }
    return false;
}
Exemple #14
0
/*!
 * Loads AWS endpoint data from \a device.
 *
 * This function parses AWS endpoint data in XML format.  The XML data is
 * expected to match the same format as the file provided by Amazon at
 * http://aws-sdk-configurations.amazonwebservices.com/endpoints.xml
 *
 * If \e any data has been loaded previously, this function will return
 * immediately with no parsing performed.
 */
void AwsEndpointPrivate::loadEndpointData(QIODevice &device)
{
    QMutexLocker locker(&mutex);
    if (!hosts.empty()) {
        return; // Already loaded.
    }

    // Open the device, if not already open.
    if ((!device.isOpen()) && (!device.open(QIODevice::ReadOnly))) {
        qWarning() << "AwsEndpoint:" << device.errorString();
        return;
    }

    // Parse the data.
    QXmlStreamReader xml(&device);
    loadEndpointData(xml);
}
Exemple #15
0
bool RkCommand::waitAnAnswer(Request &req, QIODevice &io)
{
    static const int maxCnt = 500; // ограничение ожидания ответа при длительном входящем потоке данных
    if(io.isOpen()) {
        QByteArray answer;
        if(io.waitForReadyRead(100)) {
            int cnt=0;
            answer+=io.readAll();
            while(io.waitForReadyRead(10)) {
                answer+=io.readAll();
                cnt++;
                if(cnt>=maxCnt) break;
            }
        }
        req.updateRdData(answer);
        if(answer.count()) return true;
    }
    return false;
}
bool QImageWriterPrivate::canWriteHelper()
{
    if (!device) {
        imageWriterError = QImageWriter::DeviceError;
        errorString = QImageWriter::tr("Device is not set");
        return false;
    }
    if (!device->isOpen())
        device->open(QIODevice::WriteOnly);
    if (!device->isWritable()) {
        imageWriterError = QImageWriter::DeviceError;
        errorString = QImageWriter::tr("Device not writable");
        return false;
    }
    if (!handler && (handler = createWriteHandlerHelper(device, format)) == 0) {
        imageWriterError = QImageWriter::UnsupportedFormatError;
        errorString = QImageWriter::tr("Unsupported image format");
        return false;
    }
    return true;
}
Exemple #17
0
bool MimePart::writeData(QIODevice *device)
{
    Q_D(MimePart);

    /* === Content === */
    QIODevice *input = d->contentDevice;
    if (!input->isOpen()) {
        if (!input->open(QIODevice::ReadOnly)) {
            return false;
        }
    } else if (!input->seek(0)) {
        return false;
    }

    switch (d->contentEncoding) {
    case MimePart::_7Bit:
    case MimePart::_8Bit:
        if (!d->writeRaw(input, device)) {
            return false;
        }
        break;
    case MimePart::Base64:
        if (!d->writeBase64(input, device)) {
            return false;
        }
        break;
    case MimePart::QuotedPrintable:
        if (!d->writeQuotedPrintable(input, device)) {
            return false;
        }
        break;
    }

    if (device->write("\r\n", 2) != 2) {
        return false;
    }

    return true;
}
bool CommandInterface::execute(Request &req, QIODevice &io)
{
    form(req);
    if(io.isOpen()) {
        io.readAll();
        io.write(req.getBody());
        QSerialPort &port = dynamic_cast<QSerialPort&>(io);
        if(&port != nullptr) {
            port.flush();
            int waitWritePause = (req.getBody().count()*12000.0)/port.baudRate();
            waitWritePause+=10;
            QThread::currentThread()->msleep(waitWritePause);
        }
        if(waitAnAnswer(req,io)) {
            req.setAnswerData(req.getRdData());
            if(checkAnAnswer(req)) {
                getAnAnswer(req);
                return true;
            }
        }else req.setAnswerData(QByteArray());
    }
    return false;
}
Exemple #19
0
        void testVFSLocNull ()
        {
            VFSLocalizator vfsl;

            CPPUNIT_ASSERT(
                    vfsl.resourceAsByteArray( QString::null ) == QByteArray() );
            QIODevice* io = vfsl.resourceAsIODevice( QString::null );
            CPPUNIT_ASSERT( io != NULL );
            CPPUNIT_ASSERT( io->isOpen() == false );

            CPPUNIT_ASSERT( vfsl.localizedMessages() == NULL );

            CPPUNIT_ASSERT( vfsl.localizedMessage( "" ) == "" );
            CPPUNIT_ASSERT(
                    vfsl.localizedMessage( QString::null ) == QString::null );

            CPPUNIT_ASSERT(
                    vfsl.localizedMessage( "NOT_AN_ID" ) == "NOT_AN_ID" );

            CPPUNIT_ASSERT( vfsl.localizedMessage( "THE_ID" ) == "THE_ID" );

            CPPUNIT_ASSERT(
                    vfsl.localizedMessage( "THE_ID", "LT" ) == "THE_ID" );
        }
bool QBuildingCardPropertiesWidget::write( QIODevice & device )
{
    assert( device.isOpen() && device.isWritable() );
    return true;
}
Exemple #21
0
        void testVFSWithData ()
        {
            VFSPtr root = VFSPtr( new VFSLocal( QUrl( srcdir +
                            "/tests/a_project/resources/" ) ) );

            VFSLocalizator vfsl( root, "cs_CZ" );

            // [-- VFSLocalizator native message access --]
            CPPUNIT_ASSERT( vfsl.localizedMessage( "root_only", "lt" ) ==
                    "I AM ROOT MESSAGE ONLY" );
            CPPUNIT_ASSERT( vfsl.localizedMessage( "lang_only", "lt" ) ==
                    "I AM LANGUAGE MESSAGE ONLY" );
            CPPUNIT_ASSERT( vfsl.localizedMessage( "full_only", "lt" ) ==
                    "I AM FULL MESSAGE ONLY" );

            CPPUNIT_ASSERT( vfsl.localizedMessage( "root_and_full", "lt" ) ==
                    "I AM ROOT AND FULL MESSAGE from FULL" );

            CPPUNIT_ASSERT( vfsl.localizedMessage( "root_and_lang", "lt" ) ==
                    "I AM ROOT AND LANGUAGE MESSAGE from LANG" );

            CPPUNIT_ASSERT( vfsl.localizedMessage( "lang_and_full", "lt" ) ==
                    "I AM FULL AND LANGUAGE MESSAGE from FULL" );

            // [-- VFSLocalizator's QTranslator message access --]
            const QTranslator* t = vfsl.localizedMessages();
            CPPUNIT_ASSERT( t );
            CPPUNIT_ASSERT(
                    t->findMessage( "lt", "root_only","" ).translation() ==
                    "I AM ROOT MESSAGE ONLY" );
            CPPUNIT_ASSERT(
                    t->findMessage( "lt", "lang_only","" ).translation() ==
                    "I AM LANGUAGE MESSAGE ONLY" );
            CPPUNIT_ASSERT(
                    t->findMessage( "lt", "full_only", "" ).translation() ==
                    "I AM FULL MESSAGE ONLY" );

            CPPUNIT_ASSERT(
                    t->findMessage( "lt", "root_and_full", "" )
                    .translation() ==
                    "I AM ROOT AND FULL MESSAGE from FULL" );

            CPPUNIT_ASSERT(
                    t->findMessage( "lt", "root_and_lang", "" )
                    .translation() ==
                    "I AM ROOT AND LANGUAGE MESSAGE from LANG" );

            CPPUNIT_ASSERT(
                    t->findMessage( "lt", "lang_and_full", "" )
                    .translation() ==
                    "I AM FULL AND LANGUAGE MESSAGE from FULL" );

            // [-- VFSLocalizator resourceAsByteArray test --]
            QString s;
            s = QString( vfsl.resourceAsByteArray( "file_in_full.txt" ) );
            CPPUNIT_ASSERT( s.simplifyWhiteSpace() == "full" );

            s = QString( vfsl.resourceAsByteArray( "file_in_lang.txt" ) );
            CPPUNIT_ASSERT( s .simplifyWhiteSpace() == "lang" );

            s = QString( vfsl.resourceAsByteArray( "file_in_root.txt" ) );
            CPPUNIT_ASSERT( s.simplifyWhiteSpace() == "root" );

            // [-- VFSLocalizator resourceAsIODevice test --]
            QIODevice* io = NULL;
            io = vfsl.resourceAsIODevice( "file_in_full.txt" );
            CPPUNIT_ASSERT( io->isOpen() == true );
            s = QString( io->readAll() );
            CPPUNIT_ASSERT( s.simplifyWhiteSpace() == "full" );

            io = vfsl.resourceAsIODevice( "file_in_lang.txt" );
            CPPUNIT_ASSERT( io->isOpen() == true );
            s = QString( io->readAll() );
            CPPUNIT_ASSERT( s .simplifyWhiteSpace() == "lang" );

            io = vfsl.resourceAsIODevice( "file_in_root.txt" );
            CPPUNIT_ASSERT( io->isOpen() == true );
            s = QString( io->readAll() );
            CPPUNIT_ASSERT( s.simplifyWhiteSpace() == "root" );

            // [-- Language only locale --]
            VFSLocalizator vfs2( root, "cs" );

            t = vfs2.localizedMessages();
            CPPUNIT_ASSERT( t );

            CPPUNIT_ASSERT( vfs2.localizedMessage( "lang_and_full", "lt" ) ==
                    "I AM LANGUAGE AND FULL MESSAGE from LANG" );

            s = QString( vfs2.resourceAsByteArray( "file_in_full.txt" ) );
            CPPUNIT_ASSERT( s.simplifyWhiteSpace() == "lang" );

            // [-- no locale at all --]
            VFSLocalizator vfs3( root, "" );

            t = vfs3.localizedMessages();
            CPPUNIT_ASSERT( t );

            CPPUNIT_ASSERT( vfs3.localizedMessage( "root_and_full", "lt" ) ==
                    "I AM ROOT AND FULL MESSAGE from ROOT" );
            CPPUNIT_ASSERT( vfs3.localizedMessage( "root_and_lang", "lt" ) ==
                    "I AM ROOT AND LANGUAGE MESSAGE from ROOT" );

            s = QString( vfs3.resourceAsByteArray( "file_in_full.txt" ) );
            CPPUNIT_ASSERT( s.simplifyWhiteSpace() == "root" );
            s = QString( vfs3.resourceAsByteArray( "file_in_lang.txt" ) );
            CPPUNIT_ASSERT( s.simplifyWhiteSpace() == "root" );
        }
Exemple #22
0
void MemoryMap::diffWith(MemoryMap* other)
{
    _pmemDiff.clear();

    QIODevice* dev = _vmem->physMem();
    QIODevice* otherDev = other->vmem()->physMem();
    if (!otherDev || !dev)
        return;

    assert(dev != otherDev);

    // Open devices for reading, if required
    if (!dev->isReadable()) {
        if (dev->isOpen())
            dev->close();
        assert(dev->open(QIODevice::ReadOnly));
    }
    else
        assert(dev->reset());

    if (!otherDev->isReadable()) {
        if (otherDev->isOpen())
            otherDev->close();
        assert(otherDev->open(QIODevice::ReadOnly));
    }
    else
        assert(otherDev->reset());

    QTime timer;
    timer.start();
    bool wasEqual = true, equal = true;
    quint64 addr = 0, startAddr = 0, length = 0;
    const int bufsize = 1024;
    const int granularity = 16;
    char buf1[bufsize], buf2[bufsize];
    qint64 readSize1, readSize2;
    qint64 done, prevDone = -1;
    qint64 totalSize = qMin(dev->size(), otherDev->size());
    if (totalSize < 0)
        totalSize = qMax(dev->size(), otherDev->size());

    // Compare the complete physical address space
    while (!Console::interrupted() && !dev->atEnd() && !otherDev->atEnd()) {
        readSize1 = dev->read(buf1, bufsize);
        readSize2 = otherDev->read(buf2, bufsize);

        if (readSize1 <= 0 || readSize2 <= 0)
            break;

        qint64 size = qMin(readSize1, readSize2);
        for (int i = 0; i < size; ++i) {
            if (buf1[i] != buf2[i])
                equal = false;
            // We only consider memory chunks of size "granularity"
            if (addr % granularity == granularity - 1) {
                // Memory is equal
                if (equal) {
                    // Add difference to tree
                    if (!wasEqual)
                        _pmemDiff.insert(Difference(startAddr, length));
                }
                // Memory differs
                else {
                    // Start new difference
                    if (wasEqual) {
                        startAddr = addr - (addr % granularity);
                        length = granularity;
                    }
                    // Enlarge difference
                    else
                        length += granularity;
                }
                wasEqual = equal;
            }
            ++addr;
            equal = true;
        }

        done = (int) (addr / (float) totalSize * 100);
        if (prevDone < 0 || (done != prevDone && timer.elapsed() > 500)) {
            Console::out() << "\rComparing memory dumps: " << done << "%" << flush;
            prevDone = done;
            timer.restart();
        }
    }

    // Add last difference, if any
    if (!wasEqual)
        _pmemDiff.insert(Difference(startAddr, length));

    Console::out() << "\rComparing memory dumps finished." << endl;

//    debugmsg("No. of differences: " << _pmemDiff.objectCount());
}
bool QBuildingCardPropertiesWidget::read( QIODevice & device )
{
    assert( device.isOpen() && device.isReadable() );
    return true;
}