summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkh1 <karsten.heimrich@digia.com>2014-10-14 17:03:54 +0200
committerKarsten Heimrich <karsten.heimrich@digia.com>2014-10-15 17:10:18 +0200
commit84875396b75f5615afa637f9633d19bbc79e08e0 (patch)
tree012fe931425ae267361a608c0c63e0d05e4ee03e
parentec92e19193eb9d69a3cf18979d6434cf04764902 (diff)
Overhaul the binary format API.
Adjust some naming. Add documentation. Make the Resource class handle files only, this is sufficient to read and map inbuild resources. Keep the QResources inside the manager as well, no need to handle them separate. Remove read, write functions from collection class, the API was just unclear how to use. Still it is far from intuitive in the manager class either. If we open a Resource, we need to close it on our own case they are pointers. Change-Id: Ic8aa32a84a15ac774fe1194ba0dbb5733f7216d6 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@digia.com> Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
-rw-r--r--src/libs/installer/binarycontent.cpp136
-rw-r--r--src/libs/installer/binarycontent.h6
-rw-r--r--src/libs/installer/binaryformat.cpp393
-rw-r--r--src/libs/installer/binaryformat.h41
-rw-r--r--src/libs/installer/binaryformatengine.cpp34
-rw-r--r--src/libs/installer/binaryformatenginehandler.cpp37
-rw-r--r--src/libs/installer/binaryformatenginehandler.h2
-rw-r--r--src/libs/installer/binarylayout.cpp21
-rw-r--r--src/libs/installer/createlocalrepositoryoperation.cpp16
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp2
-rw-r--r--src/sdk/installerbase.cpp16
-rw-r--r--src/sdk/sdkapp.h32
-rw-r--r--src/sdk/updatechecker.cpp11
-rw-r--r--tests/auto/installer/binaryformat/tst_binaryformat.cpp174
-rw-r--r--tools/binarycreator/binarycreator.cpp49
-rw-r--r--tools/devtool/binarydump.cpp6
-rw-r--r--tools/devtool/main.cpp17
17 files changed, 533 insertions, 460 deletions
diff --git a/src/libs/installer/binarycontent.cpp b/src/libs/installer/binarycontent.cpp
index 7ba285f3a..49f381318 100644
--- a/src/libs/installer/binarycontent.cpp
+++ b/src/libs/installer/binarycontent.cpp
@@ -49,11 +49,25 @@
namespace QInstaller {
/*!
- Search through 1MB, if smaller through the whole file. Note: QFile::map() does
- not change QFile::pos(). Fallback to read the file content in case we can't map it.
+ \class QInstaller::BinaryContent
+ \inmodule QtInstallerFramework
+ \brief The BinaryContent class handles binary information embedded into executables.
- Note: Failing to map the file can happen for example while having a remote connection
- established to the admin server process and we do not support map over the socket.
+ The following types of binary information can be embedded into executable files: Qt resources,
+ performed operations, and resource collections.
+
+ The magic marker is a \c quint64 that identifies the kind of the binary: \c installer or
+ \c uninstaller (maintenance tool).
+
+ The magic cookie is a \c quint64 describing whether the binary is the file holding just data
+ or whether it includes the executable as well.
+*/
+
+/*!
+ Searches for the given magic cookie \a magicCookie starting from the end of the file \a in.
+ Returns the position of the magic cookie inside the binary. Throws Error on failure.
+
+ \note Searches through up to 1MB of data, if smaller, through the whole file.
*/
qint64 BinaryContent::findMagicCookie(QFile *in, quint64 magicCookie)
{
@@ -68,6 +82,10 @@ qint64 BinaryContent::findMagicCookie(QFile *in, quint64 magicCookie)
QByteArray data(maxSearch, Qt::Uninitialized);
uchar *const mapped = in->map(fileSize - maxSearch, maxSearch);
if (!mapped) {
+ // Fallback to read the file content in case we can't map it.
+
+ // Note: Failing to map the file can happen for example while having a remote connection
+ // established to the privileged server process and we do not support map over the socket.
const int pos = in->pos();
try {
in->seek(fileSize - maxSearch);
@@ -78,6 +96,7 @@ qint64 BinaryContent::findMagicCookie(QFile *in, quint64 magicCookie)
throw error;
}
} else {
+ // map does not change QFile::pos()
data = QByteArray((const char*) mapped, maxSearch);
in->unmap(mapped);
}
@@ -94,6 +113,11 @@ qint64 BinaryContent::findMagicCookie(QFile *in, quint64 magicCookie)
return -1; // never reached
}
+/*!
+ Tries to read the binary layout of the file \a file. It starts searching from the end of the
+ file \a file for the given \a magicCookie using findMagicCookie(). If the cookie was found, it
+ fills a BinaryLayout structure and returns it. Throws Error on failure.
+*/
BinaryLayout BinaryContent::binaryLayout(QFile *file, quint64 magicCookie)
{
BinaryLayout layout;
@@ -110,7 +134,7 @@ BinaryLayout BinaryContent::binaryLayout(QFile *file, quint64 magicCookie)
const qint64 posOfResourceCollectionsSegment = layout.endOfBinaryContent
- ((metaResourcesCount * (2 * sizeof(qint64))) // minus the size of the meta data segments
- + (8 * sizeof(qint64))); // meta count, offset/length component index, marker, cookie...
+ + (8 * sizeof(qint64))); // meta count, offset/length collection index, marker, cookie...
if (!file->seek(posOfResourceCollectionsSegment)) {
throw Error(QCoreApplication::translate("BinaryLayout",
"Could not seek to %1 to read the resource collection segment.")
@@ -155,58 +179,92 @@ BinaryLayout BinaryContent::binaryLayout(QFile *file, quint64 magicCookie)
return layout;
}
-void BinaryContent::readBinaryContent(const QSharedPointer<QFile> &in,
- ResourceCollection *metaResources, QList<OperationBlob> *operations,
+/*!
+ Reads the binary content of the given file \a file. It starts by reading the binary layout of
+ the file using binaryLayout() using \a magicCookie. Throws Error on failure.
+
+ If \a operations is not 0, it is set to the performed operations from a previous run of for
+ example the maintenance tool.
+
+ If \a manager is not 0, it is first cleared and then set to the resource collections embedded
+ into the binary.
+
+ If \a magicMarker is not 0, it is set to the magic marker found in the binary.
+*/
+void BinaryContent::readBinaryContent(QFile *file, QList<OperationBlob> *operations,
ResourceCollectionManager *manager, qint64 *magicMarker, quint64 magicCookie)
{
- const BinaryLayout layout = BinaryContent::binaryLayout(in.data(), magicCookie);
+ const BinaryLayout layout = BinaryContent::binaryLayout(file, magicCookie);
- if (metaResources) { // append the meta resources
- foreach (const Range<qint64> &segment, layout.metaResourceSegments)
- metaResources->appendResource(QSharedPointer<Resource>(new Resource(in, segment)));
+ if (manager)
+ manager->clear();
+
+ if (manager) { // append the meta resources
+ ResourceCollection metaResources("QResources");
+ foreach (const Range<qint64> &segment, layout.metaResourceSegments) {
+ metaResources.appendResource(QSharedPointer<Resource>(new Resource(file->fileName(),
+ segment)));
+ }
+ manager->insertCollection(metaResources);
}
if (operations) {
const qint64 posOfOperationsBlock = layout.operationsSegment.start();
- if (!in->seek(posOfOperationsBlock)) {
+ if (!file->seek(posOfOperationsBlock)) {
throw Error(QCoreApplication::translate("BinaryContent",
"Could not seek to %1 to read the operation data.").arg(posOfOperationsBlock));
}
// read the operations count
- qint64 operationsCount = QInstaller::retrieveInt64(in.data());
+ qint64 operationsCount = QInstaller::retrieveInt64(file);
// read the operations
for (int i = 0; i < operationsCount; ++i) {
- const QString name = QInstaller::retrieveString(in.data());
- const QString xml = QInstaller::retrieveString(in.data());
+ const QString name = QInstaller::retrieveString(file);
+ const QString xml = QInstaller::retrieveString(file);
operations->append(OperationBlob(name, xml));
}
// operations count
- Q_UNUSED(QInstaller::retrieveInt64(in.data())) // read it, but deliberately not used
+ Q_UNUSED(QInstaller::retrieveInt64(file)) // read it, but deliberately not used
}
- if (manager) { // read the component index and data
+ if (manager) { // read the collection index and data
const qint64 posOfResourceCollectionBlock = layout.resourceCollectionsSegment.start();
- if (!in->seek(posOfResourceCollectionBlock)) {
+ if (!file->seek(posOfResourceCollectionBlock)) {
throw Error(QCoreApplication::translate("BinaryContent", "Could not seek to %1 to "
"read the resource collection block.").arg(posOfResourceCollectionBlock));
}
- manager->read(in, layout.endOfExectuable);
+ manager->read(file, layout.endOfExectuable);
}
if (magicMarker)
*magicMarker = layout.magicMarker;
}
-void BinaryContent::writeBinaryContent(const QSharedPointer<QFile> &out,
- const ResourceCollection &metaResources, const QList<OperationBlob> &operations,
+/*!
+ Writes the binary content to the given file \a out. Throws Error on failure.
+
+ The binary content is written in the following order:
+
+ \list
+ \li Meta resources \a manager
+ \li Operations \a operations
+ \li Resource collections \a manager
+ \li Magic marker \a magicMarker
+ \li Magic cookie \a magicCookie
+ \endlist
+
+ For more information see the BinaryLayout documentation.
+*/
+void BinaryContent::writeBinaryContent(QFile *out, const QList<OperationBlob> &operations,
const ResourceCollectionManager &manager, qint64 magicMarker, quint64 magicCookie)
{
const qint64 endOfBinary = out->pos();
+ ResourceCollectionManager localManager = manager;
// resources
qint64 pos = out->pos();
QVector<Range<qint64> > metaResourceSegments;
- foreach (const QSharedPointer<Resource> &resource, metaResources.resources()) {
+ const ResourceCollection collection = localManager.collectionByName("QResources");
+ foreach (const QSharedPointer<Resource> &resource, collection.resources()) {
const bool isOpen = resource->isOpen();
if ((!isOpen) && (!resource->open())) {
throw Error(QCoreApplication::translate("BinaryContent",
@@ -214,44 +272,42 @@ void BinaryContent::writeBinaryContent(const QSharedPointer<QFile> &out,
}
resource->seek(0);
- resource->copyData(out.data());
- metaResourceSegments.append(Range<qint64>::fromStartAndEnd(pos, out->pos())
- .moved(-endOfBinary));
+ resource->copyData(out);
+ metaResourceSegments.append(Range<qint64>::fromStartAndEnd(pos, out->pos()));
pos = out->pos();
if (!isOpen) // If we reach that point, either the resource was opened already...
resource->close(); // or we did open it and have to close it again.
}
+ localManager.removeCollection("QResources");
// operations
- QInstaller::appendInt64(out.data(), operations.count());
+ QInstaller::appendInt64(out, operations.count());
foreach (const OperationBlob &operation, operations) {
- QInstaller::appendString(out.data(), operation.name);
- QInstaller::appendString(out.data(), operation.xml);
+ QInstaller::appendString(out, operation.name);
+ QInstaller::appendString(out, operation.xml);
}
- QInstaller::appendInt64(out.data(), operations.count());
- const Range<qint64> operationsSegment = Range<qint64>::fromStartAndEnd(pos, out->pos())
- .moved(-endOfBinary);
+ QInstaller::appendInt64(out, operations.count());
+ const Range<qint64> operationsSegment = Range<qint64>::fromStartAndEnd(pos, out->pos());
// resource collections data and index
- const Range<qint64> resourceCollectionsSegment = manager.write(out.data(), -endOfBinary)
- .moved(-endOfBinary);
- QInstaller::appendInt64Range(out.data(), resourceCollectionsSegment);
+ const Range<qint64> resourceCollectionsSegment = localManager.write(out, -endOfBinary);
+ QInstaller::appendInt64Range(out, resourceCollectionsSegment.moved(-endOfBinary));
// meta resource segments
foreach (const Range<qint64> &segment, metaResourceSegments)
- QInstaller::appendInt64Range(out.data(), segment);
+ QInstaller::appendInt64Range(out, segment.moved(-endOfBinary));
// operations segment
- QInstaller::appendInt64Range(out.data(), operationsSegment);
+ QInstaller::appendInt64Range(out, operationsSegment.moved(-endOfBinary));
// resources count
- QInstaller::appendInt64(out.data(), metaResourceSegments.count());
+ QInstaller::appendInt64(out, metaResourceSegments.count());
const qint64 binaryContentSize = (out->pos() + (3 * sizeof(qint64))) - endOfBinary;
- QInstaller::appendInt64(out.data(), binaryContentSize);
- QInstaller::appendInt64(out.data(), magicMarker);
- QInstaller::appendInt64(out.data(), magicCookie);
+ QInstaller::appendInt64(out, binaryContentSize);
+ QInstaller::appendInt64(out, magicMarker);
+ QInstaller::appendInt64(out, magicCookie);
}
} // namespace QInstaller
diff --git a/src/libs/installer/binarycontent.h b/src/libs/installer/binarycontent.h
index b4527a74a..9821561cf 100644
--- a/src/libs/installer/binarycontent.h
+++ b/src/libs/installer/binarycontent.h
@@ -68,15 +68,13 @@ public:
static qint64 findMagicCookie(QFile *file, quint64 magicCookie);
static BinaryLayout binaryLayout(QFile *file, quint64 magicCookie);
- static void readBinaryContent(const QSharedPointer<QFile> &in,
- ResourceCollection *metaResources,
+ static void readBinaryContent(QFile *file,
QList<OperationBlob> *operations,
ResourceCollectionManager *manager,
qint64 *magicMarker,
quint64 magicCookie);
- static void writeBinaryContent(const QSharedPointer<QFile> &out,
- const ResourceCollection &metaResources,
+ static void writeBinaryContent(QFile *out,
const QList<OperationBlob> &operations,
const ResourceCollectionManager &manager,
qint64 magicMarker,
diff --git a/src/libs/installer/binaryformat.cpp b/src/libs/installer/binaryformat.cpp
index 91cfba676..b23def68c 100644
--- a/src/libs/installer/binaryformat.cpp
+++ b/src/libs/installer/binaryformat.cpp
@@ -51,86 +51,87 @@
namespace QInstaller {
/*!
- \class Resource
- \brief The Resource class provides an interface for reading from an underlying device.
+ \class QInstaller::OperationBlob
+ \inmodule QtInstallerFramework
+ \brief The OperationBlob class is a textual representation of an operation that can be
+ instantiated and executed by the Qt Installer Framework.
+*/
- Resource is an interface for reading inside a device, but is not supposed to write to the
- the device it wraps. The resource class is created by either passing a path to an already
- existing binary (e.g. a zipped archive, a Qt Resource file etc.) or by passing an name and
- segment inside an already existing QIODevice, passed as device.
+/*!
+ \fn OperationBlob::OperationBlob(const QString &n, const QString &x)
- The resource name can be set at any time using setName(). The segment passed inside the
- constructor represents the offset and size of the resource inside the device.
+ Constructs the operation blob with the given arguments, while \a n stands for the name part and
+ \a x for the XML representation of the operation.
*/
/*!
- Creates a resource providing the data in \a path.
+ \variable QInstaller::OperationBlob::name
+ \brief The name of the operation.
+*/
- \sa open()
- */
-Resource::Resource(const QString &path)
- : m_device(0)
- , m_name(QFileInfo(path).fileName().toUtf8())
- , m_deviceOpened(false)
-{
- m_inputFile.setFileName(path);
- m_segment = Range<qint64>::fromStartAndLength(0, m_inputFile.size());
-}
+/*!
+ \variable QInstaller::OperationBlob::xml
+ \brief The XML representation of the operation.
+*/
/*!
- Creates a resource identified by \a name providing the data in \a path.
+ \class QInstaller::Resource
+ \inmodule QtInstallerFramework
+ \brief The Resource class is an interface for wrapping a file as read only device.
+
+ Resource is an interface for reading inside a file, but is not supposed to write to the file it
+ wraps. The resource class is created by passing a path to an existing binary (such as a zipped
+ archive or a Qt resource file).
- \sa open()
+ The resource name can be set at any time using setName() or during construction. The segment
+ supplied during construction represents the offset and size of the resource inside the file.
*/
-Resource::Resource(const QByteArray &name, const QString &path)
- : m_device(0)
- , m_name(name)
- , m_deviceOpened(false)
-{
- m_inputFile.setFileName(path);
- m_segment = Range<qint64>::fromStartAndLength(0, m_inputFile.size());
-}
/*!
- Creates a resource providing the data in a \a device.
+ \fn Range<qint64> Resource::segment() const
- \sa open()
+ Returns the range inside the file this resource represents.
*/
-Resource::Resource(const QSharedPointer<QIODevice> &device)
- : m_device(device)
- , m_segment(Range<qint64>::fromStartAndLength(0, device->size()))
- , m_name(QUuid::createUuid().toByteArray())
- , m_deviceOpened(false)
-{
-}
/*!
- Creates a resource providing a data \a segment within a \a device.
+ \fn void Resource::setSegment(const Range<qint64> &segment)
- \sa open()
+ Sets the range inside the file this resource represents.
*/
-Resource::Resource(const QSharedPointer<QIODevice> &device, const Range<qint64> &segment)
- : m_device(device)
- , m_segment(segment)
- , m_name(QUuid::createUuid().toByteArray())
- , m_deviceOpened(false)
+
+/*!
+ Creates a resource providing the data in \a path.
+ */
+Resource::Resource(const QString &path)
+ : m_file(path)
+ , m_name(QFileInfo(path).fileName().toUtf8())
+ , m_segment(Range<qint64>::fromStartAndLength(0, m_file.size()))
{
}
/*!
- Creates a resource identified by \a name providing a data \a segment within a \a device.
+ Creates a resource providing the data in \a path identified by \a name.
+*/
+Resource::Resource(const QString &path, const QByteArray &name)
+ : m_file(path)
+ , m_name(name)
+ , m_segment(Range<qint64>::fromStartAndLength(0, m_file.size()))
+{
+}
- \sa open()
- */
-Resource::Resource(const QByteArray &name, const QSharedPointer<QIODevice> &device,
- const Range<qint64> &segment)
- : m_device(device)
+/*!
+ Creates a resource providing the data in \a path limited to \a segment.
+*/
+Resource::Resource(const QString &path, const Range<qint64> &segment)
+ : m_file(path)
+ , m_name(QFileInfo(path).fileName().toUtf8())
, m_segment(segment)
- , m_name(name)
- , m_deviceOpened(false)
{
}
+/*!
+ Destroys the resource. Calls close() if necessary before destroying the resource.
+*/
Resource::~Resource()
{
if (isOpen())
@@ -142,16 +143,20 @@ Resource::~Resource()
*/
bool Resource::seek(qint64 pos)
{
- if (m_inputFile.isOpen())
- return m_inputFile.seek(pos) && QIODevice::seek(pos);
return QIODevice::seek(pos);
}
+/*!
+ Returns the name of the resource.
+*/
QByteArray Resource::name() const
{
return m_name;
}
+/*!
+ Sets the name of the resource to \a name.
+*/
void Resource::setName(const QByteArray &name)
{
m_name = name;
@@ -166,39 +171,23 @@ bool Resource::open()
if (isOpen())
return false;
- if (m_device.isNull()) {
- if (!m_inputFile.open(QIODevice::ReadOnly)) {
- setErrorString(m_inputFile.errorString());
- return false;
- }
- return open(QIODevice::ReadOnly);
- }
-
- if (m_device->isOpen()) {
- if (!QFlags<QIODevice::OpenModeFlag>(m_device->openMode()).testFlag(QIODevice::ReadOnly)) {
- setErrorString(tr("Could not open the underlying device. Already opened write only."));
- return false;
- }
- return open(QIODevice::ReadOnly);
+ if (!m_file.open(QIODevice::ReadOnly)) {
+ setErrorString(m_file.errorString());
+ return false;
}
- m_deviceOpened = m_device->open(QIODevice::ReadOnly);
- if (!m_deviceOpened) {
- setErrorString(m_device->errorString());
+ if (!QIODevice::open(QIODevice::ReadOnly)) {
+ setErrorString(tr("Could not open Resource '%1' read-only.").arg(QString::fromUtf8(m_name)));
return false;
}
- return open(QIODevice::ReadOnly);
+ return true;
}
/*!
\reimp
*/
void Resource::close()
{
- m_inputFile.close();
- if (!m_device.isNull() && m_deviceOpened) {
- m_device->close();
- m_deviceOpened = false;
- }
+ m_file.close();
QIODevice::close();
}
@@ -215,13 +204,10 @@ qint64 Resource::size() const
*/
qint64 Resource::readData(char* data, qint64 maxSize)
{
- if (m_device == 0)
- return m_inputFile.read(data, maxSize);
-
- const qint64 p = m_device->pos();
- m_device->seek(m_segment.start() + pos());
- const qint64 amountRead = m_device->read(data, qMin<quint64>(maxSize, m_segment.length() - pos()));
- m_device->seek(p);
+ const qint64 p = m_file.pos();
+ m_file.seek(m_segment.start() + pos());
+ const qint64 amountRead = m_file.read(data, qMin<quint64>(maxSize, m_segment.length() - pos()));
+ m_file.seek(p);
return amountRead;
}
@@ -236,6 +222,17 @@ qint64 Resource::writeData(const char* data, qint64 maxSize)
return -1;
}
+/*!
+ \fn void Resource::copyData(QFileDevice *out)
+
+ Copies the resource data to a file called \a out. Throws Error on failure.
+*/
+
+/*!
+ \overload
+
+ Copies the resource data of \a resource to a file called \a out. Throws Error on failure.
+*/
void Resource::copyData(Resource *resource, QFileDevice *out)
{
qint64 left = resource->size();
@@ -258,88 +255,44 @@ void Resource::copyData(Resource *resource, QFileDevice *out)
/*!
- \class ResourceCollection
- \brief A Resource Collection is an abstraction that groups together a number of resources.
+ \class QInstaller::ResourceCollection
+ \inmodule QtInstallerFramework
+ \brief The ResourceCollection class is an abstraction that groups together a number of resources.
The resources are supposed to be sequential, so the collection keeps them ordered once a new
- resource is added.
+ resource is added. The name can be set at any time using setName().
+*/
- The resources collection can be written to and read from a QFileDevice. The resource
- collection name can be set at any time using setName().
+/*!
+ The class constructor creates an empty resource collection. By default the collection gets a
+ unique name assigned using QUuid.
*/
+ResourceCollection::ResourceCollection()
+ : ResourceCollection(QUuid::createUuid().toByteArray())
+{
+}
+/*!
+ The class constructor creates an empty resource collection with a name set to \a name.
+*/
ResourceCollection::ResourceCollection(const QByteArray &name)
: m_name(name)
-{
-}
+{}
+/*!
+ Returns the name of the resource collection.
+*/
QByteArray ResourceCollection::name() const
{
return m_name;
}
-void ResourceCollection::setName(const QByteArray &ba)
-{
- m_name = ba;
-}
-
-void ResourceCollection::write(QFileDevice *out, qint64 offset) const
-{
- const qint64 dataBegin = out->pos();
-
- QInstaller::appendInt64(out, m_resources.count());
-
- qint64 start = out->pos() + offset;
-
- // Why 16 + 16? This is 24, not 32???
- const int foo = 3 * sizeof(qint64);
- // add 16 + 16 + number of name characters for each resource (the size of the table)
- foreach (const QSharedPointer<Resource> &resource, m_resources)
- start += foo + resource->name().count();
-
- QList<qint64> starts;
- foreach (const QSharedPointer<Resource> &resource, m_resources) {
- QInstaller::appendByteArray(out, resource->name());
- starts.push_back(start);
- QInstaller::appendInt64Range(out, Range<qint64>::fromStartAndLength(start, resource->size()));
- start += resource->size();
- }
-
- foreach (const QSharedPointer<Resource> &resource, m_resources) {
- if (!resource->open()) {
- throw QInstaller::Error(tr("Could not open resource %1: %2")
- .arg(QString::fromUtf8(resource->name()), resource->errorString()));
- }
-
- const qint64 expectedStart = starts.takeFirst();
- const qint64 actualStart = out->pos() + offset;
- Q_UNUSED(expectedStart);
- Q_UNUSED(actualStart);
- Q_ASSERT(expectedStart == actualStart);
- resource->copyData(out);
- }
-
- m_segment = Range<qint64>::fromStartAndEnd(dataBegin, out->pos()).moved(offset);
-}
-
-void ResourceCollection::read(const QSharedPointer<QFile> &in, qint64 offset)
+/*!
+ Sets the name of the resource collection to \a name.
+*/
+void ResourceCollection::setName(const QByteArray &name)
{
- const qint64 pos = in->pos();
-
- in->seek(m_segment.start());
- const qint64 count = QInstaller::retrieveInt64(in.data());
-
- QList<QByteArray> names;
- QList<Range<qint64> > ranges;
- for (int i = 0; i < count; ++i) {
- names.push_back(QInstaller::retrieveByteArray(in.data()));
- ranges.push_back(QInstaller::retrieveInt64Range(in.data()).moved(offset));
- }
-
- for (int i = 0; i < ranges.count(); ++i)
- m_resources.append(QSharedPointer<Resource>(new Resource(names.at(i), in, ranges.at(i))));
-
- in->seek(pos);
+ m_name = name;
}
/*!
@@ -349,9 +302,13 @@ void ResourceCollection::appendResource(const QSharedPointer<Resource>& resource
{
Q_ASSERT(resource);
resource->setParent(0);
- m_resources.push_back(resource);
+ m_resources.append(resource);
}
+/*!
+ Appends a list of \a resources to this collection. The collection takes ownership of \a
+ resources.
+*/
void ResourceCollection::appendResources(const QList<QSharedPointer<Resource> > &resources)
{
foreach (const QSharedPointer<Resource> &resource, resources)
@@ -359,13 +316,16 @@ void ResourceCollection::appendResources(const QList<QSharedPointer<Resource> >
}
/*!
- Returns the resources associated with this component.
- */
+ Returns the resources associated with this collection.
+*/
QList<QSharedPointer<Resource> > ResourceCollection::resources() const
{
return m_resources;
}
+/*!
+ Returns the resource associated with the name \a name.
+*/
QSharedPointer<Resource> ResourceCollection::resourceByName(const QByteArray &name) const
{
foreach (const QSharedPointer<Resource>& i, m_resources) {
@@ -377,84 +337,139 @@ QSharedPointer<Resource> ResourceCollection::resourceByName(const QByteArray &na
/*!
- \class ResourceCollectionManager
- \brief A Resource Collection Manager is an abstraction that groups together a number of
- resource collections.
+ \class QInstaller::ResourceCollectionManager
+ \inmodule QtInstallerFramework
+ \brief The ResourceCollectionManager class is an abstraction that groups together a number of
+ resource collections.
- The resources collections can be written to and read from a QFileDevice.
+ The resources collections it groups can be written to and read from a QFileDevice.
*/
-void ResourceCollectionManager::read(const QSharedPointer<QFile> &dev, qint64 offset)
-{
- const qint64 size = QInstaller::retrieveInt64(dev.data());
- for (int i = 0; i < size; ++i)
- insertCollection(readIndexEntry(dev, offset));
- QInstaller::retrieveInt64(dev.data());
+/*!
+ Reads the resource collection from the file \a dev. The \a offset argument is used to
+ set the collection's resources segment information.
+*/
+void ResourceCollectionManager::read(QFileDevice *dev, qint64 offset)
+{
+ const qint64 size = QInstaller::retrieveInt64(dev);
+ for (int i = 0; i < size; ++i) {
+ ResourceCollection collection(QInstaller::retrieveByteArray(dev));
+ const Range<qint64> segment = QInstaller::retrieveInt64Range(dev).moved(offset);
+
+ const qint64 pos = dev->pos();
+
+ dev->seek(segment.start());
+ const qint64 count = QInstaller::retrieveInt64(dev);
+ for (int i = 0; i < count; ++i) {
+ QSharedPointer<Resource> resource(new Resource(dev->fileName()));
+ resource->setName(QInstaller::retrieveByteArray(dev));
+ resource->setSegment(QInstaller::retrieveInt64Range(dev).moved(offset));
+ collection.appendResource(resource);
+ }
+ dev->seek(pos);
+
+ insertCollection(collection);
+ }
}
+/*!
+ Writes the resource collection to the file \a out. The \a offset argument is used to
+ set the collection's segment information.
+*/
Range<qint64> ResourceCollectionManager::write(QFileDevice *out, qint64 offset) const
{
+ QHash < QByteArray, Range<qint64> > table;
QInstaller::appendInt64(out, collectionCount());
- foreach (const ResourceCollection &collection, m_collections)
- collection.write(out, offset);
+ foreach (const ResourceCollection &collection, m_collections) {
+ const qint64 dataBegin = out->pos();
+ QInstaller::appendInt64(out, collection.resources().count());
+
+ qint64 start = out->pos() + offset;
+ foreach (const QSharedPointer<Resource> &resource, collection.resources()) {
+ start += (sizeof(qint64)) // the number of bytes that get written and the
+ + resource->name().size() // resource name (see QInstaller::appendByteArray)
+ + (2 * sizeof(qint64)); // the resource range (see QInstaller::appendInt64Range)
+ }
+
+ foreach (const QSharedPointer<Resource> &resource, collection.resources()) {
+ QInstaller::appendByteArray(out, resource->name());
+ QInstaller::appendInt64Range(out, Range<qint64>::fromStartAndLength(start,
+ resource->size())); // the actual range once the table has been written
+ start += resource->size(); // adjust for next resource data
+ }
+
+ foreach (const QSharedPointer<Resource> &resource, collection.resources()) {
+ if (!resource->open()) {
+ throw QInstaller::Error(tr("Could not open resource %1: %2")
+ .arg(QString::fromUtf8(resource->name()), resource->errorString()));
+ }
+ resource->copyData(out);
+ }
+
+ table.insert(collection.name(), Range<qint64>::fromStartAndEnd(dataBegin, out->pos())
+ .moved(offset));
+ }
const qint64 start = out->pos();
// Q: why do we write the size twice?
// A: for us to be able to read it beginning from the end of the file as well
QInstaller::appendInt64(out, collectionCount());
- foreach (const ResourceCollection &collection, m_collections)
- writeIndexEntry(collection, out);
+ foreach (const QByteArray &name, table.keys()) {
+ QInstaller::appendByteArray(out, name);
+ QInstaller::appendInt64Range(out, table.value(name));
+ }
QInstaller::appendInt64(out, collectionCount());
return Range<qint64>::fromStartAndEnd(start, out->pos());
}
+/*!
+ Returns the collection associated with the name \a name.
+*/
ResourceCollection ResourceCollectionManager::collectionByName(const QByteArray &name) const
{
return m_collections.value(name);
}
+/*!
+ Inserts the \a collection into the collection manager.
+*/
void ResourceCollectionManager::insertCollection(const ResourceCollection& collection)
{
m_collections.insert(collection.name(), collection);
}
+/*!
+ Removes all occurrences of \a name from the collection manager.
+*/
void ResourceCollectionManager::removeCollection(const QByteArray &name)
{
m_collections.remove(name);
}
+/*!
+ Returns the collections the collection manager contains.
+*/
QList<ResourceCollection> ResourceCollectionManager::collections() const
{
return m_collections.values();
}
-void ResourceCollectionManager::reset()
+/*!
+ Clears the contents of the collection manager.
+*/
+void ResourceCollectionManager::clear()
{
m_collections.clear();
}
+/*!
+ Returns the number of collections in the collection manager.
+*/
int ResourceCollectionManager::collectionCount() const
{
- return m_collections.size();
-}
-
-void ResourceCollectionManager::writeIndexEntry(const ResourceCollection &collection,
- QFileDevice *dev) const
-{
- QInstaller::appendByteArray(dev, collection.name());
- QInstaller::appendInt64Range(dev, collection.segment());
-}
-
-ResourceCollection ResourceCollectionManager::readIndexEntry(const QSharedPointer<QFile> &in,
- qint64 offset)
-{
- ResourceCollection c(QInstaller::retrieveByteArray(in.data()));
- c.setSegment(QInstaller::retrieveInt64Range(in.data()).moved(offset));
- c.read(in, offset);
-
- return c;
+ return m_collections.count();
}
} // namespace QInstaller
diff --git a/src/libs/installer/binaryformat.h b/src/libs/installer/binaryformat.h
index d2fc68987..e09e79318 100644
--- a/src/libs/installer/binaryformat.h
+++ b/src/libs/installer/binaryformat.h
@@ -42,11 +42,13 @@
#ifndef BINARYFORMAT_H
#define BINARYFORMAT_H
+#include "installer_global.h"
#include "range.h"
-#include "qinstallerglobal.h"
+#include <QCoreApplication>
#include <QFile>
#include <QList>
+#include <QSharedPointer>
namespace QInstaller {
@@ -65,12 +67,8 @@ class INSTALLER_EXPORT Resource : public QIODevice
public:
explicit Resource(const QString &path);
- Resource(const QByteArray &name, const QString &path);
-
- explicit Resource(const QSharedPointer<QIODevice> &device);
- Resource(const QSharedPointer<QIODevice> &device, const Range<qint64> &segment);
- Resource(const QByteArray &name, const QSharedPointer<QIODevice> &device,
- const Range<qint64> &segment);
+ Resource(const QString &path, const QByteArray &name);
+ Resource(const QString &path, const Range<qint64> &segment);
~Resource();
bool open();
@@ -83,6 +81,7 @@ public:
void setName(const QByteArray &name);
Range<qint64> segment() const { return m_segment; }
+ void setSegment(const Range<qint64> &segment) { m_segment = segment; }
void copyData(QFileDevice *out) { copyData(this, out); }
static void copyData(Resource *archive, QFileDevice *out);
@@ -90,14 +89,14 @@ public:
private:
qint64 readData(char *data, qint64 maxSize);
qint64 writeData(const char *data, qint64 maxSize);
+
bool open(OpenMode mode) { return QIODevice::open(mode); }
+ void setOpenMode(OpenMode mode) { QIODevice::setOpenMode(mode); }
private:
- QSharedPointer<QIODevice> m_device;
- Range<qint64> m_segment;
- QFile m_inputFile;
+ QFile m_file;
QByteArray m_name;
- bool m_deviceOpened;
+ Range<qint64> m_segment;
};
@@ -106,39 +105,33 @@ class INSTALLER_EXPORT ResourceCollection
Q_DECLARE_TR_FUNCTIONS(ResourceCollection)
public:
- ResourceCollection() {}
+ ResourceCollection();
explicit ResourceCollection(const QByteArray &name);
QByteArray name() const;
void setName(const QByteArray &ba);
- Range<qint64> segment() const { return m_segment; }
- void setSegment(const Range<qint64> &segment) const { m_segment = segment; }
-
- void write(QFileDevice *dev, qint64 positionOffset) const;
- void read(const QSharedPointer<QFile> &dev, qint64 offset);
-
QList<QSharedPointer<Resource> > resources() const;
QSharedPointer<Resource> resourceByName(const QByteArray &name) const;
void appendResource(const QSharedPointer<Resource> &resource);
void appendResources(const QList<QSharedPointer<Resource> > &resources);
-
private:
QByteArray m_name;
- mutable Range<qint64> m_segment;
QList<QSharedPointer<Resource> > m_resources;
};
class INSTALLER_EXPORT ResourceCollectionManager
{
+ Q_DECLARE_TR_FUNCTIONS(ResourceCollectionManager)
+
public:
+ void read(QFileDevice *dev, qint64 offset);
Range<qint64> write(QFileDevice *dev, qint64 offset) const;
- void read(const QSharedPointer<QFile> &dev, qint64 offset);
- void reset();
+ void clear();
int collectionCount() const;
QList<ResourceCollection> collections() const;
@@ -148,10 +141,6 @@ public:
void insertCollection(const ResourceCollection &collection);
private:
- void writeIndexEntry(const ResourceCollection &coll, QFileDevice *dev) const;
- ResourceCollection readIndexEntry(const QSharedPointer<QFile> &dev, qint64 offset);
-
-private:
QHash<QByteArray, ResourceCollection> m_collections;
};
diff --git a/src/libs/installer/binaryformatengine.cpp b/src/libs/installer/binaryformatengine.cpp
index d493018ea..d9645c2fe 100644
--- a/src/libs/installer/binaryformatengine.cpp
+++ b/src/libs/installer/binaryformatengine.cpp
@@ -80,6 +80,13 @@ private:
namespace QInstaller {
+/*!
+ \class QInstaller::BinaryFormatEngine
+ \inmodule QtInstallerFramework
+ \brief The BinaryFormatEngine class is the default file engine for accessing resource
+ collections and resource files.
+*/
+
BinaryFormatEngine::BinaryFormatEngine(const QHash<QByteArray, ResourceCollection> &collections,
const QString &fileName)
: m_resource(0)
@@ -89,7 +96,7 @@ BinaryFormatEngine::BinaryFormatEngine(const QHash<QByteArray, ResourceCollectio
}
/*!
- \reimp
+ \internal
*/
void BinaryFormatEngine::setFileName(const QString &file)
{
@@ -110,7 +117,7 @@ void BinaryFormatEngine::setFileName(const QString &file)
}
/*!
- \reimp
+ \internal
*/
bool BinaryFormatEngine::close()
{
@@ -123,15 +130,16 @@ bool BinaryFormatEngine::close()
}
/*!
- \reimp
+ \internal
*/
-bool BinaryFormatEngine::open(QIODevice::OpenMode /*mode*/)
+bool BinaryFormatEngine::open(QIODevice::OpenMode mode)
{
+ Q_UNUSED(mode)
return m_resource.isNull() ? false : m_resource->open();
}
/*!
- \reimp
+ \internal
*/
qint64 BinaryFormatEngine::pos() const
{
@@ -139,7 +147,7 @@ qint64 BinaryFormatEngine::pos() const
}
/*!
- \reimp
+ \internal
*/
qint64 BinaryFormatEngine::read(char *data, qint64 maxlen)
{
@@ -147,7 +155,7 @@ qint64 BinaryFormatEngine::read(char *data, qint64 maxlen)
}
/*!
- \reimp
+ \internal
*/
bool BinaryFormatEngine::seek(qint64 offset)
{
@@ -155,7 +163,7 @@ bool BinaryFormatEngine::seek(qint64 offset)
}
/*!
- \reimp
+ \internal
*/
QString BinaryFormatEngine::fileName(FileName file) const
{
@@ -177,7 +185,7 @@ QString BinaryFormatEngine::fileName(FileName file) const
}
/*!
- \reimp
+ \internal
*/
bool BinaryFormatEngine::copy(const QString &newName)
{
@@ -213,7 +221,7 @@ bool BinaryFormatEngine::copy(const QString &newName)
}
/*!
- \reimp
+ \internal
*/
QAbstractFileEngine::FileFlags BinaryFormatEngine::fileFlags(FileFlags type) const
{
@@ -231,7 +239,7 @@ QAbstractFileEngine::FileFlags BinaryFormatEngine::fileFlags(FileFlags type) con
}
/*!
- \reimp
+ \internal
*/
QAbstractFileEngineIterator *BinaryFormatEngine::beginEntryList(QDir::Filters filters, const QStringList &filterNames)
{
@@ -240,7 +248,7 @@ QAbstractFileEngineIterator *BinaryFormatEngine::beginEntryList(QDir::Filters fi
}
/*!
- \reimp
+ \internal
*/
QStringList BinaryFormatEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const
{
@@ -280,7 +288,7 @@ QStringList BinaryFormatEngine::entryList(QDir::Filters filters, const QStringLi
}
/*!
- \reimp
+ \internal
*/
qint64 BinaryFormatEngine::size() const
{
diff --git a/src/libs/installer/binaryformatenginehandler.cpp b/src/libs/installer/binaryformatenginehandler.cpp
index 3388c5800..4d83a000b 100644
--- a/src/libs/installer/binaryformatenginehandler.cpp
+++ b/src/libs/installer/binaryformatenginehandler.cpp
@@ -42,33 +42,60 @@
#include "binaryformatenginehandler.h"
#include "binaryformatengine.h"
-#include <QFile>
-
namespace QInstaller {
+/*!
+ \class QInstaller::BinaryFormatEngineHandler
+ \inmodule QtInstallerFramework
+ \brief The BinaryFormatEngineHandler class provides a way to register resource collections and
+ resource files.
+*/
+
+/*!
+ Creates a file engine for the file specified by \a fileName. To be able to create a file
+ engine, the file name needs to be prefixed with \c {installer://}.
+
+ Returns 0 if the engine cannot handle \a fileName.
+*/
QAbstractFileEngine *BinaryFormatEngineHandler::create(const QString &fileName) const
{
return fileName.startsWith(QLatin1String("installer://"), Qt::CaseInsensitive )
? new BinaryFormatEngine(m_resources, fileName) : 0;
}
-void BinaryFormatEngineHandler::reset()
+/*!
+ Clears the contents of the binary format engine.
+*/
+void BinaryFormatEngineHandler::clear()
{
m_resources.clear();
}
+/*!
+ Returns the active instance of the engine.
+*/
BinaryFormatEngineHandler *BinaryFormatEngineHandler::instance()
{
static BinaryFormatEngineHandler instance;
return &instance;
}
+/*!
+ Registers the given resource collections \a collections in the engine.
+*/
void BinaryFormatEngineHandler::registerResources(const QList<ResourceCollection> &collections)
{
foreach (const ResourceCollection &collection, collections)
m_resources.insert(collection.name(), collection);
}
+/*!
+ Registers the resource specified by \a resourcePath in a resource collection specified
+ by \a fileName. The file name \a fileName must be in the form of \c {installer://}, followed
+ by the collection name and resource name separated by a forward slash.
+
+ A valid file name looks like this: installer://collectionName/resourceName
+*/
void
BinaryFormatEngineHandler::registerResource(const QString &fileName, const QString &resourcePath)
{
@@ -85,8 +112,8 @@ BinaryFormatEngineHandler::registerResource(const QString &fileName, const QStri
const QByteArray collectionName = path.section(sep, 0, 0).toUtf8();
m_resources[collectionName].setName(collectionName);
- m_resources[collectionName].appendResource(QSharedPointer<Resource>(new Resource(resourceName,
- resourcePath)));
+ m_resources[collectionName].appendResource(QSharedPointer<Resource>(new Resource(resourcePath,
+ resourceName)));
}
} // namespace QInstaller
diff --git a/src/libs/installer/binaryformatenginehandler.h b/src/libs/installer/binaryformatenginehandler.h
index 213861118..6ff56480a 100644
--- a/src/libs/installer/binaryformatenginehandler.h
+++ b/src/libs/installer/binaryformatenginehandler.h
@@ -55,7 +55,7 @@ class INSTALLER_EXPORT BinaryFormatEngineHandler : public QAbstractFileEngineHan
public:
QAbstractFileEngine *create(const QString &fileName) const;
- void reset();
+ void clear();
static BinaryFormatEngineHandler *instance();
void registerResources(const QList<ResourceCollection> &collections);
diff --git a/src/libs/installer/binarylayout.cpp b/src/libs/installer/binarylayout.cpp
index 6437262af..e759e5f17 100644
--- a/src/libs/installer/binarylayout.cpp
+++ b/src/libs/installer/binarylayout.cpp
@@ -41,11 +41,10 @@
/*!
\class QInstaller::BinaryLayout
+ \inmodule QtInstallerFramework
+ \brief The BinaryLayout class describes the binary content appended to a file.
- BinaryLayout handles binary information embedded into executables.
- Qt resources as well as resource collections can be stored.
-
- Explanation of the binary blob at the end of the installer or separate data file:
+ Explanation of the binary content at the end of the installer or the separate data file:
\code
@@ -62,8 +61,8 @@
[Format]
Operation count (qint64)
----------------------------------------------------------
- Component count
- Component data entry [1 ... n]
+ Collection count
+ Collection data entry [1 ... n]
[Format]
Archive count (qint64),
Name entry [1 ... n]
@@ -78,17 +77,17 @@
[Format]
[Format]
----------------------------------------------------------
- Component count (qint64)
- Component index entry [1 ... n]
+ Collection count (qint64)
+ Collection index entry [1 ... n]
[Format]
Name (qint64, QByteArray)
Offset (qint64)
Length (qint64)
[Format]
- Component count (qint64)
+ Collection count (qint64)
----------------------------------------------------------
- Component index block [Offset (qint64)]
- Component index block [Length (qint64)]
+ Collection index block [Offset (qint64)]
+ Collection index block [Length (qint64)]
----------------------------------------------------------
Resource segments [1 ... n]
[Format]
diff --git a/src/libs/installer/createlocalrepositoryoperation.cpp b/src/libs/installer/createlocalrepositoryoperation.cpp
index cfec09585..e550a8997 100644
--- a/src/libs/installer/createlocalrepositoryoperation.cpp
+++ b/src/libs/installer/createlocalrepositoryoperation.cpp
@@ -250,15 +250,15 @@ bool CreateLocalRepositoryOperation::performOperation()
emit progressChanged(0.50);
- QSharedPointer<QFile> file(new QFile(binaryPath));
- if (!file->open(QIODevice::ReadOnly)) {
- throw QInstaller::Error(tr("Could not open file: %1. Error: %2").arg(file->fileName(),
- file->errorString()));
+ QFile file(binaryPath);
+ if (!file.open(QIODevice::ReadOnly)) {
+ throw QInstaller::Error(tr("Could not open file: %1. Error: %2").arg(file.fileName(),
+ file.errorString()));
}
// start to read the binary layout
ResourceCollectionManager manager;
- BinaryContent::readBinaryContent(file, 0, 0, &manager, 0, BinaryContent::MagicCookie);
+ BinaryContent::readBinaryContent(&file, 0, &manager, 0, BinaryContent::MagicCookie);
QDirIterator it(repoPath, QDirIterator::Subdirectories);
while (it.hasNext() && !it.next().isEmpty()) {
@@ -277,7 +277,8 @@ bool CreateLocalRepositoryOperation::performOperation()
// copy the 7z files that are inside the component index into the target
const ResourceCollection collection = manager.collectionByName(fileName.toUtf8());
foreach (const QSharedPointer<Resource> &resource, collection.resources()) {
- if (!resource->open())
+ const bool isOpen = resource->isOpen();
+ if ((!isOpen) && (!resource->open()))
continue;
QFile target(absoluteTargetPath + QDir::separator()
@@ -286,6 +287,9 @@ bool CreateLocalRepositoryOperation::performOperation()
resource->copyData(&target);
helper.m_files.prepend(target.fileName());
emit outputTextChanged(helper.m_files.first());
+
+ if (!isOpen) // If we reach that point, either the resource was opened already.
+ resource->close(); // or we did open it and have to close it again.
}
}
}
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 5b31255e5..d7c534baa 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -410,7 +410,7 @@ void PackageManagerCorePrivate::cleanUpComponentEnvironment()
{
// clean up registered (downloaded) data
if (m_core->isUpdater() || m_core->isPackageManager())
- BinaryFormatEngineHandler::instance()->reset();
+ BinaryFormatEngineHandler::instance()->clear();
// there could be still some references to already deleted components,
// so we need to remove the current component script engine
diff --git a/src/sdk/installerbase.cpp b/src/sdk/installerbase.cpp
index 33f8d39e3..d5280a8bc 100644
--- a/src/sdk/installerbase.cpp
+++ b/src/sdk/installerbase.cpp
@@ -95,15 +95,14 @@ int InstallerBase::run()
cookie = QInstaller::BinaryContent::MagicCookie;
}
- QSharedPointer<QFile> binary(new QFile(fileName));
- QInstaller::openForRead(binary.data());
+ QFile binary(fileName);
+ QInstaller::openForRead(&binary);
qint64 magicMarker;
- QInstaller::ResourceCollection resources;
QInstaller::ResourceCollectionManager manager;
QList<QInstaller::OperationBlob> oldOperations;
- QInstaller::BinaryContent::readBinaryContent(binary, &resources, &oldOperations, &manager,
- &magicMarker, cookie);
+ QInstaller::BinaryContent::readBinaryContent(&binary, &oldOperations, &manager, &magicMarker,
+ cookie);
if (QInstaller::isVerbose()) {
qDebug() << "Language:" << QLocale().uiLanguages().value(0,
@@ -111,7 +110,7 @@ int InstallerBase::run()
qDebug() << "Arguments: " << arguments().join(QLatin1String(", ")).toUtf8().constData();
}
- registerMetaResources(resources); // the base class will unregister the resources
+ SDKApp::registerMetaResources(manager.collectionByName("QResources"));
QInstaller::BinaryFormatEngineHandler::instance()->registerResources(manager.collections());
if (QInstaller::isVerbose())
@@ -121,11 +120,6 @@ int InstallerBase::run()
m_core = new QInstaller::PackageManagerCore(magicMarker, oldOperations);
QInstaller::ProductKeyCheck::instance()->init(m_core);
- // We can close the binary file if we are an online installer or no installer at all, cause no
- // embedded archives exist inside the component index. Keeps the .dat file unlocked on Windows.
- if ((!m_core->isInstaller()) || (!m_core->isOfflineOnly()))
- binary->close();
-
CommandLineParser parser;
parser.parse(arguments());
diff --git a/src/sdk/sdkapp.h b/src/sdk/sdkapp.h
index a00e2d0e8..d6f830b37 100644
--- a/src/sdk/sdkapp.h
+++ b/src/sdk/sdkapp.h
@@ -48,7 +48,6 @@
#include <fileutils.h>
#include <QApplication>
-#include <QBuffer>
#include <QDir>
#include <QFileInfo>
#include <QResource>
@@ -64,12 +63,8 @@ public:
virtual ~SDKApp()
{
- using namespace QInstaller;
- foreach (const QSharedPointer<Resource> &resource, resourceMappings.resources()) {
- resource->open(); // ignore error here, either we opened it or it is opened
- QResource::unregisterResource((const uchar *) resource->readAll().constData(),
- QLatin1String(":/metadata"));
- }
+ foreach (const QByteArray &ba, m_resourceMappings)
+ QResource::unregisterResource((const uchar*) ba.data(), QLatin1String(":/metadata"));
}
bool notify(QObject *receiver, QEvent *event)
@@ -132,14 +127,9 @@ public:
return QString();
}
- QInstaller::ResourceCollection registeredMetaResources()
- {
- return resourceMappings;
- }
-
- void registerMetaResources(const QInstaller::ResourceCollection &resources)
+ void registerMetaResources(const QInstaller::ResourceCollection &collection)
{
- foreach (const QSharedPointer<QInstaller::Resource> &resource, resources.resources()) {
+ foreach (const QSharedPointer<QInstaller::Resource> &resource, collection.resources()) {
const bool isOpen = resource->isOpen();
if ((!isOpen) && (!resource->open()))
continue;
@@ -151,20 +141,16 @@ public:
if (ba.isEmpty())
continue;
- if (QResource::registerResource((const uchar*) ba.data(), QLatin1String(":/metadata"))) {
- using namespace QInstaller;
- QSharedPointer<QBuffer> buffer(new QBuffer);
- buffer->setData(ba); // set the buffers internal data
- resourceMappings.appendResource(QSharedPointer<Resource>(new Resource(buffer)));
- }
+ if (QResource::registerResource((const uchar*) ba.data(), QLatin1String(":/metadata")))
+ m_resourceMappings.append(ba);
- if (!isOpen) // If we reach that point, either the resource was opened already...
- resource->close(); // or we did open it and have to close it again.
+ if (!isOpen) // If we reach that point, either the resource was opened already...
+ resource->close(); // or we did open it and have to close it again.
}
}
private:
- QInstaller::ResourceCollection resourceMappings;
+ QList<QByteArray> m_resourceMappings;
};
#endif // SDKAPP_H
diff --git a/src/sdk/updatechecker.cpp b/src/sdk/updatechecker.cpp
index 115db45ea..69bfe1732 100644
--- a/src/sdk/updatechecker.cpp
+++ b/src/sdk/updatechecker.cpp
@@ -72,20 +72,19 @@ int UpdateChecker::check()
cookie = QInstaller::BinaryContent::MagicCookie;
}
- QSharedPointer<QFile> binary(new QFile(fileName));
- QInstaller::openForRead(binary.data());
+ QFile binary(fileName);
+ QInstaller::openForRead(&binary);
qint64 magicMarker;
- QInstaller::ResourceCollection resources;
QList<QInstaller::OperationBlob> operations;
QInstaller::ResourceCollectionManager manager;
- QInstaller::BinaryContent::readBinaryContent(binary, &resources, &operations, &manager,
- &magicMarker, cookie);
+ QInstaller::BinaryContent::readBinaryContent(&binary, &operations, &manager, &magicMarker,
+ cookie);
if (magicMarker != QInstaller::BinaryContent::MagicInstallerMarker)
throw QInstaller::Error(QLatin1String("Installers cannot check for updates."));
- registerMetaResources(resources); // the base class will unregister the resources
+ SDKApp::registerMetaResources(manager.collectionByName("QResources"));
// instantiate the installer we are actually going to use
QInstaller::PackageManagerCore core(QInstaller::BinaryContent::MagicUpdaterMarker, operations);
diff --git a/tests/auto/installer/binaryformat/tst_binaryformat.cpp b/tests/auto/installer/binaryformat/tst_binaryformat.cpp
index 87a1f7ef8..548d4fb1a 100644
--- a/tests/auto/installer/binaryformat/tst_binaryformat.cpp
+++ b/tests/auto/installer/binaryformat/tst_binaryformat.cpp
@@ -70,7 +70,7 @@ public:
virtual bool performOperation() { return true; }
virtual bool undoOperation() { return true; }
virtual bool testOperation() { return true; }
- virtual Operation *clone() const { return 0; }
+ virtual KDUpdater::UpdateOperation *clone() const { return 0; }
};
class tst_BinaryFormat : public QObject
@@ -183,42 +183,29 @@ private slots:
layout.operationsSegment = Range<qint64>::fromStartAndEnd(start, end);
QTemporaryFile data;
- QTemporaryFile data2;
- { // put into the scope to make the temporary file auto remove feature work
-
- ResourceCollectionManager manager;
-
- QInstaller::openForWrite(&data);
- QInstaller::blockingWrite(&data, QByteArray("Collection 1, Resource 1."));
- data.close();
-
- ResourceCollection collection;
- collection.setName(QByteArray("Collection 1"));
-
- QSharedPointer<Resource> resource(new Resource(data.fileName()));
- resource->setName("Resource 1");
- collection.appendResource(resource);
- manager.insertCollection(collection);
+ QInstaller::openForWrite(&data);
+ QInstaller::blockingWrite(&data, QByteArray("Collection 1, Resource 1."));
+ data.close();
- QInstaller::openForWrite(&data2);
- QInstaller::blockingWrite(&data2, QByteArray("Collection 2, Resource 2."));
- data2.close();
+ QSharedPointer<Resource> resource(new Resource(data.fileName(), QByteArray("Resource 1")));
+ ResourceCollection collection(QByteArray("Collection 1"));
+ collection.appendResource(resource);
- ResourceCollection collection2;
- collection2.setName(QByteArray("Collection 2"));
+ QTemporaryFile data2;
+ QInstaller::openForWrite(&data2);
+ QInstaller::blockingWrite(&data2, QByteArray("Collection 2, Resource 2."));
+ data2.close();
- QSharedPointer<Resource> resource2(new
- Resource(data2.fileName()));
- resource2->setName("Resource 2");
- collection2.appendResource(resource2);
- manager.insertCollection(collection2);
+ QSharedPointer<Resource> resource2(new Resource(data2.fileName(), QByteArray("Resource 2")));
+ ResourceCollection collection2(QByteArray("Collection 2"));
+ collection2.appendResource(resource2);
- layout.collectionCount = manager.collectionCount();
- layout.resourceCollectionsSegment = manager.write(&binary, -layout.endOfExectuable);
+ ResourceCollectionManager manager;
+ manager.insertCollection(collection);
+ manager.insertCollection(collection2);
- resource->close();
- resource2->close();
- }
+ layout.collectionCount = manager.collectionCount();
+ layout.resourceCollectionsSegment = manager.write(&binary, -layout.endOfExectuable);
QInstaller::appendInt64Range(&binary, layout.resourceCollectionsSegment.moved(-layout
.endOfExectuable));
@@ -247,35 +234,35 @@ private slots:
void readBinaryContent()
{
- const QSharedPointer<QFile> binary(new QFile(m_binary));
- QInstaller::openForRead(binary.data());
- QCOMPARE(QInstaller::retrieveData(binary.data(), scTinySize), QByteArray(scTinySize, '1'));
+ QFile binary(m_binary);
+ QInstaller::openForRead(&binary);
+ QCOMPARE(QInstaller::retrieveData(&binary, scTinySize), QByteArray(scTinySize, '1'));
Layout layout;
- layout.endOfExectuable = binary->pos();
+ layout.endOfExectuable = binary.pos();
QCOMPARE(layout.endOfExectuable, m_layout.endOfExectuable);
- const qint64 pos = BinaryContent::findMagicCookie(binary.data(), BinaryContent::MagicCookie);
+ const qint64 pos = BinaryContent::findMagicCookie(&binary, BinaryContent::MagicCookie);
layout.endOfBinaryContent = pos + sizeof(qint64);
QCOMPARE(layout.endOfBinaryContent, m_layout.endOfBinaryContent);
- binary->seek(layout.endOfBinaryContent - (4 * sizeof(qint64)));
+ binary.seek(layout.endOfBinaryContent - (4 * sizeof(qint64)));
- layout.metaSegmentsCount = QInstaller::retrieveInt64(binary.data());
+ layout.metaSegmentsCount = QInstaller::retrieveInt64(&binary);
QCOMPARE(layout.metaSegmentsCount, m_layout.metaSegmentsCount);
const qint64 offsetCollectionIndexSegments = layout.endOfBinaryContent
- ((layout.metaSegmentsCount * (2 * sizeof(qint64))) // minus size of the meta segments
- + (8 * sizeof(qint64))); // meta count, offset/length component index, marker, cookie...
+ + (8 * sizeof(qint64))); // meta count, offset/length collection index, marker, cookie...
- binary->seek(offsetCollectionIndexSegments);
+ binary.seek(offsetCollectionIndexSegments);
- layout.resourceCollectionsSegment = QInstaller::retrieveInt64Range(binary.data())
+ layout.resourceCollectionsSegment = QInstaller::retrieveInt64Range(&binary)
.moved(layout.endOfExectuable);
QCOMPARE(layout.resourceCollectionsSegment, m_layout.resourceCollectionsSegment);
for (int i = 0; i < layout.metaSegmentsCount; ++i) {
- layout.metaResourceSegments.append(QInstaller::retrieveInt64Range(binary.data())
+ layout.metaResourceSegments.append(QInstaller::retrieveInt64Range(&binary)
.moved(layout.endOfExectuable));
}
layout.metaResourcesSegment = Range<qint64>::fromStartAndEnd(layout.metaResourceSegments
@@ -285,58 +272,58 @@ private slots:
QCOMPARE(layout.metaResourceSegments.first(), m_layout.metaResourceSegments.first());
QCOMPARE(layout.metaResourceSegments.last(), m_layout.metaResourceSegments.last());
- layout.operationsSegment = QInstaller::retrieveInt64Range(binary.data()).moved(layout
+ layout.operationsSegment = QInstaller::retrieveInt64Range(&binary).moved(layout
.endOfExectuable);
QCOMPARE(layout.operationsSegment, m_layout.operationsSegment);
- QCOMPARE(layout.metaSegmentsCount, QInstaller::retrieveInt64(binary.data()));
+ QCOMPARE(layout.metaSegmentsCount, QInstaller::retrieveInt64(&binary));
- layout.binaryContentSize = QInstaller::retrieveInt64(binary.data());
+ layout.binaryContentSize = QInstaller::retrieveInt64(&binary);
QCOMPARE(layout.binaryContentSize, m_layout.binaryContentSize);
QCOMPARE(layout.endOfExectuable, layout.endOfBinaryContent - layout.binaryContentSize);
- layout.magicMarker = QInstaller::retrieveInt64(binary.data());
+ layout.magicMarker = QInstaller::retrieveInt64(&binary);
QCOMPARE(layout.magicMarker, m_layout.magicMarker);
- layout.magicCookie = QInstaller::retrieveInt64(binary.data());
+ layout.magicCookie = QInstaller::retrieveInt64(&binary);
QCOMPARE(layout.magicCookie, m_layout.magicCookie);
- binary->seek(layout.operationsSegment.start());
+ binary.seek(layout.operationsSegment.start());
- layout.operationsCount = QInstaller::retrieveInt64(binary.data());
+ layout.operationsCount = QInstaller::retrieveInt64(&binary);
QCOMPARE(layout.operationsCount, m_layout.operationsCount);
for (int i = 0; i < layout.operationsCount; ++i) {
- QCOMPARE(m_operations.at(i).name, QInstaller::retrieveString(binary.data()));
- QCOMPARE(m_operations.at(i).xml, QInstaller::retrieveString(binary.data()));
+ QCOMPARE(m_operations.at(i).name, QInstaller::retrieveString(&binary));
+ QCOMPARE(m_operations.at(i).xml, QInstaller::retrieveString(&binary));
}
- layout.operationsCount = QInstaller::retrieveInt64(binary.data());
+ layout.operationsCount = QInstaller::retrieveInt64(&binary);
QCOMPARE(layout.operationsCount, m_layout.operationsCount);
- layout.collectionCount = QInstaller::retrieveInt64(binary.data());
+ layout.collectionCount = QInstaller::retrieveInt64(&binary);
QCOMPARE(layout.collectionCount, m_layout.collectionCount);
- binary->seek(layout.resourceCollectionsSegment.start());
- m_manager.read(binary, layout.endOfExectuable);
+ binary.seek(layout.resourceCollectionsSegment.start());
+ m_manager.read(&binary, layout.endOfExectuable);
- const QList<ResourceCollection> components = m_manager.collections();
- QCOMPARE(components.count(), m_layout.collectionCount);
+ const QList<ResourceCollection> collections = m_manager.collections();
+ QCOMPARE(collections.count(), m_layout.collectionCount);
- ResourceCollection component = m_manager.collectionByName("Collection 1");
- QCOMPARE(component.resources().count(), 1);
+ ResourceCollection collection = m_manager.collectionByName(QByteArray("Collection 1"));
+ QCOMPARE(collection.resources().count(), 1);
- QSharedPointer<Resource> resource(component.resourceByName("Resource 1"));
+ QSharedPointer<Resource> resource(collection.resourceByName(QByteArray("Resource 1")));
QCOMPARE(resource.isNull(), false);
QCOMPARE(resource->isOpen(), false);
QCOMPARE(resource->open(), true);
QCOMPARE(resource->readAll(), QByteArray("Collection 1, Resource 1."));
resource->close();
- component = m_manager.collectionByName("Collection 2");
- QCOMPARE(component.resources().count(), 1);
+ collection = m_manager.collectionByName(QByteArray("Collection 2"));
+ QCOMPARE(collection.resources().count(), 1);
- resource = component.resourceByName("Resource 2");
+ resource = collection.resourceByName(QByteArray("Resource 2"));
QCOMPARE(resource.isNull(), false);
QCOMPARE(resource->isOpen(), false);
QCOMPARE(resource->open(), true);
@@ -346,46 +333,45 @@ private slots:
void testWriteBinaryContentFunction()
{
- QSharedPointer<QFile> existingBinary(new QFile(m_binary));
- QInstaller::openForRead(existingBinary.data());
-
- QSharedPointer<QFile> file(new QTemporaryFile);
- QInstaller::openForWrite(file.data());
- QInstaller::blockingWrite(file.data(), QByteArray(scTinySize, '1'));
-
- ResourceCollection resources;
- foreach (const Range<qint64> &segment, m_layout.metaResourceSegments) {
- resources.appendResource(QSharedPointer<Resource> (new Resource(existingBinary,
- segment)));
- }
+ ResourceCollection collection(QByteArray("QResources"));
+ foreach (const Range<qint64> &segment, m_layout.metaResourceSegments)
+ collection.appendResource(QSharedPointer<Resource>(new Resource(m_binary, segment)));
+ m_manager.insertCollection(collection);
QList<OperationBlob> operations;
foreach (const OperationBlob &operation, m_operations)
operations.append(operation);
- BinaryContent::writeBinaryContent(file, resources, operations, m_manager,
- m_layout.magicMarker, m_layout.magicCookie);
- file->close();
- existingBinary->close();
+ QTemporaryFile file;
+ QInstaller::openForWrite(&file);
+
+ QInstaller::blockingWrite(&file, QByteArray(scTinySize, '1'));
+ BinaryContent::writeBinaryContent(&file, operations, m_manager, m_layout.magicMarker,
+ m_layout.magicCookie);
+ file.close();
+
+ QFile existingBinary(m_binary);
+ QInstaller::openForRead(&existingBinary);
- QInstaller::openForRead(file.data());
- QInstaller::openForRead(existingBinary.data());
- QCOMPARE(file->readAll(), existingBinary->readAll());
+ QInstaller::openForRead(&file);
+ QCOMPARE(file.readAll(), existingBinary.readAll());
}
void testReadBinaryContentFunction()
{
- QSharedPointer<QFile> file(new QFile(m_binary));
- QInstaller::openForRead(file.data());
+ QFile file(m_binary);
+ QInstaller::openForRead(&file);
qint64 magicMarker;
- ResourceCollection collection;
QList<OperationBlob> operations;
ResourceCollectionManager manager;
- BinaryContent::readBinaryContent(file, &collection, &operations, &manager, &magicMarker,
+ BinaryContent::readBinaryContent(&file, &operations, &manager, &magicMarker,
m_layout.magicCookie);
+ file.close();
QCOMPARE(magicMarker, m_layout.magicMarker);
+
+ ResourceCollection collection = manager.collectionByName("QResources");
QCOMPARE(collection.resources().count(), m_layout.metaResourceSegments.count());
for (int i = 0; i < collection.resources().count(); ++i)
QCOMPARE(collection.resources().at(i)->segment(), m_layout.metaResourceSegments.at(i));
@@ -398,20 +384,20 @@ private slots:
QCOMPARE(manager.collectionCount(), m_manager.collectionCount());
- ResourceCollection component = manager.collectionByName("Collection 1");
- QCOMPARE(component.resources().count(), 1);
+ collection = manager.collectionByName(QByteArray("Collection 1"));
+ QCOMPARE(collection.resources().count(), 1);
- QSharedPointer<Resource> resource(component.resourceByName("Resource 1"));
+ QSharedPointer<Resource> resource(collection.resourceByName(QByteArray("Resource 1")));
QCOMPARE(resource.isNull(), false);
QCOMPARE(resource->isOpen(), false);
QCOMPARE(resource->open(), true);
QCOMPARE(resource->readAll(), QByteArray("Collection 1, Resource 1."));
resource->close();
- component = manager.collectionByName("Collection 2");
- QCOMPARE(component.resources().count(), 1);
+ collection = manager.collectionByName(QByteArray("Collection 2"));
+ QCOMPARE(collection.resources().count(), 1);
- resource = component.resourceByName("Resource 2");
+ resource = collection.resourceByName(QByteArray("Resource 2"));
QCOMPARE(resource.isNull(), false);
QCOMPARE(resource->isOpen(), false);
QCOMPARE(resource->open(), true);
@@ -421,7 +407,7 @@ private slots:
void cleanupTestCase()
{
- m_manager.reset();
+ m_manager.clear();
QFile::remove(m_binary);
}
diff --git a/tools/binarycreator/binarycreator.cpp b/tools/binarycreator/binarycreator.cpp
index 1a14c4bf0..6b40f44d3 100644
--- a/tools/binarycreator/binarycreator.cpp
+++ b/tools/binarycreator/binarycreator.cpp
@@ -52,10 +52,12 @@
#include <settings.h>
#include <utils.h>
-#include <QtCore/QDirIterator>
-#include <QtCore/QProcess>
-#include <QtCore/QSettings>
-#include <QtCore/QTemporaryFile>
+#include <QDateTime>
+#include <QDirIterator>
+#include <QDomDocument>
+#include <QProcess>
+#include <QSettings>
+#include <QTemporaryFile>
#include <QTemporaryDir>
#include <iostream>
@@ -66,7 +68,7 @@ struct Input {
QString outputPath;
QString installerExePath;
QInstallerTools::PackageInfoVector packages;
- QInstaller::ResourceCollection metaCollection;
+ QInstaller::ResourceCollectionManager manager;
};
class BundleBackup
@@ -250,7 +252,7 @@ static int assemble(Input input, const QInstaller::Settings &settings)
}
#endif
- QSharedPointer<QTemporaryFile> out(new QTemporaryFile);
+ QTemporaryFile out;
QString targetName = input.outputPath;
#ifdef Q_OS_OSX
QDir resourcePath(QFileInfo(input.outputPath).dir());
@@ -270,7 +272,7 @@ static int assemble(Input input, const QInstaller::Settings &settings)
}
try {
- QInstaller::openForWrite(out.data());
+ QInstaller::openForWrite(&out);
QFile exe(input.installerExePath);
#ifdef Q_OS_OSX
@@ -280,10 +282,9 @@ static int assemble(Input input, const QInstaller::Settings &settings)
}
#else
QInstaller::openForRead(&exe);
- QInstaller::appendData(out.data(), &exe, exe.size());
+ QInstaller::appendData(&out, &exe, exe.size());
#endif
- QInstaller::ResourceCollectionManager manager;
foreach (const QInstallerTools::PackageInfo &info, input.packages) {
QInstaller::ResourceCollection collection;
collection.setName(info.name.toUtf8());
@@ -295,11 +296,11 @@ static int assemble(Input input, const QInstaller::Settings &settings)
humanReadableSize(resource->size()));
collection.appendResource(resource);
}
- manager.insertCollection(collection);
+ input.manager.insertCollection(collection);
}
const QList<QInstaller::OperationBlob> operations;
- BinaryContent::writeBinaryContent(out, input.metaCollection, operations, manager,
+ BinaryContent::writeBinaryContent(&out, operations, input.manager,
BinaryContent::MagicInstallerMarker, BinaryContent::MagicCookie);
} catch (const Error &e) {
qCritical("Error occurred while assembling the installer: %s", qPrintable(e.message()));
@@ -307,16 +308,16 @@ static int assemble(Input input, const QInstaller::Settings &settings)
return EXIT_FAILURE;
}
- if (!out->rename(targetName)) {
+ if (!out.rename(targetName)) {
qCritical("Could not write installer to %s: %s", targetName.toUtf8().constData(),
- out->errorString().toUtf8().constData());
+ out.errorString().toUtf8().constData());
QFile::remove(tempFile);
return EXIT_FAILURE;
}
- out->setAutoRemove(false);
+ out.setAutoRemove(false);
#ifndef Q_OS_WIN
- chmod755(out->fileName());
+ chmod755(out.fileName());
#endif
QFile::remove(tempFile);
@@ -402,8 +403,8 @@ static QSharedPointer<QInstaller::Resource> createDefaultResourceFile(const QStr
throw Error(QString::fromLatin1("Could not compile rcc project file."));
}
- return QSharedPointer<QInstaller::Resource>(new QInstaller::Resource(binaryName.toUtf8(),
- binaryName));
+ return QSharedPointer<QInstaller::Resource>(new QInstaller::Resource(binaryName, binaryName
+ .toUtf8()));
}
static
@@ -420,8 +421,8 @@ QList<QSharedPointer<QInstaller::Resource> > createBinaryResourceFiles(const QSt
if (status != EXIT_SUCCESS)
continue;
- result.append(QSharedPointer<QInstaller::Resource> (new QInstaller::Resource(binaryName
- .toUtf8(), binaryName)));
+ result.append(QSharedPointer<QInstaller::Resource> (new QInstaller::Resource(binaryName,
+ binaryName.toUtf8())));
}
}
return result;
@@ -731,9 +732,12 @@ int main(int argc, char **argv)
input.packages = packages;
input.outputPath = target;
input.installerExePath = templateBinary;
- input.metaCollection.appendResource(createDefaultResourceFile(tmpMetaDir,
+
+ QInstaller::ResourceCollection metaCollection("QResources");
+ metaCollection.appendResource(createDefaultResourceFile(tmpMetaDir,
generateTemporaryFileName()));
- input.metaCollection.appendResources(createBinaryResourceFiles(resources));
+ metaCollection.appendResources(createBinaryResourceFiles(resources));
+ input.manager.insertCollection(metaCollection);
qDebug() << "Creating the binary";
exitCode = assemble(input, settings);
@@ -750,7 +754,8 @@ int main(int argc, char **argv)
}
qDebug() << "Cleaning up...";
- foreach (const QSharedPointer<QInstaller::Resource> &resource, input.metaCollection.resources())
+ const QInstaller::ResourceCollection collection = input.manager.collectionByName("QResources");
+ foreach (const QSharedPointer<QInstaller::Resource> &resource, collection.resources())
QFile::remove(QString::fromUtf8(resource->name()));
QInstaller::removeDirectory(tmpMetaDir, true);
diff --git a/tools/devtool/binarydump.cpp b/tools/devtool/binarydump.cpp
index 8c73d7642..7efa13960 100644
--- a/tools/devtool/binarydump.cpp
+++ b/tools/devtool/binarydump.cpp
@@ -126,13 +126,17 @@ int BinaryDump::dump(const QInstaller::ResourceCollectionManager &manager, const
continue;
foreach (const QSharedPointer<QInstaller::Resource> &resource, c.resources()) {
- if (!resource->open())
+ const bool isOpen = resource->isOpen();
+ if ((!isOpen) && (!resource->open()))
continue; // TODO: should we throw here?
QFile target(targetDir.filePath(fileName) + QDir::separator()
+ QString::fromUtf8(resource->name()));
QInstaller::openForWrite(&target);
resource->copyData(&target); // copy the 7z files into the target directory
+
+ if (!isOpen) // If we reach that point, either the resource was opened already...
+ resource->close(); // or we did open it and have to close it again.
}
}
result = EXIT_SUCCESS;
diff --git a/tools/devtool/main.cpp b/tools/devtool/main.cpp
index 9ef611ce2..61be6c9f7 100644
--- a/tools/devtool/main.cpp
+++ b/tools/devtool/main.cpp
@@ -136,24 +136,27 @@ int main(int argc, char *argv[])
}
}
- QSharedPointer<QFile> file(new QFile(path));
- QInstaller::openForRead(file.data());
+ QFile file(path);
+ QInstaller::openForRead(&file);
qint64 magicMarker;
- QInstaller::ResourceCollection meta;
QList<QInstaller::OperationBlob> operations;
QInstaller::ResourceCollectionManager manager;
- QInstaller::BinaryContent::readBinaryContent(file, &meta, &operations, &manager,
- &magicMarker, cookie);
+ QInstaller::BinaryContent::readBinaryContent(&file, &operations, &manager, &magicMarker,
+ cookie);
// map the inbuilt resources
+ const QInstaller::ResourceCollection meta = manager.collectionByName("QResources");
foreach (const QSharedPointer<QInstaller::Resource> &resource, meta.resources()) {
- const bool opened = resource->open();
+ const bool isOpen = resource->isOpen();
+ if ((!isOpen) && (!resource->open()))
+ continue; // TODO: should we throw here?
+
const QByteArray ba = resource->readAll();
if (!QResource::registerResource((const uchar*) ba.data(), QLatin1String(":/metadata")))
throw QInstaller::Error(QLatin1String("Could not register in-binary resource."));
resourceMappings.append(ba);
- if (opened)
+ if (!isOpen)
resource->close();
}