summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonathan Feenstra <26406078+JonathanFeenstra@users.noreply.github.com>2026-05-17 09:28:30 +0200
committerGitHub <noreply@github.com>2026-05-17 02:28:30 -0500
commitab38cf0e059c15af82da7e48045823a5cbbb5d52 (patch)
tree314a78b4e8bfe3ceee91474403b153c55cbf5bd6 /src
parent0c95bf22e6be661fbed83cbc7ac0a43596bc80f4 (diff)
Improve code for reading text files line-by-line
Diffstat (limited to 'src')
-rw-r--r--src/categories.cpp34
-rw-r--r--src/loot.cpp21
-rw-r--r--src/organizercore.cpp12
-rw-r--r--src/plugincontainer.cpp13
-rw-r--r--src/pluginlist.cpp10
-rw-r--r--src/profile.cpp28
6 files changed, 65 insertions, 53 deletions
diff --git a/src/categories.cpp b/src/categories.cpp
index 48ee4bc8..b5e25538 100644
--- a/src/categories.cpp
+++ b/src/categories.cpp
@@ -57,13 +57,17 @@ void CategoryFactory::loadCategories()
QFile categoryFile(categoriesFilePath());
bool needLoad = false;
- if (!categoryFile.open(QIODevice::ReadOnly)) {
+ if (!categoryFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
needLoad = true;
} else {
- int lineNum = 0;
- while (!categoryFile.atEnd()) {
- QByteArray line = categoryFile.readLine();
- ++lineNum;
+ const auto lines = categoryFile.readAll().split('\n');
+ categoryFile.close();
+ for (int lineNum = 0; lineNum < lines.size(); ++lineNum) {
+ const auto& line = lines[lineNum];
+ if (line.isEmpty()) {
+ continue;
+ }
+
QList<QByteArray> cells = line.split('|');
if (cells.count() == 4) {
std::vector<NexusCategory> nexusCats;
@@ -76,7 +80,7 @@ void CategoryFactory::loadCategories()
if (!ok) {
log::error(tr("invalid category id {0}"), iter->constData());
}
- nexusCats.push_back(NexusCategory("Unknown", temp));
+ nexusCats.emplace_back("Unknown", temp);
}
}
bool cell0Ok = true;
@@ -103,16 +107,19 @@ void CategoryFactory::loadCategories()
line.constData(), cells.count());
}
}
- categoryFile.close();
QFile nexusMapFile(nexusMappingFilePath());
- if (!nexusMapFile.open(QIODevice::ReadOnly)) {
+ if (!nexusMapFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
needLoad = true;
} else {
- int nexLineNum = 0;
- while (!nexusMapFile.atEnd()) {
- QByteArray nexLine = nexusMapFile.readLine();
- ++nexLineNum;
+ const auto nexLines = nexusMapFile.readAll().split('\n');
+ nexusMapFile.close();
+ for (int nexLineNum = 0; nexLineNum < nexLines.size(); ++nexLineNum) {
+ const auto& nexLine = nexLines[nexLineNum];
+ if (nexLine.isEmpty()) {
+ continue;
+ }
+
QList<QByteArray> nexCells = nexLine.split('|');
if (nexCells.count() == 3) {
std::vector<NexusCategory> nexusCats;
@@ -129,12 +136,11 @@ void CategoryFactory::loadCategories()
m_NexusMap.insert_or_assign(nexID, NexusCategory(nexName, nexID));
m_NexusMap.at(nexID).setCategoryID(catID);
} else {
- log::error(tr("invalid nexus category line {0}: {1} ({2} cells)"), lineNum,
+ log::error(tr("invalid nexus category line {0}: {1} ({2} cells)"), nexLineNum,
nexLine.constData(), nexCells.count());
}
}
}
- nexusMapFile.close();
}
std::sort(m_Categories.begin(), m_Categories.end());
setParents();
diff --git a/src/loot.cpp b/src/loot.cpp
index a888b577..6159521b 100644
--- a/src/loot.cpp
+++ b/src/loot.cpp
@@ -732,6 +732,7 @@ void Loot::processReport(Report& r) const
QJsonParseError e;
const QJsonDocument doc = QJsonDocument::fromJson(reportFile.readAll(), &e);
+ reportFile.close();
if (doc.isNull()) {
emit log(MOBase::log::Error,
QString("invalid json, %1 (error %2)").arg(e.errorString()).arg(e.error));
@@ -776,22 +777,27 @@ const QString Loot::getSortedPluginListMarkdown() const
log::debug("parsing sorted plugin list at '{}'", SortedPluginListPath);
QFile pluginListFile(SortedPluginListPath);
- if (!pluginListFile.open(QIODevice::ReadOnly)) {
+ if (!pluginListFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
emit log(MOBase::log::Error, QString("failed to open file, %1 (error %2)")
.arg(pluginListFile.errorString())
.arg(pluginListFile.error()));
return {};
}
- // skip "# This file was automatically generated by Mod Organizer"
- pluginListFile.readLine();
-
QString markdown = "### " + tr("Sorted plugins") + "\n<details><summary>" +
tr("Show") + "</summary>\n\n";
- const auto pluginList = m_core.pluginList();
- while (!pluginListFile.atEnd()) {
- const QString pluginName = QString::fromUtf8(pluginListFile.readLine().trimmed());
+ const auto pluginList = m_core.pluginList();
+ const QByteArray contents = pluginListFile.readAll();
+ pluginListFile.close();
+
+ for (const QString& line :
+ QString::fromUtf8(contents).split('\n', Qt::SkipEmptyParts)) {
+ if (line.at(0) == '#') {
+ continue;
+ }
+
+ const QString pluginName = line.trimmed();
const bool active = pluginList->isEnabled(pluginName);
const QString prefix = active ? " - [x] " : " - [ ] ";
markdown += prefix + pluginName + "\n";
@@ -799,7 +805,6 @@ const QString Loot::getSortedPluginListMarkdown() const
markdown += "</details>\n";
- pluginListFile.close();
return markdown;
}
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 27ab9713..cd859a3e 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -1573,11 +1573,15 @@ std::vector<QString> OrganizerCore::enabledArchives()
std::vector<QString> result;
if (settings().archiveParsing()) {
QFile archiveFile(m_CurrentProfile->getArchivesFileName());
- if (archiveFile.open(QIODevice::ReadOnly)) {
- while (!archiveFile.atEnd()) {
- result.push_back(QString::fromUtf8(archiveFile.readLine()).trimmed());
- }
+ if (archiveFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ const QByteArray contents = archiveFile.readAll();
archiveFile.close();
+ const QStringList lines =
+ QString::fromUtf8(contents).split('\n', Qt::SkipEmptyParts);
+ result.reserve(lines.size());
+ for (const QString& line : lines) {
+ result.emplace_back(line.trimmed());
+ }
}
}
return result;
diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp
index d70bdc72..8bdb41a5 100644
--- a/src/plugincontainer.cpp
+++ b/src/plugincontainer.cpp
@@ -1084,13 +1084,14 @@ void PluginContainer::loadPlugins()
loadCheck.setFileName(qApp->property("dataPath").toString() +
"/plugin_loadcheck.tmp");
- if (loadCheck.exists() && loadCheck.open(QIODevice::ReadOnly)) {
+ if (loadCheck.exists() && loadCheck.open(QIODevice::ReadOnly | QIODevice::Text)) {
// oh, there was a failed plugin load last time. Find out which plugin was loaded
// last
- QString fileName;
- while (!loadCheck.atEnd()) {
- fileName = QString::fromUtf8(loadCheck.readLine().constData()).trimmed();
- }
+ const auto contents = loadCheck.readAll();
+ loadCheck.close();
+
+ const auto fileName =
+ QString::fromUtf8(contents).split('\n', Qt::SkipEmptyParts).last().trimmed();
log::warn("loadcheck file found for plugin '{}'", fileName);
@@ -1130,8 +1131,6 @@ void PluginContainer::loadPlugins()
log::warn("user wants to load plugin '{}' anyway", fileName);
break;
}
-
- loadCheck.close();
}
loadCheck.open(QIODevice::WriteOnly);
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index 6b4c9281..021b5f5b 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -704,10 +704,11 @@ void PluginList::readLockedOrderFrom(const QString& fileName)
return;
}
- file.open(QIODevice::ReadOnly);
+ file.open(QIODevice::ReadOnly | QIODevice::Text);
+ const QByteArray contents = file.readAll();
+ file.close();
int lineNumber = 0;
- while (!file.atEnd()) {
- QByteArray line = file.readLine();
+ for (const QByteArray& line : contents.split('\n')) {
++lineNumber;
// Skip empty lines or commented out lines (#)
@@ -782,8 +783,7 @@ void PluginList::readLockedOrderFrom(const QString& fileName)
m_LockedOrder[pluginName] = priority;
continue;
}
- } /* while (!file.atEnd()) */
- file.close();
+ }
}
void PluginList::writeLockedOrder(const QString& fileName) const
diff --git a/src/profile.cpp b/src/profile.cpp
index 2d8247a7..001c9816 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -333,7 +333,7 @@ void Profile::renameModInAllProfiles(const QString& oldName, const QString& newN
void Profile::renameModInList(QFile& modList, const QString& oldName,
const QString& newName)
{
- if (!modList.open(QIODevice::ReadOnly)) {
+ if (!modList.open(QIODevice::ReadOnly | QIODevice::Text)) {
reportError(tr("failed to open %1").arg(modList.fileName()));
return;
}
@@ -342,10 +342,12 @@ void Profile::renameModInList(QFile& modList, const QString& oldName,
outBuffer.open(QIODevice::WriteOnly);
int renamed = 0;
- while (!modList.atEnd()) {
- QByteArray line = modList.readLine();
-
- if (line.length() == 0) {
+ // trim empty line at the end which should not log a warning about invalid data
+ const QByteArray contents = modList.readAll().trimmed();
+ modList.close();
+ // modList is CRLF, but the QIODevice::Text flag translates all line breaks to LF
+ for (const QByteArray& line : contents.split('\n')) {
+ if (line.isEmpty()) {
// ignore empty lines
log::warn("mod list contained invalid data: empty line");
continue;
@@ -374,7 +376,6 @@ void Profile::renameModInList(QFile& modList, const QString& oldName,
outBuffer.write(qUtf8Printable(modName));
outBuffer.write("\r\n");
}
- modList.close();
if (renamed) {
modList.open(QIODevice::WriteOnly);
@@ -438,14 +439,14 @@ void Profile::refreshModStatus()
bool warnAboutOverwrite = false;
// load mods from file and update enabled state and priority for them
- int index = 0;
- while (!file.atEnd()) {
- QByteArray line = file.readLine().trimmed();
-
+ int index = 0;
+ const QByteArray contents = file.readAll();
+ file.close();
+ for (QByteArray& line : contents.split('\n')) {
// find the mod name and the enabled status
bool enabled = true;
QString modName;
- if (line.length() == 0) {
+ if (line.isEmpty()) {
// empty line
continue;
} else if (line.at(0) == '#') {
@@ -498,10 +499,7 @@ void Profile::refreshModStatus()
// need to rewrite the modlist to fix this
modStatusModified = true;
}
-
- } // while (!file.atEnd())
-
- file.close();
+ }
const int numKnownMods = index;
int topInsert = 0;