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