From patchwork Wed Sep 18 10:31:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1979 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 08CC460BB0; Wed, 18 Sep 2019 12:30:01 +0200 (CEST) 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 relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 6F6E41BF205; Wed, 18 Sep 2019 10:30:00 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org, To:libcamera-devel@lists.libcamera.org Date: Wed, 18 Sep 2019 12:31:29 +0200 Message-Id: <20190918103133.14296-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190918103133.14296-1-jacopo@jmondi.org> References: <20190918103133.14296-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/5] libcamera: Create DataValue and DataInfo X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Sep 2019 10:30:01 -0000 Add the data_value.[h|c] files that provide an abstracted polymorphic data value type and a generic data info type that represent static information associated with a data value. DataValue is a slightly re-worked copy of the ControlValue type defined in controls.h, provided in a generic header to be used a foundation for both Controls and V4L2Controls classes that will be re-worked in the next patches in the series. Add a test for data value which is an adapted copy of the control value test, that will be removed in the next patch. Signed-off-by: Jacopo Mondi --- include/libcamera/data_value.h | 84 +++++++++ include/libcamera/meson.build | 1 + src/libcamera/data_value.cpp | 317 +++++++++++++++++++++++++++++++++ src/libcamera/meson.build | 1 + test/data_value/data_value.cpp | 59 ++++++ test/data_value/meson.build | 12 ++ test/meson.build | 1 + 7 files changed, 475 insertions(+) create mode 100644 include/libcamera/data_value.h create mode 100644 src/libcamera/data_value.cpp create mode 100644 test/data_value/data_value.cpp create mode 100644 test/data_value/meson.build diff --git a/include/libcamera/data_value.h b/include/libcamera/data_value.h new file mode 100644 index 000000000000..0fcd9bd04a65 --- /dev/null +++ b/include/libcamera/data_value.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * data_value.h - Polymorphic data value type + */ +#ifndef __LIBCAMERA_DATA_VALUE_H__ +#define __LIBCAMERA_DATA_VALUE_H__ + +#include +#include + +namespace libcamera { + +enum DataType { + DataTypeNone, + DataTypeBool, + DataTypeInteger, + DataTypeInteger64, + DataTypeNumber, +}; + +static constexpr size_t DataSize[DataTypeNumber] = { + [DataTypeNone] = 1, + [DataTypeBool] = 4, + [DataTypeInteger] = 4, + [DataTypeInteger64] = 8, +}; + +class DataValue +{ +public: + DataValue(); + DataValue(const DataValue &other); + DataValue(bool value); + DataValue(int value); + DataValue(int64_t value); + + DataValue &operator=(const DataValue &other); + + enum DataType type() const { return type_; } + size_t size() const { return size_; } + + void set(bool value); + void set(int value); + void set(int64_t value); + + bool getBool() const; + int getInt() const; + int64_t getInt64() const; + + std::string toString() const; + +private: + DataType type_; + size_t size_; + + union { + bool bool_; + int integer_; + int64_t integer64_; + }; +}; + +class DataInfo +{ +public: + DataInfo(const DataValue &min, const DataValue &max) + { + min_ = min; + max_ = max; + } + + const DataValue &min() const { return min_; } + const DataValue &max() const { return max_; } + +private: + DataValue max_; + DataValue min_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_DATA_VALUE_H__ */ diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index 868f1a6bf1ab..e3f3ad504446 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -5,6 +5,7 @@ libcamera_api = files([ 'camera_manager.h', 'control_ids.h', 'controls.h', + 'data_value.h', 'event_dispatcher.h', 'event_notifier.h', 'geometry.h', diff --git a/src/libcamera/data_value.cpp b/src/libcamera/data_value.cpp new file mode 100644 index 000000000000..f07b5fb75a8a --- /dev/null +++ b/src/libcamera/data_value.cpp @@ -0,0 +1,317 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * data_value.cpp - Polymorphic data value type + */ + +#include + +#include +#include +#include + +#include "utils.h" +#include "log.h" + +/** + * \file data_value.h + * \brief Polymorphic data type + */ + +namespace libcamera { + +/** + * \enum DataType + * \brief Define the supported data types + * \var DataTypeNone + * Identifies an unset value + * \var DataTypeBool + * Identifies DataType storing a boolean value + * \var DataTypeInteger + * Identifies DataType storing an integer value + * \var DataTypeInteger64 + * Identifies DataType storing a 64-bit integer value + */ + +/** + * \var DataSize + * \brief Associate to each data type the memory size in bytes + */ + +#if 0 +/** + * \class Data + * \brief Base class for data value and data info instances + * + * DataValue and DataInfo share basic information like size and type. + * This class provides common fields and operations for them. + */ + +/** + * \brief Construct a Data of \a type + * \param[in] type The Data type defined by DataType + */ +Data::Data(DataType type) + : type_(type) +{ + /* + * \todo The size of compound data types depend on the number of + * elements too. + */ + size_ = DataSize[type_]; +} + +/** + * \var Data::type_ + * \brief The data type + */ + +/** + * \var Data::size_ + * \brief The data size + */ + +#endif + +/** + * \class DataValue + * \brief Polymorphic data value + * + * DataValue holds values of different types, defined by DataType providing + * a unified interface to access and modify the data content. + * + * DataValue instances are used by classes that need to represent and store + * numerical values of different types. + * + * \todo Add support for compound data types, such as arrays. + */ + +/** + * \brief Construct an empty DataValue + */ +DataValue::DataValue() + : type_(DataTypeNone), size_(DataSize[type_]) +{ +} + +/** + * \brief Construct a DataValue copying data from \a other + * \param[in] other The DataValue to copy data from + * + * DataValue copy constructor. + */ +DataValue::DataValue(const DataValue &other) + : type_(other.type()), size_(DataSize[type_]) +{ + switch (type_) { + case DataTypeBool: + bool_ = other.getBool(); + break; + case DataTypeInteger: + integer_ = other.getInt(); + break; + case DataTypeInteger64: + integer64_ = other.getInt64(); + break; + default: + bool_ = integer_ = integer64_ = 0; + break; + } +} + +/** + * \brief Construct a boolean DataValue + * \param[in] value Boolean value to store + */ +DataValue::DataValue(bool value) + : type_(DataTypeBool), size_(DataSize[type_]), bool_(value) +{ +} + +/** + * \brief Construct an integer DataValue + * \param[in] value Integer value to store + */ +DataValue::DataValue(int value) + : type_(DataTypeInteger), size_(DataSize[type_]), integer_(value) +{ +} + +/** + * \brief Construct a 64 bit integer DataValue + * \param[in] value 64-bits integer value to store + */ +DataValue::DataValue(int64_t value) + : type_(DataTypeInteger64), size_(DataSize[type_]), integer64_(value) +{ +} + +/** + * \brief Assign the DataValue type and value using the ones from \a other + * \param[in] other The DataValue to copy type and value from + * + * DataValue assignement operator. + * + * \return The DataValue with fields updated using the ones from \a other + */ +DataValue &DataValue::operator=(const DataValue &other) +{ + DataType newType = other.type(); + type_ = newType; + size_ = DataSize[type_]; + + switch (newType) { + case DataTypeBool: + bool_ = other.getBool(); + break; + case DataTypeInteger: + integer_ = other.getInt(); + break; + case DataTypeInteger64: + integer64_ = other.getInt64(); + break; + default: + bool_ = integer_ = integer64_ = 0; + break; + } + + return *this; +} + +/** + * \fn DataValue::type() + * \brief Retrieve the data type of the data + * \return The type of the data + */ + +/** + * \fn DataValue::size() + * \brief Retrieve the size in bytes of the data + * \return The size in bytes of the data + */ + +/** + * \brief Set the value with a boolean + * \param[in] value Boolean value to store + */ +void DataValue::set(bool value) +{ + type_ = DataTypeBool; + size_ = DataSize[type_]; + bool_ = value; +} + +/** + * \brief Set the value with an integer + * \param[in] value Integer value to store + */ +void DataValue::set(int value) +{ + type_ = DataTypeInteger; + size_ = DataSize[type_]; + integer_ = value; +} + +/** + * \brief Set the value with a 64 bit integer + * \param[in] value 64 bit integer value to store + */ +void DataValue::set(int64_t value) +{ + type_ = DataTypeInteger64; + size_ = DataSize[type_]; + integer64_ = value; +} + +/** + * \brief Get the boolean value + * + * The value type must be Boolean. + * + * \return The boolean value + */ +bool DataValue::getBool() const +{ + ASSERT(type_ == DataTypeBool); + + return bool_; +} + +/** + * \brief Get the integer value + * + * The value type must be Integer or Integer64. + * + * \return The integer value + */ +int DataValue::getInt() const +{ + ASSERT(type_ == DataTypeInteger || type_ == DataTypeInteger64); + + return integer_; +} + +/** + * \brief Get the 64-bit integer value + * + * The value type must be Integer or Integer64. + * + * \return The 64-bit integer value + */ +int64_t DataValue::getInt64() const +{ + ASSERT(type_ == DataTypeInteger || type_ == DataTypeInteger64); + + return integer64_; +} + +/** + * \brief Assemble and return a string describing the value + * \return A string describing the DataValue + */ +std::string DataValue::toString() const +{ + switch (type_) { + case DataTypeBool: + return bool_ ? "True" : "False"; + case DataTypeInteger: + return std::to_string(integer_); + case DataTypeInteger64: + return std::to_string(integer64_); + default: + return ""; + } +} + +/** + * \class DataInfo + * \brief Validation informations associated with a data value + * + * The DataInfo class represents static information associated with data + * types that represent plymorhpic values abstracted by the DataValue class. + * + * DataInfo stores static informations such as the value minimum and maximum + * values and for compound values the maximum and minimum number of elements. + */ + +/** + * \fn DataInfo::DataInfo + * \brief Construct a data info with \a min and \a max values + * \param[in] min The minimum allowed value + * \param[in] max The maximum allowed value + */ + +/** + * \fn DataInfo::min() + * \brief Retrieve the DataInfo minimum allowed value + * \return A DataValue representing the minimum allowed value + */ + +/** + * \fn DataInfo::max() + * \brief Retrieve the DataInfo maximum allowed value + * \return A DataValue representing the maximum allowed value + */ + +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 755149c55c7b..c3100a1709e0 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -5,6 +5,7 @@ libcamera_sources = files([ 'camera_manager.cpp', 'camera_sensor.cpp', 'controls.cpp', + 'data_value.cpp', 'device_enumerator.cpp', 'device_enumerator_sysfs.cpp', 'event_dispatcher.cpp', diff --git a/test/data_value/data_value.cpp b/test/data_value/data_value.cpp new file mode 100644 index 000000000000..64061000c1e4 --- /dev/null +++ b/test/data_value/data_value.cpp @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * data_value.cpp - DataValue tests + */ + +#include + +#include + +#include "test.h" + +using namespace std; +using namespace libcamera; + +class DataValueTest : public Test +{ +protected: + int run() + { + DataValue integer(1234); + DataValue boolean(true); + + /* Just a string conversion output test... no validation */ + cout << "Int: " << integer.toString() + << " Bool: " << boolean.toString() + << endl; + + if (integer.getInt() != 1234) { + cerr << "Failed to get Integer" << endl; + return TestFail; + } + + if (boolean.getBool() != true) { + cerr << "Failed to get Boolean" << endl; + return TestFail; + } + + /* Test an uninitialised value, and updating it. */ + + DataValue value; + value.set(true); + if (value.getBool() != true) { + cerr << "Failed to get Booleans" << endl; + return TestFail; + } + + value.set(10); + if (value.getInt() != 10) { + cerr << "Failed to get Integer" << endl; + return TestFail; + } + + return TestPass; + } +}; + +TEST_REGISTER(DataValueTest) diff --git a/test/data_value/meson.build b/test/data_value/meson.build new file mode 100644 index 000000000000..3858e6085a1f --- /dev/null +++ b/test/data_value/meson.build @@ -0,0 +1,12 @@ +data_value_tests = [ + [ 'data_value', 'data_value.cpp' ], +] + +foreach t : data_value_tests + exe = executable(t[0], t[1], + dependencies : libcamera_dep, + link_with : test_libraries, + include_directories : test_includes_internal) + test(t[0], exe, suite : 'data_value', is_parallel : false) +endforeach + diff --git a/test/meson.build b/test/meson.build index 84722cceb35d..5d414b22dc0c 100644 --- a/test/meson.build +++ b/test/meson.build @@ -2,6 +2,7 @@ subdir('libtest') subdir('camera') subdir('controls') +subdir('data_value') subdir('ipa') subdir('ipc') subdir('log')