Skip to content

Instantly share code, notes, and snippets.

Created August 10, 2014 12:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/87471e4821f5353fb0f0 to your computer and use it in GitHub Desktop.
Save anonymous/87471e4821f5353fb0f0 to your computer and use it in GitHub Desktop.
bool copyData(QIODevice &inFile, QIODevice &outFile);
class JlCompress2 : public JlCompress
{
public:
static bool extractFile2(QuaZip* zip, QString fileName, QString fileDest, const QString& password, bool &bInvalidPassword)
{
if (!zip) return false;
if (zip->getMode()!=QuaZip::mdUnzip) return false;
if (!fileName.isEmpty())
zip->setCurrentFile(fileName);
QuaZipFile inFile(zip);
if(!inFile.open(QIODevice::ReadOnly, password.size() ? password.toLocal8Bit().constData() : NULL) || inFile.getZipError()!=UNZ_OK) return false;
QDir curDir;
if (fileDest.endsWith('/')) {
if (!curDir.mkpath(fileDest)) {
return false;
}
} else {
if (!curDir.mkpath(QFileInfo(fileDest).absolutePath())) {
return false;
}
}
QuaZipFileInfo64 info;
if (!zip->getCurrentFileInfo(&info))
return false;
QFile::Permissions srcPerm = info.getPermissions();
if (fileDest.endsWith('/') && QFileInfo(fileDest).isDir()) {
if (srcPerm != 0) {
QFile(fileDest).setPermissions(srcPerm);
}
return true;
}
QFile outFile;
outFile.setFileName(fileDest);
if(!outFile.open(QIODevice::WriteOnly)) return false;
if (!copyData(inFile, outFile) || inFile.getZipError()!=UNZ_OK) {
outFile.close();
removeFile(QStringList(fileDest));
bInvalidPassword = (password.size() && inFile.getZipError() == Z_DATA_ERROR);
return false;
}
outFile.close();
inFile.close();
if (inFile.getZipError()!=UNZ_OK) {
removeFile(QStringList(fileDest));
return false;
}
if (srcPerm != 0) {
outFile.setPermissions(srcPerm);
}
return true;
}
static bool extractDir2(QString fileCompressed, QString dir)
{
bool bSuccess = true;
QStringList extracted;
QuaZip zip(fileCompressed);
if(zip.open(QuaZip::mdUnzip))
{
QString password;
// calculate progress and get password (If needed)
quint64 totalUncompressedSize = 0;
if (zip.goToFirstFile())
{
do
{
if (Progress()->IsStopped())
break;
QuaZipFileInfo64 info;
if (zip.getCurrentFileInfo(&info))
{
totalUncompressedSize += info.uncompressedSize;
if ( !password.size() && info.flags & 1) // first bit is 1 (http://stackoverflow.com/questions/12081839/how-to-check-if-encrypted-zip-archive-in-php)
{
password = Progress()->PromtForPassword();
if (!password.size())
{
Progress()->Stop();
break;
}
}
}
}
while (zip.goToNextFile());
}
if (!Progress()->IsStopped())
{
Progress()->SetIncrementBySize(totalUncompressedSize);
// extract
QDir directory(dir);
if (zip.goToFirstFile())
{
do
{
if (Progress()->IsStopped())
break;
QuaZipFileInfo64 info;
zip.getCurrentFileInfo(&info);
QString name = zip.getCurrentFileName();
QString absFilePath = directory.absoluteFilePath(name);
bool bInvalidPassword = false;
if (extractFile2(&zip, "", absFilePath, password, bInvalidPassword))
{
Progress()->Tick(info.uncompressedSize);
QDateTime accessTime = info.getNTFSaTime();
QDateTime modTime = info.getNTFSmTime();
QDateTime creationTime = info.getNTFScTime();
FileSystemHelpers::SetFileDateTime(absFilePath, creationTime, accessTime, modTime);
}
else
{
bSuccess = false;
if (bInvalidPassword)
{
log (ERR, loc("PasswordDialog/InvalidPassword"));
}
break;
}
extracted.append(absFilePath);
}
while (zip.goToNextFile());
}
zip.close();
if (bSuccess)
bSuccess = (zip.getZipError()==0);
if (!bSuccess)
removeFile(extracted);
}
}
return bSuccess;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment