| Message ID | 20260423230059.3180987-21-laurent.pinchart@ideasonboard.com |
|---|---|
| State | Accepted |
| Headers | show |
| Series |
|
| Related | show |
2026. 04. 24. 1:00 keltezéssel, Laurent Pinchart írta: > 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 <laurent.pinchart@ideasonboard.com> > Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com> > --- > Changes since v2: > > - Use std::string_view() for first overload > - Add todo comment > --- Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> > 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 ccae69e25a82..cab14943c03f 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<std::string_view> path, > std::unique_ptr<ValueNode> &&child); > > + void erase(std::string_view key); > + void erase(std::initializer_list<std::string_view> path); > + > private: > LIBCAMERA_DISABLE_COPY_AND_MOVE(ValueNode) > > diff --git a/src/libcamera/value_node.cpp b/src/libcamera/value_node.cpp > index 6ab11009fccc..2c875db366e7 100644 > --- a/src/libcamera/value_node.cpp > +++ b/src/libcamera/value_node.cpp > @@ -620,4 +620,58 @@ ValueNode *ValueNode::add(std::initializer_list<std::string_view> 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<std::string_view> 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 */ > -- > Regards, > > Laurent Pinchart >
diff --git a/include/libcamera/internal/value_node.h b/include/libcamera/internal/value_node.h index ccae69e25a82..cab14943c03f 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<std::string_view> path, std::unique_ptr<ValueNode> &&child); + void erase(std::string_view key); + void erase(std::initializer_list<std::string_view> path); + private: LIBCAMERA_DISABLE_COPY_AND_MOVE(ValueNode) diff --git a/src/libcamera/value_node.cpp b/src/libcamera/value_node.cpp index 6ab11009fccc..2c875db366e7 100644 --- a/src/libcamera/value_node.cpp +++ b/src/libcamera/value_node.cpp @@ -620,4 +620,58 @@ ValueNode *ValueNode::add(std::initializer_list<std::string_view> 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<std::string_view> 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 */