{"id":1985,"url":"https://patchwork.libcamera.org/api/1.1/patches/1985/?format=json","web_url":"https://patchwork.libcamera.org/patch/1985/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20190918103424.14536-2-jacopo@jmondi.org>","date":"2019-09-18T10:34:20","name":"[libcamera-devel,1/5] libcamera: Create DataValue and DataInfo","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"f8fcfedb6a89f602e24f0e26fbcd2d6f7fe083d0","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/1.1/people/3/?format=json","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"delegate":{"id":15,"url":"https://patchwork.libcamera.org/api/1.1/users/15/?format=json","username":"jmondi","first_name":"Jacopo","last_name":"Mondi","email":"jacopo@jmondi.org"},"mbox":"https://patchwork.libcamera.org/patch/1985/mbox/","series":[{"id":501,"url":"https://patchwork.libcamera.org/api/1.1/series/501/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=501","date":"2019-09-18T10:34:19","name":"libcamera: Control framework backend rework","version":1,"mbox":"https://patchwork.libcamera.org/series/501/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/1985/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/1985/checks/","tags":{},"headers":{"Return-Path":"<jacopo@jmondi.org>","Received":["from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net\n\t[217.70.183.196])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3547460BB0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 18 Sep 2019 12:32:51 +0200 (CEST)","from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101])\n\t(Authenticated sender: jacopo@jmondi.org)\n\tby relay4-d.mail.gandi.net (Postfix) with ESMTPSA id DB585E0006\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 18 Sep 2019 10:32:50 +0000 (UTC)"],"X-Originating-IP":"2.224.242.101","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"libcamera-devel@lists.libcamera.org","Date":"Wed, 18 Sep 2019 12:34:20 +0200","Message-Id":"<20190918103424.14536-2-jacopo@jmondi.org>","X-Mailer":"git-send-email 2.23.0","In-Reply-To":"<20190918103424.14536-1-jacopo@jmondi.org>","References":"<20190918103424.14536-1-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH 1/5] libcamera: Create DataValue and\n\tDataInfo","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Wed, 18 Sep 2019 10:32:51 -0000"},"content":"Add the data_value.[h|c] files that provide an abstracted polymorphic\ndata value type and a generic data info type that represent static\ninformation associated with a data value.\n\nDataValue is a slightly re-worked copy of the ControlValue type defined\nin controls.h, provided in a generic header to be used a foundation for\nboth Controls and V4L2Controls classes that will be re-worked in the\nnext patches in the series.\n\nAdd a test for data value which is an adapted copy of the control value\ntest, that will be removed in the next patch.\n\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\n---\n include/libcamera/data_value.h |  84 +++++++++\n include/libcamera/meson.build  |   1 +\n src/libcamera/data_value.cpp   | 317 +++++++++++++++++++++++++++++++++\n src/libcamera/meson.build      |   1 +\n test/data_value/data_value.cpp |  59 ++++++\n test/data_value/meson.build    |  12 ++\n test/meson.build               |   1 +\n 7 files changed, 475 insertions(+)\n create mode 100644 include/libcamera/data_value.h\n create mode 100644 src/libcamera/data_value.cpp\n create mode 100644 test/data_value/data_value.cpp\n create mode 100644 test/data_value/meson.build\n\n--\n2.23.0","diff":"diff --git a/include/libcamera/data_value.h b/include/libcamera/data_value.h\nnew file mode 100644\nindex 000000000000..0fcd9bd04a65\n--- /dev/null\n+++ b/include/libcamera/data_value.h\n@@ -0,0 +1,84 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * data_value.h - Polymorphic data value type\n+ */\n+#ifndef __LIBCAMERA_DATA_VALUE_H__\n+#define __LIBCAMERA_DATA_VALUE_H__\n+\n+#include <cstdint>\n+#include <string>\n+\n+namespace libcamera {\n+\n+enum DataType {\n+\tDataTypeNone,\n+\tDataTypeBool,\n+\tDataTypeInteger,\n+\tDataTypeInteger64,\n+\tDataTypeNumber,\n+};\n+\n+static constexpr size_t DataSize[DataTypeNumber] = {\n+\t[DataTypeNone]\t\t= 1,\n+\t[DataTypeBool]\t\t= 4,\n+\t[DataTypeInteger]\t= 4,\n+\t[DataTypeInteger64]\t= 8,\n+};\n+\n+class DataValue\n+{\n+public:\n+\tDataValue();\n+\tDataValue(const DataValue &other);\n+\tDataValue(bool value);\n+\tDataValue(int value);\n+\tDataValue(int64_t value);\n+\n+\tDataValue &operator=(const DataValue &other);\n+\n+\tenum DataType type() const { return type_; }\n+\tsize_t size() const { return size_; }\n+\n+\tvoid set(bool value);\n+\tvoid set(int value);\n+\tvoid set(int64_t value);\n+\n+\tbool getBool() const;\n+\tint getInt() const;\n+\tint64_t getInt64() const;\n+\n+\tstd::string toString() const;\n+\n+private:\n+\tDataType type_;\n+\tsize_t size_;\n+\n+\tunion {\n+\t\tbool bool_;\n+\t\tint integer_;\n+\t\tint64_t integer64_;\n+\t};\n+};\n+\n+class DataInfo\n+{\n+public:\n+\tDataInfo(const DataValue &min, const DataValue &max)\n+\t{\n+\t\tmin_ = min;\n+\t\tmax_ = max;\n+\t}\n+\n+\tconst DataValue &min() const { return min_; }\n+\tconst DataValue &max() const { return max_; }\n+\n+private:\n+\tDataValue max_;\n+\tDataValue min_;\n+};\n+\n+} /* namespace libcamera */\n+\n+#endif /* __LIBCAMERA_DATA_VALUE_H__ */\ndiff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\nindex 868f1a6bf1ab..e3f3ad504446 100644\n--- a/include/libcamera/meson.build\n+++ b/include/libcamera/meson.build\n@@ -5,6 +5,7 @@ libcamera_api = files([\n     'camera_manager.h',\n     'control_ids.h',\n     'controls.h',\n+    'data_value.h',\n     'event_dispatcher.h',\n     'event_notifier.h',\n     'geometry.h',\ndiff --git a/src/libcamera/data_value.cpp b/src/libcamera/data_value.cpp\nnew file mode 100644\nindex 000000000000..f07b5fb75a8a\n--- /dev/null\n+++ b/src/libcamera/data_value.cpp\n@@ -0,0 +1,317 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * data_value.cpp - Polymorphic data value type\n+ */\n+\n+#include <libcamera/data_value.h>\n+\n+#include <cstdint>\n+#include <sstream>\n+#include <string>\n+\n+#include \"utils.h\"\n+#include \"log.h\"\n+\n+/**\n+ * \\file data_value.h\n+ * \\brief Polymorphic data type\n+ */\n+\n+namespace libcamera {\n+\n+/**\n+ * \\enum DataType\n+ * \\brief Define the supported data types\n+ * \\var DataTypeNone\n+ * Identifies an unset value\n+ * \\var DataTypeBool\n+ * Identifies DataType storing a boolean value\n+ * \\var DataTypeInteger\n+ * Identifies DataType storing an integer value\n+ * \\var DataTypeInteger64\n+ * Identifies DataType storing a 64-bit integer value\n+ */\n+\n+/**\n+ * \\var DataSize\n+ * \\brief Associate to each data type the memory size in bytes\n+ */\n+\n+#if 0\n+/**\n+ * \\class Data\n+ * \\brief Base class for data value and data info instances\n+ *\n+ * DataValue and DataInfo share basic information like size and type.\n+ * This class provides common fields and operations for them.\n+ */\n+\n+/**\n+ * \\brief Construct a Data of \\a type\n+ * \\param[in] type The Data type defined by DataType\n+ */\n+Data::Data(DataType type)\n+\t: type_(type)\n+{\n+\t/*\n+\t * \\todo The size of compound data types depend on the number of\n+\t * elements too.\n+\t */\n+\tsize_ = DataSize[type_];\n+}\n+\n+/**\n+ * \\var Data::type_\n+ * \\brief The data type\n+ */\n+\n+/**\n+ * \\var Data::size_\n+ * \\brief The data size\n+ */\n+\n+#endif\n+\n+/**\n+ * \\class DataValue\n+ * \\brief Polymorphic data value\n+ *\n+ * DataValue holds values of different types, defined by DataType providing\n+ * a unified interface to access and modify the data content.\n+ *\n+ * DataValue instances are used by classes that need to represent and store\n+ * numerical values of different types.\n+ *\n+ * \\todo Add support for compound data types, such as arrays.\n+ */\n+\n+/**\n+ * \\brief Construct an empty DataValue\n+ */\n+DataValue::DataValue()\n+\t: type_(DataTypeNone), size_(DataSize[type_])\n+{\n+}\n+\n+/**\n+ * \\brief Construct a DataValue copying data from \\a other\n+ * \\param[in] other The DataValue to copy data from\n+ *\n+ * DataValue copy constructor.\n+ */\n+DataValue::DataValue(const DataValue &other)\n+\t: type_(other.type()), size_(DataSize[type_])\n+{\n+\tswitch (type_) {\n+\tcase DataTypeBool:\n+\t\tbool_ = other.getBool();\n+\t\tbreak;\n+\tcase DataTypeInteger:\n+\t\tinteger_ = other.getInt();\n+\t\tbreak;\n+\tcase DataTypeInteger64:\n+\t\tinteger64_ = other.getInt64();\n+\t\tbreak;\n+\tdefault:\n+\t\tbool_ = integer_ = integer64_ = 0;\n+\t\tbreak;\n+\t}\n+}\n+\n+/**\n+ * \\brief Construct a boolean DataValue\n+ * \\param[in] value Boolean value to store\n+ */\n+DataValue::DataValue(bool value)\n+\t: type_(DataTypeBool), size_(DataSize[type_]), bool_(value)\n+{\n+}\n+\n+/**\n+ * \\brief Construct an integer DataValue\n+ * \\param[in] value Integer value to store\n+ */\n+DataValue::DataValue(int value)\n+\t: type_(DataTypeInteger), size_(DataSize[type_]), integer_(value)\n+{\n+}\n+\n+/**\n+ * \\brief Construct a 64 bit integer DataValue\n+ * \\param[in] value 64-bits integer value to store\n+ */\n+DataValue::DataValue(int64_t value)\n+\t: type_(DataTypeInteger64), size_(DataSize[type_]), integer64_(value)\n+{\n+}\n+\n+/**\n+ * \\brief Assign the DataValue type and value using the ones from \\a other\n+ * \\param[in] other The DataValue to copy type and value from\n+ *\n+ * DataValue assignement operator.\n+ *\n+ * \\return The DataValue with fields updated using the ones from \\a other\n+ */\n+DataValue &DataValue::operator=(const DataValue &other)\n+{\n+\tDataType newType = other.type();\n+\ttype_ = newType;\n+\tsize_ = DataSize[type_];\n+\n+\tswitch (newType) {\n+\tcase DataTypeBool:\n+\t\tbool_ = other.getBool();\n+\t\tbreak;\n+\tcase DataTypeInteger:\n+\t\tinteger_ = other.getInt();\n+\t\tbreak;\n+\tcase DataTypeInteger64:\n+\t\tinteger64_ = other.getInt64();\n+\t\tbreak;\n+\tdefault:\n+\t\tbool_ = integer_ = integer64_ = 0;\n+\t\tbreak;\n+\t}\n+\n+\treturn *this;\n+}\n+\n+/**\n+ * \\fn DataValue::type()\n+ * \\brief Retrieve the data type of the data\n+ * \\return The type of the data\n+ */\n+\n+/**\n+ * \\fn DataValue::size()\n+ * \\brief Retrieve the size in bytes of the data\n+ * \\return The size in bytes of the data\n+ */\n+\n+/**\n+ * \\brief Set the value with a boolean\n+ * \\param[in] value Boolean value to store\n+ */\n+void DataValue::set(bool value)\n+{\n+\ttype_ = DataTypeBool;\n+\tsize_ = DataSize[type_];\n+\tbool_ = value;\n+}\n+\n+/**\n+ * \\brief Set the value with an integer\n+ * \\param[in] value Integer value to store\n+ */\n+void DataValue::set(int value)\n+{\n+\ttype_ = DataTypeInteger;\n+\tsize_ = DataSize[type_];\n+\tinteger_ = value;\n+}\n+\n+/**\n+ * \\brief Set the value with a 64 bit integer\n+ * \\param[in] value 64 bit integer value to store\n+ */\n+void DataValue::set(int64_t value)\n+{\n+\ttype_ = DataTypeInteger64;\n+\tsize_ = DataSize[type_];\n+\tinteger64_ = value;\n+}\n+\n+/**\n+ * \\brief Get the boolean value\n+ *\n+ * The value type must be Boolean.\n+ *\n+ * \\return The boolean value\n+ */\n+bool DataValue::getBool() const\n+{\n+\tASSERT(type_ == DataTypeBool);\n+\n+\treturn bool_;\n+}\n+\n+/**\n+ * \\brief Get the integer value\n+ *\n+ * The value type must be Integer or Integer64.\n+ *\n+ * \\return The integer value\n+ */\n+int DataValue::getInt() const\n+{\n+\tASSERT(type_ == DataTypeInteger || type_ == DataTypeInteger64);\n+\n+\treturn integer_;\n+}\n+\n+/**\n+ * \\brief Get the 64-bit integer value\n+ *\n+ * The value type must be Integer or Integer64.\n+ *\n+ * \\return The 64-bit integer value\n+ */\n+int64_t DataValue::getInt64() const\n+{\n+\tASSERT(type_ == DataTypeInteger || type_ == DataTypeInteger64);\n+\n+\treturn integer64_;\n+}\n+\n+/**\n+ * \\brief Assemble and return a string describing the value\n+ * \\return A string describing the DataValue\n+ */\n+std::string DataValue::toString() const\n+{\n+\tswitch (type_) {\n+\tcase DataTypeBool:\n+\t\treturn bool_ ? \"True\" : \"False\";\n+\tcase DataTypeInteger:\n+\t\treturn std::to_string(integer_);\n+\tcase DataTypeInteger64:\n+\t\treturn std::to_string(integer64_);\n+\tdefault:\n+\t\treturn \"<None>\";\n+\t}\n+}\n+\n+/**\n+ * \\class DataInfo\n+ * \\brief Validation informations associated with a data value\n+ *\n+ * The DataInfo class represents static information associated with data\n+ * types that represent plymorhpic values abstracted by the DataValue class.\n+ *\n+ * DataInfo stores static informations such as the value minimum and maximum\n+ * values and for compound values the maximum and minimum number of elements.\n+ */\n+\n+/**\n+ * \\fn DataInfo::DataInfo\n+ * \\brief Construct a data info with \\a min and \\a max values\n+ * \\param[in] min The minimum allowed value\n+ * \\param[in] max The maximum allowed value\n+ */\n+\n+/**\n+ * \\fn DataInfo::min()\n+ * \\brief Retrieve the DataInfo minimum allowed value\n+ * \\return A DataValue representing the minimum allowed value\n+ */\n+\n+/**\n+ * \\fn DataInfo::max()\n+ * \\brief Retrieve the DataInfo maximum allowed value\n+ * \\return A DataValue representing the maximum allowed value\n+ */\n+\n+} /* namespace libcamera */\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex 755149c55c7b..c3100a1709e0 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -5,6 +5,7 @@ libcamera_sources = files([\n     'camera_manager.cpp',\n     'camera_sensor.cpp',\n     'controls.cpp',\n+    'data_value.cpp',\n     'device_enumerator.cpp',\n     'device_enumerator_sysfs.cpp',\n     'event_dispatcher.cpp',\ndiff --git a/test/data_value/data_value.cpp b/test/data_value/data_value.cpp\nnew file mode 100644\nindex 000000000000..64061000c1e4\n--- /dev/null\n+++ b/test/data_value/data_value.cpp\n@@ -0,0 +1,59 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * data_value.cpp - DataValue tests\n+ */\n+\n+#include <iostream>\n+\n+#include <libcamera/data_value.h>\n+\n+#include \"test.h\"\n+\n+using namespace std;\n+using namespace libcamera;\n+\n+class DataValueTest : public Test\n+{\n+protected:\n+\tint run()\n+\t{\n+\t\tDataValue integer(1234);\n+\t\tDataValue boolean(true);\n+\n+\t\t/* Just a string conversion output test... no validation */\n+\t\tcout << \"Int: \" << integer.toString()\n+\t\t     << \" Bool: \" << boolean.toString()\n+\t\t     << endl;\n+\n+\t\tif (integer.getInt() != 1234) {\n+\t\t\tcerr << \"Failed to get Integer\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (boolean.getBool() != true) {\n+\t\t\tcerr << \"Failed to get Boolean\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\t/* Test an uninitialised value, and updating it. */\n+\n+\t\tDataValue value;\n+\t\tvalue.set(true);\n+\t\tif (value.getBool() != true) {\n+\t\t\tcerr << \"Failed to get Booleans\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tvalue.set(10);\n+\t\tif (value.getInt() != 10) {\n+\t\t\tcerr << \"Failed to get Integer\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\treturn TestPass;\n+\t}\n+};\n+\n+TEST_REGISTER(DataValueTest)\ndiff --git a/test/data_value/meson.build b/test/data_value/meson.build\nnew file mode 100644\nindex 000000000000..3858e6085a1f\n--- /dev/null\n+++ b/test/data_value/meson.build\n@@ -0,0 +1,12 @@\n+data_value_tests = [\n+    [ 'data_value',   'data_value.cpp' ],\n+]\n+\n+foreach t : data_value_tests\n+    exe = executable(t[0], t[1],\n+                     dependencies : libcamera_dep,\n+                     link_with : test_libraries,\n+                     include_directories : test_includes_internal)\n+    test(t[0], exe, suite : 'data_value', is_parallel : false)\n+endforeach\n+\ndiff --git a/test/meson.build b/test/meson.build\nindex 84722cceb35d..5d414b22dc0c 100644\n--- a/test/meson.build\n+++ b/test/meson.build\n@@ -2,6 +2,7 @@ subdir('libtest')\n\n subdir('camera')\n subdir('controls')\n+subdir('data_value')\n subdir('ipa')\n subdir('ipc')\n subdir('log')\n","prefixes":["libcamera-devel","1/5"]}