summaryrefslogtreecommitdiff
path: root/indra/llcommon/llstring.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llstring.h')
-rw-r--r--indra/llcommon/llstring.h208
1 files changed, 84 insertions, 124 deletions
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 18cfe4b64c..50681b7967 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -1,6 +1,6 @@
/**
* @file llstring.h
- * @brief String utility functions and LLString class.
+ * @brief String utility functions and std::string class.
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
@@ -155,50 +155,19 @@ public:
static BOOL isDigit(llwchar a) { return iswdigit(a) != 0; }
};
-//RN: I used a templated base class instead of a pure interface class to minimize code duplication
-// but it might be worthwhile to just go with two implementations (LLString and LLWString) of
-// an interface class, unless we can think of a good reason to have a std::basic_string polymorphic base
-
-// ****************************************************************
-// NOTA BENE: do *NOT* dynamically allocate memory inside of LLStringBase as the {*()^#%*)#%W^*)#%*)STL implentation
-// of basic_string doesn't provide a virtual destructor. If we need to allocate resources specific to LLString
-// then we should either customize std::basic_string to linden::basic_string or change LLString to be a wrapper
-// that contains an instance of std::basic_string. Similarly, overriding methods defined in std::basic_string will *not*
-// be called in a polymorphic manner (passing an instance of basic_string to a particular function)
-// ****************************************************************
-
template <class T>
-class LLStringBase : public std::basic_string<T>
+class LLStringUtilBase
{
public:
typedef typename std::basic_string<T>::size_type size_type;
- // naming convention follows those set for LLUUID
-// static LLStringBase null; // deprecated for std::string compliance
-// static LLStringBase zero_length; // deprecated for std::string compliance
-
-
- // standard constructors
- LLStringBase() : std::basic_string<T>() {}
- LLStringBase(const LLStringBase& s): std::basic_string<T>(s) {}
- LLStringBase(const std::basic_string<T>& s) : std::basic_string<T>(s) {}
- LLStringBase(const std::basic_string<T>& s, size_type pos, size_type n = std::basic_string<T>::npos)
- : std::basic_string<T>(s, pos, n) {}
- LLStringBase(size_type count, const T& c) : std::basic_string<T>() { assign(count, c);}
- // custom constructors
- LLStringBase(const T* s);
- LLStringBase(const T* s, size_type n);
- LLStringBase(const T* s, size_type pos, size_type n );
-
- bool operator==(const T* _Right) const { return _Right ? (std::basic_string<T>::compare(_Right) == 0) : this->empty(); }
-
public:
/////////////////////////////////////////////////////////////////////////////////////////
// Static Utility functions that operate on std::strings
- static LLStringBase null;
+ static std::basic_string<T> null;
- typedef std::map<std::string, std::string> format_map_t;
+ typedef std::map<std::basic_string<T>, std::basic_string<T> > format_map_t;
static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map);
static BOOL isValidIndex(const std::basic_string<T>& string, size_type i)
@@ -230,8 +199,8 @@ public:
/**
* @brief Unsafe way to make ascii characters. You should probably
* only call this when interacting with the host operating system.
- * The 1 byte LLString does not work correctly.
- * The 2 and 4 byte LLString probably work, so LLWString::_makeASCII
+ * The 1 byte std::string does not work correctly.
+ * The 2 and 4 byte std::string probably work, so LLWStringUtil::_makeASCII
* should work.
*/
static void _makeASCII(std::basic_string<T>& string);
@@ -253,11 +222,13 @@ public:
// Like strcmp but also handles empty strings. Uses
// current locale.
static S32 compareStrings(const T* lhs, const T* rhs);
+ static S32 compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
// case insensitive version of above. Uses current locale on
// Win32, and falls back to a non-locale aware comparison on
// Linux.
static S32 compareInsensitive(const T* lhs, const T* rhs);
+ static S32 compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
// Case sensitive comparison with good handling of numbers. Does not use current locale.
// a.k.a. strdictcmp()
@@ -284,21 +255,21 @@ public:
};
-template<class T> LLStringBase<T> LLStringBase<T>::null;
+template<class T> std::basic_string<T> LLStringUtilBase<T>::null;
-typedef LLStringBase<char> LLString;
-typedef LLStringBase<llwchar> LLWString;
+typedef LLStringUtilBase<char> LLStringUtil;
+typedef LLStringUtilBase<llwchar> LLWStringUtil;
+typedef std::basic_string<llwchar> LLWString;
//@ Use this where we want to disallow input in the form of "foo"
// This is used to catch places where english text is embedded in the code
// instead of in a translatable XUI file.
-class LLStringExplicit : public LLString
+class LLStringExplicit : public std::string
{
public:
- explicit LLStringExplicit(const char* s) : LLString(s) {}
- LLStringExplicit(const LLString& s) : LLString(s) {}
- LLStringExplicit(const std::string& s) : LLString(s) {}
- LLStringExplicit(const std::string& s, size_type pos, size_type n = std::string::npos) : LLString(s, pos, n) {}
+ explicit LLStringExplicit(const char* s) : std::string(s) {}
+ LLStringExplicit(const std::string& s) : std::string(s) {}
+ LLStringExplicit(const std::string& s, size_type pos, size_type n = std::string::npos) : std::string(s, pos, n) {}
};
struct LLDictionaryLess
@@ -306,7 +277,7 @@ struct LLDictionaryLess
public:
bool operator()(const std::string& a, const std::string& b)
{
- return (LLString::precedesDict(a, b) ? true : false);
+ return (LLStringUtil::precedesDict(a, b) ? true : false);
}
};
@@ -335,6 +306,7 @@ inline std::string chop_tail_copy(
* pointer is NULL.
*/
std::string ll_safe_string(const char* in);
+std::string ll_safe_string(const char* in, S32 maxlen);
/**
* @brief This translates a nybble stored as a hex value from 0-f back
@@ -351,7 +323,7 @@ U8 hex_as_nybble(char hex);
* @param filename The full name of the file to read.
* @return Returns true on success. If false, str is unmodified.
*/
-bool _read_file_into_string(std::string& str, const char* filename);
+bool _read_file_into_string(std::string& str, const std::string& filename);
/**
* Unicode support
@@ -373,20 +345,17 @@ LLWString utf16str_to_wstring(const llutf16string &utf16str);
llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len);
llutf16string wstring_to_utf16str(const LLWString &utf32str);
-llutf16string utf8str_to_utf16str ( const LLString& utf8str, S32 len);
-llutf16string utf8str_to_utf16str ( const LLString& utf8str );
+llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len);
+llutf16string utf8str_to_utf16str ( const std::string& utf8str );
LLWString utf8str_to_wstring(const std::string &utf8str, S32 len);
LLWString utf8str_to_wstring(const std::string &utf8str);
// Same function, better name. JC
inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); }
-// Special hack for llfilepicker.cpp:
-S32 utf16chars_to_utf8chars(const U16* inchars, char* outchars, S32* nchars8 = 0);
-S32 utf16chars_to_wchar(const U16* inchars, llwchar* outchar);
+//
S32 wchar_to_utf8chars(llwchar inchar, char* outchars);
-//
std::string wstring_to_utf8str(const LLWString &utf32str, S32 len);
std::string wstring_to_utf8str(const LLWString &utf32str);
@@ -448,15 +417,6 @@ std::string mbcsstring_makeASCII(const std::string& str);
std::string utf8str_removeCRLF(const std::string& utf8str);
-template <class T>
-std::ostream& operator<<(std::ostream &s, const LLStringBase<T> &str)
-{
- s << ((std::basic_string<T>)str);
- return s;
-}
-
-std::ostream& operator<<(std::ostream &s, const LLWString &wstr);
-
#if LL_WINDOWS
/* @name Windows string helpers
*/
@@ -492,7 +452,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in);
#endif // LL_WINDOWS
/**
- * Many of the 'strip' and 'replace' methods of LLStringBase need
+ * Many of the 'strip' and 'replace' methods of LLStringUtilBase need
* specialization to work with the signed char type.
* Sadly, it is not possible (AFAIK) to specialize a single method of
* a template class.
@@ -558,11 +518,12 @@ namespace LLStringFn
// static
template<class T>
-S32 LLStringBase<T>::format(std::basic_string<T>& s, const format_map_t& fmt_map)
+S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const format_map_t& fmt_map)
{
typedef typename std::basic_string<T>::size_type string_size_type_t;
+ typedef typename format_map_t::const_iterator format_map_const_iterator_t;
S32 res = 0;
- for (format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter)
+ for (format_map_const_iterator_t iter = fmt_map.begin(); iter != fmt_map.end(); ++iter)
{
U32 fmtlen = iter->first.size();
string_size_type_t n = 0;
@@ -584,7 +545,7 @@ S32 LLStringBase<T>::format(std::basic_string<T>& s, const format_map_t& fmt_map
// static
template<class T>
-S32 LLStringBase<T>::compareStrings(const T* lhs, const T* rhs)
+S32 LLStringUtilBase<T>::compareStrings(const T* lhs, const T* rhs)
{
S32 result;
if( lhs == rhs )
@@ -608,9 +569,16 @@ S32 LLStringBase<T>::compareStrings(const T* lhs, const T* rhs)
return result;
}
+//static
+template<class T>
+S32 LLStringUtilBase<T>::compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
+{
+ return LLStringOps::collate(lhs.c_str(), rhs.c_str());
+}
+
// static
template<class T>
-S32 LLStringBase<T>::compareInsensitive(const T* lhs, const T* rhs )
+S32 LLStringUtilBase<T>::compareInsensitive(const T* lhs, const T* rhs )
{
S32 result;
if( lhs == rhs )
@@ -629,22 +597,32 @@ S32 LLStringBase<T>::compareInsensitive(const T* lhs, const T* rhs )
}
else
{
- LLStringBase<T> lhs_string(lhs);
- LLStringBase<T> rhs_string(rhs);
- LLStringBase<T>::toUpper(lhs_string);
- LLStringBase<T>::toUpper(rhs_string);
+ std::basic_string<T> lhs_string(lhs);
+ std::basic_string<T> rhs_string(rhs);
+ LLStringUtilBase<T>::toUpper(lhs_string);
+ LLStringUtilBase<T>::toUpper(rhs_string);
result = LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
}
return result;
}
+//static
+template<class T>
+S32 LLStringUtilBase<T>::compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
+{
+ std::basic_string<T> lhs_string(lhs);
+ std::basic_string<T> rhs_string(rhs);
+ LLStringUtilBase<T>::toUpper(lhs_string);
+ LLStringUtilBase<T>::toUpper(rhs_string);
+ return LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
+}
// Case sensitive comparison with good handling of numbers. Does not use current locale.
// a.k.a. strdictcmp()
//static
template<class T>
-S32 LLStringBase<T>::compareDict(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
+S32 LLStringUtilBase<T>::compareDict(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
{
const T* a = astr.c_str();
const T* b = bstr.c_str();
@@ -683,8 +661,9 @@ S32 LLStringBase<T>::compareDict(const std::basic_string<T>& astr, const std::ba
return ca-cb;
}
+// static
template<class T>
-S32 LLStringBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
+S32 LLStringUtilBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
{
const T* a = astr.c_str();
const T* b = bstr.c_str();
@@ -719,11 +698,11 @@ S32 LLStringBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, co
// Puts compareDict() in a form appropriate for LL container classes to use for sorting.
// static
template<class T>
-BOOL LLStringBase<T>::precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b )
+BOOL LLStringUtilBase<T>::precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b )
{
if( a.size() && b.size() )
{
- return (LLStringBase<T>::compareDict(a.c_str(), b.c_str()) < 0);
+ return (LLStringUtilBase<T>::compareDict(a.c_str(), b.c_str()) < 0);
}
else
{
@@ -731,28 +710,9 @@ BOOL LLStringBase<T>::precedesDict( const std::basic_string<T>& a, const std::ba
}
}
-// Constructors
-template<class T>
-LLStringBase<T>::LLStringBase(const T* s ) : std::basic_string<T>()
-{
- if (s) assign(s);
-}
-
-template<class T>
-LLStringBase<T>::LLStringBase(const T* s, size_type n ) : std::basic_string<T>()
-{
- if (s) assign(s, n);
-}
-
-// Init from a substring
-template<class T>
-LLStringBase<T>::LLStringBase(const T* s, size_type pos, size_type n )
-: std::basic_string<T>( (s ? s : std::basic_string<T>() ), pos, n )
-{ }
-
//static
template<class T>
-void LLStringBase<T>::toUpper(std::basic_string<T>& string)
+void LLStringUtilBase<T>::toUpper(std::basic_string<T>& string)
{
if( !string.empty() )
{
@@ -766,7 +726,7 @@ void LLStringBase<T>::toUpper(std::basic_string<T>& string)
//static
template<class T>
-void LLStringBase<T>::toLower(std::basic_string<T>& string)
+void LLStringUtilBase<T>::toLower(std::basic_string<T>& string)
{
if( !string.empty() )
{
@@ -780,7 +740,7 @@ void LLStringBase<T>::toLower(std::basic_string<T>& string)
//static
template<class T>
-void LLStringBase<T>::trimHead(std::basic_string<T>& string)
+void LLStringUtilBase<T>::trimHead(std::basic_string<T>& string)
{
if( !string.empty() )
{
@@ -795,7 +755,7 @@ void LLStringBase<T>::trimHead(std::basic_string<T>& string)
//static
template<class T>
-void LLStringBase<T>::trimTail(std::basic_string<T>& string)
+void LLStringUtilBase<T>::trimTail(std::basic_string<T>& string)
{
if( string.size() )
{
@@ -814,7 +774,7 @@ void LLStringBase<T>::trimTail(std::basic_string<T>& string)
// Replace line feeds with carriage return-line feed pairs.
//static
template<class T>
-void LLStringBase<T>::addCRLF(std::basic_string<T>& string)
+void LLStringUtilBase<T>::addCRLF(std::basic_string<T>& string)
{
const T LF = 10;
const T CR = 13;
@@ -855,7 +815,7 @@ void LLStringBase<T>::addCRLF(std::basic_string<T>& string)
// Remove all carriage returns
//static
template<class T>
-void LLStringBase<T>::removeCRLF(std::basic_string<T>& string)
+void LLStringUtilBase<T>::removeCRLF(std::basic_string<T>& string)
{
const T CR = 13;
@@ -876,7 +836,7 @@ void LLStringBase<T>::removeCRLF(std::basic_string<T>& string)
//static
template<class T>
-void LLStringBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement )
+void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement )
{
size_type found_pos = 0;
for (found_pos = string.find(target, found_pos);
@@ -889,7 +849,7 @@ void LLStringBase<T>::replaceChar( std::basic_string<T>& string, T target, T rep
//static
template<class T>
-void LLStringBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T replacement )
+void LLStringUtilBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T replacement )
{
const char LF = 10;
const S8 MIN = 32;
@@ -909,12 +869,12 @@ void LLStringBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T r
//static
template<class T>
-void LLStringBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_type spaces_per_tab )
+void LLStringUtilBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_type spaces_per_tab )
{
const T TAB = '\t';
const T SPACE = ' ';
- LLStringBase<T> out_str;
+ std::basic_string<T> out_str;
// Replace tabs with spaces
for (size_type i = 0; i < str.length(); i++)
{
@@ -933,7 +893,7 @@ void LLStringBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_typ
//static
template<class T>
-BOOL LLStringBase<T>::containsNonprintable(const std::basic_string<T>& string)
+BOOL LLStringUtilBase<T>::containsNonprintable(const std::basic_string<T>& string)
{
const char MIN = 32;
BOOL rv = FALSE;
@@ -950,7 +910,7 @@ BOOL LLStringBase<T>::containsNonprintable(const std::basic_string<T>& string)
//static
template<class T>
-void LLStringBase<T>::stripNonprintable(std::basic_string<T>& string)
+void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string)
{
const char MIN = 32;
size_type j = 0;
@@ -981,7 +941,7 @@ void LLStringBase<T>::stripNonprintable(std::basic_string<T>& string)
}
template<class T>
-void LLStringBase<T>::_makeASCII(std::basic_string<T>& string)
+void LLStringUtilBase<T>::_makeASCII(std::basic_string<T>& string)
{
// Replace non-ASCII chars with LL_UNKNOWN_CHAR
for (size_type i = 0; i < string.length(); i++)
@@ -995,7 +955,7 @@ void LLStringBase<T>::_makeASCII(std::basic_string<T>& string)
// static
template<class T>
-void LLStringBase<T>::copy( T* dst, const T* src, size_type dst_size )
+void LLStringUtilBase<T>::copy( T* dst, const T* src, size_type dst_size )
{
if( dst_size > 0 )
{
@@ -1011,7 +971,7 @@ void LLStringBase<T>::copy( T* dst, const T* src, size_type dst_size )
// static
template<class T>
-void LLStringBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset)
+void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset)
{
if ( offset == dst.length() )
{
@@ -1032,7 +992,7 @@ void LLStringBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_strin
// True if this is the head of s.
//static
template<class T>
-BOOL LLStringBase<T>::isHead( const std::basic_string<T>& string, const T* s )
+BOOL LLStringUtilBase<T>::isHead( const std::basic_string<T>& string, const T* s )
{
if( string.empty() )
{
@@ -1046,14 +1006,14 @@ BOOL LLStringBase<T>::isHead( const std::basic_string<T>& string, const T* s )
}
template<class T>
-BOOL LLStringBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& value)
+BOOL LLStringUtilBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& value)
{
if( string.empty() )
{
return FALSE;
}
- LLStringBase<T> temp( string );
+ std::basic_string<T> temp( string );
trim(temp);
if(
(temp == "1") ||
@@ -1083,7 +1043,7 @@ BOOL LLStringBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& va
}
template<class T>
-BOOL LLStringBase<T>::convertToU8(const std::basic_string<T>& string, U8& value)
+BOOL LLStringUtilBase<T>::convertToU8(const std::basic_string<T>& string, U8& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1096,7 +1056,7 @@ BOOL LLStringBase<T>::convertToU8(const std::basic_string<T>& string, U8& value)
}
template<class T>
-BOOL LLStringBase<T>::convertToS8(const std::basic_string<T>& string, S8& value)
+BOOL LLStringUtilBase<T>::convertToS8(const std::basic_string<T>& string, S8& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1109,7 +1069,7 @@ BOOL LLStringBase<T>::convertToS8(const std::basic_string<T>& string, S8& value)
}
template<class T>
-BOOL LLStringBase<T>::convertToS16(const std::basic_string<T>& string, S16& value)
+BOOL LLStringUtilBase<T>::convertToS16(const std::basic_string<T>& string, S16& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1122,7 +1082,7 @@ BOOL LLStringBase<T>::convertToS16(const std::basic_string<T>& string, S16& valu
}
template<class T>
-BOOL LLStringBase<T>::convertToU16(const std::basic_string<T>& string, U16& value)
+BOOL LLStringUtilBase<T>::convertToU16(const std::basic_string<T>& string, U16& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1135,14 +1095,14 @@ BOOL LLStringBase<T>::convertToU16(const std::basic_string<T>& string, U16& valu
}
template<class T>
-BOOL LLStringBase<T>::convertToU32(const std::basic_string<T>& string, U32& value)
+BOOL LLStringUtilBase<T>::convertToU32(const std::basic_string<T>& string, U32& value)
{
if( string.empty() )
{
return FALSE;
}
- LLStringBase<T> temp( string );
+ std::basic_string<T> temp( string );
trim(temp);
U32 v;
std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
@@ -1162,14 +1122,14 @@ BOOL LLStringBase<T>::convertToU32(const std::basic_string<T>& string, U32& valu
}
template<class T>
-BOOL LLStringBase<T>::convertToS32(const std::basic_string<T>& string, S32& value)
+BOOL LLStringUtilBase<T>::convertToS32(const std::basic_string<T>& string, S32& value)
{
if( string.empty() )
{
return FALSE;
}
- LLStringBase<T> temp( string );
+ std::basic_string<T> temp( string );
trim(temp);
S32 v;
std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
@@ -1189,7 +1149,7 @@ BOOL LLStringBase<T>::convertToS32(const std::basic_string<T>& string, S32& valu
}
template<class T>
-BOOL LLStringBase<T>::convertToF32(const std::basic_string<T>& string, F32& value)
+BOOL LLStringUtilBase<T>::convertToF32(const std::basic_string<T>& string, F32& value)
{
F64 value64 = 0.0;
BOOL success = convertToF64(string, value64);
@@ -1202,14 +1162,14 @@ BOOL LLStringBase<T>::convertToF32(const std::basic_string<T>& string, F32& valu
}
template<class T>
-BOOL LLStringBase<T>::convertToF64(const std::basic_string<T>& string, F64& value)
+BOOL LLStringUtilBase<T>::convertToF64(const std::basic_string<T>& string, F64& value)
{
if( string.empty() )
{
return FALSE;
}
- LLStringBase<T> temp( string );
+ std::basic_string<T> temp( string );
trim(temp);
F64 v;
std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
@@ -1229,7 +1189,7 @@ BOOL LLStringBase<T>::convertToF64(const std::basic_string<T>& string, F64& valu
}
template<class T>
-void LLStringBase<T>::truncate(std::basic_string<T>& string, size_type count)
+void LLStringUtilBase<T>::truncate(std::basic_string<T>& string, size_type count)
{
size_type cur_size = string.size();
string.resize(count < cur_size ? count : cur_size);