-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Wrap GKeyFile from glib which used for parsing ini-like config file. Log:
- Loading branch information
Showing
3 changed files
with
197 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. | ||
* | ||
* SPDX-License-Identifier: LGPL-3.0-or-later | ||
*/ | ||
|
||
#include "linglong/utils/gkeyfile_wrapper.h" | ||
|
||
namespace linglong::utils { | ||
|
||
const GKeyFileWrapper::GroupName GKeyFileWrapper::DesktopEntry = "Desktop Entry"; | ||
const GKeyFileWrapper::GroupName GKeyFileWrapper::DBusService = "D-BUS Service"; | ||
const GKeyFileWrapper::GroupName GKeyFileWrapper::SystemdService = "Service"; | ||
const GKeyFileWrapper::GroupName GKeyFileWrapper::ContextMenu = "Menu Entry"; | ||
|
||
} // namespace linglong::utils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. | ||
* | ||
* SPDX-License-Identifier: LGPL-3.0-or-later | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "linglong/utils/error/error.h" | ||
|
||
#include <glib.h> | ||
#include <tl/expected.hpp> | ||
|
||
#include <QFile> | ||
#include <QString> | ||
|
||
|
||
namespace linglong::utils { | ||
|
||
class GKeyFileWrapper final | ||
{ | ||
// constructors | ||
public: | ||
GKeyFileWrapper(GKeyFileWrapper &&) = default; | ||
GKeyFileWrapper(const GKeyFileWrapper &) = delete; | ||
auto operator=(GKeyFileWrapper &&) -> GKeyFileWrapper & = default; | ||
auto operator=(const GKeyFileWrapper &) -> GKeyFileWrapper & = delete; | ||
~GKeyFileWrapper() = default; | ||
|
||
static auto New(const QString &filePath) -> error::Result<GKeyFileWrapper> | ||
{ | ||
LINGLONG_TRACE(QString("create GKeyFileWrapper for %1").arg(filePath)); | ||
|
||
auto desktopEntryFile = QFile(filePath); | ||
if (!desktopEntryFile.exists()) { | ||
return LINGLONG_ERR("no such file"); | ||
} | ||
|
||
g_autoptr(GError) gErr = nullptr; | ||
GKeyFileWrapper entry; | ||
g_key_file_load_from_file(entry.gKeyFile.get(), | ||
filePath.toLocal8Bit().constData(), | ||
G_KEY_FILE_KEEP_TRANSLATIONS, | ||
&gErr); | ||
if (gErr != nullptr) { | ||
return LINGLONG_ERR("g_key_file_load_from_file", gErr); | ||
} | ||
|
||
return entry; | ||
} | ||
|
||
private: | ||
GKeyFileWrapper() | ||
: gKeyFile(std::unique_ptr<GKeyFile, decltype(&g_key_file_free)>(g_key_file_new(), | ||
g_key_file_free)){}; | ||
|
||
// types | ||
public: | ||
using GroupName = QString; | ||
|
||
public: | ||
static const GroupName DesktopEntry; | ||
static const GroupName DBusService; | ||
static const GroupName SystemdService; | ||
static const GroupName ContextMenu; | ||
|
||
// data members | ||
private: | ||
std::unique_ptr<GKeyFile, decltype(&g_key_file_free)> gKeyFile; | ||
|
||
// methods | ||
public: | ||
template<typename Value> | ||
void setValue(const QString &key, const Value &value, const GroupName &group); | ||
|
||
template<typename Value> | ||
auto getValue(const QString &key, const GroupName &group) const -> error::Result<Value>; | ||
|
||
auto getGroups() -> QStringList | ||
{ | ||
gsize length = 0; | ||
g_auto(GStrv) groups = g_key_file_get_groups(this->gKeyFile.get(), &length); | ||
|
||
QStringList result; | ||
for (gsize i = 0; i < length; i++) { | ||
auto group = groups[i]; // NOLINT | ||
result << group; | ||
} | ||
|
||
return result; | ||
} | ||
|
||
auto getkeys(const QString &group) -> error::Result<QStringList> | ||
{ | ||
LINGLONG_TRACE("get keys from " + group); | ||
|
||
g_autoptr(GError) gErr = nullptr; | ||
gsize length; | ||
g_auto(GStrv) keys = g_key_file_get_keys(this->gKeyFile.get(), | ||
group.toLocal8Bit().constData(), | ||
&length, | ||
&gErr); | ||
if (gErr != nullptr) { | ||
return LINGLONG_ERR("g_key_file_get_keys", gErr); | ||
} | ||
|
||
QStringList result; | ||
for (gsize i = 0; i < length; i++) { | ||
auto key = keys[i]; // NOLINT | ||
result << key; | ||
} | ||
|
||
return result; | ||
} | ||
|
||
auto saveToFile(const QString &filepath) -> error::Result<void> | ||
{ | ||
LINGLONG_TRACE(QString("save to %1").arg(filepath)); | ||
|
||
g_autoptr(GError) gErr = nullptr; | ||
|
||
g_key_file_save_to_file(this->gKeyFile.get(), filepath.toLocal8Bit().constData(), &gErr); | ||
if (gErr != nullptr) { | ||
return LINGLONG_ERR("g_key_file_save_to_file", gErr); | ||
} | ||
|
||
return LINGLONG_OK; | ||
} | ||
|
||
auto hasKey(const QString &key, const GroupName &group) -> error::Result<bool> | ||
{ | ||
LINGLONG_TRACE(QString("check %1 is in %2 or not").arg(key).arg(group)); | ||
|
||
g_autoptr(GError) gErr = nullptr; | ||
if (!g_key_file_has_key(this->gKeyFile.get(), | ||
group.toLocal8Bit().constData(), | ||
key.toLocal8Bit().constData(), | ||
&gErr)) { | ||
if (gErr != nullptr) { | ||
return LINGLONG_ERR("g_key_file_has_key", gErr); | ||
} | ||
return false; | ||
} | ||
return true; | ||
} | ||
}; | ||
|
||
template<> | ||
inline void GKeyFileWrapper::setValue(const QString &key, | ||
const QString &value, | ||
const GroupName &group) | ||
{ | ||
g_key_file_set_string(this->gKeyFile.get(), | ||
group.toLocal8Bit().constData(), | ||
key.toLocal8Bit().constData(), | ||
value.toLocal8Bit().constData()); | ||
} | ||
|
||
template<> | ||
[[nodiscard]] inline auto GKeyFileWrapper::getValue( | ||
const QString &key, const GroupName &group) const -> error::Result<QString> | ||
{ | ||
LINGLONG_TRACE(QString("get %1 from %2").arg(key, group)); | ||
|
||
g_autoptr(GError) gErr = nullptr; | ||
|
||
g_autofree gchar *value = g_key_file_get_string(this->gKeyFile.get(), | ||
group.toLocal8Bit().constData(), | ||
key.toLocal8Bit().constData(), | ||
&gErr); | ||
|
||
if (gErr != nullptr) { | ||
return LINGLONG_ERR("g_key_file_get_string", gErr); | ||
} | ||
|
||
return value; | ||
} | ||
|
||
} // namespace linglong::utils |