mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-21 22:13:25 -06:00
1565 lines
52 KiB
C++
1565 lines
52 KiB
C++
//##################################################################################################
|
|
//
|
|
// Custom Visualization Core library
|
|
// Copyright (C) 2011-2013 Ceetron AS
|
|
//
|
|
// This library may be used under the terms of either the GNU General Public License or
|
|
// the GNU Lesser General Public License as follows:
|
|
//
|
|
// GNU General Public License Usage
|
|
// This library is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
|
// for more details.
|
|
//
|
|
// GNU Lesser General Public License Usage
|
|
// This library is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
// the Free Software Foundation; either version 2.1 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
|
// for more details.
|
|
//
|
|
//##################################################################################################
|
|
|
|
|
|
#include "cvfBase.h"
|
|
#include "cvfString.h"
|
|
#include "cvfSystem.h"
|
|
#include "cvfMath.h"
|
|
|
|
#include <vector>
|
|
#include <sstream>
|
|
#include <iomanip>
|
|
#include <cstring>
|
|
#include <cctype>
|
|
#include <limits>
|
|
#include <iosfwd>
|
|
|
|
namespace cvf {
|
|
|
|
|
|
|
|
//==================================================================================================
|
|
///
|
|
/// \class cvf::String
|
|
/// \ingroup Core
|
|
///
|
|
/// A general unicode based string class.
|
|
///
|
|
/// The string class supports conversion to and from
|
|
/// - std::string
|
|
/// - std::wstring
|
|
/// - const char*
|
|
/// - const wchar_t*
|
|
///
|
|
/// A separate class cvf::CharArray is used to be able to support the toAscii() method (conversion
|
|
/// to a const char* string).
|
|
///
|
|
//==================================================================================================
|
|
|
|
const size_t String::npos = static_cast<size_t>(-1);
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Constructor
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String()
|
|
{
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a string from the given std::string
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String(const std::string& str)
|
|
{
|
|
m_string.resize(str.size(), L' ');
|
|
std::copy(str.begin(), str.end(), m_string.begin());
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a string from the given std::wstring
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String(const std::wstring& str)
|
|
{
|
|
m_string = str;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a string from the given String
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String(const String& str)
|
|
{
|
|
m_string = str.m_string;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a string from the given char* string
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String(const char* str)
|
|
{
|
|
if (str != NULL)
|
|
{
|
|
// Raw conversion, no UTF8
|
|
m_string = std::wstring(str, str + strlen(str));
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a string from the given wchar_t* string
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String(const wchar_t* str)
|
|
{
|
|
if (str != NULL)
|
|
{
|
|
m_string = str;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a string from the given char
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String(char c)
|
|
{
|
|
std::wstringstream sstr;
|
|
sstr << c;
|
|
m_string = sstr.str();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a string from the given integer (using default formatting)
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String(int number)
|
|
{
|
|
std::wstringstream sstr;
|
|
sstr << number;
|
|
m_string = sstr.str();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a string from the given 64 bit integer (using default formatting)
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String(int64 number)
|
|
{
|
|
std::wstringstream sstr;
|
|
sstr << number;
|
|
m_string = sstr.str();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a string from the given unsigned integer (using default formatting)
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String(uint number)
|
|
{
|
|
std::wstringstream sstr;
|
|
sstr << number;
|
|
m_string = sstr.str();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a string from the given float (using default formatting)
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String(float number)
|
|
{
|
|
std::wstringstream sstr;
|
|
sstr << number;
|
|
m_string = sstr.str();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a string from the given double (using default formatting)
|
|
//--------------------------------------------------------------------------------------------------
|
|
String::String(double number)
|
|
{
|
|
std::wstringstream sstr;
|
|
sstr << number;
|
|
m_string = sstr.str();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Set the contents of this string to the passed string
|
|
//--------------------------------------------------------------------------------------------------
|
|
String& String::operator=(String rhs)
|
|
{
|
|
// Copy-and-swap (copy already done since parameter is passed by value)
|
|
rhs.swap(*this);
|
|
return *this;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Check if this string is equal to the passed string
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool String::operator==(const String& rhs) const
|
|
{
|
|
return m_string == rhs.m_string;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Check if this string is equal to the passed wchar_t* string
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool String::operator==(const wchar_t* rhs) const
|
|
{
|
|
return m_string == rhs;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Check if this string is less than the passed string
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool String::operator<(const String& rhs) const
|
|
{
|
|
return m_string < rhs.m_string;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Check if this string is not equal to the passed string
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool String::operator!=(const String& rhs) const
|
|
{
|
|
return !operator==(rhs);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Return the concatenation of this string and the passed string (rhs)
|
|
//--------------------------------------------------------------------------------------------------
|
|
const String String::operator+(const String& rhs) const
|
|
{
|
|
std::wstring sum = m_string + rhs.m_string;
|
|
|
|
return sum;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Set this string to the concatenation of this string and the passed string (rhs)
|
|
//--------------------------------------------------------------------------------------------------
|
|
String& String::operator+=(const String& rhs)
|
|
{
|
|
m_string += rhs.m_string;
|
|
return *this;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Get a const ref to the unicode character at the given position
|
|
//--------------------------------------------------------------------------------------------------
|
|
const wchar_t& String::operator[](size_t pos) const
|
|
{
|
|
CVF_TIGHT_ASSERT(pos < size());
|
|
|
|
return m_string[pos];
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Get a modifiable ref to the unicode character at the given position
|
|
//--------------------------------------------------------------------------------------------------
|
|
wchar_t& String::operator[](size_t pos)
|
|
{
|
|
CVF_TIGHT_ASSERT(pos < size());
|
|
|
|
return m_string[pos];
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns true if the string has no characters, otherwise returns false.
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool String::isEmpty() const
|
|
{
|
|
return m_string.empty();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns the length of the string
|
|
//--------------------------------------------------------------------------------------------------
|
|
size_t String::size() const
|
|
{
|
|
return m_string.size();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void String::resize(size_t size)
|
|
{
|
|
m_string.resize(size);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns a lowercase copy of the string.
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::toLower() const
|
|
{
|
|
std::wstring retStr;
|
|
|
|
size_t strLen = m_string.size();
|
|
if (strLen > 0)
|
|
{
|
|
retStr.resize(strLen);
|
|
|
|
size_t i;
|
|
for (i = 0; i < strLen; ++i)
|
|
{
|
|
retStr[i] = towlower(m_string[i]);
|
|
}
|
|
}
|
|
|
|
return retStr;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns an uppercase copy of the string.
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::toUpper() const
|
|
{
|
|
std::wstring retStr;
|
|
|
|
size_t strLen = m_string.size();
|
|
if (strLen > 0)
|
|
{
|
|
retStr.resize(strLen);
|
|
|
|
size_t i;
|
|
for (i = 0; i < strLen; ++i)
|
|
{
|
|
retStr[i] = towupper(m_string[i]);
|
|
}
|
|
}
|
|
|
|
return retStr;
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns string with trailing whitespace removed
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::trimmedRight() const
|
|
{
|
|
// Same whitespace characters as isspace()
|
|
const std::wstring whitespaces(L" \t\n\v\f\r");
|
|
|
|
size_t pos = m_string.find_last_not_of(whitespaces);
|
|
if (pos != std::wstring::npos)
|
|
{
|
|
std::wstring retStr(m_string);
|
|
retStr.erase(pos + 1);
|
|
return retStr;
|
|
}
|
|
else
|
|
{
|
|
// string is all whitespace
|
|
return String();
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns string with leading whitespace removed
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::trimmedLeft() const
|
|
{
|
|
// Same whitespace characters as isspace()
|
|
const std::wstring whitespaces(L" \t\n\v\f\r");
|
|
|
|
size_t pos = m_string.find_first_not_of(whitespaces);
|
|
if (pos != std::wstring::npos)
|
|
{
|
|
std::wstring retStr = m_string.substr(pos);
|
|
return retStr;
|
|
}
|
|
else
|
|
{
|
|
return String();
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Return string with leading and trailing whitespace removed
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::trimmed() const
|
|
{
|
|
// Same whitespace characters as isspace()
|
|
const std::wstring whitespaces(L" \t\n\v\f\r");
|
|
|
|
size_t startpos = m_string.find_first_not_of(whitespaces);
|
|
size_t endpos = m_string.find_last_not_of(whitespaces);
|
|
|
|
// If all spaces or empty return an empty string
|
|
if ((startpos == std::wstring::npos) || (endpos == std::wstring::npos))
|
|
{
|
|
return String();
|
|
}
|
|
else
|
|
{
|
|
std::wstring retStr = m_string.substr(startpos, endpos - startpos + 1);
|
|
return retStr;
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns simplified string.
|
|
///
|
|
/// Strips leading and trailing whitespace. Replaces sequences of internal whitespace with one space
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::simplified() const
|
|
{
|
|
// Get rid of leading and trailing whitespace
|
|
String str = this->trimmed();
|
|
|
|
std::wstring newStr;
|
|
size_t length = str.size();
|
|
size_t i;
|
|
for (i = 0; i < length; i++)
|
|
{
|
|
bool charIsWhitespace = iswspace(str[i]) ? true : false;
|
|
if (charIsWhitespace && i > 0 && iswspace(str[i - 1]))
|
|
{
|
|
}
|
|
else
|
|
{
|
|
if (charIsWhitespace)
|
|
{
|
|
// replace whitespace with space
|
|
newStr += L" ";
|
|
}
|
|
else
|
|
{
|
|
newStr += str[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return String(newStr);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Get the string as an ASCII 8 bit char text.
|
|
///
|
|
/// A CharArray is used as a transport vehicle. This class has a ptr() method which allows for
|
|
/// conversion to const char*.\n
|
|
/// To get a const char pointer, do the following:
|
|
/// \code
|
|
/// System::strcpy(szString, 20, myString.toAscii().ptr());
|
|
/// \endcode
|
|
///
|
|
/// \sa CharArray
|
|
//--------------------------------------------------------------------------------------------------
|
|
CharArray String::toAscii() const
|
|
{
|
|
CharArray ascii;
|
|
|
|
size_t numUnicodeChars = m_string.size();
|
|
size_t i;
|
|
for(i = 0; i < numUnicodeChars; i++)
|
|
{
|
|
unsigned int uc = m_string[i];
|
|
if (uc < 0xff)
|
|
{
|
|
ascii.push_back(static_cast<char>(uc));
|
|
}
|
|
else
|
|
{
|
|
ascii.push_back('?');
|
|
}
|
|
}
|
|
|
|
return ascii;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert a string to a std::string.
|
|
///
|
|
/// Note that conversion is done via a call to toAscii()
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::string String::toStdString() const
|
|
{
|
|
CharArray array = toAscii();
|
|
std::string str = array.ptr();
|
|
|
|
return str;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert a string to a std::wstring (std unicode string)
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::wstring String::toStdWString() const
|
|
{
|
|
return m_string;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
CharArray String::toUtf8() const
|
|
{
|
|
// From http://www.codeguru.com/cpp/misc/misc/multi-lingualsupport/article.php/c10451
|
|
static const unsigned int MASKBITS = 0x3F;
|
|
static const unsigned int MASKBYTE = 0x80;
|
|
static const unsigned int MASK2BYTES = 0xC0;
|
|
static const unsigned int MASK3BYTES = 0xE0;
|
|
static const unsigned int MASK4BYTES = 0xF0;
|
|
static const unsigned int MASK5BYTES = 0xF8;
|
|
static const unsigned int MASK6BYTES = 0xFC;
|
|
|
|
size_t numUnicodeChars = m_string.size();
|
|
|
|
CharArray charArr;
|
|
|
|
size_t i;
|
|
for(i = 0; i < numUnicodeChars; i++)
|
|
{
|
|
unsigned int uc = m_string[i];
|
|
|
|
// 0xxxxxxx
|
|
if (uc < 0x80)
|
|
{
|
|
charArr.push_back(static_cast<char>(uc));
|
|
}
|
|
// 110xxxxx 10xxxxxx
|
|
else if (uc < 0x800)
|
|
{
|
|
charArr.push_back(static_cast<char>(MASK2BYTES | (uc >> 6)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | (uc & MASKBITS)));
|
|
}
|
|
// 1110xxxx 10xxxxxx 10xxxxxx
|
|
else if (uc < 0x10000)
|
|
{
|
|
charArr.push_back(static_cast<char>(MASK3BYTES | (uc >> 12)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | ((uc >> 6) & MASKBITS)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | (uc & MASKBITS)));
|
|
}
|
|
|
|
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
else if (uc < 0x200000)
|
|
{
|
|
charArr.push_back(static_cast<char>(MASK4BYTES | (uc >> 18)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | ((uc >> 12) & MASKBITS)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | ((uc >> 6) & MASKBITS)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | (uc & MASKBITS)));
|
|
}
|
|
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
else if (uc < 0x4000000)
|
|
{
|
|
charArr.push_back(static_cast<char>(MASK5BYTES | (uc >> 24)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | ((uc >> 18) & MASKBITS)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | ((uc >> 12) & MASKBITS)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | ((uc >> 6) & MASKBITS)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | (uc & MASKBITS)));
|
|
}
|
|
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
else if (uc < 0x8000000)
|
|
{
|
|
charArr.push_back(static_cast<char>(MASK6BYTES | (uc >> 30)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | ((uc >> 18) & MASKBITS)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | ((uc >> 12) & MASKBITS)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | ((uc >> 6) & MASKBITS)));
|
|
charArr.push_back(static_cast<char>(MASKBYTE | (uc & MASKBITS)));
|
|
}
|
|
}
|
|
|
|
return charArr;
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns a String initialized with the first \a strSize characters from the string str
|
|
///
|
|
/// If \a strSize is npos, this function will compute the length of the string.
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::String String::fromAscii(const char* str, size_t strSize)
|
|
{
|
|
if (str != NULL)
|
|
{
|
|
if (strSize == npos)
|
|
{
|
|
strSize = strlen(str);
|
|
}
|
|
|
|
// Raw conversion, no UTF8
|
|
return String(std::wstring(str, str + strSize));
|
|
}
|
|
else
|
|
{
|
|
return String();
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::fromUtf8(const char* utfStr)
|
|
{
|
|
// From http://www.codeguru.com/cpp/misc/misc/multi-lingualsupport/article.php/c10451
|
|
static const unsigned int MASKBITS = 0x3F;
|
|
//static const unsigned int MASKBYTE = 0x80;
|
|
static const unsigned int MASK2BYTES = 0xC0;
|
|
static const unsigned int MASK3BYTES = 0xE0;
|
|
static const unsigned int MASK4BYTES = 0xF0;
|
|
static const unsigned int MASK5BYTES = 0xF8;
|
|
static const unsigned int MASK6BYTES = 0xFC;
|
|
|
|
|
|
size_t utfStringLength = System::strlen(utfStr);
|
|
if (utfStringLength == 0)
|
|
{
|
|
return String();
|
|
}
|
|
|
|
|
|
std::wstring uStr;
|
|
|
|
size_t i = 0;
|
|
while (i < utfStringLength)
|
|
{
|
|
// 4 byte unicode character
|
|
unsigned int unicodeChar = 0;
|
|
|
|
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
if ((utfStr[i] & MASK6BYTES) == MASK6BYTES)
|
|
{
|
|
if (i + 5 < utfStringLength)
|
|
{
|
|
unicodeChar = ((utfStr[i] & 0x01) << 30) | ((utfStr[i + 1] & MASKBITS) << 24) | ((utfStr[i + 2] & MASKBITS) << 18) | ((utfStr[i + 3] & MASKBITS) << 12) | ((utfStr[i + 4] & MASKBITS) << 6) | (utfStr[i + 5] & MASKBITS);
|
|
}
|
|
|
|
i += 6;
|
|
}
|
|
|
|
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
else if ((utfStr[i] & MASK5BYTES) == MASK5BYTES)
|
|
{
|
|
if (i + 4 < utfStringLength)
|
|
{
|
|
unicodeChar = ((utfStr[i] & 0x03) << 24) | ((utfStr[i + 1] & MASKBITS) << 18) | ((utfStr[i + 2] & MASKBITS) << 12) | ((utfStr[i + 3] & MASKBITS) << 6) | (utfStr[i + 4] & MASKBITS);
|
|
}
|
|
|
|
i += 5;
|
|
}
|
|
|
|
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
else if ((utfStr[i] & MASK4BYTES) == MASK4BYTES)
|
|
{
|
|
if (i + 3 < utfStringLength)
|
|
{
|
|
unicodeChar = ((utfStr[i] & 0x07) << 18) | ((utfStr[i + 1] & MASKBITS) << 12) | ((utfStr[i + 2] & MASKBITS) << 6) | (utfStr[i + 3] & MASKBITS);
|
|
}
|
|
|
|
i += 4;
|
|
}
|
|
|
|
|
|
// 1110xxxx 10xxxxxx 10xxxxxx
|
|
else if ((utfStr[i] & MASK3BYTES) == MASK3BYTES)
|
|
{
|
|
if (i + 2 < utfStringLength)
|
|
{
|
|
unicodeChar = ((utfStr[i] & 0x0F) << 12) | ((utfStr[i + 1] & MASKBITS) << 6) | (utfStr[i + 2] & MASKBITS);
|
|
}
|
|
|
|
i += 3;
|
|
}
|
|
|
|
// 110xxxxx 10xxxxxx
|
|
else if ((utfStr[i] & MASK2BYTES) == MASK2BYTES)
|
|
{
|
|
if (i + 1 < utfStringLength)
|
|
{
|
|
unicodeChar = ((utfStr[i] & 0x1F) << 6) | (utfStr[i + 1] & MASKBITS);
|
|
}
|
|
|
|
i += 2;
|
|
}
|
|
|
|
// 0xxxxxxx (utfStr[i] < MASKBYTE)
|
|
else
|
|
{
|
|
CVF_TIGHT_ASSERT(utfStr[i] >= 0);
|
|
unicodeChar = static_cast<unsigned int>(utfStr[i]);
|
|
i += 1;
|
|
}
|
|
|
|
wchar_t uc = static_cast<wchar_t>(unicodeChar);
|
|
uStr.push_back(uc);
|
|
}
|
|
|
|
return String(uStr);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns a null-terminated sequence of wchar_t characters
|
|
//--------------------------------------------------------------------------------------------------
|
|
const wchar_t* String::c_str() const
|
|
{
|
|
return m_string.c_str();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert the given number to a string with the specified format
|
|
///
|
|
/// \param n The number to convert
|
|
/// \param format 'g': default, 'e' : scientific notation (1.234e4). 'f' : Fixed notation (1234.0)
|
|
/// \param precision The precision for floating-point values. Only used for 'f' and 'e'
|
|
///
|
|
/// \return A string with the given number
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::number(float n, char format, int precision)
|
|
{
|
|
std::wstringstream sstr;
|
|
|
|
switch(format)
|
|
{
|
|
case 'g' : sstr << n; break;
|
|
case 'f' : sstr << std::fixed << std::setprecision(precision) << n; break;
|
|
case 'e' : sstr << std::scientific << std::setprecision(precision) << n; break;
|
|
}
|
|
|
|
std::wstring str = sstr.str();
|
|
return str;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert the contents of the string to a double value (if possible)
|
|
///
|
|
/// \param ok If not NULL, this will be set to true if conversion is ok, or to false if not
|
|
///
|
|
/// \return Returns the double value found at the start of the string. 0.0 if an error occurred.
|
|
//--------------------------------------------------------------------------------------------------
|
|
double String::toDouble(bool* ok) const
|
|
{
|
|
double val = 0;
|
|
std::wstringstream stream(m_string);
|
|
stream >> val;
|
|
|
|
bool convertOk = !stream.fail();
|
|
|
|
if (ok)
|
|
{
|
|
*ok = convertOk;
|
|
}
|
|
|
|
if (convertOk)
|
|
{
|
|
return val;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert the contents of the string to a double value (if possible)
|
|
///
|
|
/// \param defaultValue The value returned if the conversion failed.
|
|
///
|
|
/// \return Returns the double value found at the start of the string or defaultValue if the
|
|
/// conversion was not possible.
|
|
//--------------------------------------------------------------------------------------------------
|
|
double String::toDouble(double defaultValue) const
|
|
{
|
|
bool ok = false;
|
|
double val = toDouble(&ok);
|
|
if (ok)
|
|
{
|
|
return val;
|
|
}
|
|
else
|
|
{
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert the contents of the string to a float value (if possible)
|
|
///
|
|
/// \param ok If not NULL, this will be set to true if conversion is ok, or to false if not
|
|
///
|
|
/// \return Returns the float value found at the start of the string. 0.0f if an error occurred.
|
|
//--------------------------------------------------------------------------------------------------
|
|
float String::toFloat(bool* ok) const
|
|
{
|
|
float val = 0;
|
|
std::wstringstream stream(m_string);
|
|
stream >> val;
|
|
|
|
bool convertOk = !stream.fail();
|
|
|
|
if (ok)
|
|
{
|
|
*ok = convertOk;
|
|
}
|
|
|
|
if (convertOk)
|
|
{
|
|
return val;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert the contents of the string to a float value (if possible)
|
|
///
|
|
/// \param defaultValue The value returned if the conversion failed.
|
|
///
|
|
/// \return Returns the float value found at the start of the string or defaultValue if the
|
|
/// conversion was not possible.
|
|
//--------------------------------------------------------------------------------------------------
|
|
float String::toFloat(float defaultValue) const
|
|
{
|
|
bool ok = false;
|
|
float val = toFloat(&ok);
|
|
if (ok)
|
|
{
|
|
return val;
|
|
}
|
|
else
|
|
{
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert the contents of the string to a integer value (if possible)
|
|
///
|
|
/// \param ok If not NULL, this will be set to true if conversion is ok, or to false if not
|
|
///
|
|
/// \return Returns the integer value found at the start of the string. 0 if an error occurred.
|
|
//--------------------------------------------------------------------------------------------------
|
|
int String::toInt(bool* ok) const
|
|
{
|
|
int val = 0;
|
|
std::wstringstream stream(m_string);
|
|
stream >> val;
|
|
|
|
bool convertOk = !stream.fail();
|
|
|
|
if (ok)
|
|
{
|
|
*ok = convertOk;
|
|
}
|
|
|
|
if (convertOk)
|
|
{
|
|
return val;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert the contents of the string to a integer value (if possible)
|
|
///
|
|
/// \param defaultValue The value returned if the conversion failed.
|
|
///
|
|
/// \return Returns the integer value found at the start of the string or defaultValue if the
|
|
/// conversion was not possible.
|
|
//--------------------------------------------------------------------------------------------------
|
|
int String::toInt(int defaultValue) const
|
|
{
|
|
bool ok = false;
|
|
int val = toInt(&ok);
|
|
if (ok)
|
|
{
|
|
return val;
|
|
}
|
|
else
|
|
{
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert the contents of the string to an unsigned integer value
|
|
///
|
|
/// \param ok If not NULL, this will be set to true if conversion is ok, or to false if not
|
|
///
|
|
/// \return Returns the unsigned integer value found at the start of the string. 0 if an error occurred.
|
|
//--------------------------------------------------------------------------------------------------
|
|
uint String::toUInt(bool* ok) const
|
|
{
|
|
// The functions in the standard library does not honor unsignedness but gladly converts a negative integer
|
|
// to an unsigned integer, so use our int64 implementation instead
|
|
bool convertOk = false;
|
|
int64 val = toInt64(&convertOk);
|
|
if (convertOk)
|
|
{
|
|
if (val > std::numeric_limits<uint>::max() || val < 0)
|
|
{
|
|
convertOk = false;
|
|
}
|
|
}
|
|
|
|
if (ok)
|
|
{
|
|
*ok = convertOk;
|
|
}
|
|
|
|
if (convertOk)
|
|
{
|
|
return static_cast<uint>(val);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert the contents of the string to an unsigned integer value
|
|
///
|
|
/// \param defaultValue The value returned if the conversion failed.
|
|
///
|
|
/// \return Returns the value found at the start of the string or defaultValue if the
|
|
/// conversion was not possible.
|
|
//--------------------------------------------------------------------------------------------------
|
|
uint String::toUInt(uint defaultValue) const
|
|
{
|
|
bool ok = false;
|
|
uint val = toUInt(&ok);
|
|
if (ok)
|
|
{
|
|
return val;
|
|
}
|
|
else
|
|
{
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
int64 String::toInt64(bool* ok) const
|
|
{
|
|
int64 val = 0;
|
|
std::wstringstream stream(m_string);
|
|
stream >> val;
|
|
|
|
bool convertOk = !stream.fail();
|
|
|
|
if (ok)
|
|
{
|
|
*ok = convertOk;
|
|
}
|
|
|
|
if (convertOk)
|
|
{
|
|
return val;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
int64 String::toInt64(int64 defaultValue) const
|
|
{
|
|
bool ok = false;
|
|
int64 val = toInt64(&ok);
|
|
if (ok)
|
|
{
|
|
return val;
|
|
}
|
|
else
|
|
{
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert the given number to a string with the specified format
|
|
///
|
|
/// \param n The number to convert
|
|
/// \param format 'g': default, 'e' : scientific notation (1.234e4). 'f' : Fixed notation (1234.0)
|
|
/// \param precision The precision for floating-point values. Only used for 'f' and 'e'
|
|
///
|
|
/// \return A string with the given number
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::number(double n, char format, int precision)
|
|
{
|
|
std::wstringstream sstr;
|
|
|
|
switch(format)
|
|
{
|
|
case 'g' : sstr << n; break;
|
|
case 'f' : sstr << std::fixed << std::setprecision(precision) << n; break;
|
|
case 'e' : sstr << std::scientific << std::setprecision(precision) << n; break;
|
|
}
|
|
|
|
std::wstring str = sstr.str();
|
|
return str;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// To allow String s1 = "Test" + s2;
|
|
//--------------------------------------------------------------------------------------------------
|
|
String operator+(const char* str1, const String& str2)
|
|
{
|
|
return String(str1) + str2;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Create a collection of token string based on specified delimiters.
|
|
///
|
|
/// \param delimiters String containing characters used to split into token strings
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<String> String::split(const String& delimiters) const
|
|
{
|
|
std::vector<String> tokens;
|
|
if (size() == 0) return tokens;
|
|
|
|
std::wstring stdString = m_string;
|
|
std::wstring stdDelimiters = delimiters.toStdWString();
|
|
|
|
std::wstring::size_type lastPos = stdString.find_first_not_of(stdDelimiters, 0);
|
|
std::wstring::size_type pos = stdString.find_first_of(stdDelimiters, lastPos);
|
|
|
|
while (std::wstring::npos != pos || std::wstring::npos != lastPos)
|
|
{
|
|
std::wstring stdToken = stdString.substr(lastPos, pos - lastPos);
|
|
tokens.push_back(String(stdToken));
|
|
lastPos = stdString.find_first_not_of(stdDelimiters, pos);
|
|
pos = stdString.find_first_of(stdDelimiters, lastPos);
|
|
}
|
|
|
|
return tokens;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns the position of the first occurrence of str starting from start
|
|
/// Returns String::npos if not found
|
|
//--------------------------------------------------------------------------------------------------
|
|
size_t String::find(const String& str, size_t start) const
|
|
{
|
|
std::wstring stdFindStr= str.toStdWString();
|
|
std::wstring::size_type pos = m_string.find(stdFindStr, start);
|
|
|
|
if (pos == std::string::npos)
|
|
{
|
|
return npos;
|
|
}
|
|
|
|
return pos;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool String::startsWith(const String& str) const
|
|
{
|
|
return (find(str) == 0);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::subString(size_t pos, size_t length) const
|
|
{
|
|
CVF_ASSERT(pos < size());
|
|
|
|
return m_string.substr(pos, length);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Replaces occurrences of the string \a before with the string \a after
|
|
//--------------------------------------------------------------------------------------------------
|
|
void String::replace(const String& before, const String& after)
|
|
{
|
|
// Guard against empty string to avoid endless loop
|
|
if (before.isEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Try and find the first match, next is npos if nothing was found
|
|
std::wstring::size_type next = m_string.find(before.m_string);
|
|
while (next != std::wstring::npos)
|
|
{
|
|
// Inside the loop, so we found a match. Do the replacement.
|
|
m_string.replace(next, before.m_string.length(), after.m_string);
|
|
|
|
// Move to just after the replace
|
|
// This is the point were we start the next search from.
|
|
next += after.m_string.length();
|
|
|
|
// Search for the next match starting after the last match that was found.
|
|
next = m_string.find(before.m_string, next);
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Convert a wchar_t to a single digit. Return -1 if not between 0-9
|
|
//--------------------------------------------------------------------------------------------------
|
|
int digitValue(const wchar_t& character)
|
|
{
|
|
int val = character - '0';
|
|
if (val < 0 || val > 9)
|
|
{
|
|
val = -1;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
|
|
// Local helper struct for storing found arg info
|
|
struct ArgInfo
|
|
{
|
|
int smallestArgIndex; // lowest %x sequence number
|
|
int smallestArgCount; // number of occurrences of the lowest #x sequence number
|
|
int totalArgLength; // total length of %x sequences which will be replaced
|
|
};
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Find the smallest %x, and count the number of occurrences and the total length used by them
|
|
//--------------------------------------------------------------------------------------------------
|
|
static ArgInfo findSmallestArgs(const String &s)
|
|
{
|
|
const wchar_t* strBegin = s.c_str();
|
|
const wchar_t* strEnd = strBegin + s.size();
|
|
|
|
ArgInfo argInfo;
|
|
|
|
argInfo.smallestArgIndex = UNDEFINED_INT;
|
|
argInfo.smallestArgCount = 0;
|
|
argInfo.totalArgLength = 0;
|
|
|
|
const wchar_t* c = strBegin;
|
|
while (c != strEnd)
|
|
{
|
|
while (c != strEnd && *c != '%')
|
|
{
|
|
++c;
|
|
}
|
|
|
|
if (c == strEnd)
|
|
{
|
|
break;
|
|
}
|
|
|
|
const wchar_t* argStart = c;
|
|
|
|
if (++c == strEnd)
|
|
{
|
|
break;
|
|
}
|
|
|
|
int argNumber = digitValue(*c);
|
|
|
|
if (argNumber == -1)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
++c;
|
|
|
|
int secondArgDigit = digitValue(*c);
|
|
|
|
if (c != strEnd && secondArgDigit != -1)
|
|
{
|
|
argNumber = (10*argNumber) + secondArgDigit;
|
|
++c;
|
|
}
|
|
|
|
if (argNumber > argInfo.smallestArgIndex)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (argNumber < argInfo.smallestArgIndex)
|
|
{
|
|
argInfo.smallestArgIndex = argNumber;
|
|
argInfo.smallestArgCount = 0;
|
|
argInfo.totalArgLength = 0;
|
|
}
|
|
|
|
++argInfo.smallestArgCount;
|
|
argInfo.totalArgLength += static_cast<int>(c - argStart);
|
|
}
|
|
|
|
return argInfo;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Return a string where the %x (where x=info.smallestArgIndex) is replaced with the given value
|
|
//--------------------------------------------------------------------------------------------------
|
|
static String replaceArgs(const String &s, const ArgInfo& info, int fieldWidth, const String& arg, const wchar_t& fillChar)
|
|
{
|
|
const wchar_t* strBegin = s.c_str();
|
|
const wchar_t* strEnd = strBegin + s.size();
|
|
|
|
unsigned int absFieldWidth = static_cast<unsigned int>(Math::abs(fieldWidth));
|
|
size_t resultLength = s.size() - info.totalArgLength + info.smallestArgCount*CVF_MAX(absFieldWidth, arg.size());
|
|
|
|
std::wstring resultString;
|
|
resultString.resize(resultLength);
|
|
wchar_t* resultBuffer = &resultString[0];
|
|
wchar_t* rc = resultBuffer;
|
|
const wchar_t* c = strBegin;
|
|
int repl_cnt = 0;
|
|
|
|
while (c != strEnd)
|
|
{
|
|
const wchar_t *textStart = c;
|
|
|
|
while (*c != '%')
|
|
{
|
|
++c;
|
|
}
|
|
|
|
const wchar_t* argStart = c++;
|
|
|
|
int argIdx = digitValue(*c);
|
|
|
|
if (argIdx != -1)
|
|
{
|
|
if (c + 1 != strEnd && digitValue(*(c + 1)) != -1)
|
|
{
|
|
argIdx = (10*argIdx) + digitValue(*(c + 1));
|
|
++c;
|
|
}
|
|
}
|
|
|
|
if (argIdx != info.smallestArgIndex)
|
|
{
|
|
memcpy(rc, textStart, (c - textStart)*sizeof(wchar_t));
|
|
rc += c - textStart;
|
|
}
|
|
else
|
|
{
|
|
++c;
|
|
|
|
memcpy(rc, textStart, (argStart - textStart)*sizeof(wchar_t));
|
|
rc += argStart - textStart;
|
|
|
|
size_t pad_chars = CVF_MAX(absFieldWidth, arg.size()) - arg.size();
|
|
|
|
if (fieldWidth > 0)
|
|
{
|
|
// left padded
|
|
unsigned int i;
|
|
for (i = 0; i < pad_chars; ++i)
|
|
{
|
|
*(rc++) = fillChar;;
|
|
}
|
|
}
|
|
|
|
memcpy(rc, arg.c_str(), arg.size()*sizeof(wchar_t));
|
|
rc += arg.size();
|
|
|
|
if (fieldWidth < 0)
|
|
{
|
|
// right padded
|
|
unsigned int i;
|
|
for (i = 0; i < pad_chars; ++i)
|
|
{
|
|
*(rc++) = fillChar;
|
|
}
|
|
}
|
|
|
|
if (++repl_cnt == info.smallestArgCount)
|
|
{
|
|
memcpy(rc, c, (strEnd - c)*sizeof(wchar_t));
|
|
rc += strEnd - c;
|
|
CVF_ASSERT(((rc - resultBuffer) >= 0) && (static_cast<size_t>(rc - resultBuffer) == resultLength));
|
|
c = strEnd;
|
|
}
|
|
}
|
|
}
|
|
|
|
CVF_ASSERT(rc == resultBuffer + resultLength);
|
|
|
|
return String(resultString);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns a copy of this string with the lowest numbered place marker (e.g. %1, %2,..%99) replaced
|
|
/// by string a.
|
|
///
|
|
/// \param a The string to insert at the lowest %x
|
|
/// \param fieldWidth The minimal number of characters the argument will occupy. Positive for right
|
|
/// aligned text, negative for left aligned text.
|
|
/// \param fillChar The character that will be inserted if the passed string is shorter than
|
|
/// the specified fieldWidth. If the length of a is shorter than fieldWidth,
|
|
/// the string will be padded with this character.
|
|
///
|
|
/// This method searches the current string for the lowest %x value, and then replaces all of the
|
|
/// lowest occurrence with the passed data.
|
|
/// Example of use:
|
|
/// \code
|
|
/// String test = String("Reading file %1 (%2 of %3)").arg(filename).arg(fileIndex + 1).arg(fileCount);
|
|
/// \endcode
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::arg(const String& a, int fieldWidth, const wchar_t& fillChar) const
|
|
{
|
|
ArgInfo info = findSmallestArgs(*this);
|
|
|
|
if (info.smallestArgCount == 0)
|
|
{
|
|
// Show warning??
|
|
return *this;
|
|
}
|
|
|
|
return replaceArgs(*this, info, fieldWidth, a, fillChar);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns a copy of this string with the lowest numbered place marker (e.g. %1, %2,..%99) replaced
|
|
/// by the integer a.
|
|
///
|
|
/// \param a The character to insert at the lowest %x
|
|
/// \param fieldWidth The minimal number of characters the argument will occupy. Positive for right
|
|
/// aligned text, negative for left aligned text.
|
|
/// \param fillChar The character that will be inserted if the string representation of a is shorter
|
|
/// than the specified fieldWidth. If the length of a is shorter than fieldWidth,
|
|
/// the string will be padded with this character.
|
|
///
|
|
/// This method searches the current string for the lowest %x value, and then replaces all of the
|
|
/// lowest occurrence with the passed data.
|
|
/// Example of use:
|
|
/// \code
|
|
/// String test = String("Reading file %1 (%2 of %3)").arg(filename).arg(fileIndex + 1).arg(fileCount);
|
|
/// \endcode
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::arg(char a, int fieldWidth, const wchar_t& fillChar) const
|
|
{
|
|
return arg(String(a), fieldWidth, fillChar);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns a copy of this string with the lowest numbered place marker (e.g. %1, %2,..%99) replaced
|
|
/// by the integer a.
|
|
///
|
|
/// \param a The unsigned int value to insert at the lowest %x
|
|
/// \param fieldWidth The minimal number of characters the argument will occupy. Positive for right
|
|
/// aligned text, negative for left aligned text.
|
|
/// \param fillChar The character that will be inserted if the string representation of a is shorter
|
|
/// than the specified fieldWidth. If the length of a is shorter than fieldWidth,
|
|
/// the string will be padded with this character.
|
|
///
|
|
/// This method searches the current string for the lowest %x value, and then replaces all of the
|
|
/// lowest occurrence with the passed data.
|
|
/// Example of use:
|
|
/// \code
|
|
/// String test = String("Reading file %1 (%2 of %3)").arg(filename).arg(fileIndex + 1).arg(fileCount);
|
|
/// \endcode
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::arg(uint a, int fieldWidth, const wchar_t& fillChar) const
|
|
{
|
|
return arg(String(a), fieldWidth, fillChar);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns a copy of this string with the lowest numbered place marker (e.g. %1, %2,..%99) replaced
|
|
/// by the integer a.
|
|
///
|
|
/// \param a The int value to insert at the lowest %x
|
|
/// \param fieldWidth The minimal number of characters the argument will occupy. Positive for right
|
|
/// aligned text, negative for left aligned text.
|
|
/// \param fillChar The character that will be inserted if the string representation of a is shorter
|
|
/// than the specified fieldWidth. If the length of a is shorter than fieldWidth,
|
|
/// the string will be padded with this character.
|
|
///
|
|
/// This method searches the current string for the lowest %x value, and then replaces all of the
|
|
/// lowest occurrence with the passed data.
|
|
/// Example of use:
|
|
/// \code
|
|
/// String test = String("Reading file %1 (%2 of %3)").arg(filename).arg(fileIndex + 1).arg(fileCount);
|
|
/// \endcode
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::arg(int a, int fieldWidth, const wchar_t& fillChar) const
|
|
{
|
|
return arg(static_cast<int64>(a), fieldWidth, fillChar);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns a copy of this string with the lowest numbered place marker (e.g. %1, %2,..%99) replaced
|
|
/// by the 64 bit integer a.
|
|
///
|
|
/// \param a The int64 value to insert at the lowest %x
|
|
/// \param fieldWidth The minimal number of characters the argument will occupy. Positive for right
|
|
/// aligned text, negative for left aligned text.
|
|
/// \param fillChar The character that will be inserted if the string representation of a is shorter
|
|
/// than the specified fieldWidth. If the length of a is shorter than fieldWidth,
|
|
/// the string will be padded with this character.
|
|
///
|
|
/// This method searches the current string for the lowest %x value, and then replaces all of the
|
|
/// lowest occurrence with the passed data.
|
|
/// Example of use:
|
|
/// \code
|
|
/// String test = String("Reading file %1 (%2 of %3)").arg(filename).arg(fileIndex + 1).arg(fileCount);
|
|
/// \endcode
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::arg(int64 a, int fieldWidth, const wchar_t& fillChar) const
|
|
{
|
|
ArgInfo info = findSmallestArgs(*this);
|
|
|
|
if (info.smallestArgCount == 0)
|
|
{
|
|
// Show warning??
|
|
return *this;
|
|
}
|
|
|
|
return replaceArgs(*this, info, fieldWidth, String(a), fillChar);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns a copy of this string with the lowest numbered place marker (e.g. %1, %2,..%99) replaced
|
|
/// by the float a.
|
|
///
|
|
/// \param a The float value to insert at the lowest %x
|
|
/// \param fieldWidth The minimal number of characters the argument will occupy. Positive for right
|
|
/// aligned text, negative for left aligned text.
|
|
/// \param format 'g': default, 'e' : scientific notation (1.234e4). 'f' : Fixed notation (1234.0)
|
|
/// \param precision The precision for floating-point values. Only used for 'f' and 'e'
|
|
/// \param fillChar The character that will be inserted if the string representation of a is shorter
|
|
/// than the specified fieldWidth. If the length of a is shorter than fieldWidth,
|
|
/// the string will be padded with this character.
|
|
///
|
|
/// This method searches the current string for the lowest %x value, and then replaces all of the
|
|
/// lowest occurrence with the passed data.
|
|
/// Example of use:
|
|
/// \code
|
|
/// String test = String("Reading file %1 (%2 of %3)").arg(filename).arg(fileIndex + 1).arg(fileCount);
|
|
/// \endcode
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::arg(float a, int fieldWidth, char format, int precision, const wchar_t& fillChar) const
|
|
{
|
|
ArgInfo info = findSmallestArgs(*this);
|
|
|
|
if (info.smallestArgCount == 0)
|
|
{
|
|
// Show warning??
|
|
return *this;
|
|
}
|
|
|
|
return replaceArgs(*this, info, fieldWidth, String::number(a, format, precision), fillChar);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Returns a copy of this string with the lowest numbered place marker (e.g. %1, %2,..%99) replaced
|
|
/// by the double a.
|
|
///
|
|
/// \param a The double value to insert at the lowest %x
|
|
/// \param fieldWidth The minimal number of characters the argument will occupy. Positive for right
|
|
/// aligned text, negative for left aligned text.
|
|
/// \param format 'g': default, 'e' : scientific notation (1.234e4). 'f' : Fixed notation (1234.0)
|
|
/// \param precision The precision for floating-point values. Only used for 'f' and 'e'
|
|
/// \param fillChar The character that will be inserted if the string representation of a is shorter
|
|
/// than the specified fieldWidth. If the length of a is shorter than fieldWidth,
|
|
/// the string will be padded with this character.
|
|
///
|
|
/// This method searches the current string for the lowest %x value, and then replaces all of the
|
|
/// lowest occurrence with the passed data.
|
|
/// Example of use:
|
|
/// \code
|
|
/// String test = String("Reading file %1 (%2 of %3)").arg(filename).arg(fileIndex + 1).arg(fileCount);
|
|
/// \endcode
|
|
//--------------------------------------------------------------------------------------------------
|
|
String String::arg(double a, int fieldWidth, char format, int precision, const wchar_t& fillChar) const
|
|
{
|
|
ArgInfo info = findSmallestArgs(*this);
|
|
|
|
if (info.smallestArgCount == 0)
|
|
{
|
|
// Show warning??
|
|
return *this;
|
|
}
|
|
|
|
return replaceArgs(*this, info, fieldWidth, String::number(a, format, precision), fillChar);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Exchanges the contents of the two strings.
|
|
///
|
|
/// \param other Modifiable reference to the string that should have its contents swapped.
|
|
///
|
|
/// \warning Note that signature differs from normal practice. This is done to be
|
|
/// consistent with the signature of std::swap()
|
|
//--------------------------------------------------------------------------------------------------
|
|
void String::swap(String& other)
|
|
{
|
|
m_string.swap(other.m_string);
|
|
}
|
|
|
|
|
|
} // namespace cvf
|
|
|