[libcamera-devel] [RFC PATCH 6/8] libcamera: Add configuration interface

Kieran Bingham kieran.bingham at ideasonboard.com
Mon Nov 23 17:43:17 CET 2020


Provide an interface to support reading configuration files.

Initial support is included for JSON formatted files, but extending this
with other configuration file formats is not excluded.

Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
---
 README.rst                                 |  2 +-
 include/libcamera/internal/configuration.h | 37 +++++++++
 src/libcamera/configuration.cpp            | 91 ++++++++++++++++++++++
 src/libcamera/meson.build                  |  1 +
 4 files changed, 130 insertions(+), 1 deletion(-)
 create mode 100644 include/libcamera/internal/configuration.h
 create mode 100644 src/libcamera/configuration.cpp

diff --git a/README.rst b/README.rst
index 251291b77c62..c09e262fcc43 100644
--- a/README.rst
+++ b/README.rst
@@ -58,7 +58,7 @@ Meson Build system: [required]
             pip3 install --user --upgrade meson
 
 for the libcamera core: [required]
-        python3-yaml python3-ply python3-jinja2
+        python3-yaml python3-ply python3-jinja2 nlohmann-json3-dev
 
 for IPA module signing: [required]
         libgnutls28-dev openssl
diff --git a/include/libcamera/internal/configuration.h b/include/libcamera/internal/configuration.h
new file mode 100644
index 000000000000..a89732f0210f
--- /dev/null
+++ b/include/libcamera/internal/configuration.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Google Inc.
+ *
+ * configuration.h - Parsing configuration files
+ */
+#ifndef __LIBCAMERA_INTERNAL_CONFIGURATION_H__
+#define __LIBCAMERA_INTERNAL_CONFIGURATION_H__
+
+#include <fstream>
+#include <string>
+
+/* https://nlohmann.github.io/json/home/exceptions/#switch-off-exceptions */
+#define JSON_NOEXCEPTION 1
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+namespace libcamera {
+
+class Configuration
+{
+public:
+	int open(std::string filename);
+
+	json &data() { return json_; }
+
+private:
+	std::string findFile(std::string filename);
+
+	json json_;
+};
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_INTERNAL_CONFIGURATION_H__ */
+
diff --git a/src/libcamera/configuration.cpp b/src/libcamera/configuration.cpp
new file mode 100644
index 000000000000..f849088bbc45
--- /dev/null
+++ b/src/libcamera/configuration.cpp
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Google Inc.
+ *
+ * configuration.cpp - Parsing configuration files
+ */
+#include "libcamera/internal/configuration.h"
+
+#include "libcamera/internal/file.h"
+#include "libcamera/internal/log.h"
+#include "libcamera/internal/utils.h"
+
+#include <iostream>
+#include <stdlib.h>
+
+/**
+ * \file configuration.h
+ * \brief Read interface for configuration files
+ */
+
+namespace libcamera {
+
+LOG_DEFINE_CATEGORY(Configuration)
+
+/*
+ * Configuration files can be stored in system paths, which are identified
+ * through the build configuration.
+ *
+ * However, when running uninstalled - the source location takes precedence.
+ */
+std::string Configuration::findFile(std::string filename)
+{
+	static std::array<std::string, 2> searchPaths = {
+		LIBCAMERA_SYSCONF_DIR,
+		LIBCAMERA_DATA_DIR,
+	};
+
+	std::string root = utils::libcameraSourcePath();
+	if (!root.empty()) {
+		std::string configurationPath = root + "data/" + filename;
+
+		if (File::exists(configurationPath))
+			return configurationPath;
+	}
+
+	for (std::string &path : searchPaths) {
+		std::string configurationPath = path + "/" + filename;
+		if (File::exists(configurationPath))
+			return configurationPath;
+	}
+
+	return "";
+}
+
+/**
+ * \brief Open and parse a configuration file.
+ *
+ * The filename will be searched for on the libcamera configuration and paths,
+ * and then parsed.
+ *
+ * Successfully parsed files will present the data contained therein through the
+ * json object exposed from data();
+ */
+int Configuration::open(std::string filename)
+{
+	std::string data = findFile(filename);
+	if (data.empty()) {
+		LOG(Configuration, Warning)
+			<< "file: \"" << filename
+			<< "\" was not found.";
+		return -ENOENT;
+	}
+
+	LOG(Configuration, Debug) << "Reading configuration from " << data;
+
+	/* Parse with no error callbacks and exceptions disabled. */
+	std::ifstream input(data);
+	json j = json::parse(input, nullptr, false);
+	if (j.is_discarded()) {
+		LOG(Configuration, Error)
+			<< "file: \"" << data
+			<< "\" was not parsable.";
+		return -EINVAL;
+	}
+
+	json_ = std::move(j);
+
+	return 0;
+}
+
+} /* namespace libcamera */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 387d5d88ecae..5d655c87a7a0 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -9,6 +9,7 @@ libcamera_sources = files([
     'camera_controls.cpp',
     'camera_manager.cpp',
     'camera_sensor.cpp',
+    'configuration.cpp',
     'controls.cpp',
     'control_serializer.cpp',
     'control_validator.cpp',
-- 
2.25.1



More information about the libcamera-devel mailing list