From patchwork Thu Feb 13 13:09:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 2809 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0E97B61958 for ; Thu, 13 Feb 2020 14:09:13 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9E4B9ACB; Thu, 13 Feb 2020 14:09:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1581599352; bh=+AsYR35NBAexmEXP8d1OOkRLLfRkqNq0g5qcmVuwKco=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZSHRGiX8uSEk54CPuanUlG4zfF8lcVGKNKC9jG6TAQ+iUMsJXXa1HyGIJAp5nDdgj 2t6Hk2NbF0K51+/aUpMV8omI1VP9QB0YdaYxUzPMAhJwqVKl4qsyeDOEF8zP0SjMlF aeaeZu+4MbFjk9Wng6U9WxsJSeuFJYd7wy5OmKHw= From: Kieran Bingham To: libcamera devel Date: Thu, 13 Feb 2020 13:09:06 +0000 Message-Id: <20200213130908.23638-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200213130908.23638-1-kieran.bingham@ideasonboard.com> References: <20200213130908.23638-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/3] libcamera: utils: Add string splitter utility function X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Feb 2020 13:09:13 -0000 From: Laurent Pinchart 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 Reviewed-by: Kieran Bingham --- Documentation/Doxyfile.in | 1 + src/libcamera/include/utils.h | 34 +++++++++++++++++++ src/libcamera/utils.cpp | 62 +++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in index 1c46b04b3f7e..beeaf6d3cf48 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 e467eb21c518..080ea6614de0 100644 --- a/src/libcamera/include/utils.h +++ b/src/libcamera/include/utils.h @@ -108,6 +108,40 @@ inline _hex hex(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 4beffdab5eb6..fe027c0b009c 100644 --- a/src/libcamera/utils.cpp +++ b/src/libcamera/utils.cpp @@ -199,6 +199,68 @@ 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) +{ + return details::StringSplitter(str, delim); +} + } /* namespace utils */ } /* namespace libcamera */