summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-02-06 21:10:15 +0200
committerKieran Bingham <kieran.bingham@ideasonboard.com>2020-02-13 16:47:56 +0000
commit31a05b70aa4bf792aa7396b3c4a1a40a0e701f3c (patch)
tree128f9d2714399c778cfd2533b1faddeb1f3cdd3f
parentb3dbccd328dc83e1ef2f60124620957500434d3d (diff)
libcamera: utils: Add string splitter utility function
Add a utils::split() function that splits a string for the purpose of iterating over substrings. It returns an object of unspecified type that can be used in range-based for loops. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
-rw-r--r--Documentation/Doxyfile.in1
-rw-r--r--src/libcamera/include/utils.h34
-rw-r--r--src/libcamera/utils.cpp63
3 files changed, 98 insertions, 0 deletions
diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in
index 1c46b04b..beeaf6d3 100644
--- a/Documentation/Doxyfile.in
+++ b/Documentation/Doxyfile.in
@@ -880,6 +880,7 @@ EXCLUDE_SYMBOLS = libcamera::BoundMethodArgs \
libcamera::BoundMethodStatic \
libcamera::SignalBase \
libcamera::*::Private \
+ libcamera::*::details::* \
std::*
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
diff --git a/src/libcamera/include/utils.h b/src/libcamera/include/utils.h
index e467eb21..080ea661 100644
--- a/src/libcamera/include/utils.h
+++ b/src/libcamera/include/utils.h
@@ -108,6 +108,40 @@ inline _hex hex<uint64_t>(uint64_t value, unsigned int width)
size_t strlcpy(char *dst, const char *src, size_t size);
+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);
+
} /* namespace utils */
} /* namespace libcamera */
diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp
index 4beffdab..94bbb883 100644
--- a/src/libcamera/utils.cpp
+++ b/src/libcamera/utils.cpp
@@ -199,6 +199,69 @@ size_t strlcpy(char *dst, const char *src, size_t size)
return strlen(src);
}
+details::StringSplitter::StringSplitter(const std::string &str, const std::string &delim)
+ : str_(str), delim_(delim)
+{
+}
+
+details::StringSplitter::iterator::iterator(const details::StringSplitter *ss, std::string::size_type pos)
+ : ss_(ss), pos_(pos)
+{
+ next_ = ss_->str_.find(ss_->delim_, pos_);
+}
+
+details::StringSplitter::iterator &details::StringSplitter::iterator::operator++()
+{
+ pos_ = next_;
+ if (pos_ != std::string::npos) {
+ pos_ += ss_->delim_.length();
+ next_ = ss_->str_.find(ss_->delim_, pos_);
+ }
+
+ return *this;
+}
+
+std::string details::StringSplitter::iterator::operator*() const
+{
+ std::string::size_type count;
+ count = next_ != std::string::npos ? next_ - pos_ : next_;
+ return ss_->str_.substr(pos_, count);
+}
+
+bool details::StringSplitter::iterator::operator!=(const details::StringSplitter::iterator &other) const
+{
+ return pos_ != other.pos_;
+}
+
+details::StringSplitter::iterator details::StringSplitter::begin() const
+{
+ return iterator(this, 0);
+}
+
+details::StringSplitter::iterator details::StringSplitter::end() const
+{
+ return iterator(this, std::string::npos);
+}
+
+/**
+ * \fn split(const std::string &str, const std::string &delim)
+ * \brief Split a string based on a delimiter
+ * \param[in] str The string to split
+ * \param[in] delim The delimiter string
+ *
+ * This function splits the string \a str into substrings based on the
+ * delimiter \a delim. It returns an object of unspecified type that can be
+ * used in a range-based for loop and yields the substrings in sequence.
+ *
+ * \return An object that can be used in a range-based for loop to iterate over
+ * the substrings
+ */
+details::StringSplitter split(const std::string &str, const std::string &delim)
+{
+ /** \todo Try to avoid copies of str and delim */
+ return details::StringSplitter(str, delim);
+}
+
} /* namespace utils */
} /* namespace libcamera */