summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorkh1 <karsten.heimrich@digia.com>2014-07-30 17:30:29 +0200
committerKarsten Heimrich <karsten.heimrich@digia.com>2014-08-27 13:21:56 +0200
commit554a7f108ef17d8a042f2960e0a483508ca15cd3 (patch)
treea3547db4e2e3c3375ff7e911c82b82a4f8e5149a /src
parent2dfa49ac79d421c87bbc1404be56d5ae37a6a2c4 (diff)
Introduce two new functions to read and write binary content.
In addition update the auto test to test both new functions. Change-Id: I85f1e28cf486fc381941e553dac6defa9d327117 Reviewed-by: Niels Weber <niels.weber@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/libs/installer/binarycontent.cpp150
-rw-r--r--src/libs/installer/binarycontent.h15
-rw-r--r--src/libs/installer/binaryformat.h8
3 files changed, 172 insertions, 1 deletions
diff --git a/src/libs/installer/binarycontent.cpp b/src/libs/installer/binarycontent.cpp
index a60e9ebb5..33856adfa 100644
--- a/src/libs/installer/binarycontent.cpp
+++ b/src/libs/installer/binarycontent.cpp
@@ -526,4 +526,154 @@ void BinaryContent::registerAsDefaultQResource(const QString &path)
}
}
+void BinaryContent::readBinaryContent(const QSharedPointer<QFile> &in,
+ ResourceCollection *metaResources, QList<OperationBlob> *operations,
+ ResourceCollectionManager *manager, qint64 *magicMarker, quint64 magicCookie)
+{
+ const qint64 pos = BinaryContent::findMagicCookie(in.data(), magicCookie);
+ const qint64 endOfBinaryContent = pos + sizeof(qint64);
+
+ const qint64 posOfMetaDataCount = endOfBinaryContent - (4 * sizeof(qint64));
+ if (!in->seek(posOfMetaDataCount)) {
+ throw Error(QCoreApplication::translate("BinaryContent",
+ "Could not seek to %1 to read the embedded meta data count.").arg(posOfMetaDataCount));
+ }
+ // read the meta resources count
+ const qint64 metaResourcesCount = QInstaller::retrieveInt64(in.data());
+
+ const qint64 posOfResourceCollectionsSegment = endOfBinaryContent
+ - ((metaResourcesCount * (2 * sizeof(qint64))) // minus the size of the meta data segments
+ + (8 * sizeof(qint64))); // meta count, offset/length component index, marker, cookie...
+ if (!in->seek(posOfResourceCollectionsSegment)) {
+ throw Error(QCoreApplication::translate("BinaryContent",
+ "Could not seek to %1 to read the resource collection segment.")
+ .arg(posOfResourceCollectionsSegment));
+ }
+ // read the resource collection index offset and length
+ const Range<qint64> resourceCollectionsSegment = QInstaller::retrieveInt64Range(in.data());
+
+ // read the meta data resource segments
+ QVector<Range<qint64> > metaDataResourceSegments;
+ for (int i = 0; i < metaResourcesCount; ++i)
+ metaDataResourceSegments.append(QInstaller::retrieveInt64Range(in.data()));
+
+ // read the operations offset and length
+ const Range<qint64> operationsSegment = QInstaller::retrieveInt64Range(in.data());
+
+ // resources count
+ Q_UNUSED(QInstaller::retrieveInt64(in.data())) // read it, but deliberately not used
+
+ // read the binary content size
+ const qint64 binaryContentSize = QInstaller::retrieveInt64(in.data());
+ const qint64 endOfBinary = endOfBinaryContent - binaryContentSize; // end of "compiled" binary
+
+ // read the marker
+ const qint64 marker = QInstaller::retrieveInt64(in.data());
+ if (magicMarker)
+ *magicMarker = marker;
+
+ // the cookie
+ Q_UNUSED(QInstaller::retrieveInt64(in.data())) // read it, but deliberately not used
+
+ // append the calculated resource segments
+ if (metaResources) {
+ foreach (const Range<qint64> &segment, metaDataResourceSegments) {
+ metaResources->appendResource(QSharedPointer<Resource>(new Resource(in,
+ segment.moved(endOfBinary))));
+ }
+ }
+
+ const qint64 posOfOperationsBlock = endOfBinary + operationsSegment.start();
+ if (!in->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());
+ // read the operations
+ for (int i = 0; i < operationsCount; ++i) {
+ const QString name = QInstaller::retrieveString(in.data());
+ const QString xml = QInstaller::retrieveString(in.data());
+ if (operations)
+ operations->append(OperationBlob(name, xml));
+ }
+ // operations count
+ Q_UNUSED(QInstaller::retrieveInt64(in.data())) // read it, but deliberately not used
+
+ // read the resource collections count
+ const qint64 collectionCount = QInstaller::retrieveInt64(in.data());
+
+ const qint64 posOfResourceCollectionBlock = endOfBinary + resourceCollectionsSegment.start();
+ if (!in->seek(posOfResourceCollectionBlock)) {
+ throw Error(QCoreApplication::translate("BinaryContent",
+ "Could not seek to %1 to read the resource collection block.")
+ .arg(posOfResourceCollectionBlock));
+ }
+ if (manager) { // read the component index and data
+ manager->read(in, endOfBinary);
+ if (manager->collectionCount() != collectionCount) {
+ throw Error(QCoreApplication::translate("BinaryContent",
+ "Unexpected mismatch of resource collections. Read %1, expected: %2.")
+ .arg(manager->collectionCount()).arg(collectionCount));
+ }
+ }
+}
+
+void BinaryContent::writeBinaryContent(const QSharedPointer<QFile> &out,
+ const ResourceCollection &metaResources, const QList<OperationBlob> &operations,
+ const ResourceCollectionManager &manager, qint64 magicMarker, quint64 magicCookie)
+{
+ const qint64 endOfBinary = out->pos();
+
+ // resources
+ qint64 pos = out->pos();
+ QVector<Range<qint64> > metaResourceSegments;
+ foreach (const QSharedPointer<Resource> &resource, metaResources.resources()) {
+ const bool isOpen = resource->isOpen();
+ if ((!isOpen) && (!resource->open())) {
+ throw Error(QCoreApplication::translate("BinaryContent",
+ "Could not open meta resource. Error: %1").arg(resource->errorString()));
+ }
+
+ resource->seek(0);
+ resource->copyData(out.data());
+ metaResourceSegments.append(Range<qint64>::fromStartAndEnd(pos, out->pos())
+ .moved(-endOfBinary));
+ 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.
+ }
+
+ // operations
+ QInstaller::appendInt64(out.data(), operations.count());
+ foreach (const OperationBlob &operation, operations) {
+ QInstaller::appendString(out.data(), operation.name);
+ QInstaller::appendString(out.data(), operation.xml);
+ }
+ QInstaller::appendInt64(out.data(), operations.count());
+ const Range<qint64> operationsSegment = Range<qint64>::fromStartAndEnd(pos, out->pos())
+ .moved(-endOfBinary);
+
+ // resource collections data and index
+ const Range<qint64> resourceCollectionsSegment = manager.write(out.data(), -endOfBinary)
+ .moved(-endOfBinary);
+ QInstaller::appendInt64Range(out.data(), resourceCollectionsSegment);
+
+ // meta resource segments
+ foreach (const Range<qint64> &segment, metaResourceSegments)
+ QInstaller::appendInt64Range(out.data(), segment);
+
+ // operations segment
+ QInstaller::appendInt64Range(out.data(), operationsSegment);
+
+ // resources count
+ QInstaller::appendInt64(out.data(), 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);
+}
+
} // namespace QInstaller
diff --git a/src/libs/installer/binarycontent.h b/src/libs/installer/binarycontent.h
index 9cd48e4ce..f553b8b9a 100644
--- a/src/libs/installer/binarycontent.h
+++ b/src/libs/installer/binarycontent.h
@@ -42,8 +42,8 @@
#ifndef BINARYCONTENT_H
#define BINARYCONTENT_H
+#include "binaryformat.h"
#include "range.h"
-#include "qinstallerglobal.h"
#include <QVector>
@@ -97,6 +97,19 @@ public:
int registerEmbeddedQResources();
void registerAsDefaultQResource(const QString &path);
+ static void readBinaryContent(const QSharedPointer<QFile> &in,
+ ResourceCollection *metaResources,
+ QList<OperationBlob> *operations,
+ ResourceCollectionManager *manager,
+ qint64 *magicMarker,
+ quint64 magicCookie);
+
+ static void writeBinaryContent(const QSharedPointer<QFile> &out,
+ const ResourceCollection &metaResources,
+ const QList<OperationBlob> &operations,
+ const ResourceCollectionManager &manager,
+ qint64 magicMarker,
+ quint64 magicCookie);
private:
explicit BinaryContent(const QString &path);
static void readBinaryData(BinaryContent &content, const QSharedPointer<QFile> &file,
diff --git a/src/libs/installer/binaryformat.h b/src/libs/installer/binaryformat.h
index 1097b561f..162966b55 100644
--- a/src/libs/installer/binaryformat.h
+++ b/src/libs/installer/binaryformat.h
@@ -50,6 +50,14 @@
namespace QInstaller {
+struct OperationBlob {
+ OperationBlob(const QString &n, const QString &x)
+ : name(n), xml(x) {}
+ QString name;
+ QString xml;
+};
+
+
class INSTALLER_EXPORT Resource : public QIODevice
{
Q_OBJECT