[libcamera-devel] [PATCH 1/6] utils: Add function to convert string to UCS-2

Paul Elder paul.elder at ideasonboard.com
Thu Jan 14 11:40:30 CET 2021


GPSProcessingMethod and UserComment in EXIF tags can be in Unicode, but
are recommended to be in UCS-2. Add a function in utils to help with
this.

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
---
 include/libcamera/internal/utils.h |  2 ++
 src/libcamera/utils.cpp            | 30 ++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h
index f08134af..aa9cc236 100644
--- a/include/libcamera/internal/utils.h
+++ b/include/libcamera/internal/utils.h
@@ -35,6 +35,8 @@ const char *basename(const char *path);
 char *secure_getenv(const char *name);
 std::string dirname(const std::string &path);
 
+std::vector<uint8_t> string_to_c16(const std::string &str, bool le);
+
 template<typename T>
 std::vector<typename T::key_type> map_keys(const T &map)
 {
diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp
index e90375ae..89cb0f73 100644
--- a/src/libcamera/utils.cpp
+++ b/src/libcamera/utils.cpp
@@ -17,6 +17,7 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <uchar.h>
 #include <unistd.h>
 
 /**
@@ -122,6 +123,35 @@ std::string dirname(const std::string &path)
 	return path.substr(0, pos + 1);
 }
 
+/**
+ * \brief Convert string to byte array of UCS-2
+ * \param[in] str String to convert
+ * \param[in] le Little-endian (false for Big-endian)
+ *
+ * \return Byte array of UCS-2 representation of \a str, without null-terminator
+ */
+std::vector<uint8_t> string_to_c16(const std::string &str, bool le)
+{
+	std::mbstate_t state{};
+	char16_t c16;
+	const char *ptr = &str[0], *end = &str[0] + str.size();
+
+	std::vector<uint8_t> ret;
+	while (size_t rc = mbrtoc16(&c16, ptr, end - ptr + 1, &state)) {
+		if (rc == static_cast<size_t>(-2) ||
+		    rc == static_cast<size_t>(-1))
+			break;
+
+		ret.push_back(le ? (c16 & 0xff) : ((c16 >> 8) & 0xff));
+		ret.push_back(le ? ((c16 >> 8) & 0xff) : (c16 & 0xff));
+
+		if (rc > 0)
+			ptr += rc;
+	}
+
+	return ret;
+}
+
 /**
  * \fn std::vector<typename T::key_type> map_keys(const T &map)
  * \brief Retrieve the keys of a std::map<>
-- 
2.27.0



More information about the libcamera-devel mailing list