strings.cpp revision 47328c96d91ca71b57b8976df2df1fe51579a955
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "base/strings.h"
18
19#include <stdlib.h>
20
21#include <string>
22#include <vector>
23
24namespace android {
25namespace base {
26
27#define CHECK_NE(a, b) \
28  if ((a) == (b)) abort();
29
30std::vector<std::string> Split(const std::string& s,
31                               const std::string& delimiters) {
32  CHECK_NE(delimiters.size(), 0U);
33
34  std::vector<std::string> split;
35  if (s.size() == 0) {
36    // Split("", d) returns {} rather than {""}.
37    return split;
38  }
39
40  size_t base = 0;
41  size_t found;
42  do {
43    found = s.find_first_of(delimiters, base);
44    if (found != base) {
45      split.push_back(s.substr(base, found - base));
46    }
47
48    base = found + 1;
49  } while (found != s.npos);
50
51  return split;
52}
53
54std::string Trim(const std::string& s) {
55  std::string result;
56
57  if (s.size() == 0) {
58    return result;
59  }
60
61  size_t start_index = 0;
62  size_t end_index = s.size() - 1;
63
64  // Skip initial whitespace.
65  while (start_index < s.size()) {
66    if (!isspace(s[start_index])) {
67      break;
68    }
69    start_index++;
70  }
71
72  // Skip terminating whitespace.
73  while (end_index >= start_index) {
74    if (!isspace(s[end_index])) {
75      break;
76    }
77    end_index--;
78  }
79
80  // All spaces, no beef.
81  if (end_index < start_index) {
82    return "";
83  }
84  // Start_index is the first non-space, end_index is the last one.
85  return s.substr(start_index, end_index - start_index + 1);
86}
87
88template <typename StringT>
89std::string Join(const std::vector<StringT>& strings, char separator) {
90  if (strings.empty()) {
91    return "";
92  }
93
94  std::string result(strings[0]);
95  for (size_t i = 1; i < strings.size(); ++i) {
96    result += separator;
97    result += strings[i];
98  }
99  return result;
100}
101
102// Explicit instantiations.
103template std::string Join<std::string>(const std::vector<std::string>& strings,
104                                       char separator);
105template std::string Join<const char*>(const std::vector<const char*>& strings,
106                                       char separator);
107
108bool StartsWith(const std::string& s, const char* prefix) {
109  return s.compare(0, strlen(prefix), prefix) == 0;
110}
111
112bool EndsWith(const std::string& s, const char* suffix) {
113  size_t suffix_length = strlen(suffix);
114  size_t string_length = s.size();
115  if (suffix_length > string_length) {
116    return false;
117  }
118  size_t offset = string_length - suffix_length;
119  return s.compare(offset, suffix_length, suffix) == 0;
120}
121
122}  // namespace base
123}  // namespace android
124