blob: 04c70456218f6aeef4fec6fd957bf01a00d2607c [file] [log] [blame]
/*-------------------------------------------------------------------------
* drawElements C++ Base Library
* -----------------------------
*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief String utilities.
*//*--------------------------------------------------------------------*/
#include "deStringUtil.hpp"
#include "deString.h"
#include <algorithm>
#include <iterator>
#include <sstream>
#include <locale>
#include <iomanip>
#include <cctype>
using std::locale;
using std::string;
using std::vector;
using std::istringstream;
using std::istream_iterator;
namespace de
{
namespace
{
// Always use locale::classic to ensure consistent behavior in all environments.
struct ToLower
{
const locale& loc;
ToLower (void) : loc(locale::classic()) {}
char operator() (char c) { return std::tolower(c, loc); }
};
struct ToUpper
{
const locale& loc;
ToUpper (void) : loc(locale::classic()) {}
char operator() (char c) { return std::toupper(c, loc); }
};
} // anonymous
//! Convert string to lowercase using the classic "C" locale
string toLower (const string& str)
{
string ret;
std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToLower());
return ret;
}
//! Convert string to uppercase using the classic "C" locale
string toUpper (const string& str)
{
string ret;
std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToUpper());
return ret;
}
//! Convert string's first character to uppercase using the classic "C" locale
string capitalize (const string& str)
{
if (str.empty())
return str;
return ToUpper()(str[0]) + str.substr(1);
}
//! Split a string into tokens. If `delim` is `'\0'`, separate by spans of
//! whitespace. Otherwise use a single character `delim` as the separator.
vector<string> splitString (const string& s, char delim)
{
istringstream tokenStream(s);
if (delim == '\0')
return vector<string>(istream_iterator<string>(tokenStream),
istream_iterator<string>());
else
{
vector<string> ret;
string token;
while (std::getline(tokenStream, token, delim))
ret.push_back(token);
return ret;
}
}
//! Convert floating-point value to string with fixed number of fractional decimals.
std::string floatToString (float val, int precision)
{
std::ostringstream s;
s << std::fixed << std::setprecision(precision) << val;
return s.str();
}
bool beginsWith (const std::string& s, const std::string& prefix)
{
return deStringBeginsWith(s.c_str(), prefix.c_str()) == DE_TRUE;
}
bool endsWith (const std::string& s, const std::string& suffix)
{
if (suffix.length() > s.length())
return false;
else
{
const std::string::size_type offset = s.length() - suffix.length();
return s.find(suffix, offset) == offset;
}
}
char toUpper (char c)
{
return std::toupper(c, std::locale::classic());
}
char toLower (char c)
{
return std::tolower(c, std::locale::classic());
}
bool isUpper (char c)
{
return std::isupper(c, std::locale::classic());
}
bool isLower (char c)
{
return std::islower(c, std::locale::classic());
}
bool isDigit (char c)
{
return std::isdigit(c, std::locale::classic());
}
void StringUtil_selfTest (void)
{
DE_TEST_ASSERT(toString(42) == "42");
DE_TEST_ASSERT(toString("foo") == "foo");
DE_TEST_ASSERT(toLower("FooBar") == "foobar");
DE_TEST_ASSERT(toUpper("FooBar") == "FOOBAR");
{
vector <string> tokens(splitString(" foo bar\n\tbaz "));
DE_TEST_ASSERT(tokens.size() == 3);
DE_TEST_ASSERT(tokens[0] == "foo");
DE_TEST_ASSERT(tokens[1] == "bar");
DE_TEST_ASSERT(tokens[2] == "baz");
}
DE_TEST_ASSERT(floatToString(4, 1) == "4.0");
DE_TEST_ASSERT(beginsWith("foobar", "foobar"));
DE_TEST_ASSERT(beginsWith("foobar", "foo"));
DE_TEST_ASSERT(beginsWith("foobar", "f"));
DE_TEST_ASSERT(beginsWith("foobar", ""));
DE_TEST_ASSERT(beginsWith("", ""));
DE_TEST_ASSERT(!beginsWith("foobar", "bar"));
DE_TEST_ASSERT(!beginsWith("foobar", "foobarbaz"));
DE_TEST_ASSERT(!beginsWith("", "foo"));
DE_TEST_ASSERT(endsWith("foobar", "foobar"));
DE_TEST_ASSERT(endsWith("foobar", "bar"));
DE_TEST_ASSERT(endsWith("foobar", "r"));
DE_TEST_ASSERT(endsWith("foobar", ""));
DE_TEST_ASSERT(endsWith("", ""));
DE_TEST_ASSERT(!endsWith("foobar", "foo"));
DE_TEST_ASSERT(!endsWith("foobar", "bazfoobar"));
DE_TEST_ASSERT(!endsWith("foobar", "foobarbaz"));
DE_TEST_ASSERT(!endsWith("", "foo"));
DE_TEST_ASSERT(toUpper('a') == 'A');
DE_TEST_ASSERT(toUpper('A') == 'A');
DE_TEST_ASSERT(toLower('a') == 'a');
DE_TEST_ASSERT(toLower('A') == 'a');
DE_TEST_ASSERT(isUpper('A'));
DE_TEST_ASSERT(!isUpper('a'));
DE_TEST_ASSERT(isLower('a'));
DE_TEST_ASSERT(!isLower('A'));
DE_TEST_ASSERT(isDigit('0'));
DE_TEST_ASSERT(!isDigit('a'));
}
} // de