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; 49 ToLower (void) : loc(locale::classic()) {} 50 char operator() (char c) { return std::tolower(c, loc); } 51 }; 52 53 struct ToUpper 54 { 55 const locale& loc; 56 ToUpper (void) : loc(locale::classic()) {} 57 char operator() (char c) { return std::toupper(c, loc); } 58 }; 59 60 } // anonymous 61 62 //! Convert string to lowercase using the classic "C" locale 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 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 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 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. 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 116 char toUpper (char c) 117 { 118 return std::toupper(c, std::locale::classic()); 119 } 120 121 char toLower (char c) 122 { 123 return std::tolower(c, std::locale::classic()); 124 } 125 126 bool isUpper (char c) 127 { 128 return std::isupper(c, std::locale::classic()); 129 } 130 131 bool isLower (char c) 132 { 133 return std::islower(c, std::locale::classic()); 134 } 135 136 bool isDigit (char c) 137 { 138 return std::isdigit(c, std::locale::classic()); 139 } 140 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