diff options
Diffstat (limited to 'src/libs/installer/lib7z_facade.cpp')
-rw-r--r-- | src/libs/installer/lib7z_facade.cpp | 117 |
1 files changed, 80 insertions, 37 deletions
diff --git a/src/libs/installer/lib7z_facade.cpp b/src/libs/installer/lib7z_facade.cpp index 3695c0038..a818e9a61 100644 --- a/src/libs/installer/lib7z_facade.cpp +++ b/src/libs/installer/lib7z_facade.cpp @@ -1,3 +1,43 @@ +/************************************************************************** +** +** Copyright (C) 2012-2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +**************************************************************************/ #include "lib7z_facade.h" #include "errors.h" @@ -17,12 +57,13 @@ #include "Windows/PropVariant.h" #include "Windows/PropVariantConversions.h" -#include <QtCore/QDir> -#include <QtCore/QFileInfo> -#include <QtCore/QIODevice> +#include <QDir> +#include <QFileInfo> +#include <QIODevice> #include <QtCore/QMutexLocker> -#include <QtCore/QPointer> -#include <QtCore/QTemporaryFile> +#include <QPointer> +#include <QTemporaryFile> +#include <QReadWriteLock> #ifdef _MSC_VER #pragma warning(disable:4297) @@ -99,9 +140,9 @@ namespace { */ struct DirectoryGuard { explicit DirectoryGuard(const QString &path) - : m_path(path), - m_created(false), - m_released(false) + : m_path(path) + , m_created(false) + , m_released(false) { m_path.replace(QLatin1Char('\\'), QLatin1Char('/')); } @@ -293,40 +334,39 @@ namespace Lib7z { class QIODeviceSequentialOutStream : public ISequentialOutStream, public CMyUnknownImp { public: - enum DestructorBehavior{ - CloseAndDeleteIODeviceAtDestructor, - KeepIODeviceAtItIsAtDestructor + enum Behavior { + KeepDeviceUntouched, + CloseAndDeleteDevice }; MY_UNKNOWN_IMP - explicit QIODeviceSequentialOutStream(QIODevice* device, DestructorBehavior behavior); + explicit QIODeviceSequentialOutStream(QIODevice* device, Behavior behavior); ~QIODeviceSequentialOutStream(); QString errorString() const; /* reimp */ STDMETHOD(Write)(const void* data, UInt32 size, UInt32* processedSize); private: - QPointer<QIODevice> m_device; - const DestructorBehavior m_destructorBehavior; + Behavior m_behavior; QString m_errorString; + QPointer<QIODevice> m_device; }; -QIODeviceSequentialOutStream::QIODeviceSequentialOutStream(QIODevice* device, DestructorBehavior behavior) +QIODeviceSequentialOutStream::QIODeviceSequentialOutStream(QIODevice* device, Behavior behavior) : ISequentialOutStream() , CMyUnknownImp() + , m_behavior(behavior) , m_device(device) - , m_destructorBehavior(behavior) { Q_ASSERT(m_device); - if (!m_device->open(QIODevice::WriteOnly)) { + if (!device->isOpen() && !m_device->open(QIODevice::WriteOnly)) m_errorString = m_device->errorString(); - } } QIODeviceSequentialOutStream::~QIODeviceSequentialOutStream() { - if (m_destructorBehavior == CloseAndDeleteIODeviceAtDestructor) { + if (m_behavior == CloseAndDeleteDevice) { m_device->close(); delete m_device; m_device = 0; @@ -724,12 +764,12 @@ class Lib7z::ExtractCallbackImpl : public IArchiveExtractCallback, public CMyUnk public: MY_UNKNOWN_IMP explicit ExtractCallbackImpl(ExtractCallback* qq) - : q(qq), - currentIndex(0), - arc(0), - total(0), - completed(0), - device(0) + : q(qq) + , currentIndex(0) + , arc(0) + , total(0) + , completed(0) + , device(0) { } @@ -751,7 +791,7 @@ public: *outStream = 0; if (device != 0) { QIODeviceSequentialOutStream *qOutStream = new QIODeviceSequentialOutStream(device, - QIODeviceSequentialOutStream::KeepIODeviceAtItIsAtDestructor); + QIODeviceSequentialOutStream::KeepDeviceUntouched); if (!qOutStream->errorString().isEmpty()) { Lib7z::setLastError(qOutStream->errorString()); return E_FAIL; @@ -800,7 +840,7 @@ public: } #endif QIODeviceSequentialOutStream *qOutStream = new QIODeviceSequentialOutStream( - new QFile(fi.absoluteFilePath()), QIODeviceSequentialOutStream::CloseAndDeleteIODeviceAtDestructor); + new QFile(fi.absoluteFilePath()), QIODeviceSequentialOutStream::CloseAndDeleteDevice); if (!qOutStream->errorString().isEmpty()) { Lib7z::setLastError(QObject::tr("Could not open file: %1 (%2)").arg( fi.absoluteFilePath(), qOutStream->errorString())); @@ -1172,9 +1212,9 @@ class ExtractItemJob::Private { public: Private(ExtractItemJob* qq) - : q(qq), - target(0), - callback(new ExtractCallbackJobImpl(q)) + : q(qq) + , target(0) + , callback(new ExtractCallbackJobImpl(q)) { } @@ -1361,7 +1401,8 @@ void Lib7z::createArchive(QIODevice* archive, const QStringList &sourcePaths, Up } } -void Lib7z::extractArchive(QIODevice* archive, const File& item, QIODevice* target, ExtractCallback* callback) +void Lib7z::extractFileFromArchive(QIODevice* archive, const File& item, QIODevice* target, + ExtractCallback* callback) { assert(archive); assert(target); @@ -1398,20 +1439,22 @@ void Lib7z::extractArchive(QIODevice* archive, const File& item, QIODevice* targ assert(item.path == UString2QString(s).replace(QLatin1Char('\\'), QLatin1Char('/'))); callback->setTarget(target); - const LONG extractResult = parchive->Extract(&itemIdx, 1, /*testmode=*/1, callback->impl()); + const LONG extractResult = parchive->Extract(&itemIdx, 1, /*testmode=*/0, callback->impl()); if (extractResult != S_OK) throw SevenZipException(errorMessageFrom7zResult(extractResult)); } catch (const char *err) { throw SevenZipException(err); + } catch (const Lib7z::SevenZipException& e) { + throw e; } catch (...) { throw SevenZipException(QObject::tr("Unknown exception caught (%1)") .arg(QString::fromLatin1(Q_FUNC_INFO))); } } -void Lib7z::extractArchive(QIODevice* archive, const File& item, const QString &targetDirectory, +void Lib7z::extractFileFromArchive(QIODevice* archive, const File& item, const QString &targetDirectory, ExtractCallback* callback) { assert(archive); @@ -1428,10 +1471,10 @@ void Lib7z::extractArchive(QIODevice* archive, const File& item, const QString & throw SevenZipException(QObject::tr("Could not create output file for writing: %1") .arg(fi.absoluteFilePath())); } + callback->setTarget(&out); + extractFileFromArchive(archive, item, &out, callback); if (item.permissions) out.setPermissions(item.permissions); - callback->setTarget(&out); - extractArchive(archive, item, &out, callback); outDir.release(); } @@ -1518,9 +1561,9 @@ void ExtractItemJob::doStart() if (!d->archive) throw SevenZipException(tr("Could not list archive: QIODevice not set or already destroyed.")); if (d->target) - extractArchive(d->archive, d->item, d->target, d->callback); + extractFileFromArchive(d->archive, d->item, d->target, d->callback); else if (!d->item.path.isEmpty()) - extractArchive(d->archive, d->item, d->targetDirectory, d->callback); + extractFileFromArchive(d->archive, d->item, d->targetDirectory, d->callback); else extractArchive(d->archive, d->targetDirectory, d->callback); } catch (const SevenZipException& e) { |