| 159 | |
| 160 | template<typename STR> |
| 161 | TrimPositions TrimStringT(const STR& input, |
| 162 | const STR& trim_chars, |
| 163 | TrimPositions positions, |
| 164 | STR* output) { |
| 165 | // Find the edges of leading/trailing whitespace as desired. |
| 166 | const size_t last_char = input.length() - 1; |
| 167 | const size_t first_good_char = (positions & TRIM_LEADING) ? |
| 168 | input.find_first_not_of(trim_chars) : 0; |
| 169 | const size_t last_good_char = (positions & TRIM_TRAILING) ? |
| 170 | input.find_last_not_of(trim_chars) : last_char; |
| 171 | |
| 172 | // When the string was all whitespace, report that we stripped off whitespace |
| 173 | // from whichever position the caller was interested in. For empty input, we |
| 174 | // stripped no whitespace, but we still need to clear |output|. |
| 175 | if (input.empty() || |
| 176 | (first_good_char == STR::npos) || (last_good_char == STR::npos)) { |
| 177 | bool input_was_empty = input.empty(); // in case output == &input |
| 178 | output->clear(); |
| 179 | return input_was_empty ? TRIM_NONE : positions; |
| 180 | } |
| 181 | |
| 182 | // Trim the whitespace. |
| 183 | *output = |
| 184 | input.substr(first_good_char, last_good_char - first_good_char + 1); |
| 185 | |
| 186 | // Return where we trimmed from. |
| 187 | return static_cast<TrimPositions>( |
| 188 | ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) | |
| 189 | ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING)); |
| 190 | } |
| 191 | |
| 192 | bool TrimString(const string16& input, |
| 193 | const butil::StringPiece16& trim_chars, |
no test coverage detected