From b77fb059083ba04a3ccbc1b6e9ce4f5353b200ad Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 13 Jun 2023 21:07:05 +0300 Subject: [PATCH] Added back the INIFile read function Signed-off-by: Trial97 --- launcher/settings/INIFile.cpp | 85 +++++++++++++++++++++++++++++++---- tests/INIFile_test.cpp | 56 +++++++++++++++-------- 2 files changed, 115 insertions(+), 26 deletions(-) diff --git a/launcher/settings/INIFile.cpp b/launcher/settings/INIFile.cpp index f0347cabf..cb909ae75 100644 --- a/launcher/settings/INIFile.cpp +++ b/launcher/settings/INIFile.cpp @@ -45,12 +45,12 @@ #include -INIFile::INIFile() -{ -} +INIFile::INIFile() {} bool INIFile::saveFile(QString fileName) { + if (!contains("ConfigVersion")) + insert("ConfigVersion", "1.1"); QSettings _settings_obj{ fileName, QSettings::Format::IniFormat }; _settings_obj.setFallbacksEnabled(false); @@ -71,6 +71,67 @@ bool INIFile::saveFile(QString fileName) return true; } +QString unescape(QString orig) +{ + QString out; + QChar prev = QChar::Null; + for (auto c : orig) { + if (prev == '\\') { + if (c == 'n') + out += '\n'; + else if (c == 't') + out += '\t'; + else if (c == '#') + out += '#'; + else + out += c; + prev = QChar::Null; + } else { + if (c == '\\') { + prev = c; + continue; + } + out += c; + prev = QChar::Null; + } + } + return out; +} +bool parseOldFileFormat(QIODevice& device, QSettings::SettingsMap& map) +{ + QTextStream in(device.readAll()); +#if QT_VERSION <= QT_VERSION_CHECK(6, 0, 0) + in.setCodec("UTF-8"); +#endif + + QStringList lines = in.readAll().split('\n'); + for (int i = 0; i < lines.count(); i++) { + QString& lineRaw = lines[i]; + // Ignore comments. + int commentIndex = 0; + QString line = lineRaw; + // Search for comments until no more escaped # are available + while ((commentIndex = line.indexOf('#', commentIndex + 1)) != -1) { + if (commentIndex > 0 && line.at(commentIndex - 1) == '\\') { + continue; + } + line = line.left(lineRaw.indexOf('#')).trimmed(); + } + + int eqPos = line.indexOf('='); + if (eqPos == -1) + continue; + QString key = line.left(eqPos).trimmed(); + QString valueStr = line.right(line.length() - eqPos - 1).trimmed(); + + valueStr = unescape(valueStr); + + QVariant value(valueStr); + map.insert(key, value); + } + + return true; +} bool INIFile::loadFile(QString fileName) { @@ -84,10 +145,19 @@ bool INIFile::loadFile(QString fileName) qCritical() << "A format error occurred (e.g. loading a malformed INI file)."; return false; } - - for (auto&& key : _settings_obj.allKeys()) - insert(key, _settings_obj.value(key)); - + if (!_settings_obj.value("ConfigVersion").isValid()) { + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) + return false; + QSettings::SettingsMap map; + parseOldFileFormat(file, map); + file.close(); + for (auto&& key : map.keys()) + insert(key, map.value(key)); + insert("ConfigVersion", "1.1"); + } else + for (auto&& key : _settings_obj.allKeys()) + insert(key, _settings_obj.value(key)); return true; } @@ -103,4 +173,3 @@ void INIFile::set(QString key, QVariant val) { this->operator[](key) = val; } - diff --git a/tests/INIFile_test.cpp b/tests/INIFile_test.cpp index 4be8133c0..2f49e573d 100644 --- a/tests/INIFile_test.cpp +++ b/tests/INIFile_test.cpp @@ -1,24 +1,16 @@ #include +#include #include #include -#include #include -class IniFileTest : public QObject -{ +class IniFileTest : public QObject { Q_OBJECT -private -slots: - void initTestCase() - { - - } - void cleanupTestCase() - { - - } + private slots: + void initTestCase() {} + void cleanupTestCase() {} void test_Escape_data() { @@ -47,17 +39,17 @@ slots: // load INIFile f2; f2.loadFile(filename); - QCOMPARE(f2.get("a","NOT SET").toString(), a); - QCOMPARE(f2.get("b","NOT SET").toString(), b); + QCOMPARE(f2.get("a", "NOT SET").toString(), a); + QCOMPARE(f2.get("b", "NOT SET").toString(), b); } void test_SaveLoadLists() { QString slist_strings = "(\"a\",\"b\",\"c\")"; - QStringList list_strings = {"a", "b", "c"}; + QStringList list_strings = { "a", "b", "c" }; QString slist_numbers = "(1,2,3,10)"; - QList list_numbers = {1, 2, 3, 10}; + QList list_numbers = { 1, 2, 3, 10 }; QString filename = "test_SaveLoadLists.ini"; @@ -72,13 +64,41 @@ slots: QStringList out_list_strings = f2.get("list_strings", QStringList()).toStringList(); qDebug() << "OutStringList" << out_list_strings; - + QList out_list_numbers = QVariantUtils::toList(f2.get("list_numbers", QVariantUtils::fromList(QList()))); qDebug() << "OutNumbersList" << out_list_numbers; QCOMPARE(out_list_strings, list_strings); QCOMPARE(out_list_numbers, list_numbers); } + + void test_SaveAleardyExistingFile() + { + QString fileName = "test_SaveAleardyExistingFile.ini"; + QString fileContent = R"(InstanceType=OneSix +iconKey=vanillia_icon +name=Minecraft Vanillia +OverrideCommands=true +PreLaunchCommand="$INST_JAVA" -jar packwiz-installer-bootstrap.jar link +)"; + QFile file(fileName); + + if (file.open(QFile::WriteOnly | QFile::Text)) { + QTextStream stream(&file); + stream << fileContent; + file.close(); + } + + // load + INIFile f1; + f1.loadFile(fileName); + QCOMPARE(f1.get("PreLaunchCommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link"); + f1.saveFile(fileName); + INIFile f2; + f2.loadFile(fileName); + QCOMPARE(f2.get("PreLaunchCommand", "NOT SET").toString(), "\"$INST_JAVA\" -jar packwiz-installer-bootstrap.jar link"); + QCOMPARE(f2.get("ConfigVersion", "NOT SET").toString(), "1.1"); + } }; QTEST_GUILESS_MAIN(IniFileTest)