From patchwork Thu Apr 23 23:00:42 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 26542 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id C9785BDCB5 for ; Thu, 23 Apr 2026 23:01:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 524D962FD5; Fri, 24 Apr 2026 01:01:44 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="tvMHLga3"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4675D62F7B for ; Fri, 24 Apr 2026 01:01:29 +0200 (CEST) Received: from killaraus.ideasonboard.com (2001-14ba-703d-e500--2a1.rev.dnainternet.fi [IPv6:2001:14ba:703d:e500::2a1]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BCE6D802 for ; Fri, 24 Apr 2026 00:59:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1776985189; bh=WzSSponFlqQsxWhUEDvIaRQGV4bNbY+du6Wbsgii0aA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=tvMHLga3g98UUM5VeQPPDl56phhlNWUo/+lIxUQIxOzI1DaC5oP36d+kEjU8r77jl ejyShoXFTdh/u711GExDh53Bn+8dc91KPJfezR8lFHJtXiypczzaJkkMG9VB8vrFQj Z8yHcTAK26SWjhlA6xowSbK981Zp6pD18pQaTKj8= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v3 20/37] libcamera: value_node: Add functions to erase child nodes Date: Fri, 24 Apr 2026 02:00:42 +0300 Message-ID: <20260423230059.3180987-21-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260423230059.3180987-1-laurent.pinchart@ideasonboard.com> References: <20260423230059.3180987-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 --- Changes since v2: - Use std::string_view() for first overload - Add todo comment --- 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 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 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 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 */