| Message ID | 20260423230059.3180987-8-laurent.pinchart@ideasonboard.com |
|---|---|
| State | Accepted |
| Headers | show |
| Series |
|
| Related | show |
2026. 04. 24. 1:00 keltezéssel, Laurent Pinchart írta: > 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> > Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com> > --- > Changes since v2: > > - Fix typo in documentation > > Changes since v1: > > - Avoid std::map lookup before insertion in YamlObject::add() > - Don't move child node if add fails > --- Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> > include/libcamera/internal/yaml_parser.h | 5 ++- > src/libcamera/yaml_parser.cpp | 55 ++++++++++++++++++++++++ > 2 files changed, 59 insertions(+), 1 deletion(-) > > 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 8c84f560ff0f..5b2e743ee41a 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 exists, 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 > -- > Regards, > > Laurent Pinchart >
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 8c84f560ff0f..5b2e743ee41a 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 exists, 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