am a5e9639c: Merge "Update string Split API."

* commit 'a5e9639cf94aad0ed88ccd1c08d43f5084432f74':
  Update string Split API.
This commit is contained in:
Dan Albert 2015-03-23 18:02:44 +00:00 committed by Android Git Automerger
commit 97179d4a28
4 changed files with 63 additions and 28 deletions

View file

@ -23,10 +23,15 @@
namespace android { namespace android {
namespace base { namespace base {
// Splits a string using the given separator character into a vector of strings. // Splits a string into a vector of strings.
// Empty strings will be omitted. //
void Split(const std::string& s, char separator, // The string is split at each occurence of a character in delimiters.
std::vector<std::string>* result); //
// Empty splits will be omitted. I.e. Split("a,,b", ",") -> {"a", "b"}
//
// The empty string is not a valid delimiter list.
std::vector<std::string> Split(const std::string& s,
const std::string& delimiters);
// Trims whitespace off both ends of the given string. // Trims whitespace off both ends of the given string.
std::string Trim(const std::string& s); std::string Trim(const std::string& s);

View file

@ -108,8 +108,7 @@ void InitLogging(char* argv[]) {
return; return;
} }
std::vector<std::string> specs; std::vector<std::string> specs = Split(tags, " ");
Split(tags, ' ', &specs);
for (size_t i = 0; i < specs.size(); ++i) { for (size_t i = 0; i < specs.size(); ++i) {
// "tag-pattern:[vdiwefs]" // "tag-pattern:[vdiwefs]"
std::string spec(specs[i]); std::string spec(specs[i]);

View file

@ -16,27 +16,39 @@
#include "base/strings.h" #include "base/strings.h"
#include <stdlib.h>
#include <string> #include <string>
#include <vector> #include <vector>
namespace android { namespace android {
namespace base { namespace base {
void Split(const std::string& s, char separator, #define CHECK_NE(a, b) \
std::vector<std::string>* result) { if ((a) == (b)) abort();
const char* p = s.data();
const char* end = p + s.size(); std::vector<std::string> Split(const std::string& s,
while (p != end) { const std::string& delimiters) {
if (*p == separator) { CHECK_NE(delimiters.size(), 0U);
++p;
} else { std::vector<std::string> split;
const char* start = p; if (s.size() == 0) {
while (++p != end && *p != separator) { // Split("", d) returns {} rather than {""}.
// Skip to the next occurrence of the separator. return split;
}
result->push_back(std::string(start, p - start));
}
} }
size_t base = 0;
size_t found;
do {
found = s.find_first_of(delimiters, base);
if (found != base) {
split.push_back(s.substr(base, found - base));
}
base = found + 1;
} while (found != s.npos);
return split;
} }
std::string Trim(const std::string& s) { std::string Trim(const std::string& s) {

View file

@ -22,21 +22,18 @@
#include <vector> #include <vector>
TEST(strings, split_empty) { TEST(strings, split_empty) {
std::vector<std::string> parts; std::vector<std::string> parts = android::base::Split("", ",");
android::base::Split("", '\0', &parts);
ASSERT_EQ(0U, parts.size()); ASSERT_EQ(0U, parts.size());
} }
TEST(strings, split_single) { TEST(strings, split_single) {
std::vector<std::string> parts; std::vector<std::string> parts = android::base::Split("foo", ",");
android::base::Split("foo", ',', &parts);
ASSERT_EQ(1U, parts.size()); ASSERT_EQ(1U, parts.size());
ASSERT_EQ("foo", parts[0]); ASSERT_EQ("foo", parts[0]);
} }
TEST(strings, split_simple) { TEST(strings, split_simple) {
std::vector<std::string> parts; std::vector<std::string> parts = android::base::Split("foo,bar,baz", ",");
android::base::Split("foo,bar,baz", ',', &parts);
ASSERT_EQ(3U, parts.size()); ASSERT_EQ(3U, parts.size());
ASSERT_EQ("foo", parts[0]); ASSERT_EQ("foo", parts[0]);
ASSERT_EQ("bar", parts[1]); ASSERT_EQ("bar", parts[1]);
@ -44,8 +41,30 @@ TEST(strings, split_simple) {
} }
TEST(strings, split_with_empty_part) { TEST(strings, split_with_empty_part) {
std::vector<std::string> parts; std::vector<std::string> parts = android::base::Split("foo,,bar", ",");
android::base::Split("foo,,bar", ',', &parts); ASSERT_EQ(2U, parts.size());
ASSERT_EQ("foo", parts[0]);
ASSERT_EQ("bar", parts[1]);
}
TEST(strings, split_null_char) {
std::vector<std::string> parts =
android::base::Split(std::string("foo\0bar", 7), std::string("\0", 1));
ASSERT_EQ(2U, parts.size());
ASSERT_EQ("foo", parts[0]);
ASSERT_EQ("bar", parts[1]);
}
TEST(strings, split_any) {
std::vector<std::string> parts = android::base::Split("foo:bar,baz", ",:");
ASSERT_EQ(3U, parts.size());
ASSERT_EQ("foo", parts[0]);
ASSERT_EQ("bar", parts[1]);
ASSERT_EQ("baz", parts[2]);
}
TEST(strings, split_any_with_empty_part) {
std::vector<std::string> parts = android::base::Split("foo:,bar", ",:");
ASSERT_EQ(2U, parts.size()); ASSERT_EQ(2U, parts.size());
ASSERT_EQ("foo", parts[0]); ASSERT_EQ("foo", parts[0]);
ASSERT_EQ("bar", parts[1]); ASSERT_EQ("bar", parts[1]);