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