aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llstring.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcommon/llstring.h')
-rw-r--r--linden/indra/llcommon/llstring.h391
1 files changed, 141 insertions, 250 deletions
diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h
index 82ebdc9..60a4492 100644
--- a/linden/indra/llcommon/llstring.h
+++ b/linden/indra/llcommon/llstring.h
@@ -1,6 +1,6 @@
1/** 1/**
2 * @file llstring.h 2 * @file llstring.h
3 * @brief String utility functions and LLString class. 3 * @brief String utility functions and std::string class.
4 * 4 *
5 * $LicenseInfo:firstyear=2001&license=viewergpl$ 5 * $LicenseInfo:firstyear=2001&license=viewergpl$
6 * 6 *
@@ -39,15 +39,8 @@
39 39
40const char LL_UNKNOWN_CHAR = '?'; 40const char LL_UNKNOWN_CHAR = '?';
41 41
42class LLVector3; 42#if LL_DARWIN || LL_LINUX || LL_SOLARIS
43class LLVector3d; 43// Template specialization of char_traits for U16s. Only necessary on Mac and Linux (exists on Windows already)
44class LLQuaternion;
45class LLUUID;
46class LLColor4;
47class LLColor4U;
48
49#if (LL_DARWIN || LL_SOLARIS || (LL_LINUX && __GNUC__ > 2))
50// Template specialization of char_traits for U16s. Only necessary on Mac for now (exists on Windows, unused/broken on Linux/gcc2.95)
51namespace std 44namespace std
52{ 45{
53template<> 46template<>
@@ -162,79 +155,29 @@ public:
162 static BOOL isDigit(llwchar a) { return iswdigit(a) != 0; } 155 static BOOL isDigit(llwchar a) { return iswdigit(a) != 0; }
163}; 156};
164 157
165//RN: I used a templated base class instead of a pure interface class to minimize code duplication 158// Allowing assignments from non-strings into format_map_t is apparently
166// but it might be worthwhile to just go with two implementations (LLString and LLWString) of 159// *really* error-prone, so subclass std::string with just basic c'tors.
167// an interface class, unless we can think of a good reason to have a std::basic_string polymorphic base 160class FormatMapString : public std::string
168 161{
169//**************************************************************** 162public:
170// NOTA BENE: do *NOT* dynamically allocate memory inside of LLStringBase as the {*()^#%*)#%W^*)#%*)STL implentation 163 FormatMapString() : std::string() {};
171// of basic_string doesn't provide a virtual destructor. If we need to allocate resources specific to LLString 164 FormatMapString(const char* s) : std::string(s) {};
172// then we should either customize std::basic_string to linden::basic_string or change LLString to be a wrapper 165 FormatMapString(const std::string& s) : std::string(s) {};
173// that contains an instance of std::basic_string. Similarly, overriding methods defined in std::basic_string will *not* 166};
174// be called in a polymorphic manner (passing an instance of basic_string to a particular function)
175//****************************************************************
176 167
177template <class T> 168template <class T>
178class LLStringBase : public std::basic_string<T> 169class LLStringUtilBase
179{ 170{
180public: 171public:
181 typedef typename std::basic_string<T>::size_type size_type; 172 typedef typename std::basic_string<T>::size_type size_type;
182 173
183 // naming convention follows those set for LLUUID
184// static LLStringBase null; // deprecated for std::string compliance
185// static LLStringBase zero_length; // deprecated for std::string compliance
186
187
188 // standard constructors
189 LLStringBase() : std::basic_string<T>() {}
190 LLStringBase(const LLStringBase& s): std::basic_string<T>(s) {}
191 LLStringBase(const std::basic_string<T>& s) : std::basic_string<T>(s) {}
192 LLStringBase(const std::basic_string<T>& s, size_type pos, size_type n = std::basic_string<T>::npos)
193 : std::basic_string<T>(s, pos, n) {}
194 LLStringBase(size_type count, const T& c) : std::basic_string<T>() { assign(count, c);}
195 // custom constructors
196 LLStringBase(const T* s);
197 LLStringBase(const T* s, size_type n);
198 LLStringBase(const T* s, size_type pos, size_type n );
199
200#if LL_LINUX || LL_SOLARIS
201 void clear() { assign(null); }
202
203 LLStringBase<T>& assign(const T* s);
204 LLStringBase<T>& assign(const T* s, size_type n);
205 LLStringBase<T>& assign(const LLStringBase& s);
206 LLStringBase<T>& assign(size_type n, const T& c);
207 LLStringBase<T>& assign(const T* a, const T* b);
208 LLStringBase<T>& assign(typename LLStringBase<T>::iterator &it1, typename LLStringBase<T>::iterator &it2);
209 LLStringBase<T>& assign(typename LLStringBase<T>::const_iterator &it1, typename LLStringBase<T>::const_iterator &it2);
210
211 // workaround for bug in gcc2 STL headers.
212 #if ((__GNUC__ <= 2) && (!defined _STLPORT_VERSION))
213 const T* c_str () const
214 {
215 if (length () == 0)
216 {
217 static const T zero = 0;
218 return &zero;
219 }
220
221 //terminate ();
222 { string_char_traits<T>::assign(const_cast<T*>(data())[length()], string_char_traits<T>::eos()); }
223
224 return data ();
225 }
226 #endif
227#endif
228
229 bool operator==(const T* _Right) const { return _Right ? (std::basic_string<T>::compare(_Right) == 0) : this->empty(); }
230
231public: 174public:
232 ///////////////////////////////////////////////////////////////////////////////////////// 175 /////////////////////////////////////////////////////////////////////////////////////////
233 // Static Utility functions that operate on std::strings 176 // Static Utility functions that operate on std::strings
234 177
235 static LLStringBase null; 178 static std::basic_string<T> null;
236 179
237 typedef std::map<std::string, std::string> format_map_t; 180 typedef std::map<FormatMapString, FormatMapString> format_map_t;
238 static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map); 181 static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map);
239 182
240 static BOOL isValidIndex(const std::basic_string<T>& string, size_type i) 183 static BOOL isValidIndex(const std::basic_string<T>& string, size_type i)
@@ -266,8 +209,8 @@ public:
266 /** 209 /**
267 * @brief Unsafe way to make ascii characters. You should probably 210 * @brief Unsafe way to make ascii characters. You should probably
268 * only call this when interacting with the host operating system. 211 * only call this when interacting with the host operating system.
269 * The 1 byte LLString does not work correctly. 212 * The 1 byte std::string does not work correctly.
270 * The 2 and 4 byte LLString probably work, so LLWString::_makeASCII 213 * The 2 and 4 byte std::string probably work, so LLWStringUtil::_makeASCII
271 * should work. 214 * should work.
272 */ 215 */
273 static void _makeASCII(std::basic_string<T>& string); 216 static void _makeASCII(std::basic_string<T>& string);
@@ -289,11 +232,13 @@ public:
289 // Like strcmp but also handles empty strings. Uses 232 // Like strcmp but also handles empty strings. Uses
290 // current locale. 233 // current locale.
291 static S32 compareStrings(const T* lhs, const T* rhs); 234 static S32 compareStrings(const T* lhs, const T* rhs);
235 static S32 compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
292 236
293 // case insensitive version of above. Uses current locale on 237 // case insensitive version of above. Uses current locale on
294 // Win32, and falls back to a non-locale aware comparison on 238 // Win32, and falls back to a non-locale aware comparison on
295 // Linux. 239 // Linux.
296 static S32 compareInsensitive(const T* lhs, const T* rhs); 240 static S32 compareInsensitive(const T* lhs, const T* rhs);
241 static S32 compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
297 242
298 // Case sensitive comparison with good handling of numbers. Does not use current locale. 243 // Case sensitive comparison with good handling of numbers. Does not use current locale.
299 // a.k.a. strdictcmp() 244 // a.k.a. strdictcmp()
@@ -320,21 +265,21 @@ public:
320 265
321}; 266};
322 267
323template<class T> LLStringBase<T> LLStringBase<T>::null; 268template<class T> std::basic_string<T> LLStringUtilBase<T>::null;
324 269
325typedef LLStringBase<char> LLString; 270typedef LLStringUtilBase<char> LLStringUtil;
326typedef LLStringBase<llwchar> LLWString; 271typedef LLStringUtilBase<llwchar> LLWStringUtil;
272typedef std::basic_string<llwchar> LLWString;
327 273
328//@ Use this where we want to disallow input in the form of "foo" 274//@ Use this where we want to disallow input in the form of "foo"
329// This is used to catch places where english text is embedded in the code 275// This is used to catch places where english text is embedded in the code
330// instead of in a translatable XUI file. 276// instead of in a translatable XUI file.
331class LLStringExplicit : public LLString 277class LLStringExplicit : public std::string
332{ 278{
333public: 279public:
334 explicit LLStringExplicit(const char* s) : LLString(s) {} 280 explicit LLStringExplicit(const char* s) : std::string(s) {}
335 LLStringExplicit(const LLString& s) : LLString(s) {} 281 LLStringExplicit(const std::string& s) : std::string(s) {}
336 LLStringExplicit(const std::string& s) : LLString(s) {} 282 LLStringExplicit(const std::string& s, size_type pos, size_type n = std::string::npos) : std::string(s, pos, n) {}
337 LLStringExplicit(const std::string& s, size_type pos, size_type n = std::string::npos) : LLString(s, pos, n) {}
338}; 283};
339 284
340struct LLDictionaryLess 285struct LLDictionaryLess
@@ -342,7 +287,7 @@ struct LLDictionaryLess
342public: 287public:
343 bool operator()(const std::string& a, const std::string& b) 288 bool operator()(const std::string& a, const std::string& b)
344 { 289 {
345 return (LLString::precedesDict(a, b) ? true : false); 290 return (LLStringUtil::precedesDict(a, b) ? true : false);
346 } 291 }
347}; 292};
348 293
@@ -371,6 +316,7 @@ inline std::string chop_tail_copy(
371 * pointer is NULL. 316 * pointer is NULL.
372 */ 317 */
373std::string ll_safe_string(const char* in); 318std::string ll_safe_string(const char* in);
319std::string ll_safe_string(const char* in, S32 maxlen);
374 320
375/** 321/**
376 * @brief This translates a nybble stored as a hex value from 0-f back 322 * @brief This translates a nybble stored as a hex value from 0-f back
@@ -387,7 +333,7 @@ U8 hex_as_nybble(char hex);
387 * @param filename The full name of the file to read. 333 * @param filename The full name of the file to read.
388 * @return Returns true on success. If false, str is unmodified. 334 * @return Returns true on success. If false, str is unmodified.
389 */ 335 */
390bool _read_file_into_string(std::string& str, const char* filename); 336bool _read_file_into_string(std::string& str, const std::string& filename);
391 337
392/** 338/**
393 * Unicode support 339 * Unicode support
@@ -409,20 +355,17 @@ LLWString utf16str_to_wstring(const llutf16string &utf16str);
409llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len); 355llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len);
410llutf16string wstring_to_utf16str(const LLWString &utf32str); 356llutf16string wstring_to_utf16str(const LLWString &utf32str);
411 357
412llutf16string utf8str_to_utf16str ( const LLString& utf8str, S32 len); 358llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len);
413llutf16string utf8str_to_utf16str ( const LLString& utf8str ); 359llutf16string utf8str_to_utf16str ( const std::string& utf8str );
414 360
415LLWString utf8str_to_wstring(const std::string &utf8str, S32 len); 361LLWString utf8str_to_wstring(const std::string &utf8str, S32 len);
416LLWString utf8str_to_wstring(const std::string &utf8str); 362LLWString utf8str_to_wstring(const std::string &utf8str);
417// Same function, better name. JC 363// Same function, better name. JC
418inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); } 364inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); }
419 365
420// Special hack for llfilepicker.cpp: 366//
421S32 utf16chars_to_utf8chars(const U16* inchars, char* outchars, S32* nchars8 = 0);
422S32 utf16chars_to_wchar(const U16* inchars, llwchar* outchar);
423S32 wchar_to_utf8chars(llwchar inchar, char* outchars); 367S32 wchar_to_utf8chars(llwchar inchar, char* outchars);
424 368
425//
426std::string wstring_to_utf8str(const LLWString &utf32str, S32 len); 369std::string wstring_to_utf8str(const LLWString &utf32str, S32 len);
427std::string wstring_to_utf8str(const LLWString &utf32str); 370std::string wstring_to_utf8str(const LLWString &utf32str);
428 371
@@ -484,15 +427,6 @@ std::string mbcsstring_makeASCII(const std::string& str);
484std::string utf8str_removeCRLF(const std::string& utf8str); 427std::string utf8str_removeCRLF(const std::string& utf8str);
485 428
486 429
487template <class T>
488std::ostream& operator<<(std::ostream &s, const LLStringBase<T> &str)
489{
490 s << ((std::basic_string<T>)str);
491 return s;
492}
493
494std::ostream& operator<<(std::ostream &s, const LLWString &wstr);
495
496#if LL_WINDOWS 430#if LL_WINDOWS
497/* @name Windows string helpers 431/* @name Windows string helpers
498 */ 432 */
@@ -528,7 +462,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in);
528#endif // LL_WINDOWS 462#endif // LL_WINDOWS
529 463
530/** 464/**
531 * Many of the 'strip' and 'replace' methods of LLStringBase need 465 * Many of the 'strip' and 'replace' methods of LLStringUtilBase need
532 * specialization to work with the signed char type. 466 * specialization to work with the signed char type.
533 * Sadly, it is not possible (AFAIK) to specialize a single method of 467 * Sadly, it is not possible (AFAIK) to specialize a single method of
534 * a template class. 468 * a template class.
@@ -581,30 +515,68 @@ namespace LLStringFn
581 */ 515 */
582 void replace_nonprintable_and_pipe(std::basic_string<llwchar>& str, 516 void replace_nonprintable_and_pipe(std::basic_string<llwchar>& str,
583 llwchar replacement); 517 llwchar replacement);
518
519 /**
520 * @brief Remove all characters that are not allowed in XML 1.0.
521 * Returns a copy of the string with those characters removed.
522 * Works with US ASCII and UTF-8 encoded strings. JC
523 */
524 std::string strip_invalid_xml(const std::string& input);
584} 525}
585 526
586//////////////////////////////////////////////////////////// 527////////////////////////////////////////////////////////////
587 528
529// LLStringBase::format()
530//
531// This function takes a string 's' and a map 'fmt_map' of strings-to-strings.
532// All occurances of strings in 's' from the left-hand side of 'fmt_map' are
533// then replaced with the corresponding right-hand side of 'fmt_map', non-
534// recursively. The function returns the number of substitutions made.
535
588// static 536// static
589template<class T> 537template<class T>
590S32 LLStringBase<T>::format(std::basic_string<T>& s, const format_map_t& fmt_map) 538S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const format_map_t& fmt_map)
591{ 539{
592 typedef typename std::basic_string<T>::size_type string_size_type_t; 540 typedef typename std::basic_string<T>::size_type string_size_type_t;
541 string_size_type_t scanstart = 0;
593 S32 res = 0; 542 S32 res = 0;
594 for (format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter) 543
544 // Look for the first match of any keyword, replace that keyword,
545 // repeat from the end of the replacement string. This avoids
546 // accidentally performing substitution on a substituted string.
547 while (1)
595 { 548 {
596 U32 fmtlen = iter->first.size(); 549 string_size_type_t first_match_pos = scanstart;
597 string_size_type_t n = 0; 550 string_size_type_t first_match_str_length = 0;
598 while (1) 551 std::basic_string<T> first_match_str_replacement;
552
553 for (format_map_t::const_iterator iter = fmt_map.begin();
554 iter != fmt_map.end();
555 ++iter)
599 { 556 {
600 n = s.find(iter->first, n); 557 string_size_type_t n = s.find(iter->first, scanstart);
601 if (n == std::basic_string<T>::npos) 558 if (n != std::basic_string<T>::npos &&
559 (n < first_match_pos ||
560 0 == first_match_str_length))
602 { 561 {
603 break; 562 first_match_pos = n;
563 first_match_str_length = iter->first.length();
564 first_match_str_replacement = iter->second;
604 } 565 }
605 s.erase(n, fmtlen); 566 }
606 s.insert(n, iter->second); 567
607 n += fmtlen; 568 if (0 == first_match_str_length)
569 {
570 // no more keys found to substitute from this point
571 // in the string forward.
572 break;
573 }
574 else
575 {
576 s.erase(first_match_pos, first_match_str_length);
577 s.insert(first_match_pos, first_match_str_replacement);
578 scanstart = first_match_pos +
579 first_match_str_replacement.length();
608 ++res; 580 ++res;
609 } 581 }
610 } 582 }
@@ -613,7 +585,7 @@ S32 LLStringBase<T>::format(std::basic_string<T>& s, const format_map_t& fmt_map
613 585
614// static 586// static
615template<class T> 587template<class T>
616S32 LLStringBase<T>::compareStrings(const T* lhs, const T* rhs) 588S32 LLStringUtilBase<T>::compareStrings(const T* lhs, const T* rhs)
617{ 589{
618 S32 result; 590 S32 result;
619 if( lhs == rhs ) 591 if( lhs == rhs )
@@ -637,9 +609,16 @@ S32 LLStringBase<T>::compareStrings(const T* lhs, const T* rhs)
637 return result; 609 return result;
638} 610}
639 611
612//static
613template<class T>
614S32 LLStringUtilBase<T>::compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
615{
616 return LLStringOps::collate(lhs.c_str(), rhs.c_str());
617}
618
640// static 619// static
641template<class T> 620template<class T>
642S32 LLStringBase<T>::compareInsensitive(const T* lhs, const T* rhs ) 621S32 LLStringUtilBase<T>::compareInsensitive(const T* lhs, const T* rhs )
643{ 622{
644 S32 result; 623 S32 result;
645 if( lhs == rhs ) 624 if( lhs == rhs )
@@ -658,22 +637,32 @@ S32 LLStringBase<T>::compareInsensitive(const T* lhs, const T* rhs )
658 } 637 }
659 else 638 else
660 { 639 {
661 LLStringBase<T> lhs_string(lhs); 640 std::basic_string<T> lhs_string(lhs);
662 LLStringBase<T> rhs_string(rhs); 641 std::basic_string<T> rhs_string(rhs);
663 LLStringBase<T>::toUpper(lhs_string); 642 LLStringUtilBase<T>::toUpper(lhs_string);
664 LLStringBase<T>::toUpper(rhs_string); 643 LLStringUtilBase<T>::toUpper(rhs_string);
665 result = LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str()); 644 result = LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
666 } 645 }
667 return result; 646 return result;
668} 647}
669 648
649//static
650template<class T>
651S32 LLStringUtilBase<T>::compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
652{
653 std::basic_string<T> lhs_string(lhs);
654 std::basic_string<T> rhs_string(rhs);
655 LLStringUtilBase<T>::toUpper(lhs_string);
656 LLStringUtilBase<T>::toUpper(rhs_string);
657 return LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
658}
670 659
671// Case sensitive comparison with good handling of numbers. Does not use current locale. 660// Case sensitive comparison with good handling of numbers. Does not use current locale.
672// a.k.a. strdictcmp() 661// a.k.a. strdictcmp()
673 662
674//static 663//static
675template<class T> 664template<class T>
676S32 LLStringBase<T>::compareDict(const std::basic_string<T>& astr, const std::basic_string<T>& bstr) 665S32 LLStringUtilBase<T>::compareDict(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
677{ 666{
678 const T* a = astr.c_str(); 667 const T* a = astr.c_str();
679 const T* b = bstr.c_str(); 668 const T* b = bstr.c_str();
@@ -712,8 +701,9 @@ S32 LLStringBase<T>::compareDict(const std::basic_string<T>& astr, const std::ba
712 return ca-cb; 701 return ca-cb;
713} 702}
714 703
704// static
715template<class T> 705template<class T>
716S32 LLStringBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, const std::basic_string<T>& bstr) 706S32 LLStringUtilBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
717{ 707{
718 const T* a = astr.c_str(); 708 const T* a = astr.c_str();
719 const T* b = bstr.c_str(); 709 const T* b = bstr.c_str();
@@ -748,11 +738,11 @@ S32 LLStringBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, co
748// Puts compareDict() in a form appropriate for LL container classes to use for sorting. 738// Puts compareDict() in a form appropriate for LL container classes to use for sorting.
749// static 739// static
750template<class T> 740template<class T>
751BOOL LLStringBase<T>::precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b ) 741BOOL LLStringUtilBase<T>::precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b )
752{ 742{
753 if( a.size() && b.size() ) 743 if( a.size() && b.size() )
754 { 744 {
755 return (LLStringBase<T>::compareDict(a.c_str(), b.c_str()) < 0); 745 return (LLStringUtilBase<T>::compareDict(a.c_str(), b.c_str()) < 0);
756 } 746 }
757 else 747 else
758 { 748 {
@@ -760,108 +750,9 @@ BOOL LLStringBase<T>::precedesDict( const std::basic_string<T>& a, const std::ba
760 } 750 }
761} 751}
762 752
763// Constructors
764template<class T>
765LLStringBase<T>::LLStringBase(const T* s ) : std::basic_string<T>()
766{
767 if (s) assign(s);
768}
769
770template<class T>
771LLStringBase<T>::LLStringBase(const T* s, size_type n ) : std::basic_string<T>()
772{
773 if (s) assign(s, n);
774}
775
776// Init from a substring
777template<class T>
778LLStringBase<T>::LLStringBase(const T* s, size_type pos, size_type n ) : std::basic_string<T>()
779{
780 if( s )
781 {
782 assign(s + pos, n);
783 }
784 else
785 {
786 assign(LLStringBase<T>::null);
787 }
788}
789
790#if LL_LINUX || LL_SOLARIS
791template<class T>
792LLStringBase<T>& LLStringBase<T>::assign(const T* s)
793{
794 if (s)
795 {
796 std::basic_string<T>::assign(s);
797 }
798 else
799 {
800 assign(LLStringBase<T>::null);
801 }
802 return *this;
803}
804
805template<class T>
806LLStringBase<T>& LLStringBase<T>::assign(const T* s, size_type n)
807{
808 if (s)
809 {
810 std::basic_string<T>::assign(s, n);
811 }
812 else
813 {
814 assign(LLStringBase<T>::null);
815 }
816 return *this;
817}
818
819template<class T>
820LLStringBase<T>& LLStringBase<T>::assign(const LLStringBase<T>& s)
821{
822 std::basic_string<T>::assign(s);
823 return *this;
824}
825
826template<class T>
827LLStringBase<T>& LLStringBase<T>::assign(size_type n, const T& c)
828{
829 std::basic_string<T>::assign(n, c);
830 return *this;
831}
832
833template<class T>
834LLStringBase<T>& LLStringBase<T>::assign(const T* a, const T* b)
835{
836 if (a > b)
837 assign(LLStringBase<T>::null);
838 else
839 assign(a, (size_type) (b-a));
840 return *this;
841}
842
843template<class T>
844LLStringBase<T>& LLStringBase<T>::assign(typename LLStringBase<T>::iterator &it1, typename LLStringBase<T>::iterator &it2)
845{
846 assign(LLStringBase<T>::null);
847 while(it1 != it2)
848 *this += *it1++;
849 return *this;
850}
851
852template<class T>
853LLStringBase<T>& LLStringBase<T>::assign(typename LLStringBase<T>::const_iterator &it1, typename LLStringBase<T>::const_iterator &it2)
854{
855 assign(LLStringBase<T>::null);
856 while(it1 != it2)
857 *this += *it1++;
858 return *this;
859}
860#endif
861
862//static 753//static
863template<class T> 754template<class T>
864void LLStringBase<T>::toUpper(std::basic_string<T>& string) 755void LLStringUtilBase<T>::toUpper(std::basic_string<T>& string)
865{ 756{
866 if( !string.empty() ) 757 if( !string.empty() )
867 { 758 {
@@ -875,7 +766,7 @@ void LLStringBase<T>::toUpper(std::basic_string<T>& string)
875 766
876//static 767//static
877template<class T> 768template<class T>
878void LLStringBase<T>::toLower(std::basic_string<T>& string) 769void LLStringUtilBase<T>::toLower(std::basic_string<T>& string)
879{ 770{
880 if( !string.empty() ) 771 if( !string.empty() )
881 { 772 {
@@ -889,7 +780,7 @@ void LLStringBase<T>::toLower(std::basic_string<T>& string)
889 780
890//static 781//static
891template<class T> 782template<class T>
892void LLStringBase<T>::trimHead(std::basic_string<T>& string) 783void LLStringUtilBase<T>::trimHead(std::basic_string<T>& string)
893{ 784{
894 if( !string.empty() ) 785 if( !string.empty() )
895 { 786 {
@@ -904,7 +795,7 @@ void LLStringBase<T>::trimHead(std::basic_string<T>& string)
904 795
905//static 796//static
906template<class T> 797template<class T>
907void LLStringBase<T>::trimTail(std::basic_string<T>& string) 798void LLStringUtilBase<T>::trimTail(std::basic_string<T>& string)
908{ 799{
909 if( string.size() ) 800 if( string.size() )
910 { 801 {
@@ -923,7 +814,7 @@ void LLStringBase<T>::trimTail(std::basic_string<T>& string)
923// Replace line feeds with carriage return-line feed pairs. 814// Replace line feeds with carriage return-line feed pairs.
924//static 815//static
925template<class T> 816template<class T>
926void LLStringBase<T>::addCRLF(std::basic_string<T>& string) 817void LLStringUtilBase<T>::addCRLF(std::basic_string<T>& string)
927{ 818{
928 const T LF = 10; 819 const T LF = 10;
929 const T CR = 13; 820 const T CR = 13;
@@ -964,7 +855,7 @@ void LLStringBase<T>::addCRLF(std::basic_string<T>& string)
964// Remove all carriage returns 855// Remove all carriage returns
965//static 856//static
966template<class T> 857template<class T>
967void LLStringBase<T>::removeCRLF(std::basic_string<T>& string) 858void LLStringUtilBase<T>::removeCRLF(std::basic_string<T>& string)
968{ 859{
969 const T CR = 13; 860 const T CR = 13;
970 861
@@ -985,7 +876,7 @@ void LLStringBase<T>::removeCRLF(std::basic_string<T>& string)
985 876
986//static 877//static
987template<class T> 878template<class T>
988void LLStringBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement ) 879void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement )
989{ 880{
990 size_type found_pos = 0; 881 size_type found_pos = 0;
991 for (found_pos = string.find(target, found_pos); 882 for (found_pos = string.find(target, found_pos);
@@ -998,7 +889,7 @@ void LLStringBase<T>::replaceChar( std::basic_string<T>& string, T target, T rep
998 889
999//static 890//static
1000template<class T> 891template<class T>
1001void LLStringBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T replacement ) 892void LLStringUtilBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T replacement )
1002{ 893{
1003 const char LF = 10; 894 const char LF = 10;
1004 const S8 MIN = 32; 895 const S8 MIN = 32;
@@ -1018,12 +909,12 @@ void LLStringBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T r
1018 909
1019//static 910//static
1020template<class T> 911template<class T>
1021void LLStringBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_type spaces_per_tab ) 912void LLStringUtilBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_type spaces_per_tab )
1022{ 913{
1023 const T TAB = '\t'; 914 const T TAB = '\t';
1024 const T SPACE = ' '; 915 const T SPACE = ' ';
1025 916
1026 LLStringBase<T> out_str; 917 std::basic_string<T> out_str;
1027 // Replace tabs with spaces 918 // Replace tabs with spaces
1028 for (size_type i = 0; i < str.length(); i++) 919 for (size_type i = 0; i < str.length(); i++)
1029 { 920 {
@@ -1042,7 +933,7 @@ void LLStringBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_typ
1042 933
1043//static 934//static
1044template<class T> 935template<class T>
1045BOOL LLStringBase<T>::containsNonprintable(const std::basic_string<T>& string) 936BOOL LLStringUtilBase<T>::containsNonprintable(const std::basic_string<T>& string)
1046{ 937{
1047 const char MIN = 32; 938 const char MIN = 32;
1048 BOOL rv = FALSE; 939 BOOL rv = FALSE;
@@ -1059,7 +950,7 @@ BOOL LLStringBase<T>::containsNonprintable(const std::basic_string<T>& string)
1059 950
1060//static 951//static
1061template<class T> 952template<class T>
1062void LLStringBase<T>::stripNonprintable(std::basic_string<T>& string) 953void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string)
1063{ 954{
1064 const char MIN = 32; 955 const char MIN = 32;
1065 size_type j = 0; 956 size_type j = 0;
@@ -1090,7 +981,7 @@ void LLStringBase<T>::stripNonprintable(std::basic_string<T>& string)
1090} 981}
1091 982
1092template<class T> 983template<class T>
1093void LLStringBase<T>::_makeASCII(std::basic_string<T>& string) 984void LLStringUtilBase<T>::_makeASCII(std::basic_string<T>& string)
1094{ 985{
1095 // Replace non-ASCII chars with LL_UNKNOWN_CHAR 986 // Replace non-ASCII chars with LL_UNKNOWN_CHAR
1096 for (size_type i = 0; i < string.length(); i++) 987 for (size_type i = 0; i < string.length(); i++)
@@ -1104,7 +995,7 @@ void LLStringBase<T>::_makeASCII(std::basic_string<T>& string)
1104 995
1105// static 996// static
1106template<class T> 997template<class T>
1107void LLStringBase<T>::copy( T* dst, const T* src, size_type dst_size ) 998void LLStringUtilBase<T>::copy( T* dst, const T* src, size_type dst_size )
1108{ 999{
1109 if( dst_size > 0 ) 1000 if( dst_size > 0 )
1110 { 1001 {
@@ -1120,7 +1011,7 @@ void LLStringBase<T>::copy( T* dst, const T* src, size_type dst_size )
1120 1011
1121// static 1012// static
1122template<class T> 1013template<class T>
1123void LLStringBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset) 1014void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset)
1124{ 1015{
1125 if ( offset == dst.length() ) 1016 if ( offset == dst.length() )
1126 { 1017 {
@@ -1141,7 +1032,7 @@ void LLStringBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_strin
1141// True if this is the head of s. 1032// True if this is the head of s.
1142//static 1033//static
1143template<class T> 1034template<class T>
1144BOOL LLStringBase<T>::isHead( const std::basic_string<T>& string, const T* s ) 1035BOOL LLStringUtilBase<T>::isHead( const std::basic_string<T>& string, const T* s )
1145{ 1036{
1146 if( string.empty() ) 1037 if( string.empty() )
1147 { 1038 {
@@ -1155,14 +1046,14 @@ BOOL LLStringBase<T>::isHead( const std::basic_string<T>& string, const T* s )
1155} 1046}
1156 1047
1157template<class T> 1048template<class T>
1158BOOL LLStringBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& value) 1049BOOL LLStringUtilBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& value)
1159{ 1050{
1160 if( string.empty() ) 1051 if( string.empty() )
1161 { 1052 {
1162 return FALSE; 1053 return FALSE;
1163 } 1054 }
1164 1055
1165 LLStringBase<T> temp( string ); 1056 std::basic_string<T> temp( string );
1166 trim(temp); 1057 trim(temp);
1167 if( 1058 if(
1168 (temp == "1") || 1059 (temp == "1") ||
@@ -1192,7 +1083,7 @@ BOOL LLStringBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& va
1192} 1083}
1193 1084
1194template<class T> 1085template<class T>
1195BOOL LLStringBase<T>::convertToU8(const std::basic_string<T>& string, U8& value) 1086BOOL LLStringUtilBase<T>::convertToU8(const std::basic_string<T>& string, U8& value)
1196{ 1087{
1197 S32 value32 = 0; 1088 S32 value32 = 0;
1198 BOOL success = convertToS32(string, value32); 1089 BOOL success = convertToS32(string, value32);
@@ -1205,7 +1096,7 @@ BOOL LLStringBase<T>::convertToU8(const std::basic_string<T>& string, U8& value)
1205} 1096}
1206 1097
1207template<class T> 1098template<class T>
1208BOOL LLStringBase<T>::convertToS8(const std::basic_string<T>& string, S8& value) 1099BOOL LLStringUtilBase<T>::convertToS8(const std::basic_string<T>& string, S8& value)
1209{ 1100{
1210 S32 value32 = 0; 1101 S32 value32 = 0;
1211 BOOL success = convertToS32(string, value32); 1102 BOOL success = convertToS32(string, value32);
@@ -1218,7 +1109,7 @@ BOOL LLStringBase<T>::convertToS8(const std::basic_string<T>& string, S8& value)
1218} 1109}
1219 1110
1220template<class T> 1111template<class T>
1221BOOL LLStringBase<T>::convertToS16(const std::basic_string<T>& string, S16& value) 1112BOOL LLStringUtilBase<T>::convertToS16(const std::basic_string<T>& string, S16& value)
1222{ 1113{
1223 S32 value32 = 0; 1114 S32 value32 = 0;
1224 BOOL success = convertToS32(string, value32); 1115 BOOL success = convertToS32(string, value32);
@@ -1231,7 +1122,7 @@ BOOL LLStringBase<T>::convertToS16(const std::basic_string<T>& string, S16& valu
1231} 1122}
1232 1123
1233template<class T> 1124template<class T>
1234BOOL LLStringBase<T>::convertToU16(const std::basic_string<T>& string, U16& value) 1125BOOL LLStringUtilBase<T>::convertToU16(const std::basic_string<T>& string, U16& value)
1235{ 1126{
1236 S32 value32 = 0; 1127 S32 value32 = 0;
1237 BOOL success = convertToS32(string, value32); 1128 BOOL success = convertToS32(string, value32);
@@ -1244,14 +1135,14 @@ BOOL LLStringBase<T>::convertToU16(const std::basic_string<T>& string, U16& valu
1244} 1135}
1245 1136
1246template<class T> 1137template<class T>
1247BOOL LLStringBase<T>::convertToU32(const std::basic_string<T>& string, U32& value) 1138BOOL LLStringUtilBase<T>::convertToU32(const std::basic_string<T>& string, U32& value)
1248{ 1139{
1249 if( string.empty() ) 1140 if( string.empty() )
1250 { 1141 {
1251 return FALSE; 1142 return FALSE;
1252 } 1143 }
1253 1144
1254 LLStringBase<T> temp( string ); 1145 std::basic_string<T> temp( string );
1255 trim(temp); 1146 trim(temp);
1256 U32 v; 1147 U32 v;
1257 std::basic_istringstream<T> i_stream((std::basic_string<T>)temp); 1148 std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
@@ -1271,14 +1162,14 @@ BOOL LLStringBase<T>::convertToU32(const std::basic_string<T>& string, U32& valu
1271} 1162}
1272 1163
1273template<class T> 1164template<class T>
1274BOOL LLStringBase<T>::convertToS32(const std::basic_string<T>& string, S32& value) 1165BOOL LLStringUtilBase<T>::convertToS32(const std::basic_string<T>& string, S32& value)
1275{ 1166{
1276 if( string.empty() ) 1167 if( string.empty() )
1277 { 1168 {
1278 return FALSE; 1169 return FALSE;
1279 } 1170 }
1280 1171
1281 LLStringBase<T> temp( string ); 1172 std::basic_string<T> temp( string );
1282 trim(temp); 1173 trim(temp);
1283 S32 v; 1174 S32 v;
1284 std::basic_istringstream<T> i_stream((std::basic_string<T>)temp); 1175 std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
@@ -1298,7 +1189,7 @@ BOOL LLStringBase<T>::convertToS32(const std::basic_string<T>& string, S32& valu
1298} 1189}
1299 1190
1300template<class T> 1191template<class T>
1301BOOL LLStringBase<T>::convertToF32(const std::basic_string<T>& string, F32& value) 1192BOOL LLStringUtilBase<T>::convertToF32(const std::basic_string<T>& string, F32& value)
1302{ 1193{
1303 F64 value64 = 0.0; 1194 F64 value64 = 0.0;
1304 BOOL success = convertToF64(string, value64); 1195 BOOL success = convertToF64(string, value64);
@@ -1311,14 +1202,14 @@ BOOL LLStringBase<T>::convertToF32(const std::basic_string<T>& string, F32& valu
1311} 1202}
1312 1203
1313template<class T> 1204template<class T>
1314BOOL LLStringBase<T>::convertToF64(const std::basic_string<T>& string, F64& value) 1205BOOL LLStringUtilBase<T>::convertToF64(const std::basic_string<T>& string, F64& value)
1315{ 1206{
1316 if( string.empty() ) 1207 if( string.empty() )
1317 { 1208 {
1318 return FALSE; 1209 return FALSE;
1319 } 1210 }
1320 1211
1321 LLStringBase<T> temp( string ); 1212 std::basic_string<T> temp( string );
1322 trim(temp); 1213 trim(temp);
1323 F64 v; 1214 F64 v;
1324 std::basic_istringstream<T> i_stream((std::basic_string<T>)temp); 1215 std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
@@ -1338,7 +1229,7 @@ BOOL LLStringBase<T>::convertToF64(const std::basic_string<T>& string, F64& valu
1338} 1229}
1339 1230
1340template<class T> 1231template<class T>
1341void LLStringBase<T>::truncate(std::basic_string<T>& string, size_type count) 1232void LLStringUtilBase<T>::truncate(std::basic_string<T>& string, size_type count)
1342{ 1233{
1343 size_type cur_size = string.size(); 1234 size_type cur_size = string.size();
1344 string.resize(count < cur_size ? count : cur_size); 1235 string.resize(count < cur_size ? count : cur_size);