From e0ba5a6ba2c2b2ba846308ccc2d7f4b8c293feb4 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 3 Sep 2020 20:15:28 +0200 Subject: [PATCH] [libcalamares] Convenience functions for localeConf GS entry --- src/libcalamares/CMakeLists.txt | 1 + src/libcalamares/locale/Global.cpp | 78 ++++++++++++++++++++++++++++ src/libcalamares/locale/Global.h | 82 ++++++++++++++++++++++++++++++ src/libcalamares/locale/Tests.cpp | 71 ++++++++++++++++++++++++++ 4 files changed, 232 insertions(+) create mode 100644 src/libcalamares/locale/Global.cpp create mode 100644 src/libcalamares/locale/Global.h diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index 849896446..be5b252f0 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -39,6 +39,7 @@ set( libSources geoip/Handler.cpp # Locale-data service + locale/Global.cpp locale/Label.cpp locale/LabelModel.cpp locale/Lookup.cpp diff --git a/src/libcalamares/locale/Global.cpp b/src/libcalamares/locale/Global.cpp new file mode 100644 index 000000000..a23a10478 --- /dev/null +++ b/src/libcalamares/locale/Global.cpp @@ -0,0 +1,78 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2020 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + * + */ +#include "Global.h" + +#include "GlobalStorage.h" +#include "utils/Logger.h" + +namespace CalamaresUtils +{ +namespace Locale +{ + +static const char gsKey[] = "localeConf"; + +template < typename T > +void +insertGS( const QMap< QString, T >& values, QVariantMap& localeConf ) +{ + for ( auto it = values.constBegin(); it != values.constEnd(); ++it ) + { + localeConf.insert( it.key(), it.value() ); + } +} + +void +insertGS( Calamares::GlobalStorage& gs, const QMap< QString, QString >& values, InsertMode mode ) +{ + QVariantMap localeConf = mode == InsertMode::Overwrite ? QVariantMap() : gs.value( gsKey ).toMap(); + insertGS( values, localeConf ); + gs.insert( gsKey, localeConf ); +} + +void +insertGS( Calamares::GlobalStorage& gs, const QVariantMap& values, InsertMode mode ) +{ + QVariantMap localeConf = mode == InsertMode::Overwrite ? QVariantMap() : gs.value( gsKey ).toMap(); + insertGS( values, localeConf ); + gs.insert( gsKey, localeConf ); +} + +void +insertGS( Calamares::GlobalStorage& gs, const QString& key, const QString& value ) +{ + QVariantMap localeConf = gs.value( gsKey ).toMap(); + localeConf.insert( key, value ); + gs.insert( gsKey, localeConf ); +} + +void +removeGS( Calamares::GlobalStorage& gs, const QString& key ) +{ + if ( gs.contains( gsKey ) ) + { + QVariantMap localeConf = gs.value( gsKey ).toMap(); + if ( localeConf.contains( key ) ) + { + localeConf.remove( key ); + gs.insert( gsKey, localeConf ); + } + } +} + +void +clearGS( Calamares::GlobalStorage& gs ) +{ + gs.remove( gsKey ); +} + + +} // namespace Locale +} // namespace CalamaresUtils diff --git a/src/libcalamares/locale/Global.h b/src/libcalamares/locale/Global.h new file mode 100644 index 000000000..56f09ce4c --- /dev/null +++ b/src/libcalamares/locale/Global.h @@ -0,0 +1,82 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2020 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + * + */ + +/** @file GlobalStorage management for Locale settings + * + * The *localeConf* key in Global Storage is semi-structured, + * and there are multiple modules that write to it (and some that + * read from it). Functions in this file provide access to + * that semi-structured data. + */ + +#ifndef LOCALE_GLOBAL_H +#define LOCALE_GLOBAL_H + +#include "DllMacro.h" + +#include +#include +#include + +namespace Calamares +{ +class GlobalStorage; +} + +namespace CalamaresUtils +{ +namespace Locale +{ + +/** @brief Selector for methods that insert multiple values. + * + * When inserting, use @c Overwrite to remove all keys not in the collection + * of values being inserted; use @c Merge to preserve whatever is + * already in Global Storage but not mentioned in the collection. + */ +enum class InsertMode +{ + Overwrite, + Merge +}; + +/** @brief Insert the given @p values into the *localeConf* map in @p gs + * + * @param gs The Global Storage to write to + * @param values The collection of keys and values to write to @p gs + * @param mode Indicates whether the *localeConf* key is cleared first + * + * The keys in the collection @p values should be first-level keys + * in *localeConf*, e.g. "LANG" or "LC_TIME". No effort is made to + * enforce this. + */ +DLLEXPORT void +insertGS( Calamares::GlobalStorage& gs, const QVariantMap& values, InsertMode mode = InsertMode::Merge ); +/** @brief Insert the given @p values into the *localeConf* map in @p gs + * + * Alternate way of providing the keys and values. + */ +DLLEXPORT void insertGS( Calamares::GlobalStorage& gs, + const QMap< QString, QString >& values, + InsertMode mode = InsertMode::Merge ); +/** @brief Write a single @p key and @p value to the *localeConf* map + */ +DLLEXPORT void insertGS( Calamares::GlobalStorage& gs, const QString& key, const QString& value ); +/** @brief Remove a single @p key from the *localeConf* map + */ +DLLEXPORT void removeGS( Calamares::GlobalStorage& gs, const QString& key ); +/** @brief Remove the *localeConf* map from Global Storage + */ +DLLEXPORT void clearGS( Calamares::GlobalStorage& gs ); + +} // namespace Locale +} // namespace CalamaresUtils + +#endif diff --git a/src/libcalamares/locale/Tests.cpp b/src/libcalamares/locale/Tests.cpp index 6e0140e79..b701ce849 100644 --- a/src/libcalamares/locale/Tests.cpp +++ b/src/libcalamares/locale/Tests.cpp @@ -8,11 +8,13 @@ * */ +#include "locale/Global.h" #include "locale/LabelModel.h" #include "locale/TimeZone.h" #include "locale/TranslatableConfiguration.h" #include "CalamaresVersion.h" +#include "GlobalStorage.h" #include "utils/Logger.h" #include @@ -45,6 +47,9 @@ private Q_SLOTS: void testLocationLookup_data(); void testLocationLookup(); void testLocationLookup2(); + + // Global Storage updates + void testGSUpdates(); }; LocaleTests::LocaleTests() {} @@ -446,6 +451,72 @@ LocaleTests::testLocationLookup2() QCOMPARE( trunc( altzone->latitude() * 1000.0 ), -29466 ); } +void +LocaleTests::testGSUpdates() +{ + Calamares::GlobalStorage gs; + + const QString gsKey( "localeConf" ); + + QCOMPARE( gs.value( gsKey ), QVariant() ); + + // Insert one + { + CalamaresUtils::Locale::insertGS( gs, "LANG", "en_US" ); + auto map = gs.value( gsKey ).toMap(); + QCOMPARE( map.count(), 1 ); + QCOMPARE( map.value( "LANG" ).toString(), QString( "en_US" ) ); + } + + // Overwrite one + { + CalamaresUtils::Locale::insertGS( gs, "LANG", "nl_BE" ); + auto map = gs.value( gsKey ).toMap(); + QCOMPARE( map.count(), 1 ); + QCOMPARE( map.value( "LANG" ).toString(), QString( "nl_BE" ) ); + } + + // Insert a second value + { + CalamaresUtils::Locale::insertGS( gs, "LC_TIME", "UTC" ); + auto map = gs.value( gsKey ).toMap(); + QCOMPARE( map.count(), 2 ); + QCOMPARE( map.value( "LANG" ).toString(), QString( "nl_BE" ) ); + QCOMPARE( map.value( "LC_TIME" ).toString(), QString( "UTC" ) ); + } + + // Overwrite parts + { + QMap< QString, QString > kv; + kv.insert( "LANG", "en_SU" ); + kv.insert( "LC_CURRENCY", "rbl" ); + + // Overwrite one, add one + CalamaresUtils::Locale::insertGS( gs, kv, CalamaresUtils::Locale::InsertMode::Merge ); + auto map = gs.value( gsKey ).toMap(); + QCOMPARE( map.count(), 3 ); + QCOMPARE( map.value( "LANG" ).toString(), QString( "en_SU" ) ); + QCOMPARE( map.value( "LC_TIME" ).toString(), QString( "UTC" ) ); // unchanged + QCOMPARE( map.value( "LC_CURRENCY" ).toString(), QString( "rbl" ) ); + } + + // Overwrite with clear + { + QMap< QString, QString > kv; + kv.insert( "LANG", "en_US" ); + kv.insert( "LC_CURRENCY", "peso" ); + + // Overwrite one, add one + CalamaresUtils::Locale::insertGS( gs, kv, CalamaresUtils::Locale::InsertMode::Overwrite ); + auto map = gs.value( gsKey ).toMap(); + QCOMPARE( map.count(), 2 ); // the rest were cleared + QCOMPARE( map.value( "LANG" ).toString(), QString( "en_US" ) ); + QVERIFY( !map.contains( "LC_TIME" ) ); + QCOMPARE( map.value( "LC_TIME" ).toString(), QString() ); // removed + QCOMPARE( map.value( "LC_CURRENCY" ).toString(), QString( "peso" ) ); + } +} + QTEST_GUILESS_MAIN( LocaleTests )