13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements C++ Base Library
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -----------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief String utilities.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm>
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iterator>
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream>
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <locale>
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iomanip>
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cctype>
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::locale;
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::istringstream;
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::istream_iterator;
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace de
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Always use locale::classic to ensure consistent behavior in all environments.
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ToLower
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const locale&	loc;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ToLower 	(void) : loc(locale::classic()) {}
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	char			operator()	(char c) { return std::tolower(c, loc); }
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ToUpper
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const locale&	loc;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ToUpper 	(void) : loc(locale::classic()) {}
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	char			operator()	(char c) { return std::toupper(c, loc); }
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Convert string to lowercase using the classic "C" locale
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring toLower (const string& str)
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string ret;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToLower());
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Convert string to uppercase using the classic "C" locale
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring toUpper (const string& str)
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string ret;
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToUpper());
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Convert string's first character to uppercase using the classic "C" locale
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring capitalize (const string& str)
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (str.empty())
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return str;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ToUpper()(str[0]) + str.substr(1);
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Split a string into tokens. If `delim` is `'\0'`, separate by spans of
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! whitespace. Otherwise use a single character `delim` as the separator.
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<string> splitString (const string& s, char delim)
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	istringstream tokenStream(s);
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (delim == '\0')
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return vector<string>(istream_iterator<string>(tokenStream),
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							  istream_iterator<string>());
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<string>	ret;
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			token;
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (std::getline(tokenStream, token, delim))
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ret.push_back(token);
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return ret;
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Convert floating-point value to string with fixed number of fractional decimals.
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string floatToString (float val, int precision)
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream s;
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	s << std::fixed << std::setprecision(precision) << val;
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s.str();
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrychar toUpper (char c)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return std::toupper(c, std::locale::classic());
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrychar toLower (char c)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return std::tolower(c, std::locale::classic());
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool isUpper (char c)
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return std::isupper(c, std::locale::classic());
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool isLower (char c)
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return std::islower(c, std::locale::classic());
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool isDigit (char c)
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return std::isdigit(c, std::locale::classic());
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid StringUtil_selfTest (void)
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(toString(42) == "42");
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(toString("foo") == "foo");
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(toLower("FooBar") == "foobar");
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(toUpper("FooBar") == "FOOBAR");
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector <string> tokens(splitString(" foo bar\n\tbaz   "));
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(tokens.size() == 3);
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(tokens[0] == "foo");
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(tokens[1] == "bar");
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(tokens[2] == "baz");
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(floatToString(4, 1) == "4.0");
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(toUpper('a') == 'A');
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(toUpper('A') == 'A');
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(toLower('a') == 'a');
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(toLower('A') == 'a');
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(isUpper('A'));
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(!isUpper('a'));
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(isLower('a'));
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(!isLower('A'));
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(isDigit('0'));
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_TEST_ASSERT(!isDigit('a'));
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // de
172