From patchwork Tue Apr 7 15:34:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 26466 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 43065C330F for ; Tue, 7 Apr 2026 15:35:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B369C62E19; Tue, 7 Apr 2026 17:35:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="AUTP5JaN"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3D3AB62DFA for ; Tue, 7 Apr 2026 17:35:04 +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 UTF8SMTPSA id B400C6DC for ; Tue, 7 Apr 2026 17:33:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1775576016; bh=RBN/KyATuh2ePugqLEn7mn3YOx/34nrCZSFLXo1eNVY=; h=From:To:Subject:Date:In-Reply-To:References:From; b=AUTP5JaN9PfD6C1g2s4Uf/LKAYp0QebhbXGdhcuyu9KICQr6HNO1QqMn2wEf9TEPF YDokhjOIFULlgHYXRcg262PUtCnRgHQ+iveqSWbiXKbJpvia6h+GOPWI1ef7CZ3bBR wZ+A4t/U0DcXkkKSVaK9fc5pkUEjJs5YVXXd2DL0= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 26/42] libcamera: value_node: Add functions to erase child nodes Date: Tue, 7 Apr 2026 18:34:11 +0300 Message-ID: <20260407153427.1825999-27-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260407153427.1825999-1-laurent.pinchart@ideasonboard.com> References: <20260407153427.1825999-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 --- include/libcamera/internal/value_node.h | 3 ++ src/libcamera/value_node.cpp | 51 +++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/include/libcamera/internal/value_node.h b/include/libcamera/internal/value_node.h index 14c5e0eb0202..4e3757af7d09 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(const std::string &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 990e46d70358..8a1af13a5d6e 100644 --- a/src/libcamera/value_node.cpp +++ b/src/libcamera/value_node.cpp @@ -621,4 +621,55 @@ 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(const std::string &key) +{ + auto node = dictionary_.extract(key); + if (node.empty()) + return; + + for (auto iter = list_.begin(); iter != list_.end(); ++iter) { + if (iter->value.get() != node.mapped()) + continue; + + list_.erase(iter); + return; + } +} + +/** + * \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(std::string{ name }); + return; + } + + auto iter = node->dictionary_.find(name); + if (iter == node->dictionary_.end()) + return; + + node = iter->second; + } +} + } /* namespace libcamera */