//! @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; }