Example #1
0
//! @brief extract currently opened archive
//! @brief dest path to extract archive to, can be filename when extracting a
//!             single file.
//! @brief file file to extract from archive, full archive if empty.
//! @return true on success, false otherwise
bool ZipUtil::extractArchive(QString& dest, QString file)
{
    qDebug() << "[ZipUtil] extractArchive" << dest << file;
    bool result = true;
    if(!m_zip) {
        return false;
    }
    QuaZipFile *currentFile = new QuaZipFile(m_zip);
    int entries = m_zip->getEntriesCount();
    int current = 0;
    // construct the filename when extracting a single file from an archive.
    // if the given destination is a full path use it as output name,
    // otherwise use it as path to place the file as named in the archive.
    QString singleoutfile;
    if(!file.isEmpty() && QFileInfo(dest).isDir()) {
        singleoutfile = dest + "/" + file;
    }
    else if(!file.isEmpty()){
        singleoutfile = dest;
    }
    for(bool more = m_zip->goToFirstFile(); more; more = m_zip->goToNextFile())
    {
        ++current;
        // if the entry is a path ignore it. Path existence is ensured separately.
        if(m_zip->getCurrentFileName().split("/").last() == "")
            continue;
        // some tools set the MS-DOS file attributes. Check those for D flag,
        // since in some cases a folder entry does not end with a /
        QuaZipFileInfo fi;
        currentFile->getFileInfo(&fi);
        if(fi.externalAttr & 0x10) // FAT entry bit 4 indicating directory
            continue;

        QString outfilename;
        if(!singleoutfile.isEmpty()
                && QFileInfo(m_zip->getCurrentFileName()).fileName() == file) {
            outfilename = singleoutfile;
        }
        else if(singleoutfile.isEmpty()) {
            outfilename = dest + "/" + m_zip->getCurrentFileName();
        }
        if(outfilename.isEmpty())
            continue;
        QFile outputFile(outfilename);
        // make sure the output path exists
        if(!QDir().mkpath(QFileInfo(outfilename).absolutePath())) {
            result = false;
            emit logItem(tr("Creating output path failed"), LOGERROR);
            qDebug() << "[ZipUtil] creating output path failed for:"
                     << outfilename;
            break;
        }
        if(!outputFile.open(QFile::WriteOnly)) {
            result = false;
            emit logItem(tr("Creating output file failed"), LOGERROR);
            qDebug() << "[ZipUtil] creating output file failed:"
                     << outfilename;
            break;
        }
        currentFile->open(QIODevice::ReadOnly);
        outputFile.write(currentFile->readAll());
        if(currentFile->getZipError() != UNZ_OK) {
            result = false;
            emit logItem(tr("Error during Zip operation"), LOGERROR);
            qDebug() << "[ZipUtil] QuaZip error:" << currentFile->getZipError()
                     << "on file" << currentFile->getFileName();
            break;
        }
        currentFile->close();
        outputFile.close();

        emit logProgress(current, entries);
    }
    delete currentFile;
    emit logProgress(1, 1);

    return result;
}