From cbdc93e9d1666010d49e06940158a37c61cc6fa7 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Tue, 15 Jun 2021 15:40:45 +0100 Subject: libcamera/base: Move utils to the base library Move the utils functionality to the libcamera/base library. Reviewed-by: Hirokazu Honda Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart Signed-off-by: Kieran Bingham --- include/libcamera/base/meson.build | 1 + include/libcamera/base/utils.h | 355 +++++++++++++++++++++++++++++++++ include/libcamera/internal/log.h | 2 +- include/libcamera/internal/meson.build | 1 - include/libcamera/internal/thread.h | 3 +- include/libcamera/internal/utils.h | 355 --------------------------------- 6 files changed, 359 insertions(+), 358 deletions(-) create mode 100644 include/libcamera/base/utils.h delete mode 100644 include/libcamera/internal/utils.h (limited to 'include') diff --git a/include/libcamera/base/meson.build b/include/libcamera/base/meson.build index 0a7a57b8..9f0ba6b0 100644 --- a/include/libcamera/base/meson.build +++ b/include/libcamera/base/meson.build @@ -3,6 +3,7 @@ libcamera_base_include_dir = libcamera_include_dir / 'base' libcamera_base_headers = files([ + 'utils.h', ]) install_headers(libcamera_base_headers, diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h new file mode 100644 index 00000000..d1aaff65 --- /dev/null +++ b/include/libcamera/base/utils.h @@ -0,0 +1,355 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018, Google Inc. + * + * utils.h - Miscellaneous utility functions + */ +#ifndef __LIBCAMERA_BASE_UTILS_H__ +#define __LIBCAMERA_BASE_UTILS_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __DOXYGEN__ + +/* uClibc and uClibc-ng don't provide O_TMPFILE */ +#ifndef O_TMPFILE +#define O_TMPFILE (020000000 | O_DIRECTORY) +#endif + +#endif + +namespace libcamera { + +namespace utils { + +const char *basename(const char *path); + +char *secure_getenv(const char *name); +std::string dirname(const std::string &path); + +template +std::vector map_keys(const T &map) +{ + std::vector keys; + std::transform(map.begin(), map.end(), std::back_inserter(keys), + [](const auto &value) { return value.first; }); + return keys; +} + +template +unsigned int set_overlap(InputIt1 first1, InputIt1 last1, + InputIt2 first2, InputIt2 last2) +{ + unsigned int count = 0; + + while (first1 != last1 && first2 != last2) { + if (*first1 < *first2) { + ++first1; + } else { + if (!(*first2 < *first1)) + count++; + ++first2; + } + } + + return count; +} + +using clock = std::chrono::steady_clock; +using duration = std::chrono::steady_clock::duration; +using time_point = std::chrono::steady_clock::time_point; + +struct timespec duration_to_timespec(const duration &value); +std::string time_point_to_string(const time_point &time); + +#ifndef __DOXYGEN__ +struct _hex { + uint64_t v; + unsigned int w; +}; + +std::basic_ostream> & +operator<<(std::basic_ostream> &stream, const _hex &h); +#endif + +template +_hex hex(T value, unsigned int width = 0); + +#ifndef __DOXYGEN__ +template<> +inline _hex hex(int32_t value, unsigned int width) +{ + return { static_cast(value), width ? width : 8 }; +} + +template<> +inline _hex hex(uint32_t value, unsigned int width) +{ + return { static_cast(value), width ? width : 8 }; +} + +template<> +inline _hex hex(int64_t value, unsigned int width) +{ + return { static_cast(value), width ? width : 16 }; +} + +template<> +inline _hex hex(uint64_t value, unsigned int width) +{ + return { static_cast(value), width ? width : 16 }; +} +#endif + +size_t strlcpy(char *dst, const char *src, size_t size); + +#ifndef __DOXYGEN__ +template +std::string join(const Container &items, const std::string &sep, UnaryOp op) +{ + std::ostringstream ss; + bool first = true; + + for (typename Container::const_iterator it = std::begin(items); + it != std::end(items); ++it) { + if (!first) + ss << sep; + else + first = false; + + ss << op(*it); + } + + return ss.str(); +} + +template +std::string join(const Container &items, const std::string &sep) +{ + std::ostringstream ss; + bool first = true; + + for (typename Container::const_iterator it = std::begin(items); + it != std::end(items); ++it) { + if (!first) + ss << sep; + else + first = false; + + ss << *it; + } + + return ss.str(); +} +#else +template +std::string join(const Container &items, const std::string &sep, UnaryOp op = nullptr); +#endif + +namespace details { + +class StringSplitter +{ +public: + StringSplitter(const std::string &str, const std::string &delim); + + class iterator + { + public: + iterator(const StringSplitter *ss, std::string::size_type pos); + + iterator &operator++(); + std::string operator*() const; + bool operator!=(const iterator &other) const; + + private: + const StringSplitter *ss_; + std::string::size_type pos_; + std::string::size_type next_; + }; + + iterator begin() const; + iterator end() const; + +private: + std::string str_; + std::string delim_; +}; + +} /* namespace details */ + +details::StringSplitter split(const std::string &str, const std::string &delim); + +std::string toAscii(const std::string &str); + +std::string libcameraBuildPath(); +std::string libcameraSourcePath(); + +constexpr unsigned int alignDown(unsigned int value, unsigned int alignment) +{ + return value / alignment * alignment; +} + +constexpr unsigned int alignUp(unsigned int value, unsigned int alignment) +{ + return (value + alignment - 1) / alignment * alignment; +} + +namespace details { + +template +struct reverse_adapter { + T &iterable; +}; + +template +auto begin(reverse_adapter r) +{ + return std::rbegin(r.iterable); +} + +template +auto end(reverse_adapter r) +{ + return std::rend(r.iterable); +} + +} /* namespace details */ + +template +details::reverse_adapter reverse(T &&iterable) +{ + return { iterable }; +} + +namespace details { + +template +class enumerate_iterator +{ +private: + using base_reference = typename std::iterator_traits::reference; + +public: + using difference_type = typename std::iterator_traits::difference_type; + using value_type = std::pair; + using pointer = value_type *; + using reference = value_type &; + using iterator_category = std::input_iterator_tag; + + explicit enumerate_iterator(Base iter) + : current_(iter), pos_(0) + { + } + + enumerate_iterator &operator++() + { + ++current_; + ++pos_; + return *this; + } + + bool operator!=(const enumerate_iterator &other) const + { + return current_ != other.current_; + } + + value_type operator*() const + { + return { pos_, *current_ }; + } + +private: + Base current_; + difference_type pos_; +}; + +template +class enumerate_adapter +{ +public: + using iterator = enumerate_iterator; + + enumerate_adapter(Base begin, Base end) + : begin_(begin), end_(end) + { + } + + iterator begin() const + { + return iterator{ begin_ }; + } + + iterator end() const + { + return iterator{ end_ }; + } + +private: + const Base begin_; + const Base end_; +}; + +} /* namespace details */ + +template +auto enumerate(T &iterable) -> details::enumerate_adapter +{ + return { std::begin(iterable), std::end(iterable) }; +} + +#ifndef __DOXYGEN__ +template +auto enumerate(T (&iterable)[N]) -> details::enumerate_adapter +{ + return { std::begin(iterable), std::end(iterable) }; +} +#endif + +class Duration : public std::chrono::duration +{ + using BaseDuration = std::chrono::duration; + +public: + Duration() = default; + + template + constexpr Duration(const std::chrono::duration &d) + : BaseDuration(d) + { + } + + template + double get() const + { + auto const c = std::chrono::duration_cast>(*this); + return c.count(); + } + + explicit constexpr operator bool() const + { + return *this != BaseDuration::zero(); + } +}; + +} /* namespace utils */ + +#ifndef __DOXYGEN__ +template +std::basic_ostream &operator<<(std::basic_ostream &os, + const utils::Duration &d); +#endif + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BASE_UTILS_H__ */ diff --git a/include/libcamera/internal/log.h b/include/libcamera/internal/log.h index b8efb161..9c2beab6 100644 --- a/include/libcamera/internal/log.h +++ b/include/libcamera/internal/log.h @@ -12,7 +12,7 @@ #include -#include "libcamera/internal/utils.h" +#include namespace libcamera { diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index 205b36a9..1348e926 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -43,7 +43,6 @@ libcamera_internal_headers = files([ 'sysfs.h', 'thread.h', 'timer.h', - 'utils.h', 'v4l2_device.h', 'v4l2_pixelformat.h', 'v4l2_subdevice.h', diff --git a/include/libcamera/internal/thread.h b/include/libcamera/internal/thread.h index 25d0308d..9662e28b 100644 --- a/include/libcamera/internal/thread.h +++ b/include/libcamera/internal/thread.h @@ -14,8 +14,9 @@ #include +#include + #include "libcamera/internal/message.h" -#include "libcamera/internal/utils.h" namespace libcamera { diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h deleted file mode 100644 index 15beb0f4..00000000 --- a/include/libcamera/internal/utils.h +++ /dev/null @@ -1,355 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2018, Google Inc. - * - * utils.h - Miscellaneous utility functions - */ -#ifndef __LIBCAMERA_INTERNAL_UTILS_H__ -#define __LIBCAMERA_INTERNAL_UTILS_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef __DOXYGEN__ - -/* uClibc and uClibc-ng don't provide O_TMPFILE */ -#ifndef O_TMPFILE -#define O_TMPFILE (020000000 | O_DIRECTORY) -#endif - -#endif - -namespace libcamera { - -namespace utils { - -const char *basename(const char *path); - -char *secure_getenv(const char *name); -std::string dirname(const std::string &path); - -template -std::vector map_keys(const T &map) -{ - std::vector keys; - std::transform(map.begin(), map.end(), std::back_inserter(keys), - [](const auto &value) { return value.first; }); - return keys; -} - -template -unsigned int set_overlap(InputIt1 first1, InputIt1 last1, - InputIt2 first2, InputIt2 last2) -{ - unsigned int count = 0; - - while (first1 != last1 && first2 != last2) { - if (*first1 < *first2) { - ++first1; - } else { - if (!(*first2 < *first1)) - count++; - ++first2; - } - } - - return count; -} - -using clock = std::chrono::steady_clock; -using duration = std::chrono::steady_clock::duration; -using time_point = std::chrono::steady_clock::time_point; - -struct timespec duration_to_timespec(const duration &value); -std::string time_point_to_string(const time_point &time); - -#ifndef __DOXYGEN__ -struct _hex { - uint64_t v; - unsigned int w; -}; - -std::basic_ostream> & -operator<<(std::basic_ostream> &stream, const _hex &h); -#endif - -template -_hex hex(T value, unsigned int width = 0); - -#ifndef __DOXYGEN__ -template<> -inline _hex hex(int32_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 8 }; -} - -template<> -inline _hex hex(uint32_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 8 }; -} - -template<> -inline _hex hex(int64_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 16 }; -} - -template<> -inline _hex hex(uint64_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 16 }; -} -#endif - -size_t strlcpy(char *dst, const char *src, size_t size); - -#ifndef __DOXYGEN__ -template -std::string join(const Container &items, const std::string &sep, UnaryOp op) -{ - std::ostringstream ss; - bool first = true; - - for (typename Container::const_iterator it = std::begin(items); - it != std::end(items); ++it) { - if (!first) - ss << sep; - else - first = false; - - ss << op(*it); - } - - return ss.str(); -} - -template -std::string join(const Container &items, const std::string &sep) -{ - std::ostringstream ss; - bool first = true; - - for (typename Container::const_iterator it = std::begin(items); - it != std::end(items); ++it) { - if (!first) - ss << sep; - else - first = false; - - ss << *it; - } - - return ss.str(); -} -#else -template -std::string join(const Container &items, const std::string &sep, UnaryOp op = nullptr); -#endif - -namespace details { - -class StringSplitter -{ -public: - StringSplitter(const std::string &str, const std::string &delim); - - class iterator - { - public: - iterator(const StringSplitter *ss, std::string::size_type pos); - - iterator &operator++(); - std::string operator*() const; - bool operator!=(const iterator &other) const; - - private: - const StringSplitter *ss_; - std::string::size_type pos_; - std::string::size_type next_; - }; - - iterator begin() const; - iterator end() const; - -private: - std::string str_; - std::string delim_; -}; - -} /* namespace details */ - -details::StringSplitter split(const std::string &str, const std::string &delim); - -std::string toAscii(const std::string &str); - -std::string libcameraBuildPath(); -std::string libcameraSourcePath(); - -constexpr unsigned int alignDown(unsigned int value, unsigned int alignment) -{ - return value / alignment * alignment; -} - -constexpr unsigned int alignUp(unsigned int value, unsigned int alignment) -{ - return (value + alignment - 1) / alignment * alignment; -} - -namespace details { - -template -struct reverse_adapter { - T &iterable; -}; - -template -auto begin(reverse_adapter r) -{ - return std::rbegin(r.iterable); -} - -template -auto end(reverse_adapter r) -{ - return std::rend(r.iterable); -} - -} /* namespace details */ - -template -details::reverse_adapter reverse(T &&iterable) -{ - return { iterable }; -} - -namespace details { - -template -class enumerate_iterator -{ -private: - using base_reference = typename std::iterator_traits::reference; - -public: - using difference_type = typename std::iterator_traits::difference_type; - using value_type = std::pair; - using pointer = value_type *; - using reference = value_type &; - using iterator_category = std::input_iterator_tag; - - explicit enumerate_iterator(Base iter) - : current_(iter), pos_(0) - { - } - - enumerate_iterator &operator++() - { - ++current_; - ++pos_; - return *this; - } - - bool operator!=(const enumerate_iterator &other) const - { - return current_ != other.current_; - } - - value_type operator*() const - { - return { pos_, *current_ }; - } - -private: - Base current_; - difference_type pos_; -}; - -template -class enumerate_adapter -{ -public: - using iterator = enumerate_iterator; - - enumerate_adapter(Base begin, Base end) - : begin_(begin), end_(end) - { - } - - iterator begin() const - { - return iterator{ begin_ }; - } - - iterator end() const - { - return iterator{ end_ }; - } - -private: - const Base begin_; - const Base end_; -}; - -} /* namespace details */ - -template -auto enumerate(T &iterable) -> details::enumerate_adapter -{ - return { std::begin(iterable), std::end(iterable) }; -} - -#ifndef __DOXYGEN__ -template -auto enumerate(T (&iterable)[N]) -> details::enumerate_adapter -{ - return { std::begin(iterable), std::end(iterable) }; -} -#endif - -class Duration : public std::chrono::duration -{ - using BaseDuration = std::chrono::duration; - -public: - Duration() = default; - - template - constexpr Duration(const std::chrono::duration &d) - : BaseDuration(d) - { - } - - template - double get() const - { - auto const c = std::chrono::duration_cast>(*this); - return c.count(); - } - - explicit constexpr operator bool() const - { - return *this != BaseDuration::zero(); - } -}; - -} /* namespace utils */ - -#ifndef __DOXYGEN__ -template -std::basic_ostream &operator<<(std::basic_ostream &os, - const utils::Duration &d); -#endif - -} /* namespace libcamera */ - -#endif /* __LIBCAMERA_INTERNAL_UTILS_H__ */ -- cgit v1.2.1