• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*-------------------------------------------------------------------------
2   * drawElements C++ Base Library
3   * -----------------------------
4   *
5   * Copyright 2014 The Android Open Source Project
6   *
7   * Licensed under the Apache License, Version 2.0 (the "License");
8   * you may not use this file except in compliance with the License.
9   * You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   *
19   *//*!
20   * \file
21   * \brief String utilities.
22   *//*--------------------------------------------------------------------*/
23  
24  #include "deStringUtil.hpp"
25  #include "deString.h"
26  
27  #include <algorithm>
28  #include <iterator>
29  #include <sstream>
30  #include <locale>
31  #include <iomanip>
32  #include <cctype>
33  
34  using std::locale;
35  using std::string;
36  using std::vector;
37  using std::istringstream;
38  using std::istream_iterator;
39  
40  namespace de
41  {
42  namespace
43  {
44  
45  // Always use locale::classic to ensure consistent behavior in all environments.
46  
47  struct ToLower
48  {
49  	const locale&	loc;
ToLowerde::__anon68e20e3e0111::ToLower50  					ToLower		(void) : loc(locale::classic()) {}
operator ()de::__anon68e20e3e0111::ToLower51  	char			operator()	(char c) { return std::tolower(c, loc); }
52  };
53  
54  struct ToUpper
55  {
56  	const locale&	loc;
ToUpperde::__anon68e20e3e0111::ToUpper57  					ToUpper		(void) : loc(locale::classic()) {}
operator ()de::__anon68e20e3e0111::ToUpper58  	char			operator()	(char c) { return std::toupper(c, loc); }
59  };
60  
61  } // anonymous
62  
63  //! Convert string to lowercase using the classic "C" locale
toLower(const string & str)64  string toLower (const string& str)
65  {
66  	string ret;
67  	std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToLower());
68  	return ret;
69  }
70  
71  //! Convert string to uppercase using the classic "C" locale
toUpper(const string & str)72  string toUpper (const string& str)
73  {
74  	string ret;
75  	std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToUpper());
76  	return ret;
77  }
78  
79  //! Convert string's first character to uppercase using the classic "C" locale
capitalize(const string & str)80  string capitalize (const string& str)
81  {
82  	if (str.empty())
83  		return str;
84  	return ToUpper()(str[0]) + str.substr(1);
85  }
86  
87  //! Split a string into tokens. If `delim` is `'\0'`, separate by spans of
88  //! whitespace. Otherwise use a single character `delim` as the separator.
89  
splitString(const string & s,char delim)90  vector<string> splitString (const string& s, char delim)
91  {
92  	istringstream tokenStream(s);
93  
94  	if (delim == '\0')
95  		return vector<string>(istream_iterator<string>(tokenStream),
96  							  istream_iterator<string>());
97  	else
98  	{
99  		vector<string>	ret;
100  		string			token;
101  
102  		while (std::getline(tokenStream, token, delim))
103  			ret.push_back(token);
104  
105  		return ret;
106  	}
107  }
108  
109  //! Convert floating-point value to string with fixed number of fractional decimals.
floatToString(float val,int precision)110  std::string floatToString (float val, int precision)
111  {
112  	std::ostringstream s;
113  	s << std::fixed << std::setprecision(precision) << val;
114  	return s.str();
115  }
116  
beginsWith(const std::string & s,const std::string & prefix)117  bool beginsWith (const std::string& s, const std::string& prefix)
118  {
119  	return deStringBeginsWith(s.c_str(), prefix.c_str()) == DE_TRUE;
120  }
121  
endsWith(const std::string & s,const std::string & suffix)122  bool endsWith (const std::string& s, const std::string& suffix)
123  {
124  	if (suffix.length() > s.length())
125  		return false;
126  	else
127  	{
128  		const std::string::size_type offset = s.length() - suffix.length();
129  		return s.find(suffix, offset) == offset;
130  	}
131  }
132  
toUpper(char c)133  char toUpper (char c)
134  {
135  	return std::toupper(c, std::locale::classic());
136  }
137  
toLower(char c)138  char toLower (char c)
139  {
140  	return std::tolower(c, std::locale::classic());
141  }
142  
isUpper(char c)143  bool isUpper (char c)
144  {
145  	return std::isupper(c, std::locale::classic());
146  }
147  
isLower(char c)148  bool isLower (char c)
149  {
150  	return std::islower(c, std::locale::classic());
151  }
152  
isDigit(char c)153  bool isDigit (char c)
154  {
155  	return std::isdigit(c, std::locale::classic());
156  }
157  
StringUtil_selfTest(void)158  void StringUtil_selfTest (void)
159  {
160  
161  	DE_TEST_ASSERT(toString(42) == "42");
162  	DE_TEST_ASSERT(toString("foo") == "foo");
163  	DE_TEST_ASSERT(toLower("FooBar") == "foobar");
164  	DE_TEST_ASSERT(toUpper("FooBar") == "FOOBAR");
165  
166  	{
167  		vector <string> tokens(splitString(" foo bar\n\tbaz   "));
168  		DE_TEST_ASSERT(tokens.size() == 3);
169  		DE_TEST_ASSERT(tokens[0] == "foo");
170  		DE_TEST_ASSERT(tokens[1] == "bar");
171  		DE_TEST_ASSERT(tokens[2] == "baz");
172  	}
173  
174  	DE_TEST_ASSERT(floatToString(4, 1) == "4.0");
175  
176  	DE_TEST_ASSERT(beginsWith("foobar", "foobar"));
177  	DE_TEST_ASSERT(beginsWith("foobar", "foo"));
178  	DE_TEST_ASSERT(beginsWith("foobar", "f"));
179  	DE_TEST_ASSERT(beginsWith("foobar", ""));
180  	DE_TEST_ASSERT(beginsWith("", ""));
181  	DE_TEST_ASSERT(!beginsWith("foobar", "bar"));
182  	DE_TEST_ASSERT(!beginsWith("foobar", "foobarbaz"));
183  	DE_TEST_ASSERT(!beginsWith("", "foo"));
184  
185  	DE_TEST_ASSERT(endsWith("foobar", "foobar"));
186  	DE_TEST_ASSERT(endsWith("foobar", "bar"));
187  	DE_TEST_ASSERT(endsWith("foobar", "r"));
188  	DE_TEST_ASSERT(endsWith("foobar", ""));
189  	DE_TEST_ASSERT(endsWith("", ""));
190  	DE_TEST_ASSERT(!endsWith("foobar", "foo"));
191  	DE_TEST_ASSERT(!endsWith("foobar", "bazfoobar"));
192  	DE_TEST_ASSERT(!endsWith("foobar", "foobarbaz"));
193  	DE_TEST_ASSERT(!endsWith("", "foo"));
194  
195  	DE_TEST_ASSERT(toUpper('a') == 'A');
196  	DE_TEST_ASSERT(toUpper('A') == 'A');
197  	DE_TEST_ASSERT(toLower('a') == 'a');
198  	DE_TEST_ASSERT(toLower('A') == 'a');
199  	DE_TEST_ASSERT(isUpper('A'));
200  	DE_TEST_ASSERT(!isUpper('a'));
201  	DE_TEST_ASSERT(isLower('a'));
202  	DE_TEST_ASSERT(!isLower('A'));
203  	DE_TEST_ASSERT(isDigit('0'));
204  	DE_TEST_ASSERT(!isDigit('a'));
205  }
206  
207  } // de
208