summaryrefslogtreecommitdiffstats
path: root/rbutil/rbutilqt/base
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2011-03-25 22:16:12 +0000
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2011-03-25 22:16:12 +0000
commit8c1d114dcfcc8b3d47505e3139151eec43ebbdc4 (patch)
tree4925e1900520b0c89001c95c9da83f3533903d1e /rbutil/rbutilqt/base
parent0258895faa9a18c0b620ae0a63ee3768ba62747a (diff)
downloadrockbox-8c1d114dcfcc8b3d47505e3139151eec43ebbdc4.tar.gz
rockbox-8c1d114dcfcc8b3d47505e3139151eec43ebbdc4.zip
Rockbox Utility: Replace OSDaB Zip with QuaZip.
This change fixes problems with zip files created with newer zip utilities (a known issue is the iLike theme). QuaZip also allows better feedback during operations without changing the imported code. Additionally Rockbox Utility and the Theme Editor are now both using QuaZip; currently Rockbox Utility uses a copy of the sources, merging them later is planned. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29645 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'rbutil/rbutilqt/base')
-rw-r--r--rbutil/rbutilqt/base/rbunzip.cpp66
-rw-r--r--rbutil/rbutilqt/base/rbunzip.h47
-rw-r--r--rbutil/rbutilqt/base/rbzip.cpp65
-rw-r--r--rbutil/rbutilqt/base/rbzip.h45
-rw-r--r--rbutil/rbutilqt/base/zipinstaller.cpp35
-rw-r--r--rbutil/rbutilqt/base/ziputil.cpp261
-rw-r--r--rbutil/rbutilqt/base/ziputil.h54
7 files changed, 327 insertions, 246 deletions
diff --git a/rbutil/rbutilqt/base/rbunzip.cpp b/rbutil/rbutilqt/base/rbunzip.cpp
deleted file mode 100644
index f71db5377e..0000000000
--- a/rbutil/rbutilqt/base/rbunzip.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- *
- * Copyright (C) 2008 by Dominik Riebeling
- * $Id$
- *
- * All files in this archive are subject to the GNU General Public License.
- * See the file COPYING in the source tree root for full license agreement.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#include "rbunzip.h"
-#include <QtCore>
-
-
-//! @brief extract archive to destination
-UnZip::ErrorCode RbUnZip::extractArchive(const QString& dest)
-{
- qDebug() << "[UNZIP] extracting archive to" << dest;
- QStringList files = this->fileList();
- UnZip::ErrorCode error = Ok;
- m_abortunzip = false;
-
- int total = files.size();
- for(int i = 0; i < total; i++) {
- error = this->extractFile(files.at(i), dest, UnZip::ExtractPaths);
- emit unzipProgress(i + 1, total);
- QCoreApplication::processEvents(); // update UI
- if(m_abortunzip)
- error = SkipAll;
- if(error != Ok)
- break;
- }
- return error;
-}
-
-
-//! @brief abort an extractArchive() operation.
-void RbUnZip::abortUnzip(void)
-{
- m_abortunzip = true;
-}
-
-
-//! @brief return total size of extracted files in archive.
-qulonglong RbUnZip::totalSize(void)
-{
- QList<ZipEntry> l = this->entryList();
- qulonglong total = 0;
-
- int i = l.size();
- while(i--)
- total += l.at(i).uncompressedSize;
-
- return total;
-
-}
-
diff --git a/rbutil/rbutilqt/base/rbunzip.h b/rbutil/rbutilqt/base/rbunzip.h
deleted file mode 100644
index c0b7215b6a..0000000000
--- a/rbutil/rbutilqt/base/rbunzip.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- *
- * Copyright (C) 2008 by Dominik Riebeling
- * $Id$
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#ifndef RBUNZIP_H
-#define RBUNZIP_H
-
-#include <QtCore>
-#include "zip/unzip.h"
-#include "zip/zip.h"
-
-class RbUnZip : public QObject, public UnZip
-{
- Q_OBJECT
- public:
- UnZip::ErrorCode extractArchive(const QString&);
- qulonglong totalSize(void);
-
- signals:
- void unzipProgress(int, int);
-
- public slots:
- void abortUnzip(void);
-
- private:
- bool m_abortunzip;
-};
-
-#endif
-
diff --git a/rbutil/rbutilqt/base/rbzip.cpp b/rbutil/rbutilqt/base/rbzip.cpp
deleted file mode 100644
index c011c0ccbc..0000000000
--- a/rbutil/rbutilqt/base/rbzip.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- *
- * Copyright (C) 2008 by Dominik Wenger
- * $Id$
- *
- * All files in this archive are subject to the GNU General Public License.
- * See the file COPYING in the source tree root for full license agreement.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#include "rbzip.h"
-#include <QtCore>
-
-
-Zip::ErrorCode RbZip::createZip(QString zip,QString dir)
-{
- Zip::ErrorCode error = Ok;
- m_curEntry = 1;
- m_numEntrys=0;
-
- QCoreApplication::processEvents();
-
- // get number of entrys in dir
- QDirIterator it(dir, QDirIterator::Subdirectories);
- while (it.hasNext())
- {
- it.next();
- m_numEntrys++;
- QCoreApplication::processEvents();
- }
-
-
- //! create zip
- error = Zip::createArchive(zip);
- if(error != Ok)
- return error;
-
- //! add the content
- error = Zip::addDirectory(dir);
- if(error != Ok)
- return error;
-
- //! close zip
- error = Zip::closeArchive();
-
- return error;
-}
-
-void RbZip::progress()
-{
- m_curEntry++;
- emit zipProgress(m_curEntry,m_numEntrys);
- QCoreApplication::processEvents(); // update UI
-}
-
-
diff --git a/rbutil/rbutilqt/base/rbzip.h b/rbutil/rbutilqt/base/rbzip.h
deleted file mode 100644
index d2681ec097..0000000000
--- a/rbutil/rbutilqt/base/rbzip.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- *
- * Copyright (C) 2008 by Dominik Wenger
- * $Id$
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#ifndef RBZIP_H
-#define RBZIP_H
-
-#include <QtCore>
-#include "zip/zip.h"
-
-class RbZip : public QObject, public Zip
-{
- Q_OBJECT
- public:
- Zip::ErrorCode createZip(QString zip,QString dir);
-
- virtual void progress();
-
- signals:
- void zipProgress(int, int);
-
- private:
- int m_curEntry;
- int m_numEntrys;
-};
-
-#endif
-
diff --git a/rbutil/rbutilqt/base/zipinstaller.cpp b/rbutil/rbutilqt/base/zipinstaller.cpp
index 1822d3c9ed..07a901ddf4 100644
--- a/rbutil/rbutilqt/base/zipinstaller.cpp
+++ b/rbutil/rbutilqt/base/zipinstaller.cpp
@@ -19,8 +19,8 @@
#include <QtCore>
#include "zipinstaller.h"
-#include "rbunzip.h"
#include "utils.h"
+#include "ziputil.h"
ZipInstaller::ZipInstaller(QObject* parent): QObject(parent)
{
@@ -132,39 +132,28 @@ void ZipInstaller::downloadDone(bool error)
emit logItem(tr("Extracting file."), LOGINFO);
QCoreApplication::processEvents();
- UnZip::ErrorCode ec;
- RbUnZip uz;
- connect(&uz, SIGNAL(unzipProgress(int, int)), this, SIGNAL(logProgress(int, int)));
- connect(this, SIGNAL(internalAborted()), &uz, SLOT(abortUnzip()));
- ec = uz.openArchive(m_file);
- if(ec != UnZip::Ok) {
- emit logItem(tr("Opening archive failed: %1.")
- .arg(uz.formatError(ec)),LOGERROR);
- emit logProgress(1, 1);
- emit done(true);
- return;
- }
-
+ ZipUtil zip(this);
+ connect(&zip, SIGNAL(logProgress(int, int)), this, SIGNAL(logProgress(int, int)));
+ connect(&zip, SIGNAL(logItem(QString, int)), this, SIGNAL(logItem(QString, int)));
+ zip.open(m_file, QuaZip::mdUnzip);
// check for free space. Make sure after installation will still be
// some room for operating (also includes calculation mistakes due to
// cluster sizes on the player).
- if(Utils::filesystemFree(m_mountpoint) < (uz.totalSize() + 1000000)) {
+ if(Utils::filesystemFree(m_mountpoint)
+ < (zip.totalUncompressedSize() + 1000000)) {
emit logItem(tr("Not enough disk space! Aborting."), LOGERROR);
emit logProgress(1, 1);
emit done(true);
return;
}
- ec = uz.extractArchive(m_mountpoint);
- // TODO: better handling of aborted unzip operation.
- if(ec != UnZip::Ok) {
- emit logItem(tr("Extracting failed: %1.")
- .arg(uz.formatError(ec)),LOGERROR);
+ zipContents = zip.files();
+ if(!zip.extractArchive(m_mountpoint)) {
+ emit logItem(tr("Extraction failed!"), LOGERROR);
emit logProgress(1, 1);
emit done(true);
return;
}
- // prepare file list for log
- zipContents = uz.fileList();
+ zip.close();
}
else {
// only copy the downloaded file to the output location / name
@@ -185,7 +174,7 @@ void ZipInstaller::downloadDone(bool error)
}
// add file to log
- zipContents.append( m_target);
+ zipContents.append(m_target);
}
emit logItem(tr("Creating installation log"),LOGINFO);
diff --git a/rbutil/rbutilqt/base/ziputil.cpp b/rbutil/rbutilqt/base/ziputil.cpp
new file mode 100644
index 0000000000..ed8f17eefe
--- /dev/null
+++ b/rbutil/rbutilqt/base/ziputil.cpp
@@ -0,0 +1,261 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2011 Dominik Riebeling
+ * $Id$
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <QtCore>
+#include <QDebug>
+#include "ziputil.h"
+#include "progressloggerinterface.h"
+
+#include "quazip.h"
+#include "quazipfile.h"
+#include "quazipfileinfo.h"
+
+
+ZipUtil::ZipUtil(QObject* parent) : QObject(parent)
+{
+ m_zip = NULL;
+}
+
+
+ZipUtil::~ZipUtil()
+{
+ if(m_zip) {
+ delete m_zip;
+ }
+}
+
+//! @brief open zip file.
+//! @param zipfile path to zip file
+//! @param mode open mode (see QuaZip::Mode)
+//! @return true on success, false otherwise
+bool ZipUtil::open(QString& zipfile, QuaZip::Mode mode)
+{
+ m_zip = new QuaZip(zipfile);
+ return m_zip->open(mode);
+}
+
+
+//! @brief close zip file.
+//! @return true on success, false otherwise
+bool ZipUtil::close(void)
+{
+ if(!m_zip) {
+ return false;
+ }
+
+ int error = UNZ_OK;
+ if(m_zip->isOpen()) {
+ m_zip->close();
+ error = m_zip->getZipError();
+ }
+ delete m_zip;
+ m_zip = NULL;
+ return (error == UNZ_OK) ? true : false;
+}
+
+
+//! @brief extract currently opened archive
+//! @brief dest path to extract archive to
+//! @return true on success, false otherwise
+bool ZipUtil::extractArchive(QString& dest)
+{
+ bool result = true;
+ if(!m_zip) {
+ return false;
+ }
+ QuaZipFile *currentFile = new QuaZipFile(m_zip);
+ int entries = m_zip->getEntriesCount();
+ int current = 0;
+ 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;
+
+ QString outfilename = dest + "/" + m_zip->getCurrentFileName();
+ 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;
+}
+
+
+//! @brief append a folder to current archive
+//! @param source source folder
+//! @param basedir base folder for archive. Will get stripped from zip paths.
+//! @return true on success, false otherwise
+bool ZipUtil::appendDirToArchive(QString& source, QString& basedir)
+{
+ bool result = true;
+ if(!m_zip || !m_zip->isOpen()) {
+ qDebug() << "[ZipUtil] Zip file not open!";
+ return false;
+ }
+ // get a list of all files and folders. Needed for progress info and avoids
+ // recursive calls.
+ QDirIterator iterator(source, QDirIterator::Subdirectories);
+ QStringList fileList;
+ while(iterator.hasNext()) {
+ iterator.next();
+ // skip folders, we can't add them.
+ if(!QFileInfo(iterator.filePath()).isDir()) {
+ fileList.append(iterator.filePath());
+ }
+ }
+ qDebug() << "[ZipUtil] Adding" << fileList.size() << "files to archive";
+
+ int max = fileList.size();
+ for(int i = 0; i < max; i++) {
+ QString current = fileList.at(i);
+ if(!appendFileToArchive(current, basedir)) {
+ qDebug() << "[ZipUtil] Error appending file" << current
+ << "to archive" << m_zip->getZipName();
+ result = false;
+ break;
+ }
+ emit logProgress(i, max);
+ }
+ return result;
+}
+
+
+//! @brief append a single file to current archive
+//!
+bool ZipUtil::appendFileToArchive(QString& file, QString& basedir)
+{
+ bool result = true;
+ if(!m_zip || !m_zip->isOpen()) {
+ qDebug() << "[ZipUtil] Zip file not open!";
+ return false;
+ }
+ // skip folders, we can't add them.
+ QFileInfo fileinfo(file);
+ if(fileinfo.isDir()) {
+ return false;
+ }
+ QString infile = fileinfo.canonicalFilePath();
+ QString newfile = infile;
+ newfile.remove(QDir(basedir).canonicalPath() + "/");
+
+ QuaZipFile fout(m_zip);
+ QFile fin(file);
+
+ if(!fin.open(QFile::ReadOnly)) {
+ qDebug() << "[ZipUtil] Could not open file for reading:" << file;
+ return false;
+ }
+ if(!fout.open(QIODevice::WriteOnly, QuaZipNewInfo(newfile, infile))) {
+ fin.close();
+ qDebug() << "[ZipUtil] Could not open file for writing:" << newfile;
+ return false;
+ }
+
+ result = (fout.write(fin.readAll()) < 0) ? false : true;
+ fin.close();
+ fout.close();
+ return result;
+}
+
+
+//! @brief calculate total size of extracted files
+qint64 ZipUtil::totalUncompressedSize(void)
+{
+ qint64 uncompressed = 0;
+
+ QList<QuaZipFileInfo> items = contentProperties();
+ if(items.size() == 0) {
+ return -1;
+ }
+ int max = items.size();
+ for(int i = 0; i < max; ++i) {
+ uncompressed += items.at(i).uncompressedSize;
+ }
+ qDebug() << "[ZipUtil] size of archive files uncompressed:" << uncompressed;
+ return uncompressed;
+}
+
+
+QStringList ZipUtil::files(void)
+{
+ QList<QuaZipFileInfo> items = contentProperties();
+ QStringList fileList;
+ if(items.size() == 0) {
+ return fileList;
+ }
+ int max = items.size();
+ for(int i = 0; i < max; ++i) {
+ fileList.append(items.at(i).name);
+ }
+ return fileList;
+}
+
+
+QList<QuaZipFileInfo> ZipUtil::contentProperties()
+{
+ QList<QuaZipFileInfo> items;
+ if(!m_zip || !m_zip->isOpen()) {
+ qDebug() << "[ZipUtil] Zip file not open!";
+ return items;
+ }
+ QuaZipFileInfo info;
+ QuaZipFile currentFile(m_zip);
+ for(bool more = m_zip->goToFirstFile(); more; more = m_zip->goToNextFile())
+ {
+ currentFile.getFileInfo(&info);
+ if(currentFile.getZipError() != UNZ_OK) {
+ qDebug() << "[ZipUtil] QuaZip error:" << currentFile.getZipError()
+ << "on file" << currentFile.getFileName();
+ return QList<QuaZipFileInfo>();
+ }
+ items.append(info);
+ }
+ return items;
+}
+
diff --git a/rbutil/rbutilqt/base/ziputil.h b/rbutil/rbutilqt/base/ziputil.h
new file mode 100644
index 0000000000..cfafb96566
--- /dev/null
+++ b/rbutil/rbutilqt/base/ziputil.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2011 Dominik Riebeling
+ * $Id$
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef ZIPUTIL_H
+#define ZIPUTIL_H
+
+#include <QtCore>
+#include "quazip.h"
+#include "quazipfile.h"
+#include "quazipfileinfo.h"
+
+class ZipUtil : public QObject
+{
+ Q_OBJECT
+
+ public:
+ ZipUtil(QObject* parent);
+ ~ZipUtil();
+ bool open(QString& zipfile, QuaZip::Mode mode);
+ bool close(void);
+ bool extractArchive(QString& dest);
+ bool appendDirToArchive(QString& source, QString& basedir);
+ bool appendFileToArchive(QString& file, QString& basedir);
+ qint64 totalUncompressedSize(void);
+ QStringList files(void);
+
+ signals:
+ void logProgress(int, int);
+ void logItem(QString, int);
+
+ private:
+ QList<QuaZipFileInfo> contentProperties();
+ QuaZip* m_zip;
+ QuaZipFile* m_file;
+
+};
+#endif
+