• 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 
26 #include <algorithm>
27 #include <iterator>
28 #include <sstream>
29 #include <locale>
30 #include <iomanip>
31 #include <cctype>
32 
33 using std::locale;
34 using std::string;
35 using std::vector;
36 using std::istringstream;
37 using std::istream_iterator;
38 
39 namespace de
40 {
41 namespace
42 {
43 
44 // Always use locale::classic to ensure consistent behavior in all environments.
45 
46 struct ToLower
47 {
48 	const locale&	loc;
ToLowerde::__anon3cb02d0a0111::ToLower49 					ToLower 	(void) : loc(locale::classic()) {}
operator ()de::__anon3cb02d0a0111::ToLower50 	char			operator()	(char c) { return std::tolower(c, loc); }
51 };
52 
53 struct ToUpper
54 {
55 	const locale&	loc;
ToUpperde::__anon3cb02d0a0111::ToUpper56 					ToUpper 	(void) : loc(locale::classic()) {}
operator ()de::__anon3cb02d0a0111::ToUpper57 	char			operator()	(char c) { return std::toupper(c, loc); }
58 };
59 
60 } // anonymous
61 
62 //! Convert string to lowercase using the classic "C" locale
toLower(const string & str)63 string toLower (const string& str)
64 {
65 	string ret;
66 	std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToLower());
67 	return ret;
68 }
69 
70 //! Convert string to uppercase using the classic "C" locale
toUpper(const string & str)71 string toUpper (const string& str)
72 {
73 	string ret;
74 	std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToUpper());
75 	return ret;
76 }
77 
78 //! Convert string's first character to uppercase using the classic "C" locale
capitalize(const string & str)79 string capitalize (const string& str)
80 {
81 	if (str.empty())
82 		return str;
83 	return ToUpper()(str[0]) + str.substr(1);
84 }
85 
86 //! Split a string into tokens. If `delim` is `'\0'`, separate by spans of
87 //! whitespace. Otherwise use a single character `delim` as the separator.
88 
splitString(const string & s,char delim)89 vector<string> splitString (const string& s, char delim)
90 {
91 	istringstream tokenStream(s);
92 
93 	if (delim == '\0')
94 		return vector<string>(istream_iterator<string>(tokenStream),
95 							  istream_iterator<string>());
96 	else
97 	{
98 		vector<string>	ret;
99 		string			token;
100 
101 		while (std::getline(tokenStream, token, delim))
102 			ret.push_back(token);
103 
104 		return ret;
105 	}
106 }
107 
108 //! Convert floating-point value to string with fixed number of fractional decimals.
floatToString(float val,int precision)109 std::string floatToString (float val, int precision)
110 {
111 	std::ostringstream s;
112 	s << std::fixed << std::setprecision(precision) << val;
113 	return s.str();
114 }
115 
toUpper(char c)116 char toUpper (char c)
117 {
118 	return std::toupper(c, std::locale::classic());
119 }
120 
toLower(char c)121 char toLower (char c)
122 {
123 	return std::tolower(c, std::locale::classic());
124 }
125 
isUpper(char c)126 bool isUpper (char c)
127 {
128 	return std::isupper(c, std::locale::classic());
129 }
130 
isLower(char c)131 bool isLower (char c)
132 {
133 	return std::islower(c, std::locale::classic());
134 }
135 
isDigit(char c)136 bool isDigit (char c)
137 {
138 	return std::isdigit(c, std::locale::classic());
139 }
140 
StringUtil_selfTest(void)141 void StringUtil_selfTest (void)
142 {
143 
144 	DE_TEST_ASSERT(toString(42) == "42");
145 	DE_TEST_ASSERT(toString("foo") == "foo");
146 	DE_TEST_ASSERT(toLower("FooBar") == "foobar");
147 	DE_TEST_ASSERT(toUpper("FooBar") == "FOOBAR");
148 
149 	{
150 		vector <string> tokens(splitString(" foo bar\n\tbaz   "));
151 		DE_TEST_ASSERT(tokens.size() == 3);
152 		DE_TEST_ASSERT(tokens[0] == "foo");
153 		DE_TEST_ASSERT(tokens[1] == "bar");
154 		DE_TEST_ASSERT(tokens[2] == "baz");
155 	}
156 
157 	DE_TEST_ASSERT(floatToString(4, 1) == "4.0");
158 
159 	DE_TEST_ASSERT(toUpper('a') == 'A');
160 	DE_TEST_ASSERT(toUpper('A') == 'A');
161 	DE_TEST_ASSERT(toLower('a') == 'a');
162 	DE_TEST_ASSERT(toLower('A') == 'a');
163 	DE_TEST_ASSERT(isUpper('A'));
164 	DE_TEST_ASSERT(!isUpper('a'));
165 	DE_TEST_ASSERT(isLower('a'));
166 	DE_TEST_ASSERT(!isLower('A'));
167 	DE_TEST_ASSERT(isDigit('0'));
168 	DE_TEST_ASSERT(!isDigit('a'));
169 }
170 
171 } // de
172