qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset) { const bool text = (lib.m_format == RCCResourceLibrary::C_Code || lib.m_format == RCCResourceLibrary::Go_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(qHash(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; }
int runRcc(int argc, char *argv[]) { QString outFilename; bool helpRequested = false; bool list = false; bool projectRequested = false; QStringList filenamesIn; QStringList args = qCmdLineArgs(argc, argv); RCCResourceLibrary library; //parse options QString errorMsg; for (int i = 1; i < args.count() && errorMsg.isEmpty(); i++) { if (args[i].isEmpty()) continue; if (args[i][0] == QLatin1Char('-')) { // option QString opt = args[i]; if (opt == QLatin1String("-o")) { if (!(i < argc-1)) { errorMsg = QLatin1String("Missing output name"); break; } outFilename = args[++i]; } else if (opt == QLatin1String("-name")) { if (!(i < argc-1)) { errorMsg = QLatin1String("Missing target name"); break; } library.setInitName(args[++i]); } else if (opt == QLatin1String("-root")) { if (!(i < argc-1)) { errorMsg = QLatin1String("Missing root path"); break; } library.setResourceRoot(QDir::cleanPath(args[++i])); if (library.resourceRoot().isEmpty() || library.resourceRoot().at(0) != QLatin1Char('/')) errorMsg = QLatin1String("Root must start with a /"); } else if (opt == QLatin1String("-compress")) { if (!(i < argc-1)) { errorMsg = QLatin1String("Missing compression level"); break; } library.setCompressLevel(args[++i].toInt()); } else if (opt == QLatin1String("-threshold")) { if (!(i < argc-1)) { errorMsg = QLatin1String("Missing compression threshold"); break; } library.setCompressThreshold(args[++i].toInt()); } else if (opt == QLatin1String("-binary")) { library.setFormat(RCCResourceLibrary::Binary); } else if (opt == QLatin1String("-namespace")) { library.setUseNameSpace(!library.useNameSpace()); } else if (opt == QLatin1String("-verbose")) { library.setVerbose(true); } else if (opt == QLatin1String("-list")) { list = true; } else if (opt == QLatin1String("-version") || opt == QLatin1String("-v")) { fprintf(stderr, "Qt Resource Compiler version %s\n", QT_VERSION_STR); return 1; } else if (opt == QLatin1String("-help") || opt == QLatin1String("-h")) { helpRequested = true; } else if (opt == QLatin1String("-no-compress")) { library.setCompressLevel(-2); } else if (opt == QLatin1String("-project")) { projectRequested = true; } else { errorMsg = QString::fromLatin1("Unknown option: '%1'").arg(args[i]); } } else { if (!QFile::exists(args[i])) { qWarning("%s: File does not exist '%s'", qPrintable(args[0]), qPrintable(args[i])); return 1; } filenamesIn.append(args[i]); } } if (projectRequested && !helpRequested) { return createProject(outFilename); } if (!filenamesIn.size() || !errorMsg.isEmpty() || helpRequested) { showHelp(args[0], errorMsg); return 1; } QFile errorDevice; errorDevice.open(stderr, QIODevice::WriteOnly|QIODevice::Text); if (library.verbose()) errorDevice.write("Qt resource compiler\n"); library.setInputFiles(filenamesIn); if (!library.readFiles(list, errorDevice)) return 1; // open output QFile out; QIODevice::OpenMode mode = QIODevice::WriteOnly; if (library.format() == RCCResourceLibrary::C_Code) mode |= QIODevice::Text; if (outFilename.isEmpty() || outFilename == QLatin1String("-")) { // using this overload close() only flushes. out.open(stdout, mode); } else { out.setFileName(outFilename); if (!out.open(mode)) { const QString msg = QString::fromUtf8("Unable to open %1 for writing: %2\n").arg(outFilename).arg(out.errorString()); errorDevice.write(msg.toUtf8()); return 1; } } // do the task if (list) { const QStringList data = library.dataFiles(); for (int i = 0; i < data.size(); ++i) { out.write(qPrintable(QDir::cleanPath(data.at(i)))); out.write("\n"); } return 0; } return library.output(out, errorDevice) ? 0 : 1; }
int runRcc(int argc, char *argv[]) { QCoreApplication app(argc, argv); QCoreApplication::setApplicationVersion(QStringLiteral(QT_VERSION_STR)); // Note that rcc isn't translated. // If you use this code as an example for a translated app, make sure to translate the strings. QCommandLineParser parser; parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); parser.setApplicationDescription(QLatin1String("Qt Resource Compiler version " QT_VERSION_STR)); parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption outputOption(QStringList() << QStringLiteral("o") << QStringLiteral("output")); outputOption.setDescription(QStringLiteral("Write output to <file> rather than stdout.")); outputOption.setValueName(QStringLiteral("file")); parser.addOption(outputOption); QCommandLineOption tempOption(QStringList() << QStringLiteral("t") << QStringLiteral("temp")); tempOption.setDescription(QStringLiteral("Use temporary <file> for big resources.")); tempOption.setValueName(QStringLiteral("file")); parser.addOption(tempOption); QCommandLineOption nameOption(QStringLiteral("name"), QStringLiteral("Create an external initialization function with <name>."), QStringLiteral("name")); parser.addOption(nameOption); QCommandLineOption rootOption(QStringLiteral("root"), QStringLiteral("Prefix resource access path with root path."), QStringLiteral("path")); parser.addOption(rootOption); QCommandLineOption compressOption(QStringLiteral("compress"), QStringLiteral("Compress input files by <level>."), QStringLiteral("level")); parser.addOption(compressOption); QCommandLineOption nocompressOption(QStringLiteral("no-compress"), QStringLiteral("Disable all compression.")); parser.addOption(nocompressOption); QCommandLineOption thresholdOption(QStringLiteral("threshold"), QStringLiteral("Threshold to consider compressing files."), QStringLiteral("level")); parser.addOption(thresholdOption); QCommandLineOption binaryOption(QStringLiteral("binary"), QStringLiteral("Output a binary file for use as a dynamic resource.")); parser.addOption(binaryOption); QCommandLineOption passOption(QStringLiteral("pass"), QStringLiteral("Pass number for big resources"), QStringLiteral("number")); parser.addOption(passOption); QCommandLineOption namespaceOption(QStringLiteral("namespace"), QStringLiteral("Turn off namespace macros.")); parser.addOption(namespaceOption); QCommandLineOption verboseOption(QStringLiteral("verbose"), QStringLiteral("Enable verbose mode.")); parser.addOption(verboseOption); QCommandLineOption listOption(QStringLiteral("list"), QStringLiteral("Only list .qrc file entries, do not generate code.")); parser.addOption(listOption); QCommandLineOption projectOption(QStringLiteral("project"), QStringLiteral("Output a resource file containing all files from the current directory.")); parser.addOption(projectOption); parser.addPositionalArgument(QStringLiteral("inputs"), QStringLiteral("Input files (*.qrc).")); //parse options parser.process(app); QString errorMsg; RCCResourceLibrary library; if (parser.isSet(nameOption)) library.setInitName(parser.value(nameOption)); if (parser.isSet(rootOption)) { library.setResourceRoot(QDir::cleanPath(parser.value(rootOption))); if (library.resourceRoot().isEmpty() || library.resourceRoot().at(0) != QLatin1Char('/')) errorMsg = QLatin1String("Root must start with a /"); } if (parser.isSet(compressOption)) library.setCompressLevel(parser.value(compressOption).toInt()); if (parser.isSet(nocompressOption)) library.setCompressLevel(-2); if (parser.isSet(thresholdOption)) library.setCompressThreshold(parser.value(thresholdOption).toInt()); if (parser.isSet(binaryOption)) library.setFormat(RCCResourceLibrary::Binary); if (parser.isSet(passOption)) { if (parser.value(passOption) == QLatin1String("1")) library.setFormat(RCCResourceLibrary::Pass1); else if (parser.value(passOption) == QLatin1String("2")) library.setFormat(RCCResourceLibrary::Pass2); else errorMsg = QLatin1String("Pass number must be 1 or 2"); } if (parser.isSet(namespaceOption)) library.setUseNameSpace(!library.useNameSpace()); if (parser.isSet(verboseOption)) library.setVerbose(true); const bool list = parser.isSet(listOption); const bool projectRequested = parser.isSet(projectOption); const QStringList filenamesIn = parser.positionalArguments(); foreach (const QString &file, filenamesIn) { if (!QFile::exists(file)) { qWarning("%s: File does not exist '%s'", argv[0], qPrintable(file)); return 1; } } QString outFilename = parser.value(outputOption); QString tempFilename = parser.value(tempOption); if (projectRequested) { return createProject(outFilename); } if (filenamesIn.isEmpty()) errorMsg = QStringLiteral("No input files specified."); if (!errorMsg.isEmpty()) { fprintf(stderr, "%s: %s\n", argv[0], qPrintable(errorMsg)); parser.showHelp(1); return 1; } QFile errorDevice; errorDevice.open(stderr, QIODevice::WriteOnly|QIODevice::Text); if (library.verbose()) errorDevice.write("Qt resource compiler\n"); library.setInputFiles(filenamesIn); if (!library.readFiles(list, errorDevice)) return 1; QFile out; // open output QIODevice::OpenMode mode = QIODevice::NotOpen; switch (library.format()) { case RCCResourceLibrary::C_Code: case RCCResourceLibrary::Pass1: mode = QIODevice::WriteOnly | QIODevice::Text; break; case RCCResourceLibrary::Pass2: case RCCResourceLibrary::Binary: mode = QIODevice::WriteOnly; break; } if (outFilename.isEmpty() || outFilename == QLatin1String("-")) { #ifdef Q_OS_WIN // Make sure fwrite to stdout doesn't do LF->CRLF if (library.format() == RCCResourceLibrary::Binary) _setmode(_fileno(stdout), _O_BINARY); #endif // Q_OS_WIN // using this overload close() only flushes. out.open(stdout, mode); } else { out.setFileName(outFilename); if (!out.open(mode)) { const QString msg = QString::fromLatin1("Unable to open %1 for writing: %2\n").arg(outFilename).arg(out.errorString()); errorDevice.write(msg.toUtf8()); return 1; } } // do the task if (list) { const QStringList data = library.dataFiles(); for (int i = 0; i < data.size(); ++i) { out.write(qPrintable(QDir::cleanPath(data.at(i)))); out.write("\n"); } return 0; } QFile temp; if (!tempFilename.isEmpty()) { temp.setFileName(tempFilename); if (!temp.open(QIODevice::ReadOnly)) { const QString msg = QString::fromUtf8("Unable to open temporary file %1 for reading: %2\n") .arg(outFilename).arg(out.errorString()); errorDevice.write(msg.toUtf8()); return 1; } } bool success = library.output(out, temp, errorDevice); if (!success) { // erase the output file if we failed out.remove(); return 1; } return 0; }
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; }
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'); }
bool processResourceFile(const QStringList &filenamesIn, const QString &filenameOut, bool list) { if (verbose) fprintf(stderr, "Qt resource compiler\n"); //setup RCCResourceLibrary library; library.setFormat(writeBinary ? RCCResourceLibrary::Binary : RCCResourceLibrary::C_Code); library.setInputFiles(filenamesIn); library.setInitName(initName); library.setVerbose(verbose); library.setCompressLevel(compressLevel); library.setCompressThreshold(compressThreshold); library.setResourceRoot(resourceRoot); if(!library.readFiles(list)) return false; //open output FILE *out_fd = stdout; if (!filenameOut.isEmpty() && filenameOut != QLatin1String("-")) { #if defined(_MSC_VER) && _MSC_VER >= 1400 if (fopen_s(&out_fd, filenameOut.toLocal8Bit().constData(), writeBinary ? "wb": "w")) { #else if(!(out_fd = fopen(filenameOut.toLocal8Bit().constData(), writeBinary ? "wb": "w"))) { #endif fprintf(stderr, "Unable to open %s for writing\n", qPrintable(filenameOut)); return false; } } //do the task bool ret = true; if(list) { const QStringList data = library.dataFiles(); for(int i = 0; i < data.size(); ++i) fprintf(out_fd, "%s\n", qPrintable(QDir::cleanPath(data.at(i)))); } else { ret = library.output(out_fd); } if(out_fd != stdout) fclose(out_fd); //done return ret; } int showHelp(const QString &argv0, const QString &error) { fprintf(stderr, "Qt resource compiler\n"); if (!error.isEmpty()) fprintf(stderr, "%s: %s\n", argv0.toLocal8Bit().constData(), error.toLocal8Bit().constData()); fprintf(stderr, "Usage: %s [options] <inputs>\n\n" "Options:\n" " -o file write output to file rather than stdout\n" " -name name create an external initialization function with name\n" " -threshold level threshold to consider compressing files\n" " -compress level compress input files by level\n" " -root path prefix resource access path with root path\n" " -no-compress disable all compression\n" " -binary output a binary file for use as a dynamic resource\n" " -version display version\n" " -help display this information\n", argv0.toLocal8Bit().constData()); return 1; }