QString LayerListModel::getAvailableLayerName(QString basename) const { // Return a layer name of format "basename n" where n is one bigger than the // biggest suffix number of layers named "basename n". // First, strip suffix number from the basename (if it exists) QRegularExpression suffixNumRe("(\\d+)$"); { auto m = suffixNumRe.match(basename); if(m.hasMatch()) { basename = basename.mid(0, m.capturedStart()).trimmed(); } } // Find the biggest suffix in the layer stack int suffix = 0; for(const LayerListItem &l : _items) { auto m = suffixNumRe.match(l.title); if(m.hasMatch()) { if(l.title.startsWith(basename)) { suffix = qMax(suffix, m.captured(1).toInt()); } } } // Make unique name return QString("%2 %1").arg(suffix+1).arg(basename); }
void FrostEdit::parseCompileOut(QString line) { auto match = mFrostCompilerErrorRegEx.match(line); while(match.hasMatch()) { ui->consoleTabs->setCurrentIndex(0); QStringList captures = match.capturedTexts(); QString wholeMsg = captures[0]; QString file = captures[1]; int row = captures[2].toInt(); int col = captures[3].toInt(); QString type = captures[4]; int code = captures[5].toInt(); QString explanation = captures[6]; QString prevfile = file; if(file != mCompiledFile && file.right(4) == ".tmp") { file = mCompiledFile; wholeMsg.replace(prevfile, file); } if(type.toLower() == "warning") mIssueList->addWarning(wholeMsg, file, explanation, row, col); else if(type.toLower() == "error") mIssueList->addError(wholeMsg, file, explanation, row, col); match = mFrostCompilerErrorRegEx.match(line, match.capturedEnd()); } }
static QString getXdgValue(const QString& contents, const QString& key, const QString& accessor = "") { QString fullkey = accessor.length() ? key + "[" + accessor + "]" : key; QRegularExpression re("^" + fullkey + "=(.*)$", QRegularExpression::MultilineOption); auto match = re.match(contents); return match.hasMatch() ? match.captured(1) : ""; }
// Delete all temporary directories for an application int PathUtils::removeTemporaryApplicationDirs(QString appName) { if (appName.isNull()) { appName = qApp->applicationName(); } auto dirName = TEMP_DIR_FORMAT.arg(appName).arg("*").arg("*"); QDir rootTempDir = QDir::tempPath(); auto dirs = rootTempDir.entryInfoList({ dirName }, QDir::Dirs); int removed = 0; for (auto& dir : dirs) { auto dirName = dir.fileName(); auto absoluteDirPath = QDir(dir.absoluteFilePath()); QRegularExpression re { "^" + QRegularExpression::escape(appName) + "\\-(?<pid>\\d+)\\-(?<timestamp>\\d+)$" }; auto match = re.match(dirName); if (match.hasMatch()) { auto pid = match.capturedRef("pid").toLongLong(); auto timestamp = match.capturedRef("timestamp"); if (!processIsRunning(pid)) { qDebug() << " Removing old temporary directory: " << dir.absoluteFilePath(); absoluteDirPath.removeRecursively(); removed++; } else { qDebug() << " Not removing (process is running): " << dir.absoluteFilePath(); } } } return removed; }
TextWithTags::Tags ConvertEntitiesToTextTags(const EntitiesInText &entities) { TextWithTags::Tags result; if (entities.isEmpty()) { return result; } result.reserve(entities.size()); for (const auto &entity : entities) { const auto push = [&](const QString &tag) { result.push_back({ entity.offset(), entity.length(), tag }); }; switch (entity.type()) { case EntityInTextMentionName: { auto match = QRegularExpression("^(\\d+\\.\\d+)$").match(entity.data()); if (match.hasMatch()) { push(kMentionTagStart + entity.data()); } } break; case EntityInTextCustomUrl: { const auto url = entity.data(); if (Ui::InputField::IsValidMarkdownLink(url) && !IsMentionLink(url)) { push(url); } } break; case EntityInTextBold: push(Ui::InputField::kTagBold); break; case EntityInTextItalic: push(Ui::InputField::kTagItalic); break; case EntityInTextCode: push(Ui::InputField::kTagCode); break; case EntityInTextPre: push(Ui::InputField::kTagPre); break; } } return result; }
QStringList KateProjectWorker::filesFromDarcs(const QDir &dir, bool recursive) { QStringList files; const QString cmd = QStringLiteral("darcs"); QString root; { QProcess darcs; darcs.setWorkingDirectory(dir.absolutePath()); QStringList args; args << QStringLiteral("list") << QStringLiteral("repo"); darcs.start(cmd, args); if (!darcs.waitForStarted() || !darcs.waitForFinished()) return files; auto str = QString::fromLocal8Bit(darcs.readAllStandardOutput()); QRegularExpression exp(QStringLiteral("Root: ([^\\n\\r]*)")); auto match = exp.match(str); if(!match.hasMatch()) return files; root = match.captured(1); } QStringList relFiles; { QProcess darcs; QStringList args; darcs.setWorkingDirectory(dir.absolutePath()); args << QStringLiteral("list") << QStringLiteral("files") << QStringLiteral("--no-directories") << QStringLiteral("--pending"); darcs.start(cmd, args); if(!darcs.waitForStarted() || !darcs.waitForFinished()) return files; relFiles = QString::fromLocal8Bit(darcs.readAllStandardOutput()) .split(QRegularExpression(QStringLiteral("[\n\r]")), QString::SkipEmptyParts); } for (const QString &relFile: relFiles) { const QString path = dir.relativeFilePath(root + QStringLiteral("/") + relFile); if ((!recursive && (relFile.indexOf(QStringLiteral("/")) != -1)) || (recursive && (relFile.indexOf(QStringLiteral("..")) == 0)) ) { continue; } files.append(dir.absoluteFilePath(path)); } return files; }
void LoginHandler::handleHostMessage(const QString &message) { Q_ASSERT(!_client->username().isEmpty()); if(_server->sessionCount() >= _server->sessionLimit()) { send("ERROR CLOSED"); _client->disconnectError("login error"); return; } const QRegularExpression re("\\AHOST (\\*|[a-zA-Z0-9:-]{1,64}) (\\d+) (\\d+)\\s*(?:;(.+))?\\z"); auto m = re.match(message); if(!m.hasMatch()) { send("ERROR SYNTAX"); _client->disconnectError("login error"); return; } QString sessionId = m.captured(1); int minorVersion = m.captured(2).toInt(); int userId = m.captured(3).toInt(); // Check if session ID is available if(sessionId == "*") { // Generated session ID sessionId = QUuid::createUuid().toString(); sessionId = sessionId.mid(1, sessionId.length()-2); // strip the { and } chars } if(!_server->getSessionDescriptionById(sessionId).id.isEmpty()) { send("ERROR SESSIONIDINUSE"); _client->disconnectError("login error"); return; } QString password = m.captured(4); if(password != _server->hostPassword() && !_hostPrivilege) { send("ERROR BADPASS"); _client->disconnectError("login error"); return; } _client->setId(userId); // Mark login phase as complete. No more login messages will be sent to this user send(QString("OK %1 %2").arg(sessionId).arg(userId)); _complete = true; // Create a new session SessionState *session = _server->createSession(sessionId, minorVersion, _client->username()); session->joinUser(_client, true); deleteLater(); }
std::vector<BankAccount> OfxParser::parse() { std::vector<BankAccount> result; QTextStream stream(m_file); QString line; QRegularExpression newTagMatcher("^<(\\w+)>$"); QRegularExpression endTagMatcher("^</(\\w+)>$"); QRegularExpression dataTagMatcher("^<(\\w+)>(.*)$"); QStringList tagList; QMap<QString, QString> dataMap; while (stream.readLineInto(&line)) { if (line.isEmpty()) continue; auto match = newTagMatcher.match(line); if (match.hasMatch()) { if (!dataMap.isEmpty()) { parsedData(result, tagList.join('/'), dataMap); dataMap.clear(); } tagList.append(match.captured(1)); continue; } match = endTagMatcher.match(line); if (match.hasMatch()) { if (!dataMap.isEmpty()) { parsedData(result, tagList.join('/'), dataMap); dataMap.clear(); } tagList.pop_back(); continue; } match = dataTagMatcher.match(line); if (match.hasMatch()) { dataMap.insert(match.captured(1), match.captured(2)); continue; } qFatal("Invalid content"); } return result; }
StringList RegExpMatch::captured() const { StringList r; if (hasMatch()) { iterator it = begin(); iterator itEnd = end(); while (it != itEnd) { r.append(*it++); } } return r; }
QByteArray LSHttpdRequest::extractOption(QByteArray headerValue, QByteArray optionTag) { if(headerValue.isEmpty() || optionTag.isEmpty()) { return QByteArray(); } QString pattern = QStringLiteral("%1=\"([^\"]+)\""); QRegularExpression rx(pattern.arg(QString::fromLocal8Bit(optionTag))); auto rxMatch = rx.match(QString::fromLocal8Bit(headerValue)); if(rxMatch.hasMatch()) { return rxMatch.captured(1).toLocal8Bit(); } return ""; }
/** * @brief prepend the match string with specify symbol * @param input string need to prepend symbol * @param number_length the length of the number, will prepend symbol * if the length smaller than this number * @param symbol symbol prepand before the number * @return the name after alter * @example ex : number_length == 3, reg = (\\d+), symbol = '0' * then "1" == "001", "10" == "010" * ex : number_length == 2, reg = (\\d+), symbol = '0' * then "1" == "01", "10" == "10" */ QString prepend_symbol_on_match(QString const &input, int number_length, QRegularExpression const ®, QChar symbol) { auto new_file_name = input; auto match = reg.match(new_file_name); if(match.hasMatch()){ auto const Captured = match.captured(0); if(Captured.size() < number_length){ new_file_name.insert(match.capturedStart(0), QString(number_length - match.capturedLength(1), symbol)); } } return new_file_name; }
KTextEditor::Cursor KTextEditorHelpers::extractCursor(const QString& input, int* pathLength) { static const QRegularExpression pattern(QStringLiteral(":(\\d+)(?::(\\d+))?$")); const auto match = pattern.match(input); if (!match.hasMatch()) { if (pathLength) *pathLength = input.length(); return KTextEditor::Cursor::invalid(); } int line = match.capturedRef(1).toInt() - 1; // don't use an invalid column when the line is valid int column = qMax(0, match.captured(2).toInt() - 1); if (pathLength) *pathLength = match.capturedStart(0); return {line, column}; }
const QString clearHTMLTags(const QString &text) { const QRegularExpression regex("<(\\w+)[^>]*>([^<]*)</\\1>"); QString ret = text; do { const auto match = regex.match(ret); if (!match.isValid() || !match.hasMatch()) break; const int start = match.capturedStart(); const int len = match.capturedLength(); const QString &cap = match.captured(2); ret.replace(start, len, cap); } while (true); return ret; }
QString Mrl::displayName() const { if (isLocalFile()) return fileName(); QString disc; if (isDvd()) disc = qApp->translate("Mrl", "DVD"); else if (isBluray()) disc = qApp->translate("Mrl", "Blu-ray"); if (disc.isEmpty()) return location(); auto dev = device(); if (dev.isEmpty()) return disc; if (!dev.startsWith(_L("/dev/"))) { QRegularExpression regex("/([^/]+)/*$"); auto match = regex.match(dev); if (match.hasMatch()) dev = match.captured(1); } return disc % _L(" (") % dev % _L(')'); }
bool PathUtils::deleteMyTemporaryDir(QString dirName) { QDir rootTempDir = QDir::tempPath(); QString appName = qApp->applicationName(); QRegularExpression re { "^" + QRegularExpression::escape(appName) + "\\-(?<pid>\\d+)\\-(?<timestamp>\\d+)$" }; auto match = re.match(dirName); auto pid = match.capturedRef("pid").toLongLong(); if (match.hasMatch() && rootTempDir.exists(dirName) && pid == qApp->applicationPid()) { auto absoluteDirPath = QDir(rootTempDir.absoluteFilePath(dirName)); bool success = absoluteDirPath.removeRecursively(); if (success) { qDebug() << " Removing temporary directory: " << absoluteDirPath.absolutePath(); } else { qDebug() << " Failed to remove temporary directory: " << absoluteDirPath.absolutePath(); } return success; } return false; }
/** * @brief toBool * @param in * @param ok * @return */ bool toBool(const QString &in, bool &ok) { auto match = QRegularExpression("^(true|false)$").match(in); return (ok = match.hasMatch()) ? match.captured(1) == "true" ? true : false : ok; }
bool Headline::isMatch(const QRegularExpression &pattern) const { auto const match = pattern.match(caption()); //qDebug() << caption() << "matches" << pattern << "?" << (match.hasMatch() ? "yes" : "no"); return match.hasMatch(); }
void LoginHandler::handleJoinMessage(const QString &message) { Q_ASSERT(!_client->username().isEmpty()); const QRegularExpression re("\\AJOIN ([a-zA-Z0-9:-]{1,64})\\s*(?:;(.+))?\\z"); auto m = re.match(message); if(!m.hasMatch()) { send("ERROR SYNTAX"); _client->disconnectError("login error"); return; } QString sessionId = m.captured(1); SessionDescription sessiondesc = _server->getSessionDescriptionById(sessionId); if(sessiondesc.id==0) { send("ERROR NOSESSION"); _client->disconnectError("login error"); return; } if(sessiondesc.closed && !_client->isModerator()) { send("ERROR CLOSED"); _client->disconnectError("login error"); return; } QString password = m.captured(2); if(!passwordhash::check(password, sessiondesc.passwordHash) && !_client->isModerator()) { send("ERROR BADPASS"); _client->disconnectError("login error"); return; } // Just the username uniqueness check to go, we can wake up the session now // A freshly de-hibernated session will not have any users, so the last check // will never fail in that case. SessionState *session = _server->getSessionById(sessionId); if(!session) { // The session was just deleted from under us! (or de-hibernation failed) send("ERROR NOSESSION"); _client->disconnectError("login error"); return; } if(session->getClientByUsername(_client->username())) { #ifdef NDEBUG send("ERROR NAMEINUSE"); _client->disconnectError("login error"); return; #else // Allow identical usernames in debug builds, so I don't have to keep changing // the username when testing. There is no technical requirement for unique usernames; // the limitation is solely for the benefit of the human users. logger::warning() << "Username clash" << _client->username() << "for" << session << "ignored because this is a debug build."; #endif } // Ok, join the session session->assignId(_client); send(QString("OK %1 %2").arg(session->id()).arg(_client->id())); _complete = true; session->joinUser(_client, false); deleteLater(); }
ParsedPage HtmlApi::parsePage(Page *parentPage, const QString &source, int first, int limit) const { ParsedPage ret; // Getting tags if (contains("Regex/Tags")) { QList<Tag> tgs = Tag::FromRegexp(value("Regex/Tags"), source); if (!tgs.isEmpty()) { ret.tags = tgs; } } // Getting images QRegularExpression rxImages(value("Regex/Image"), QRegularExpression::DotMatchesEverythingOption); auto matches = rxImages.globalMatch(source); int id = 0; while (matches.hasNext()) { auto match = matches.next(); QMap<QString, QString> d = multiMatchToMap(match, rxImages.namedCaptureGroups()); // JSON elements if (d.contains("json") && !d["json"].isEmpty()) { QVariant src = Json::parse(d["json"]); if (!src.isNull()) { QMap<QString, QVariant> map = src.toMap(); for (auto it = map.begin(); it != map.end(); ++it) { d[it.key()] = it.value().toString(); } } } QSharedPointer<Image> img = parseImage(parentPage, d, id + first); if (!img.isNull()) { ret.images.append(img); } id++; } // Navigation if (contains("Regex/NextPage")) { QRegularExpression rxNextPage(value("Regex/NextPage")); auto match = rxNextPage.match(source); if (match.hasMatch()) { ret.urlNextPage = QUrl(match.captured(1)); } } if (contains("Regex/PrevPage")) { QRegularExpression rxPrevPage(value("Regex/PrevPage")); auto match = rxPrevPage.match(source); if (match.hasMatch()) { ret.urlPrevPage = QUrl(match.captured(1)); } } // Last page if (contains("LastPage")) { ret.pageCount = value("LastPage").toInt(); } else if (contains("Regex/LastPage")) { QRegularExpression rxlast(value("Regex/LastPage")); auto match = rxlast.match(source); int cnt = match.hasMatch() ? match.captured(1).remove(",").toInt() : 0; if (cnt > 0) { int pagesCount = cnt; if (value("Urls/Tags").contains("{pid}") || (contains("Urls/PagePart") && value("Urls/PagePart").contains("{pid}"))) { int forced = forcedLimit(); int ppid = forced > 0 ? forced : limit; pagesCount = qFloor(static_cast<qreal>(pagesCount) / static_cast<qreal>(ppid)) + 1; } ret.pageCount = pagesCount; } } // Count images if (contains("Regex/Count")) { QRegularExpression rxlast(value("Regex/Count")); auto match = rxlast.match(source); int cnt = match.hasMatch() ? match.captured(1).remove(",").toInt() : 0; if (cnt > 0) { ret.imageCount = cnt; } } // Wiki if (contains("Regex/Wiki")) { QRegularExpression rxwiki(value("Regex/Wiki"), QRegularExpression::DotMatchesEverythingOption); auto match = rxwiki.match(source); if (match.hasMatch()) { QString wiki = match.captured(1); wiki.remove("/wiki/show?title="); wiki.remove(QRegularExpression("<p><a href=\"([^\"]+)\">Full entry »</a></p>")); wiki.replace("<h6>", "<span class=\"title\">").replace("</h6>", "</span>"); ret.wiki = wiki; } } return ret; }
void LoginHandler::handleIdentMessage(const QString &message) { const QRegularExpression re("\\IDENT \"([^\"]+)\"\\s*(?:;(.+))?\\z"); auto m = re.match(message); if(!m.hasMatch()) { send("ERROR SYNTAX"); _client->disconnectError("login error"); return; } QString username = m.captured(1); QString password; if(m.lastCapturedIndex() == 2) password = m.captured(2); if(!validateUsername(username)) { send("ERROR BADNAME"); _client->disconnectError("login error"); return; } if(_server->identityManager()) { _state = WAIT_FOR_IDENTITYMANAGER_REPLY; IdentityResult *result = _server->identityManager()->checkLogin(username, password); connect(result, &IdentityResult::resultAvailable, [this, username, password](IdentityResult *result) { QString error; Q_ASSERT(result->status() != IdentityResult::INPROGRESS); switch(result->status()) { case IdentityResult::INPROGRESS: /* can't happen */ break; case IdentityResult::NOTFOUND: if(!_server->identityManager()->isAuthorizedOnly()) { guestLogin(username); break; } // fall through to badpass if guest logins are disabled case IdentityResult::BADPASS: if(password.isEmpty()) { // No password: tell client that guest login is not possible (for this username) _state = WAIT_FOR_IDENT; send("NEEDPASS"); return; } error = "BADPASS"; break; case IdentityResult::BANNED: error = "BANNED"; break; case IdentityResult::OK: { // Yay, username and password were valid! QString okstr = "IDENTIFIED USER "; if(result->flags().isEmpty()) okstr += "-"; else okstr += result->flags().join(","); if(validateUsername(result->canonicalName())) { _client->setUsername(result->canonicalName()); } else { logger::warning() << "Identity manager gave us an invalid username:"******"MOD")); _hostPrivilege = result->flags().contains("HOST"); _state = WAIT_FOR_LOGIN; send(okstr); announceServerInfo(); } break; } if(!error.isEmpty()) { send("ERROR " + error); _client->disconnectError("login error"); } }); } else { if(!password.isNull()) { // if we have no identity manager, we can't accept passwords send("ERROR NOIDENT"); _client->disconnectError("login error"); return; } guestLogin(username); } }
void MessageLinksParser::parse() { const auto &textWithTags = _field->getTextWithTags(); const auto &text = textWithTags.text; const auto &tags = textWithTags.tags; const auto &markdownTags = _field->getMarkdownTags(); if (text.isEmpty()) { _list = QStringList(); return; } auto ranges = QVector<LinkRange>(); auto tag = tags.begin(); const auto tagsEnd = tags.end(); const auto processTag = [&] { Expects(tag != tagsEnd); if (Ui::InputField::IsValidMarkdownLink(tag->id) && !IsMentionLink(tag->id)) { ranges.push_back({ tag->offset, tag->length, tag->id }); } ++tag; }; const auto processTagsBefore = [&](int offset) { while (tag != tagsEnd && tag->offset + tag->length <= offset) { processTag(); } }; const auto hasTagsIntersection = [&](int till) { if (tag == tagsEnd || tag->offset >= till) { return false; } while (tag != tagsEnd && tag->offset < till) { processTag(); } return true; }; auto markdownTag = markdownTags.begin(); const auto markdownTagsEnd = markdownTags.end(); const auto markdownTagsAllow = [&](int from, int length) { while (markdownTag != markdownTagsEnd && (markdownTag->adjustedStart + markdownTag->adjustedLength <= from || !markdownTag->closed)) { ++markdownTag; continue; } if (markdownTag == markdownTagsEnd || markdownTag->adjustedStart >= from + length) { return true; } // Ignore http-links that are completely inside some tags. // This will allow sending http://test.com/__test__/test correctly. return (markdownTag->adjustedStart > from) || (markdownTag->adjustedStart + markdownTag->adjustedLength < from + length); }; const auto len = text.size(); const QChar *start = text.unicode(), *end = start + text.size(); for (auto offset = 0, matchOffset = offset; offset < len;) { auto m = TextUtilities::RegExpDomain().match(text, matchOffset); if (!m.hasMatch()) break; auto domainOffset = m.capturedStart(); auto protocol = m.captured(1).toLower(); auto topDomain = m.captured(3).toLower(); auto isProtocolValid = protocol.isEmpty() || TextUtilities::IsValidProtocol(protocol); auto isTopDomainValid = !protocol.isEmpty() || TextUtilities::IsValidTopDomain(topDomain); if (protocol.isEmpty() && domainOffset > offset + 1 && *(start + domainOffset - 1) == QChar('@')) { auto forMailName = text.mid(offset, domainOffset - offset - 1); auto mMailName = TextUtilities::RegExpMailNameAtEnd().match(forMailName); if (mMailName.hasMatch()) { offset = matchOffset = m.capturedEnd(); continue; } } if (!isProtocolValid || !isTopDomainValid) { offset = matchOffset = m.capturedEnd(); continue; } QStack<const QChar*> parenth; const QChar *domainEnd = start + m.capturedEnd(), *p = domainEnd; for (; p < end; ++p) { QChar ch(*p); if (chIsLinkEnd(ch)) break; // link finished if (chIsAlmostLinkEnd(ch)) { const QChar *endTest = p + 1; while (endTest < end && chIsAlmostLinkEnd(*endTest)) { ++endTest; } if (endTest >= end || chIsLinkEnd(*endTest)) { break; // link finished at p } p = endTest; ch = *p; } if (ch == '(' || ch == '[' || ch == '{' || ch == '<') { parenth.push(p); } else if (ch == ')' || ch == ']' || ch == '}' || ch == '>') { if (parenth.isEmpty()) break; const QChar *q = parenth.pop(), open(*q); if ((ch == ')' && open != '(') || (ch == ']' && open != '[') || (ch == '}' && open != '{') || (ch == '>' && open != '<')) { p = q; break; } } } if (p > domainEnd) { // check, that domain ended if (domainEnd->unicode() != '/' && domainEnd->unicode() != '?') { matchOffset = domainEnd - start; continue; } } const auto range = LinkRange { domainOffset, static_cast<int>(p - start - domainOffset), QString() }; processTagsBefore(domainOffset); if (!hasTagsIntersection(range.start + range.length)) { if (markdownTagsAllow(range.start, range.length)) { ranges.push_back(range); } } offset = matchOffset = p - start; } processTagsBefore(QFIXED_MAX); apply(text, ranges); }
bool OsmAnd::CoreResourcesEmbeddedBundle_P::loadResources() { typedef const void* (*GetPointerFunctionPtr)(); typedef const char* NamePtr; typedef const uint8_t* DataPtr; // Regular expressions to extract pure resource name or qualifiers const QRegularExpression resourceNameWithQualifiersRegExp("(?:\\[(.*)\\])(.*)"); // Find out what number of resources there is in the bundle const auto pGetResourcesCount = reinterpret_cast<GetPointerFunctionPtr>(loadSymbol("__get____CoreResourcesEmbeddedBundle__ResourcesCount")); if (pGetResourcesCount == nullptr) return false; const auto resourcesCount = *reinterpret_cast<const uint32_t*>(pGetResourcesCount()); for (auto resourceIdx = 0u; resourceIdx < resourcesCount; resourceIdx++) { ResourceData resourceData; const auto pGetResourceName = reinterpret_cast<GetPointerFunctionPtr>(loadSymbol( QString(QLatin1String("__get____CoreResourcesEmbeddedBundle__ResourceName_%1")).arg(resourceIdx).toLatin1())); if (pGetResourceName == nullptr) return false; const auto resourceName = reinterpret_cast<const char*>(pGetResourceName()); const auto pGetResourceSize = reinterpret_cast<GetPointerFunctionPtr>(loadSymbol( QString(QLatin1String("__get____CoreResourcesEmbeddedBundle__ResourceSize_%1")).arg(resourceIdx).toLatin1())); if (pGetResourceSize == nullptr) return false; resourceData.size = *reinterpret_cast<const size_t*>(pGetResourceSize()); const auto pGetResourceData = reinterpret_cast<GetPointerFunctionPtr>(loadSymbol( QString(QLatin1String("__get____CoreResourcesEmbeddedBundle__ResourceData_%1")).arg(resourceIdx).toLatin1())); if (pGetResourceData == nullptr) return false; resourceData.data = reinterpret_cast<const uint8_t*>(pGetResourceData()); // Process resource name QStringList qualifiers; QString pureResourceName; const auto resourceNameComponents = resourceNameWithQualifiersRegExp.match(QLatin1String(resourceName)); if (resourceNameComponents.hasMatch()) { qualifiers = resourceNameComponents.captured(1).split(QLatin1Char(';'), QString::SkipEmptyParts); pureResourceName = resourceNameComponents.captured(2); } else { pureResourceName = QLatin1String(resourceName); } // Get resource entry for this resource auto& resourceEntry = _resources[pureResourceName]; if (qualifiers.isEmpty()) { resourceEntry.defaultVariant = resourceData; } else { for (const auto& qualifier : constOf(qualifiers)) { const auto qualifierComponents = qualifier.trimmed().split(QLatin1Char('='), QString::SkipEmptyParts); bool ok = false; if (qualifierComponents.size() == 2 && qualifierComponents.first() == QLatin1String("ddf")) { const auto ddfValue = qualifierComponents.last().toFloat(&ok); if (!ok) { LogPrintf(LogSeverityLevel::Warning, "Unsupported value '%s' for DDF qualifier", qPrintable(qualifierComponents.last())); } resourceEntry.variantsByDisplayDensityFactor.insert(ddfValue, resourceData); } else { LogPrintf(LogSeverityLevel::Warning, "Unsupported qualifier '%s'", qPrintable(qualifier.trimmed())); } } } } return true; }