1// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef LIBBRILLO_BRILLO_STRINGS_STRING_UTILS_H_
6#define LIBBRILLO_BRILLO_STRINGS_STRING_UTILS_H_
7
8#include <string>
9#include <utility>
10#include <vector>
11
12#include <brillo/brillo_export.h>
13
14namespace brillo {
15namespace string_utils {
16
17// Treats the string as a delimited list of substrings and returns the array
18// of original elements of the list.
19// |trim_whitespaces| causes each element to have all whitespaces trimmed off.
20// |purge_empty_strings| specifies whether empty elements from the original
21// string should be omitted.
22BRILLO_EXPORT std::vector<std::string> Split(const std::string& str,
23                                             const std::string& delimiter,
24                                             bool trim_whitespaces,
25                                             bool purge_empty_strings);
26// Splits the string, trims all whitespaces, omits empty string parts.
27inline std::vector<std::string> Split(const std::string& str,
28                                      const std::string& delimiter) {
29  return Split(str, delimiter, true, true);
30}
31// Splits the string, omits empty string parts.
32inline std::vector<std::string> Split(const std::string& str,
33                                      const std::string& delimiter,
34                                      bool trim_whitespaces) {
35  return Split(str, delimiter, trim_whitespaces, true);
36}
37
38// Splits the string into two pieces at the first position of the specified
39// delimiter.
40BRILLO_EXPORT std::pair<std::string, std::string> SplitAtFirst(
41    const std::string& str,
42    const std::string& delimiter,
43    bool trim_whitespaces);
44// Splits the string into two pieces at the first position of the specified
45// delimiter. Both parts have all whitespaces trimmed off.
46inline std::pair<std::string, std::string> SplitAtFirst(
47    const std::string& str,
48    const std::string& delimiter) {
49  return SplitAtFirst(str, delimiter, true);
50}
51
52// The following overload returns false if the delimiter was not found in the
53// source string. In this case, |left_part| will be set to |str| and
54// |right_part| will be empty.
55BRILLO_EXPORT bool SplitAtFirst(const std::string& str,
56                                const std::string& delimiter,
57                                std::string* left_part,
58                                std::string* right_part,
59                                bool trim_whitespaces);
60// Always trims the white spaces in the split parts.
61inline bool SplitAtFirst(const std::string& str,
62                         const std::string& delimiter,
63                         std::string* left_part,
64                         std::string* right_part) {
65  return SplitAtFirst(str, delimiter, left_part, right_part, true);
66}
67
68// Joins strings into a single string separated by |delimiter|.
69template <class InputIterator>
70std::string JoinRange(const std::string& delimiter,
71                      InputIterator first,
72                      InputIterator last) {
73  std::string result;
74  if (first == last)
75    return result;
76  result = *first;
77  for (++first; first != last; ++first) {
78    result += delimiter;
79    result += *first;
80  }
81  return result;
82}
83
84template <class Container>
85std::string Join(const std::string& delimiter, const Container& strings) {
86  using std::begin;
87  using std::end;
88  return JoinRange(delimiter, begin(strings), end(strings));
89}
90
91inline std::string Join(const std::string& delimiter,
92                        std::initializer_list<std::string> strings) {
93  return JoinRange(delimiter, strings.begin(), strings.end());
94}
95
96inline std::string Join(const std::string& delimiter,
97                        const std::string& str1,
98                        const std::string& str2) {
99  return str1 + delimiter + str2;
100}
101
102// string_utils::ToString() is a helper function to convert any scalar type
103// to a string. In most cases, it redirects the call to std::to_string with
104// two exceptions: for std::string itself and for double and bool.
105template <typename T>
106inline std::string ToString(T value) {
107  return std::to_string(value);
108}
109// Having the following overload is handy for templates where the type
110// of template parameter isn't known and could be a string itself.
111inline std::string ToString(std::string value) {
112  return value;
113}
114// We overload this for double because std::to_string(double) uses %f to
115// format the value and I would like to use a shorter %g format instead.
116BRILLO_EXPORT std::string ToString(double value);
117// And the bool to be converted as true/false instead of 1/0.
118BRILLO_EXPORT std::string ToString(bool value);
119
120// Converts a byte-array into a string. This method doesn't perform any
121// data re-encoding. It just takes every byte from the buffer and appends it
122// to the string as a character.
123BRILLO_EXPORT std::string GetBytesAsString(const std::vector<uint8_t>& buf);
124
125// Converts a string into a byte-array. Opposite of GetBytesAsString().
126BRILLO_EXPORT std::vector<uint8_t> GetStringAsBytes(const std::string& str);
127
128}  // namespace string_utils
129}  // namespace brillo
130
131#endif  // LIBBRILLO_BRILLO_STRINGS_STRING_UTILS_H_
132