Merge "Report tests using Draw*BaseVertex as NotSupported" am: f96636fdfa
[platform/upstream/VK-GL-CTS.git] / framework / delibs / decpp / deStringUtil.cpp
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 #include "deString.h"
26
27 #include <algorithm>
28 #include <iterator>
29 #include <sstream>
30 #include <locale>
31 #include <iomanip>
32 #include <cctype>
33
34 using std::locale;
35 using std::string;
36 using std::vector;
37 using std::istringstream;
38 using std::istream_iterator;
39
40 namespace de
41 {
42 namespace
43 {
44
45 // Always use locale::classic to ensure consistent behavior in all environments.
46
47 struct ToLower
48 {
49         const locale&   loc;
50                                         ToLower         (void) : loc(locale::classic()) {}
51         char                    operator()      (char c) { return std::tolower(c, loc); }
52 };
53
54 struct ToUpper
55 {
56         const locale&   loc;
57                                         ToUpper         (void) : loc(locale::classic()) {}
58         char                    operator()      (char c) { return std::toupper(c, loc); }
59 };
60
61 } // anonymous
62
63 //! Convert string to lowercase using the classic "C" locale
64 string toLower (const string& str)
65 {
66         string ret;
67         std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToLower());
68         return ret;
69 }
70
71 //! Convert string to uppercase using the classic "C" locale
72 string toUpper (const string& str)
73 {
74         string ret;
75         std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToUpper());
76         return ret;
77 }
78
79 //! Convert string's first character to uppercase using the classic "C" locale
80 string capitalize (const string& str)
81 {
82         if (str.empty())
83                 return str;
84         return ToUpper()(str[0]) + str.substr(1);
85 }
86
87 //! Split a string into tokens. If `delim` is `'\0'`, separate by spans of
88 //! whitespace. Otherwise use a single character `delim` as the separator.
89
90 vector<string> splitString (const string& s, char delim)
91 {
92         istringstream tokenStream(s);
93
94         if (delim == '\0')
95                 return vector<string>(istream_iterator<string>(tokenStream),
96                                                           istream_iterator<string>());
97         else
98         {
99                 vector<string>  ret;
100                 string                  token;
101
102                 while (std::getline(tokenStream, token, delim))
103                         ret.push_back(token);
104
105                 return ret;
106         }
107 }
108
109 //! Convert floating-point value to string with fixed number of fractional decimals.
110 std::string floatToString (float val, int precision)
111 {
112         std::ostringstream s;
113         s << std::fixed << std::setprecision(precision) << val;
114         return s.str();
115 }
116
117 bool beginsWith (const std::string& s, const std::string& prefix)
118 {
119         return deStringBeginsWith(s.c_str(), prefix.c_str()) == DE_TRUE;
120 }
121
122 bool endsWith (const std::string& s, const std::string& suffix)
123 {
124         if (suffix.length() > s.length())
125                 return false;
126         else
127         {
128                 const std::string::size_type offset = s.length() - suffix.length();
129                 return s.find(suffix, offset) == offset;
130         }
131 }
132
133 char toUpper (char c)
134 {
135         return std::toupper(c, std::locale::classic());
136 }
137
138 char toLower (char c)
139 {
140         return std::tolower(c, std::locale::classic());
141 }
142
143 bool isUpper (char c)
144 {
145         return std::isupper(c, std::locale::classic());
146 }
147
148 bool isLower (char c)
149 {
150         return std::islower(c, std::locale::classic());
151 }
152
153 bool isDigit (char c)
154 {
155         return std::isdigit(c, std::locale::classic());
156 }
157
158 void StringUtil_selfTest (void)
159 {
160
161         DE_TEST_ASSERT(toString(42) == "42");
162         DE_TEST_ASSERT(toString("foo") == "foo");
163         DE_TEST_ASSERT(toLower("FooBar") == "foobar");
164         DE_TEST_ASSERT(toUpper("FooBar") == "FOOBAR");
165
166         {
167                 vector <string> tokens(splitString(" foo bar\n\tbaz   "));
168                 DE_TEST_ASSERT(tokens.size() == 3);
169                 DE_TEST_ASSERT(tokens[0] == "foo");
170                 DE_TEST_ASSERT(tokens[1] == "bar");
171                 DE_TEST_ASSERT(tokens[2] == "baz");
172         }
173
174         DE_TEST_ASSERT(floatToString(4, 1) == "4.0");
175
176         DE_TEST_ASSERT(beginsWith("foobar", "foobar"));
177         DE_TEST_ASSERT(beginsWith("foobar", "foo"));
178         DE_TEST_ASSERT(beginsWith("foobar", "f"));
179         DE_TEST_ASSERT(beginsWith("foobar", ""));
180         DE_TEST_ASSERT(beginsWith("", ""));
181         DE_TEST_ASSERT(!beginsWith("foobar", "bar"));
182         DE_TEST_ASSERT(!beginsWith("foobar", "foobarbaz"));
183         DE_TEST_ASSERT(!beginsWith("", "foo"));
184
185         DE_TEST_ASSERT(endsWith("foobar", "foobar"));
186         DE_TEST_ASSERT(endsWith("foobar", "bar"));
187         DE_TEST_ASSERT(endsWith("foobar", "r"));
188         DE_TEST_ASSERT(endsWith("foobar", ""));
189         DE_TEST_ASSERT(endsWith("", ""));
190         DE_TEST_ASSERT(!endsWith("foobar", "foo"));
191         DE_TEST_ASSERT(!endsWith("foobar", "bazfoobar"));
192         DE_TEST_ASSERT(!endsWith("foobar", "foobarbaz"));
193         DE_TEST_ASSERT(!endsWith("", "foo"));
194
195         DE_TEST_ASSERT(toUpper('a') == 'A');
196         DE_TEST_ASSERT(toUpper('A') == 'A');
197         DE_TEST_ASSERT(toLower('a') == 'a');
198         DE_TEST_ASSERT(toLower('A') == 'a');
199         DE_TEST_ASSERT(isUpper('A'));
200         DE_TEST_ASSERT(!isUpper('a'));
201         DE_TEST_ASSERT(isLower('a'));
202         DE_TEST_ASSERT(!isLower('A'));
203         DE_TEST_ASSERT(isDigit('0'));
204         DE_TEST_ASSERT(!isDigit('a'));
205 }
206
207 } // de