diff options
Diffstat (limited to 'tools/binarycreator/rcc/rcc.cpp')
-rw-r--r-- | tools/binarycreator/rcc/rcc.cpp | 1038 |
1 files changed, 0 insertions, 1038 deletions
diff --git a/tools/binarycreator/rcc/rcc.cpp b/tools/binarycreator/rcc/rcc.cpp deleted file mode 100644 index 10b7cbc4f..000000000 --- a/tools/binarycreator/rcc/rcc.cpp +++ /dev/null @@ -1,1038 +0,0 @@ -/************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Installer Framework. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -**************************************************************************/ - -#include "rcc.h" - -#include <QtCore/QByteArray> -#include <QtCore/QDateTime> -#include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtCore/QDirIterator> -#include <QtCore/QFile> -#include <QtCore/QIODevice> -#include <QtCore/QLocale> -#include <QtCore/QRegExp> -#include <QtCore/QStack> - -#include <QXmlStreamReader> - -QT_BEGIN_NAMESPACE - -enum { - CONSTANT_USENAMESPACE = 1, - CONSTANT_COMPRESSLEVEL_DEFAULT = -1, - CONSTANT_COMPRESSTHRESHOLD_DEFAULT = 70 -}; - - -#define writeString(s) write(s, sizeof(s)) - -void RCCResourceLibrary::write(const char *str, int len) -{ - --len; // trailing \0 on string literals... - int n = m_out.size(); - m_out.resize(n + len); - memcpy(m_out.data() + n, str, len); -} - -void RCCResourceLibrary::writeByteArray(const QByteArray &other) -{ - m_out.append(other); -} - -static inline QString msgOpenReadFailed(const QString &fname, const QString &why) -{ - return QString::fromUtf8("Unable to open %1 for reading: %2\n").arg(fname).arg(why); -} - - -/////////////////////////////////////////////////////////// -// -// RCCFileInfo -// -/////////////////////////////////////////////////////////// - -class RCCFileInfo -{ -public: - enum Flags - { - NoFlags = 0x00, - Compressed = 0x01, - Directory = 0x02 - }; - - RCCFileInfo(const QString &name = QString(), const QFileInfo &fileInfo = QFileInfo(), - QLocale::Language language = QLocale::C, - QLocale::Country country = QLocale::AnyCountry, - uint flags = NoFlags, - int compressLevel = CONSTANT_COMPRESSLEVEL_DEFAULT, - int compressThreshold = CONSTANT_COMPRESSTHRESHOLD_DEFAULT); - ~RCCFileInfo(); - - QString resourceName() const; - -public: - qint64 writeDataBlob(RCCResourceLibrary &lib, qint64 offset, QString *errorMessage); - qint64 writeDataName(RCCResourceLibrary &, qint64 offset); - void writeDataInfo(RCCResourceLibrary &lib); - - int m_flags; - QString m_name; - QLocale::Language m_language; - QLocale::Country m_country; - QFileInfo m_fileInfo; - RCCFileInfo *m_parent; - QHash<QString, RCCFileInfo*> m_children; - int m_compressLevel; - int m_compressThreshold; - - qint64 m_nameOffset; - qint64 m_dataOffset; - qint64 m_childOffset; -}; - -RCCFileInfo::RCCFileInfo(const QString &name, const QFileInfo &fileInfo, - QLocale::Language language, QLocale::Country country, uint flags, - int compressLevel, int compressThreshold) -{ - m_name = name; - m_fileInfo = fileInfo; - m_language = language; - m_country = country; - m_flags = flags; - m_parent = nullptr; - m_nameOffset = 0; - m_dataOffset = 0; - m_childOffset = 0; - m_compressLevel = compressLevel; - m_compressThreshold = compressThreshold; -} - -RCCFileInfo::~RCCFileInfo() -{ - qDeleteAll(m_children); -} - -QString RCCFileInfo::resourceName() const -{ - QString resource = m_name; - for (RCCFileInfo *p = m_parent; p; p = p->m_parent) - resource = resource.prepend(p->m_name + QLatin1Char('/')); - return QLatin1Char(':') + resource; -} - -void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib) -{ - const bool text = (lib.m_format == RCCResourceLibrary::C_Code); - //some info - if (text) { - if (m_language != QLocale::C) { - lib.writeString(" // "); - lib.writeByteArray(resourceName().toLocal8Bit()); - lib.writeString(" ["); - lib.writeByteArray(QByteArray::number(m_country)); - lib.writeString("::"); - lib.writeByteArray(QByteArray::number(m_language)); - lib.writeString("[\n "); - } else { - lib.writeString(" // "); - lib.writeByteArray(resourceName().toLocal8Bit()); - lib.writeString("\n "); - } - } - - //pointer data - if (m_flags & RCCFileInfo::Directory) { - // name offset - lib.writeNumber4(m_nameOffset); - - // flags - lib.writeNumber2(m_flags); - - // child count - lib.writeNumber4(m_children.size()); - - // first child offset - lib.writeNumber4(m_childOffset); - } else { - // name offset - lib.writeNumber4(m_nameOffset); - - // flags - lib.writeNumber2(m_flags); - - // locale - lib.writeNumber2(m_country); - lib.writeNumber2(m_language); - - //data offset - lib.writeNumber4(m_dataOffset); - } - if (text) - lib.writeChar('\n'); -} - -qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset, - QString *errorMessage) -{ - const bool text = (lib.m_format == RCCResourceLibrary::C_Code); - - //capture the offset - m_dataOffset = offset; - - //find the data to be written - QFile file(m_fileInfo.absoluteFilePath()); - if (!file.open(QFile::ReadOnly)) { - *errorMessage = msgOpenReadFailed(m_fileInfo.absoluteFilePath(), file.errorString()); - return 0; - } - QByteArray data = file.readAll(); - -#ifndef QT_NO_COMPRESS - // Check if compression is useful for this file - if (m_compressLevel != 0 && data.size() != 0) { - QByteArray compressed = - qCompress(reinterpret_cast<uchar *>(data.data()), data.size(), m_compressLevel); - - int compressRatio = int(100.0 * (data.size() - compressed.size()) / data.size()); - if (compressRatio >= m_compressThreshold) { - data = compressed; - m_flags |= Compressed; - } - } -#endif // QT_NO_COMPRESS - - // some info - if (text) { - lib.writeString(" // "); - lib.writeByteArray(m_fileInfo.absoluteFilePath().toLocal8Bit()); - lib.writeString("\n "); - } - - // write the length - - lib.writeNumber4(data.size()); - if (text) - lib.writeString("\n "); - offset += 4; - - // write the payload - const char *p = data.constData(); - if (text) { - for (int i = data.size(), j = 0; --i >= 0; --j) { - lib.writeHex(*p++); - if (j == 0) { - lib.writeString("\n "); - j = 16; - } - } - } else { - for (int i = data.size(); --i >= 0; ) - lib.writeChar(*p++); - } - offset += data.size(); - - // done - if (text) - lib.writeString("\n "); - return offset; -} - -qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset) -{ - const bool text = (lib.m_format == RCCResourceLibrary::C_Code); - - // capture the offset - m_nameOffset = offset; - - // some info - if (text) { - lib.writeString(" // "); - lib.writeByteArray(m_name.toLocal8Bit()); - lib.writeString("\n "); - } - - // write the length - lib.writeNumber2(m_name.length()); - if (text) - lib.writeString("\n "); - offset += 2; - - // write the hash - lib.writeNumber4(qt_hash(m_name)); - if (text) - lib.writeString("\n "); - offset += 4; - - // write the m_name - const QChar *unicode = m_name.unicode(); - for (int i = 0; i < m_name.length(); ++i) { - lib.writeNumber2(unicode[i].unicode()); - if (text && i % 16 == 0) - lib.writeString("\n "); - } - offset += m_name.length()*2; - - // done - if (text) - lib.writeString("\n "); - return offset; -} - - -/////////////////////////////////////////////////////////// -// -// RCCResourceLibrary -// -/////////////////////////////////////////////////////////// - -RCCResourceLibrary::Strings::Strings() : - TAG_RCC(QLatin1String("RCC")), - TAG_RESOURCE(QLatin1String("qresource")), - TAG_FILE(QLatin1String("file")), - ATTRIBUTE_LANG(QLatin1String("lang")), - ATTRIBUTE_PREFIX(QLatin1String("prefix")), - ATTRIBUTE_ALIAS(QLatin1String("alias")), - ATTRIBUTE_THRESHOLD(QLatin1String("threshold")), - ATTRIBUTE_COMPRESS(QLatin1String("compress")) -{ -} - -RCCResourceLibrary::RCCResourceLibrary() - : m_root(nullptr), - m_format(C_Code), - m_verbose(false), - m_compressLevel(CONSTANT_COMPRESSLEVEL_DEFAULT), - m_compressThreshold(CONSTANT_COMPRESSTHRESHOLD_DEFAULT), - m_treeOffset(0), - m_namesOffset(0), - m_dataOffset(0), - m_useNameSpace(CONSTANT_USENAMESPACE), - m_errorDevice(nullptr) -{ - m_out.reserve(30 * 1000 * 1000); -} - -RCCResourceLibrary::~RCCResourceLibrary() -{ - delete m_root; -} - -enum RCCXmlTag { - RccTag, - ResourceTag, - FileTag -}; - -bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, - const QString &fname, QString currentPath, bool ignoreErrors) -{ - Q_ASSERT(m_errorDevice); - const QChar slash = QLatin1Char('/'); - if (!currentPath.isEmpty() && !currentPath.endsWith(slash)) - currentPath += slash; - - QXmlStreamReader reader(inputDevice); - QStack<RCCXmlTag> tokens; - - QString prefix; - QLocale::Language language = QLocale::c().language(); - QLocale::Country country = QLocale::c().country(); - QString alias; - int compressLevel = m_compressLevel; - int compressThreshold = m_compressThreshold; - - while (!reader.atEnd()) { - QXmlStreamReader::TokenType t = reader.readNext(); - switch (t) { - case QXmlStreamReader::StartElement: - if (reader.name() == m_strings.TAG_RCC) { - if (!tokens.isEmpty()) - reader.raiseError(QLatin1String("expected <RCC> tag")); - else - tokens.push(RccTag); - } else if (reader.name() == m_strings.TAG_RESOURCE) { - if (tokens.isEmpty() || tokens.top() != RccTag) { - reader.raiseError(QLatin1String("unexpected <RESOURCE> tag")); - } else { - tokens.push(ResourceTag); - - QXmlStreamAttributes attributes = reader.attributes(); - language = QLocale::c().language(); - country = QLocale::c().country(); - - if (attributes.hasAttribute(m_strings.ATTRIBUTE_LANG)) { - QString attribute = attributes.value(m_strings.ATTRIBUTE_LANG).toString(); - QLocale lang = QLocale(attribute); - language = lang.language(); - if (2 == attribute.length()) { - // Language only - country = QLocale::AnyCountry; - } else { - country = lang.country(); - } - } - - prefix.clear(); - if (attributes.hasAttribute(m_strings.ATTRIBUTE_PREFIX)) - prefix = attributes.value(m_strings.ATTRIBUTE_PREFIX).toString(); - if (!prefix.startsWith(slash)) - prefix.prepend(slash); - if (!prefix.endsWith(slash)) - prefix += slash; - } - } else if (reader.name() == m_strings.TAG_FILE) { - if (tokens.isEmpty() || tokens.top() != ResourceTag) { - reader.raiseError(QLatin1String("unexpected <FILE> tag")); - } else { - tokens.push(FileTag); - - QXmlStreamAttributes attributes = reader.attributes(); - alias.clear(); - if (attributes.hasAttribute(m_strings.ATTRIBUTE_ALIAS)) - alias = attributes.value(m_strings.ATTRIBUTE_ALIAS).toString(); - - compressLevel = m_compressLevel; - if (attributes.hasAttribute(m_strings.ATTRIBUTE_COMPRESS)) - compressLevel = attributes.value(m_strings.ATTRIBUTE_COMPRESS).toString().toInt(); - - compressThreshold = m_compressThreshold; - if (attributes.hasAttribute(m_strings.ATTRIBUTE_THRESHOLD)) - compressThreshold = attributes.value(m_strings.ATTRIBUTE_THRESHOLD).toString().toInt(); - - // Special case for -no-compress. Overrides all other settings. - if (m_compressLevel == -2) - compressLevel = 0; - } - } else { - reader.raiseError(QString(QLatin1String("unexpected tag: %1")).arg(reader.name().toString())); - } - break; - - case QXmlStreamReader::EndElement: - if (reader.name() == m_strings.TAG_RCC) { - if (!tokens.isEmpty() && tokens.top() == RccTag) - tokens.pop(); - else - reader.raiseError(QLatin1String("unexpected closing tag")); - } else if (reader.name() == m_strings.TAG_RESOURCE) { - if (!tokens.isEmpty() && tokens.top() == ResourceTag) - tokens.pop(); - else - reader.raiseError(QLatin1String("unexpected closing tag")); - } else if (reader.name() == m_strings.TAG_FILE) { - if (!tokens.isEmpty() && tokens.top() == FileTag) - tokens.pop(); - else - reader.raiseError(QLatin1String("unexpected closing tag")); - } - break; - - case QXmlStreamReader::Characters: - if (reader.isWhitespace()) - break; - if (tokens.isEmpty() || tokens.top() != FileTag) { - reader.raiseError(QLatin1String("unexpected text")); - } else { - QString fileName = reader.text().toString(); - if (fileName.isEmpty()) { - const QString msg = QString::fromLatin1("RCC: Warning: Null node in XML of '%1'\n").arg(fname); - m_errorDevice->write(msg.toUtf8()); - } - - if (alias.isNull()) - alias = fileName; - - alias = QDir::cleanPath(alias); - while (alias.startsWith(QLatin1String("../"))) - alias.remove(0, 3); - alias = QDir::cleanPath(m_resourceRoot) + prefix + alias; - - QString absFileName = fileName; - if (QDir::isRelativePath(absFileName)) - absFileName.prepend(currentPath); - QFileInfo file(absFileName); - if (!file.exists()) { - m_failedResources.push_back(absFileName); - const QString msg = QString::fromLatin1("RCC: Error in '%1': Cannot find file '%2'\n").arg(fname).arg(fileName); - m_errorDevice->write(msg.toUtf8()); - if (ignoreErrors) - continue; - else - return false; - } else if (file.isFile()) { - const bool arc = - addFile(alias, - RCCFileInfo(alias.section(slash, -1), - file, - language, - country, - RCCFileInfo::NoFlags, - compressLevel, - compressThreshold) - ); - if (!arc) - m_failedResources.push_back(absFileName); - } else { - QDir dir; - if (file.isDir()) { - dir.setPath(file.filePath()); - } else { - dir.setPath(file.path()); - dir.setNameFilters(QStringList(file.fileName())); - if (alias.endsWith(file.fileName())) - alias = alias.left(alias.length()-file.fileName().length()); - } - if (!alias.endsWith(slash)) - alias += slash; - QDirIterator it(dir, QDirIterator::FollowSymlinks|QDirIterator::Subdirectories); - while (it.hasNext()) { - it.next(); - QFileInfo child(it.fileInfo()); - if (child.fileName() != QLatin1String(".") && child.fileName() != QLatin1String("..")) { - const bool arc = - addFile(alias + child.fileName(), - RCCFileInfo(child.fileName(), - child, - language, - country, - child.isDir() ? RCCFileInfo::Directory : RCCFileInfo::NoFlags, - compressLevel, - compressThreshold) - ); - if (!arc) - m_failedResources.push_back(child.fileName()); - } - } - } - } - break; - - default: - break; - } - } - - if (reader.hasError()) { - if (ignoreErrors) - return true; - int errorLine = reader.lineNumber(); - int errorColumn = reader.columnNumber(); - QString errorMessage = reader.errorString(); - QString msg = QString::fromLatin1("RCC Parse Error: '%1' Line: %2 Column: %3 [%4]\n").arg(fname).arg(errorLine).arg(errorColumn).arg(errorMessage); - m_errorDevice->write(msg.toUtf8()); - return false; - } - - if (m_root == nullptr) { - const QString msg = QString::fromUtf8("RCC: Warning: No resources in '%1'.\n").arg(fname); - m_errorDevice->write(msg.toUtf8()); - if (!ignoreErrors && m_format == Binary) { - // create dummy entry, otherwise loading with QResource will crash - m_root = new RCCFileInfo(QString(), QFileInfo(), - QLocale::C, QLocale::AnyCountry, RCCFileInfo::Directory); - } - } - - return true; -} - -bool RCCResourceLibrary::addFile(const QString &alias, const RCCFileInfo &file) -{ - Q_ASSERT(m_errorDevice); - if (file.m_fileInfo.size() > 0xffffffff) { - const QString msg = QString::fromUtf8("File too big: %1\n").arg(file.m_fileInfo.absoluteFilePath()); - m_errorDevice->write(msg.toUtf8()); - return false; - } - if (!m_root) - m_root = new RCCFileInfo(QString(), QFileInfo(), QLocale::C, QLocale::AnyCountry, RCCFileInfo::Directory); - - RCCFileInfo *parent = m_root; - const QStringList nodes = alias.split(QLatin1Char('/')); - for (int i = 1; i < nodes.size()-1; ++i) { - const QString node = nodes.at(i); - if (node.isEmpty()) - continue; - if (!parent->m_children.contains(node)) { - RCCFileInfo *s = new RCCFileInfo(node, QFileInfo(), QLocale::C, QLocale::AnyCountry, RCCFileInfo::Directory); - s->m_parent = parent; - parent->m_children.insert(node, s); - parent = s; - } else { - parent = parent->m_children[node]; - } - } - - const QString filename = nodes.at(nodes.size()-1); - RCCFileInfo *s = new RCCFileInfo(file); - s->m_parent = parent; - if (parent->m_children.contains(filename)) { - foreach (const QString &fileName, m_fileNames) - qWarning("%s: Warning: potential duplicate alias detected: '%s'", - qPrintable(fileName), qPrintable(filename)); - } - parent->m_children.insertMulti(filename, s); - return true; -} - -void RCCResourceLibrary::reset() -{ - if (m_root) { - delete m_root; - m_root = nullptr; - } - m_errorDevice = nullptr; - m_failedResources.clear(); -} - - -bool RCCResourceLibrary::readFiles(bool ignoreErrors, QIODevice &errorDevice) -{ - reset(); - m_errorDevice = &errorDevice; - //read in data - if (m_verbose) { - const QString msg = QString::fromUtf8("Processing %1 files [%2]\n") - .arg(m_fileNames.size()).arg(static_cast<int>(ignoreErrors)); - m_errorDevice->write(msg.toUtf8()); - } - for (int i = 0; i < m_fileNames.size(); ++i) { - QFile fileIn; - QString fname = m_fileNames.at(i); - QString pwd; - if (fname == QLatin1String("-")) { - fname = QLatin1String("(stdin)"); - pwd = QDir::currentPath(); - fileIn.setFileName(fname); - if (!fileIn.open(stdin, QIODevice::ReadOnly)) { - m_errorDevice->write(msgOpenReadFailed(fname, fileIn.errorString()).toUtf8()); - return false; - } - } else { - pwd = QFileInfo(fname).path(); - fileIn.setFileName(fname); - if (!fileIn.open(QIODevice::ReadOnly)) { - m_errorDevice->write(msgOpenReadFailed(fname, fileIn.errorString()).toUtf8()); - return false; - } - } - if (m_verbose) { - const QString msg = QString::fromUtf8("Interpreting %1\n").arg(fname); - m_errorDevice->write(msg.toUtf8()); - } - - if (!interpretResourceFile(&fileIn, fname, pwd, ignoreErrors)) - return false; - } - return true; -} - -QStringList RCCResourceLibrary::dataFiles() const -{ - QStringList ret; - QStack<RCCFileInfo*> pending; - - if (!m_root) - return ret; - pending.push(m_root); - while (!pending.isEmpty()) { - RCCFileInfo *file = pending.pop(); - for (QHash<QString, RCCFileInfo*>::iterator it = file->m_children.begin(); - it != file->m_children.end(); ++it) { - RCCFileInfo *child = it.value(); - if (child->m_flags & RCCFileInfo::Directory) - pending.push(child); - ret.append(child->m_fileInfo.filePath()); - } - } - return ret; -} - -// Determine map of resource identifier (':/newPrefix/images/p1.png') to file via recursion -static void resourceDataFileMapRecursion(const RCCFileInfo *m_root, const QString &path, RCCResourceLibrary::ResourceDataFileMap &m) -{ - typedef QHash<QString, RCCFileInfo*>::const_iterator ChildConstIterator; - const QChar slash = QLatin1Char('/'); - const ChildConstIterator cend = m_root->m_children.constEnd(); - for (ChildConstIterator it = m_root->m_children.constBegin(); it != cend; ++it) { - const RCCFileInfo *child = it.value(); - QString childName = path; - childName += slash; - childName += child->m_name; - if (child->m_flags & RCCFileInfo::Directory) { - resourceDataFileMapRecursion(child, childName, m); - } else { - m.insert(childName, child->m_fileInfo.filePath()); - } - } -} - -RCCResourceLibrary::ResourceDataFileMap RCCResourceLibrary::resourceDataFileMap() const -{ - ResourceDataFileMap rc; - if (m_root) - resourceDataFileMapRecursion(m_root, QString(QLatin1Char(':')), rc); - return rc; -} - -bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &errorDevice) -{ - m_errorDevice = &errorDevice; - //write out - if (m_verbose) - m_errorDevice->write("Outputting code\n"); - if (!writeHeader()) { - m_errorDevice->write("Cannot write header\n"); - return false; - } - if (m_root) { - if (!writeDataBlobs()) { - m_errorDevice->write("Cannot write data blobs.\n"); - return false; - } - if (!writeDataNames()) { - m_errorDevice->write("Cannot write file names\n"); - return false; - } - if (!writeDataStructure()) { - m_errorDevice->write("Cannot write data tree\n"); - return false; - } - } - if (!writeInitializer()) { - m_errorDevice->write("Cannot write footer\n"); - return false; - } - outDevice.write(m_out.constData(), m_out.size()); - return true; -} - -void RCCResourceLibrary::writeHex(quint8 tmp) -{ - const char digits[] = "0123456789abcdef"; - writeChar('0'); - writeChar('x'); - if (tmp < 16) { - writeChar(digits[tmp]); - } else { - writeChar(digits[tmp >> 4]); - writeChar(digits[tmp & 0xf]); - } - writeChar(','); -} - -void RCCResourceLibrary::writeNumber2(quint16 number) -{ - if (m_format == RCCResourceLibrary::Binary) { - writeChar(number >> 8); - writeChar(number); - } else { - writeHex(number >> 8); - writeHex(number); - } -} - -void RCCResourceLibrary::writeNumber4(quint32 number) -{ - if (m_format == RCCResourceLibrary::Binary) { - writeChar(number >> 24); - writeChar(number >> 16); - writeChar(number >> 8); - writeChar(number); - } else { - writeHex(number >> 24); - writeHex(number >> 16); - writeHex(number >> 8); - writeHex(number); - } -} - -bool RCCResourceLibrary::writeHeader() -{ - if (m_format == C_Code) { - writeString("/****************************************************************************\n"); - writeString("** Resource object code\n"); - writeString("**\n"); - writeString("** Created: "); - writeByteArray(QDateTime::currentDateTime().toString().toLatin1()); - writeString("\n** by: The Resource Compiler for Qt version "); - writeByteArray(QT_VERSION_STR); - writeString("\n**\n"); - writeString("** WARNING! All changes made in this file will be lost!\n"); - writeString( "*****************************************************************************/\n\n"); - writeString("#include <QtCore/qglobal.h>\n\n"); - } else if (m_format == Binary) { - writeString("qres"); - writeNumber4(0); - writeNumber4(0); - writeNumber4(0); - writeNumber4(0); - } - return true; -} - -bool RCCResourceLibrary::writeDataBlobs() -{ - Q_ASSERT(m_errorDevice); - if (m_format == C_Code) - writeString("static const unsigned char qt_resource_data[] = {\n"); - else if (m_format == Binary) - m_dataOffset = m_out.size(); - QStack<RCCFileInfo*> pending; - - if (!m_root) - return false; - - pending.push(m_root); - qint64 offset = 0; - QString errorMessage; - while (!pending.isEmpty()) { - RCCFileInfo *file = pending.pop(); - for (QHash<QString, RCCFileInfo*>::iterator it = file->m_children.begin(); - it != file->m_children.end(); ++it) { - RCCFileInfo *child = it.value(); - if (child->m_flags & RCCFileInfo::Directory) - pending.push(child); - else { - offset = child->writeDataBlob(*this, offset, &errorMessage); - if (offset == 0) { - m_errorDevice->write(errorMessage.toUtf8()); - return false; - } - } - } - } - if (m_format == C_Code) - writeString("\n};\n\n"); - return true; -} - -bool RCCResourceLibrary::writeDataNames() -{ - if (m_format == C_Code) - writeString("static const unsigned char qt_resource_name[] = {\n"); - else if (m_format == Binary) - m_namesOffset = m_out.size(); - - QHash<QString, int> names; - QStack<RCCFileInfo*> pending; - - if (!m_root) - return false; - - pending.push(m_root); - qint64 offset = 0; - while (!pending.isEmpty()) { - RCCFileInfo *file = pending.pop(); - for (QHash<QString, RCCFileInfo*>::iterator it = file->m_children.begin(); - it != file->m_children.end(); ++it) { - RCCFileInfo *child = it.value(); - if (child->m_flags & RCCFileInfo::Directory) - pending.push(child); - if (names.contains(child->m_name)) { - child->m_nameOffset = names.value(child->m_name); - } else { - names.insert(child->m_name, offset); - offset = child->writeDataName(*this, offset); - } - } - } - if (m_format == C_Code) - writeString("\n};\n\n"); - return true; -} - -static bool qt_rcc_compare_hash(const RCCFileInfo *left, const RCCFileInfo *right) -{ - return qt_hash(left->m_name) < qt_hash(right->m_name); -} - -bool RCCResourceLibrary::writeDataStructure() -{ - if (m_format == C_Code) - writeString("static const unsigned char qt_resource_struct[] = {\n"); - else if (m_format == Binary) - m_treeOffset = m_out.size(); - QStack<RCCFileInfo*> pending; - - if (!m_root) - return false; - - //calculate the child offsets (flat) - pending.push(m_root); - int offset = 1; - while (!pending.isEmpty()) { - RCCFileInfo *file = pending.pop(); - file->m_childOffset = offset; - - //sort by hash value for binary lookup - QList<RCCFileInfo*> m_children = file->m_children.values(); - qSort(m_children.begin(), m_children.end(), qt_rcc_compare_hash); - - //write out the actual data now - for (int i = 0; i < m_children.size(); ++i) { - RCCFileInfo *child = m_children.at(i); - ++offset; - if (child->m_flags & RCCFileInfo::Directory) - pending.push(child); - } - } - - //write out the structure (ie iterate again!) - pending.push(m_root); - m_root->writeDataInfo(*this); - while (!pending.isEmpty()) { - RCCFileInfo *file = pending.pop(); - - //sort by hash value for binary lookup - QList<RCCFileInfo*> m_children = file->m_children.values(); - qSort(m_children.begin(), m_children.end(), qt_rcc_compare_hash); - - //write out the actual data now - for (int i = 0; i < m_children.size(); ++i) { - RCCFileInfo *child = m_children.at(i); - child->writeDataInfo(*this); - if (child->m_flags & RCCFileInfo::Directory) - pending.push(child); - } - } - if (m_format == C_Code) - writeString("\n};\n\n"); - - return true; -} - -void RCCResourceLibrary::writeMangleNamespaceFunction(const QByteArray &name) -{ - if (m_useNameSpace) { - writeString("QT_MANGLE_NAMESPACE("); - writeByteArray(name); - writeChar(')'); - } else { - writeByteArray(name); - } -} - -void RCCResourceLibrary::writeAddNamespaceFunction(const QByteArray &name) -{ - if (m_useNameSpace) { - writeString("QT_PREPEND_NAMESPACE("); - writeByteArray(name); - writeChar(')'); - } else { - writeByteArray(name); - } -} - -bool RCCResourceLibrary::writeInitializer() -{ - if (m_format == C_Code) { - //write("\nQT_BEGIN_NAMESPACE\n"); - QString initName = m_initName; - if (!initName.isEmpty()) { - initName.prepend(QLatin1Char('_')); - initName.replace(QRegExp(QLatin1String("[^a-zA-Z0-9_]")), QLatin1String("_")); - } - - //init - if (m_useNameSpace) - writeString("QT_BEGIN_NAMESPACE\n\n"); - if (m_root) { - writeString("extern Q_CORE_EXPORT bool qRegisterResourceData\n " - "(int, const unsigned char *, " - "const unsigned char *, const unsigned char *);\n\n"); - writeString("extern Q_CORE_EXPORT bool qUnregisterResourceData\n " - "(int, const unsigned char *, " - "const unsigned char *, const unsigned char *);\n\n"); - } - if (m_useNameSpace) - writeString("QT_END_NAMESPACE\n\n\n"); - QString initResources = QLatin1String("qInitResources"); - initResources += initName; - writeString("int "); - writeMangleNamespaceFunction(initResources.toLatin1()); - writeString("()\n{\n"); - - if (m_root) { - writeString(" "); - writeAddNamespaceFunction("qRegisterResourceData"); - writeString("\n (0x01, qt_resource_struct, " - "qt_resource_name, qt_resource_data);\n"); - } - writeString(" return 1;\n"); - writeString("}\n\n"); - writeString("Q_CONSTRUCTOR_FUNCTION("); - writeMangleNamespaceFunction(initResources.toLatin1()); - writeString(")\n\n"); - - //cleanup - QString cleanResources = QLatin1String("qCleanupResources"); - cleanResources += initName; - writeString("int "); - writeMangleNamespaceFunction(cleanResources.toLatin1()); - writeString("()\n{\n"); - if (m_root) { - writeString(" "); - writeAddNamespaceFunction("qUnregisterResourceData"); - writeString("\n (0x01, qt_resource_struct, " - "qt_resource_name, qt_resource_data);\n"); - } - writeString(" return 1;\n"); - writeString("}\n\n"); - writeString("Q_DESTRUCTOR_FUNCTION("); - writeMangleNamespaceFunction(cleanResources.toLatin1()); - writeString(")\n\n"); - } else if (m_format == Binary) { - int i = 4; - char *p = m_out.data(); - p[i++] = 0; // 0x01 - p[i++] = 0; - p[i++] = 0; - p[i++] = 1; - - p[i++] = (m_treeOffset >> 24) & 0xff; - p[i++] = (m_treeOffset >> 16) & 0xff; - p[i++] = (m_treeOffset >> 8) & 0xff; - p[i++] = (m_treeOffset >> 0) & 0xff; - - p[i++] = (m_dataOffset >> 24) & 0xff; - p[i++] = (m_dataOffset >> 16) & 0xff; - p[i++] = (m_dataOffset >> 8) & 0xff; - p[i++] = (m_dataOffset >> 0) & 0xff; - - p[i++] = (m_namesOffset >> 24) & 0xff; - p[i++] = (m_namesOffset >> 16) & 0xff; - p[i++] = (m_namesOffset >> 8) & 0xff; - p[i++] = (m_namesOffset >> 0) & 0xff; - } - return true; -} - -QT_END_NAMESPACE |