[v2,13/42] libcamera: yaml_parser: Add functions to add children
diff mbox series

Message ID 20260407153427.1825999-14-laurent.pinchart@ideasonboard.com
State New
Headers show
Series
  • libcamera: Global configuration file improvements
Related show

Commit Message

Laurent Pinchart April 7, 2026, 3:33 p.m. UTC
Add YamlObject::add() functions to add children to a list or dictionary
object. This will be used by the YamlParserContext to replace direct
access to YamlObject member variables to decouple the two classes.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
Changes since v1:

- Avoid std::map lookup before insertion in YamlObject::add()
- Don't move child node if add fails
---
 include/libcamera/internal/yaml_parser.h |  5 ++-
 src/libcamera/yaml_parser.cpp            | 55 ++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h
index 0666762308ac..3be61c503c88 100644
--- a/include/libcamera/internal/yaml_parser.h
+++ b/include/libcamera/internal/yaml_parser.h
@@ -28,7 +28,7 @@  class YamlObject
 {
 private:
 	struct Value {
-		Value(std::string &&k, std::unique_ptr<YamlObject> &&v)
+		Value(std::string k, std::unique_ptr<YamlObject> &&v)
 			: key(std::move(k)), value(std::move(v))
 		{
 		}
@@ -197,6 +197,9 @@  public:
 	bool contains(std::string_view key) const;
 	const YamlObject &operator[](std::string_view key) const;
 
+	YamlObject *add(std::unique_ptr<YamlObject> &&child);
+	YamlObject *add(std::string key, std::unique_ptr<YamlObject> &&child);
+
 private:
 	LIBCAMERA_DISABLE_COPY_AND_MOVE(YamlObject)
 
diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp
index 3119ab41d89e..61088c7aed4f 100644
--- a/src/libcamera/yaml_parser.cpp
+++ b/src/libcamera/yaml_parser.cpp
@@ -436,6 +436,61 @@  const YamlObject &YamlObject::operator[](std::string_view key) const
 	return *iter->second;
 }
 
+/**
+ * \brief Add a child object to a list
+ * \param[in] child The child object
+ *
+ * Append the \a child object as the last element of this object's children
+ * list. This object must be empty, in which case it is converted to the
+ * Type::List type, or be a list. Otherwise, the function returns a nullptr and
+ * the \a child is not modified.
+ *
+ * \return A pointer to the child object if successfully added, nullptr
+ * otherwise
+ */
+YamlObject *YamlObject::add(std::unique_ptr<YamlObject> &&child)
+{
+	if (type_ == Type::Empty)
+		type_ = Type::List;
+
+	if (type_ != Type::List)
+		return nullptr;
+
+	Value &elem = list_.emplace_back(std::string{}, std::move(child));
+	return elem.value.get();
+}
+
+/**
+ * \brief Add a child object to a dictionary
+ * \param[in] key The dictionary key
+ * \param[in] child The child object
+ *
+ * Add the \a child object with the given \a key to this object's children. This
+ * object must be empty, in which case it is converted to the Type::Dictionary
+ * type, or be a dictionary. Otherwise, the function returns a nullptr and the
+ * \a child is not modified.
+ *
+ * Keys are unique. If a child with the same \a key already exist, the function
+ * returns a nullptr and the \a child is not modified.
+ *
+ * \return A pointer to the child object if successfully added, nullptr
+ * otherwise
+ */
+YamlObject *YamlObject::add(std::string key, std::unique_ptr<YamlObject> &&child)
+{
+	if (type_ == Type::Empty)
+		type_ = Type::Dictionary;
+
+	if (type_ != Type::Dictionary)
+		return nullptr;
+
+	auto [it, inserted] = dictionary_.try_emplace(std::move(key), child.get());
+	if (!inserted)
+		return nullptr;
+
+	return list_.emplace_back(it->first, std::move(child)).value.get();
+}
+
 #ifndef __DOXYGEN__
 
 class YamlParserContext