From 52e65c9f38ed53f0fb30dc084f7f36e22fa752b8 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 26 Mar 2026 17:16:19 +0200 Subject: [PATCH] libcamera: value_node: Add functions to erase child nodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There will be a need to erase child nodes when implementing support for overriding configuration options. Add two erase() functions to the ValueNode class, mimicking the add() API. More erase() overloads could be added, for instance taking iterators as parameters, to improve efficiency. This should be considered later, when usage of the ValueNode class will expand, based on the actual usage patterns. Signed-off-by: Laurent Pinchart Reviewed-by: Isaac Scott Reviewed-by: Barnabás Pőcze --- include/libcamera/internal/value_node.h | 3 ++ src/libcamera/value_node.cpp | 54 +++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/include/libcamera/internal/value_node.h b/include/libcamera/internal/value_node.h index ccae69e2..cab14943 100644 --- a/include/libcamera/internal/value_node.h +++ b/include/libcamera/internal/value_node.h @@ -244,6 +244,9 @@ public: ValueNode *add(std::initializer_list path, std::unique_ptr &&child); + void erase(std::string_view key); + void erase(std::initializer_list path); + private: LIBCAMERA_DISABLE_COPY_AND_MOVE(ValueNode) diff --git a/src/libcamera/value_node.cpp b/src/libcamera/value_node.cpp index e1c0c37a..bb641ab6 100644 --- a/src/libcamera/value_node.cpp +++ b/src/libcamera/value_node.cpp @@ -622,4 +622,58 @@ ValueNode *ValueNode::add(std::initializer_list path, return node; } +/** + * \brief Erase a child node in a dictionary + * \param[in] key The dictionary key + * + * Erase the child node referenced by \a key in a dictionary node. If the \a + * key does not exist, or if this node is not a dictionary, the function + * returns without performing any operation. + */ +void ValueNode::erase(std::string_view key) +{ + auto node = dictionary_.find(key); + if (node == dictionary_.end()) + return; + + /* \todo Not an ideal algorithm */ + for (auto iter = list_.begin(); iter != list_.end(); ++iter) { + if (iter->value.get() != node->second) + continue; + + list_.erase(iter); + break; + } + + dictionary_.erase(node); +} + +/** + * \brief Erase the child node at the given path + * \param[in] path The path + * + * Erase the child node at the given \a path. If no child node exists for the + * path, the function returns without performing any operation. + */ +void ValueNode::erase(std::initializer_list path) +{ + if (!path.size()) + return; + + ValueNode *node = this; + + for (const auto [i, name] : utils::enumerate(path)) { + if (i == path.size() - 1) { + node->erase(name); + return; + } + + auto iter = node->dictionary_.find(name); + if (iter == node->dictionary_.end()) + return; + + node = iter->second; + } +} + } /* namespace libcamera */