Browse Source

Adding light StrCat and SimpleItoa and tests.

pull/567/head
Philip Liard 15 years ago
committed by Mihaela Rosca
parent
commit
dbb360c89e
4 changed files with 418 additions and 0 deletions
  1. +2
    -0
      cpp/CMakeLists.txt
  2. +186
    -0
      cpp/src/stringutil.cc
  3. +100
    -0
      cpp/src/stringutil.h
  4. +130
    -0
      cpp/src/stringutil_test.cc

+ 2
- 0
cpp/CMakeLists.txt View File

@ -98,6 +98,7 @@ set (
"src/base/synchronization/lock.cc"
"src/base/threading/thread_restrictions.cc"
"src/phonenumberutil.cc"
"src/stringutil.cc"
"src/utf/rune.c"
)
@ -150,6 +151,7 @@ target_link_libraries (phonenumber re2)
set (TEST_SOURCES
"src/phonenumberutil_test.cc"
"src/run_tests.cc"
"src/stringutil_test.cc"
)
add_executable (libphonenumber_test ${TEST_SOURCES})


+ 186
- 0
cpp/src/stringutil.cc View File

@ -0,0 +1,186 @@
// Copyright (C) 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Author: Philippe Liard
#include <cassert>
#include <cstring>
#include <sstream>
#include "stringutil.h"
namespace i18n {
namespace phonenumbers {
using std::stringstream;
string operator+(const string& s, int n) {
stringstream ss;
ss << s << n;
string result;
ss >> result;
return result;
}
string SimpleItoa(int n) {
stringstream ss;
ss << n;
string result;
ss >> result;
return result;
}
bool TryStripPrefixString(const string& in, const string& prefix, string* out) {
assert(out);
const bool has_prefix = in.compare(0, prefix.length(), prefix) == 0;
out->assign(has_prefix ? in.substr(prefix.length()) : in);
return has_prefix;
}
bool HasSuffixString(const string& s, const string& suffix) {
if (s.length() < suffix.length()) {
return false;
}
return s.compare(s.length() - suffix.length(), suffix.length(), suffix) == 0;
}
// StringHolder class
StringHolder::StringHolder(const string& s) :
string_(&s),
cstring_(NULL),
len_(s.size())
{}
StringHolder::StringHolder(const char* s) :
string_(NULL),
cstring_(s),
len_(std::strlen(s))
{}
StringHolder::~StringHolder() {}
// StrCat
// Implement s += sh; (s: string, sh: StringHolder)
string& operator+=(string& lhs, const StringHolder& rhs) {
const string* const s = rhs.GetString();
if (s) {
lhs += *s;
} else {
const char* const cs = rhs.GetCString();
if (cs)
lhs.append(cs, rhs.Length());
}
return lhs;
}
string StrCat(const StringHolder& s1, const StringHolder& s2) {
string result;
result.reserve(s1.Length() + s2.Length() + 1);
result += s1;
result += s2;
return result;
}
string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + 1);
result += s1;
result += s2;
result += s3;
return result;
}
string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() + 1);
result += s1;
result += s2;
result += s3;
result += s4;
return result;
}
string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4,
const StringHolder& s5) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + 1);
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
return result;
}
string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4,
const StringHolder& s5, const StringHolder& s6) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + 1);
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
return result;
}
string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4,
const StringHolder& s5, const StringHolder& s6,
const StringHolder& s7, const StringHolder& s8,
const StringHolder& s9, const StringHolder& s10,
const StringHolder& s11) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + s7.Length() + s8.Length() +
s9.Length() + s10.Length() + s11.Length());
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
result += s7;
result += s8;
result += s9;
result += s10;
result += s11;
return result;
}
} // namespace phonenumbers
} // namespace i18n

+ 100
- 0
cpp/src/stringutil.h View File

@ -0,0 +1,100 @@
// Copyright (C) 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Author: Philippe Liard
#ifndef I18N_PHONENUMBERS_STRINGUTIL_H_
#define I18N_PHONENUMBERS_STRINGUTIL_H_
#include <cstddef>
#include <string>
namespace i18n {
namespace phonenumbers {
using std::string;
// Support string("hello") + 10
string operator+(const string& s, int n);
// Convert integer into string
string SimpleItoa(int n);
// Return true if 'in' starts with 'prefix' and write into 'out'
// 'in' minus 'prefix'
bool TryStripPrefixString(const string& in, const string& prefix, string* out);
// Return true if 's' ends with 'suffix'
bool HasSuffixString(const string& s, const string& suffix);
// Hold a reference to a std::string or C string.
class StringHolder {
public:
// Don't make the constructors explicit to make the StrCat usage convenient.
StringHolder(const string& s);
StringHolder(const char* s);
~StringHolder();
const string* GetString() const {
return string_;
}
const char* GetCString() const {
return cstring_;
}
size_t Length() const {
return len_;
}
private:
const string* const string_;
const char* const cstring_;
const size_t len_;
};
string& operator+=(string& lhs, const StringHolder& rhs);
// Efficient string concatenation
string StrCat(const StringHolder& s1, const StringHolder& s2);
string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3);
string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4);
string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4,
const StringHolder& s5);
string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4,
const StringHolder& s5, const StringHolder& s6);
string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4,
const StringHolder& s5, const StringHolder& s6,
const StringHolder& s7, const StringHolder& s8,
const StringHolder& s9, const StringHolder& s10,
const StringHolder& s11);
} // namespace phonenumbers
} // namespace i18n
#endif // I18N_PHONENUMBERS_STRINGUTIL_H_

+ 130
- 0
cpp/src/stringutil_test.cc View File

@ -0,0 +1,130 @@
// Copyright (C) 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Author: Philippe Liard
#include <gtest/gtest.h>
#include "stringutil.h"
namespace i18n {
namespace phonenumbers {
// Test operator+(const string&, int)
TEST(StringUtilTest, OperatorPlus) {
EXPECT_EQ("hello10", string("hello") + 10);
}
// Test SimpleItoa implementation
TEST(StringUtilTest, SimpleItoa) {
EXPECT_EQ("10", SimpleItoa(10));
}
// Test TryStripPrefixString
TEST(StringUtilTest, TryStripPrefixString) {
string s;
EXPECT_TRUE(TryStripPrefixString("hello world", "hello", &s));
EXPECT_EQ(" world", s);
s.clear();
EXPECT_FALSE(TryStripPrefixString("hello world", "helloa", &s));
s.clear();
EXPECT_TRUE(TryStripPrefixString("hello world", "", &s));
EXPECT_EQ("hello world", s);
s.clear();
EXPECT_FALSE(TryStripPrefixString("", "hello", &s));
s.clear();
}
// Test HasSuffixString
TEST(StringUtilTest, HasSuffixString) {
EXPECT_TRUE(HasSuffixString("hello world", "hello world"));
EXPECT_TRUE(HasSuffixString("hello world", "world"));
EXPECT_FALSE(HasSuffixString("hello world", "world!"));
EXPECT_TRUE(HasSuffixString("hello world", ""));
EXPECT_FALSE(HasSuffixString("", "hello"));
}
// Test the StringHolder class
TEST(StringUtilTest, StringHolder) {
// Test with C string
static const char cstring[] = "aaa";
StringHolder sh1(cstring);
EXPECT_EQ(cstring, sh1.GetCString());
EXPECT_EQ(NULL, sh1.GetString());
// Test with std::string
string s = "bbb";
StringHolder sh2(s);
EXPECT_EQ(NULL, sh2.GetCString());
EXPECT_EQ(&s, sh2.GetString());
// Test GetLength()
string s2 = "hello";
StringHolder sh3(s2);
EXPECT_EQ(5, sh3.Length());
}
// Test the operator+=(string& lhs, const StringHolder& rhs) implementation
TEST(StringUtilTest, OperatorPlusEquals) {
// Test with a const char* string to append
string s = "h";
static const char append1[] = "ello";
s += StringHolder(append1); // force StringHolder usage
EXPECT_EQ("hello", s);
// Test with a std::string to append
s = "h";
string append2 = "ello";
s += StringHolder(append2); // force StringHolder usage
EXPECT_EQ("hello", s);
}
// Test the StrCat implementations
TEST(StringUtilTest, StrCat) {
string s;
// Test with 2 arguments
s = StrCat("a", "b");
EXPECT_EQ("ab", s);
// Test with 3 arguments
s = StrCat("a", "b", "c");
EXPECT_EQ("abc", s);
// Test with 4 arguments
s = StrCat("a", "b", "c", "d");
EXPECT_EQ("abcd", s);
// Test with 5 arguments
s = StrCat("a", "b", "c", "d", "e");
EXPECT_EQ("abcde", s);
// Test with 6 arguments
s = StrCat("a", "b", "c", "d", "e", "f");
EXPECT_EQ("abcdef", s);
// Test with 11 arguments
s = StrCat("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k");
EXPECT_EQ("abcdefghijk", s);
}
} // namespace phonenumbers
} // namespace i18n

Loading…
Cancel
Save