aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/module/GlobalRegisterTable.cpp
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2024-04-14 12:56:18 +0000
committersaturneric <[email protected]>2024-04-14 12:56:18 +0000
commitcb2672ca430c54244df7bd46ef97256c3d840cbf (patch)
treea54bb28d61cf9dbf608261782c4f3febec72ea8c /src/core/module/GlobalRegisterTable.cpp
parentfix: use qt designer placeholder instead of custom initialized (diff)
downloadGpgFrontend-cb2672ca430c54244df7bd46ef97256c3d840cbf.tar.gz
GpgFrontend-cb2672ca430c54244df7bd46ef97256c3d840cbf.zip
feat: add a grt viewer and solve some issues in gnupg info tab
Diffstat (limited to 'src/core/module/GlobalRegisterTable.cpp')
-rw-r--r--src/core/module/GlobalRegisterTable.cpp238
1 files changed, 208 insertions, 30 deletions
diff --git a/src/core/module/GlobalRegisterTable.cpp b/src/core/module/GlobalRegisterTable.cpp
index c16eba37..006118b3 100644
--- a/src/core/module/GlobalRegisterTable.cpp
+++ b/src/core/module/GlobalRegisterTable.cpp
@@ -31,10 +31,10 @@
#include <any>
#include <optional>
#include <shared_mutex>
-#include <sstream>
-#include <unordered_map>
+#include <utility>
#include <vector>
+#include "GlobalRegisterTableTreeModel.h"
#include "function/SecureMemoryAllocator.h"
#include "utils/MemoryUtils.h"
@@ -43,33 +43,45 @@ namespace GpgFrontend::Module {
class GlobalRegisterTable::Impl {
public:
struct RTNode {
- std::optional<std::any> value = std::nullopt;
- std::unordered_map<QString, SecureUniquePtr<RTNode>> children;
+ QString name;
+ QString type = "NODE";
int version = 0;
- const std::type_info* type = nullptr;
+ const std::type_info* value_type = nullptr;
+ std::optional<std::any> value = std::nullopt;
+ QMap<QString, QSharedPointer<RTNode>> children;
+ QWeakPointer<RTNode> parent;
+
+ explicit RTNode(QString name, const QSharedPointer<RTNode>& parent)
+ : name(std::move(name)), parent(parent) {}
};
- explicit Impl(GlobalRegisterTable* parent) : parent_(parent) {}
+ using RTNodePtr = QSharedPointer<RTNode>;
+
+ explicit Impl(GlobalRegisterTable* parent)
+ : parent_(parent),
+ root_node_(SecureCreateQSharedObject<RTNode>("", nullptr)) {}
auto PublishKV(const Namespace& n, const Key& k, std::any v) -> bool {
- QStringList const segments = k.split('.');
+ QStringList const segments = (n + "." + k).split('.');
int version = 0;
{
std::unique_lock lock(lock_);
- auto& root_rt_node =
- global_register_table_.emplace(n, SecureCreateUniqueObject<RTNode>())
- .first->second;
- RTNode* current = root_rt_node.get();
+ auto current = root_node_;
for (const QString& segment : segments) {
- current = current->children
- .emplace(segment, SecureCreateUniqueObject<RTNode>())
- .first->second.get();
+ auto it = current->children.find(segment);
+ if (it == current->children.end()) {
+ it = current->children.insert(
+ segment, SecureCreateQSharedObject<RTNode>(segment, current));
+ }
+ current = it.value();
}
+ current->name = segments.back();
+ current->type = "LEAF";
current->value = v;
- current->type = &v.type();
+ current->value_type = &v.type();
version = ++current->version;
}
@@ -78,19 +90,17 @@ class GlobalRegisterTable::Impl {
}
auto LookupKV(const Namespace& n, const Key& k) -> std::optional<std::any> {
- QStringList const segments = k.split('.');
+ QStringList const segments = (n + "." + k).split('.');
std::optional<std::any> rtn = std::nullopt;
{
std::shared_lock const lock(lock_);
- auto it = global_register_table_.find(n);
- if (it == global_register_table_.end()) return std::nullopt;
- RTNode* current = it->second.get();
+ auto current = root_node_;
for (const QString& segment : segments) {
auto it = current->children.find(segment);
if (it == current->children.end()) return std::nullopt;
- current = it->second.get();
+ current = it.value();
}
rtn = current->value;
}
@@ -98,24 +108,20 @@ class GlobalRegisterTable::Impl {
}
auto ListChildKeys(const Namespace& n, const Key& k) -> std::vector<Key> {
- QStringList const segments = k.split('.');
+ QStringList const segments = (n + "." + k).split('.');
std::vector<Key> rtn;
{
std::shared_lock lock(lock_);
- auto it = global_register_table_.find(n);
- if (it == global_register_table_.end()) return {};
- RTNode* current = it->second.get();
+ auto current = root_node_;
for (const QString& segment : segments) {
auto it = current->children.find(segment);
if (it == current->children.end()) return {};
- current = it->second.get();
+ current = it.value();
}
- for (auto& it : current->children) {
- rtn.emplace_back(it.first);
- }
+ for (auto& key : current->children.keys()) rtn.emplace_back(key);
}
return rtn;
}
@@ -132,12 +138,149 @@ class GlobalRegisterTable::Impl {
}) == nullptr;
}
+ auto RootRTNode() -> RTNode* { return root_node_.get(); }
+
private:
- using Table = std::map<Namespace, SecureUniquePtr<RTNode>>;
std::shared_mutex lock_;
GlobalRegisterTable* parent_;
- Table global_register_table_;
+ RTNodePtr root_node_;
+};
+
+class GlobalRegisterTableTreeModel::Impl {
+ public:
+ using RTNode = GlobalRegisterTable::Impl::RTNode;
+
+ Impl(GlobalRegisterTableTreeModel* parent, GlobalRegisterTable::Impl* grt)
+ : parent_(parent), root_node_(grt->RootRTNode()) {}
+
+ [[nodiscard]] auto RowCount(const QModelIndex& parent) const -> int {
+ auto* parent_node = !parent.isValid()
+ ? root_node_.get()
+ : static_cast<RTNode*>(parent.internalPointer());
+ return parent_node->children.size();
+ }
+
+ [[nodiscard]] auto ColumnCount(const QModelIndex& parent) const -> int {
+ return 4;
+ }
+
+ [[nodiscard]] auto Data(const QModelIndex& index, int role) const
+ -> QVariant {
+ if (!index.isValid()) return {};
+
+ if (role == Qt::DisplayRole) {
+ auto* node = static_cast<RTNode*>(index.internalPointer());
+ switch (index.column()) {
+ case 0:
+ return node->name;
+ case 1:
+ return node->type;
+ case 2:
+ return QString(node->value && node->value.has_value()
+ ? node->value->type().name()
+ : "");
+ case 3:
+ return Any2QVariant(node->value);
+ default:
+ return {};
+ }
+ }
+ return {};
+ }
+
+ static auto Any2QVariant(std::optional<std::any> op) -> QVariant {
+ if (!op) return "<EMPTY>";
+
+ auto& o = op.value();
+ if (o.type() == typeid(QString)) {
+ return QVariant::fromValue(std::any_cast<QString>(o));
+ }
+ if (o.type() == typeid(std::string)) {
+ return QVariant::fromValue(
+ QString::fromStdString(std::any_cast<std::string>(o)));
+ }
+ if (o.type() == typeid(int)) {
+ return QVariant::fromValue(std::any_cast<int>(o));
+ }
+ if (o.type() == typeid(long)) {
+ return QVariant::fromValue(
+ static_cast<qlonglong>(std::any_cast<long>(o)));
+ }
+ if (o.type() == typeid(long long)) {
+ return QVariant::fromValue(std::any_cast<long long>(o));
+ }
+ if (o.type() == typeid(unsigned)) {
+ return QVariant::fromValue(std::any_cast<unsigned>(o));
+ }
+ if (o.type() == typeid(unsigned long)) {
+ return QVariant::fromValue(
+ static_cast<qulonglong>(std::any_cast<unsigned long>(o)));
+ }
+ if (o.type() == typeid(unsigned long long)) {
+ return QVariant::fromValue(std::any_cast<unsigned long long>(o));
+ }
+ if (o.type() == typeid(float)) {
+ return QVariant::fromValue(std::any_cast<float>(o));
+ }
+ if (o.type() == typeid(double)) {
+ return QVariant::fromValue(std::any_cast<double>(o));
+ }
+ if (o.type() == typeid(bool)) {
+ return QVariant::fromValue(std::any_cast<bool>(o));
+ }
+ return "<UNSUPPORTED>";
+ }
+
+ [[nodiscard]] auto Index(int row, int column, const QModelIndex& parent) const
+ -> QModelIndex {
+ if (!parent_->hasIndex(row, column, parent)) return {};
+
+ auto* parent_node = !parent.isValid()
+ ? root_node_.get()
+ : static_cast<RTNode*>(parent.internalPointer());
+ auto key = parent_node->children.keys().at(row);
+ auto child_node = parent_node->children.value(key);
+ return parent_->createIndex(row, column, child_node.get());
+ }
+
+ [[nodiscard]] auto Parent(const QModelIndex& index) const -> QModelIndex {
+ if (!index.isValid()) return {};
+
+ auto* child_node = static_cast<RTNode*>(index.internalPointer());
+ auto parent_node = child_node->parent.lock();
+
+ if (!parent_node || parent_node == root_node_) return {};
+
+ int row =
+ parent_node->parent.lock()->children.keys().indexOf(parent_node->name);
+ return parent_->createIndex(row, 0, parent_node.data());
+ }
+
+ [[nodiscard]] static auto HeaderData(int section, Qt::Orientation orientation,
+ int role) -> QVariant {
+ if (role != Qt::DisplayRole) return QVariant();
+
+ if (orientation == Qt::Horizontal) {
+ switch (section) {
+ case 0:
+ return QString("Key");
+ case 1:
+ return QString("Type");
+ case 2:
+ return QString("Value Type");
+ case 3:
+ return QString("Value");
+ default:
+ return {};
+ }
+ }
+ return {};
+ }
+
+ private:
+ GlobalRegisterTableTreeModel* parent_;
+ GlobalRegisterTable::Impl::RTNodePtr root_node_;
};
GlobalRegisterTable::GlobalRegisterTable()
@@ -164,4 +307,39 @@ auto GlobalRegisterTable::ListChildKeys(Namespace n, Key k)
return p_->ListChildKeys(n, k);
}
+GlobalRegisterTableTreeModel::GlobalRegisterTableTreeModel(
+ GlobalRegisterTable* grt)
+ : p_(SecureCreateUniqueObject<Impl>(this, grt->p_.get())) {}
+
+auto GlobalRegisterTableTreeModel::rowCount(const QModelIndex& parent) const
+ -> int {
+ return p_->RowCount(parent);
+}
+
+auto GlobalRegisterTableTreeModel::columnCount(const QModelIndex& parent) const
+ -> int {
+ return p_->ColumnCount(parent);
+}
+
+auto GlobalRegisterTableTreeModel::data(const QModelIndex& index,
+ int role) const -> QVariant {
+ return p_->Data(index, role);
+}
+
+auto GlobalRegisterTableTreeModel::index(int row, int column,
+ const QModelIndex& parent) const
+ -> QModelIndex {
+ return p_->Index(row, column, parent);
+}
+
+auto GlobalRegisterTableTreeModel::parent(const QModelIndex& index) const
+ -> QModelIndex {
+ return p_->Parent(index);
+}
+
+auto GlobalRegisterTableTreeModel::headerData(int section,
+ Qt::Orientation orientation,
+ int role) const -> QVariant {
+ return p_->HeaderData(section, orientation, role);
+}
} // namespace GpgFrontend::Module \ No newline at end of file