From patchwork Tue Jan 14 16:32:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2646 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 02A866074F for ; Tue, 14 Jan 2020 17:30:35 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 984CE2001B; Tue, 14 Jan 2020 16:30:34 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jan 2020 17:32:56 +0100 Message-Id: <20200114163256.39236-1-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200113164245.52535-18-jacopo@jmondi.org> References: <20200113164245.52535-18-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1.1 17/23] libcamera: control: Deep-copy control values 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: , X-List-Received-Date: Tue, 14 Jan 2020 16:30:35 -0000 Implement operator=() and copy constructor for the ControlValue class, deep-copying the content of the 'other' ControlValue by using ControlValue::set() operation which, in case of compound ControlValue, guarantees proper memory allocation and data copy. Signed-off-by: Jacopo Mondi --- Valgrind reports the usage of unitialized value in ControlValue::relase() This was caused by the copy constructor calling set<>() which calls release() before the type of the control values was initialized (we're at construction time) Fix this by initializing type before calling operator=() -- 2.24.1 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -201,6 +201,11 @@ void ControlValue::copyValue(const ControlValue &other) */ ControlValue::ControlValue(const ControlValue &other) { + /* + * Initialze the type: operator=() calls set() which calls release() + * which inspects the control value type. Be safe and set it to none. + */ + type_ = ControlTypeNone; *this = other; } --- include/libcamera/controls.h | 5 +++ src/libcamera/controls.cpp | 67 ++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index bdbdb213528d..d13144b69198 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -43,6 +43,9 @@ public: ControlValue(Span &values); ~ControlValue(); + ControlValue(const ControlValue &other); + ControlValue &operator=(const ControlValue &other); + ControlType type() const { return type_; } bool isNone() const { return type_ == ControlTypeNone; } std::size_t numElements() const { return numElements_; } @@ -81,6 +84,8 @@ private: std::size_t numElements_; void release(); + template + void copyValue(const ControlValue &source); bool compareElement(const ControlValue &other) const; bool compareElement(const ControlValue &other, unsigned int i) const; std::string elemToString(unsigned int i) const; diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index c311ab1d6af1..ddf666040ae7 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -189,6 +189,73 @@ ControlValue::~ControlValue() release(); } +template +void ControlValue::copyValue(const ControlValue &other) +{ + set(other.get()); +} + +/** + * \brief Contruct a ControlValue with the content of \a other + * \param[in] other The ControlValue to copy content from + */ +ControlValue::ControlValue(const ControlValue &other) +{ + /* + * Initialze the type: operator=() calls set() which calls release() + * which inspects the control value type. Be safe and set it to none. + */ + type_ = ControlTypeNone; + *this = other; +} + +/** + * \brief Replace the content of the ControlValue with the one of \a other + * \param[in] other The ControlValue to copy content from + * + * Deep-copy the content of \a other into the ControlValue by reserving memory + * and copy data there in case \a other transports arrays of values in one of + * its pointer data members. + * + * \return The ControlValue with its content replaced with the one of \a other + */ +ControlValue &ControlValue::operator=(const ControlValue &other) +{ + switch (other.type_) { + case ControlTypeBool: + copyValue(other); + break; + case ControlTypeInteger32: + copyValue(other); + break; + case ControlTypeInteger64: + copyValue(other); + break; + case ControlTypeFloat: + copyValue(other); + break; + case ControlTypeCompoundBool: + copyValue>(other); + break; + case ControlTypeCompoundInt32: + copyValue>(other); + break; + case ControlTypeCompoundInt64: + copyValue>(other); + break; + case ControlTypeCompoundFloat: + copyValue>(other); + break; + default: + break; + } + + type_ = other.type_; + numElements_ = other.numElements_; + + return *this; +} + /** * \fn ControlValue::type() * \brief Retrieve the data type of the value