diff options
Diffstat (limited to 'linden/indra/llcommon/llstring.h')
-rw-r--r-- | linden/indra/llcommon/llstring.h | 391 |
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 | ||
40 | const char LL_UNKNOWN_CHAR = '?'; | 40 | const char LL_UNKNOWN_CHAR = '?'; |
41 | 41 | ||
42 | class LLVector3; | 42 | #if LL_DARWIN || LL_LINUX || LL_SOLARIS |
43 | class LLVector3d; | 43 | // Template specialization of char_traits for U16s. Only necessary on Mac and Linux (exists on Windows already) |
44 | class LLQuaternion; | ||
45 | class LLUUID; | ||
46 | class LLColor4; | ||
47 | class 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) | ||
51 | namespace std | 44 | namespace std |
52 | { | 45 | { |
53 | template<> | 46 | template<> |
@@ -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 | 160 | class FormatMapString : public std::string |
168 | 161 | { | |
169 | //**************************************************************** | 162 | public: |
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 | ||
177 | template <class T> | 168 | template <class T> |
178 | class LLStringBase : public std::basic_string<T> | 169 | class LLStringUtilBase |
179 | { | 170 | { |
180 | public: | 171 | public: |
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 | |||
231 | public: | 174 | public: |
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 | ||
323 | template<class T> LLStringBase<T> LLStringBase<T>::null; | 268 | template<class T> std::basic_string<T> LLStringUtilBase<T>::null; |
324 | 269 | ||
325 | typedef LLStringBase<char> LLString; | 270 | typedef LLStringUtilBase<char> LLStringUtil; |
326 | typedef LLStringBase<llwchar> LLWString; | 271 | typedef LLStringUtilBase<llwchar> LLWStringUtil; |
272 | typedef 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. |
331 | class LLStringExplicit : public LLString | 277 | class LLStringExplicit : public std::string |
332 | { | 278 | { |
333 | public: | 279 | public: |
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 | ||
340 | struct LLDictionaryLess | 285 | struct LLDictionaryLess |
@@ -342,7 +287,7 @@ struct LLDictionaryLess | |||
342 | public: | 287 | public: |
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 | */ |
373 | std::string ll_safe_string(const char* in); | 318 | std::string ll_safe_string(const char* in); |
319 | std::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 | */ |
390 | bool _read_file_into_string(std::string& str, const char* filename); | 336 | bool _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); | |||
409 | llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len); | 355 | llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len); |
410 | llutf16string wstring_to_utf16str(const LLWString &utf32str); | 356 | llutf16string wstring_to_utf16str(const LLWString &utf32str); |
411 | 357 | ||
412 | llutf16string utf8str_to_utf16str ( const LLString& utf8str, S32 len); | 358 | llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len); |
413 | llutf16string utf8str_to_utf16str ( const LLString& utf8str ); | 359 | llutf16string utf8str_to_utf16str ( const std::string& utf8str ); |
414 | 360 | ||
415 | LLWString utf8str_to_wstring(const std::string &utf8str, S32 len); | 361 | LLWString utf8str_to_wstring(const std::string &utf8str, S32 len); |
416 | LLWString utf8str_to_wstring(const std::string &utf8str); | 362 | LLWString utf8str_to_wstring(const std::string &utf8str); |
417 | // Same function, better name. JC | 363 | // Same function, better name. JC |
418 | inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); } | 364 | inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); } |
419 | 365 | ||
420 | // Special hack for llfilepicker.cpp: | 366 | // |
421 | S32 utf16chars_to_utf8chars(const U16* inchars, char* outchars, S32* nchars8 = 0); | ||
422 | S32 utf16chars_to_wchar(const U16* inchars, llwchar* outchar); | ||
423 | S32 wchar_to_utf8chars(llwchar inchar, char* outchars); | 367 | S32 wchar_to_utf8chars(llwchar inchar, char* outchars); |
424 | 368 | ||
425 | // | ||
426 | std::string wstring_to_utf8str(const LLWString &utf32str, S32 len); | 369 | std::string wstring_to_utf8str(const LLWString &utf32str, S32 len); |
427 | std::string wstring_to_utf8str(const LLWString &utf32str); | 370 | std::string wstring_to_utf8str(const LLWString &utf32str); |
428 | 371 | ||
@@ -484,15 +427,6 @@ std::string mbcsstring_makeASCII(const std::string& str); | |||
484 | std::string utf8str_removeCRLF(const std::string& utf8str); | 427 | std::string utf8str_removeCRLF(const std::string& utf8str); |
485 | 428 | ||
486 | 429 | ||
487 | template <class T> | ||
488 | std::ostream& operator<<(std::ostream &s, const LLStringBase<T> &str) | ||
489 | { | ||
490 | s << ((std::basic_string<T>)str); | ||
491 | return s; | ||
492 | } | ||
493 | |||
494 | std::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 |
589 | template<class T> | 537 | template<class T> |
590 | S32 LLStringBase<T>::format(std::basic_string<T>& s, const format_map_t& fmt_map) | 538 | S32 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 |
615 | template<class T> | 587 | template<class T> |
616 | S32 LLStringBase<T>::compareStrings(const T* lhs, const T* rhs) | 588 | S32 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 | ||
613 | template<class T> | ||
614 | S32 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 |
641 | template<class T> | 620 | template<class T> |
642 | S32 LLStringBase<T>::compareInsensitive(const T* lhs, const T* rhs ) | 621 | S32 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 | ||
650 | template<class T> | ||
651 | S32 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 |
675 | template<class T> | 664 | template<class T> |
676 | S32 LLStringBase<T>::compareDict(const std::basic_string<T>& astr, const std::basic_string<T>& bstr) | 665 | S32 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 | ||
715 | template<class T> | 705 | template<class T> |
716 | S32 LLStringBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, const std::basic_string<T>& bstr) | 706 | S32 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 |
750 | template<class T> | 740 | template<class T> |
751 | BOOL LLStringBase<T>::precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b ) | 741 | BOOL 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 | ||
764 | template<class T> | ||
765 | LLStringBase<T>::LLStringBase(const T* s ) : std::basic_string<T>() | ||
766 | { | ||
767 | if (s) assign(s); | ||
768 | } | ||
769 | |||
770 | template<class T> | ||
771 | LLStringBase<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 | ||
777 | template<class T> | ||
778 | LLStringBase<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 | ||
791 | template<class T> | ||
792 | LLStringBase<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 | |||
805 | template<class T> | ||
806 | LLStringBase<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 | |||
819 | template<class T> | ||
820 | LLStringBase<T>& LLStringBase<T>::assign(const LLStringBase<T>& s) | ||
821 | { | ||
822 | std::basic_string<T>::assign(s); | ||
823 | return *this; | ||
824 | } | ||
825 | |||
826 | template<class T> | ||
827 | LLStringBase<T>& LLStringBase<T>::assign(size_type n, const T& c) | ||
828 | { | ||
829 | std::basic_string<T>::assign(n, c); | ||
830 | return *this; | ||
831 | } | ||
832 | |||
833 | template<class T> | ||
834 | LLStringBase<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 | |||
843 | template<class T> | ||
844 | LLStringBase<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 | |||
852 | template<class T> | ||
853 | LLStringBase<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 |
863 | template<class T> | 754 | template<class T> |
864 | void LLStringBase<T>::toUpper(std::basic_string<T>& string) | 755 | void 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 |
877 | template<class T> | 768 | template<class T> |
878 | void LLStringBase<T>::toLower(std::basic_string<T>& string) | 769 | void 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 |
891 | template<class T> | 782 | template<class T> |
892 | void LLStringBase<T>::trimHead(std::basic_string<T>& string) | 783 | void 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 |
906 | template<class T> | 797 | template<class T> |
907 | void LLStringBase<T>::trimTail(std::basic_string<T>& string) | 798 | void 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 |
925 | template<class T> | 816 | template<class T> |
926 | void LLStringBase<T>::addCRLF(std::basic_string<T>& string) | 817 | void 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 |
966 | template<class T> | 857 | template<class T> |
967 | void LLStringBase<T>::removeCRLF(std::basic_string<T>& string) | 858 | void 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 |
987 | template<class T> | 878 | template<class T> |
988 | void LLStringBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement ) | 879 | void 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 |
1000 | template<class T> | 891 | template<class T> |
1001 | void LLStringBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T replacement ) | 892 | void 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 |
1020 | template<class T> | 911 | template<class T> |
1021 | void LLStringBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_type spaces_per_tab ) | 912 | void 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 |
1044 | template<class T> | 935 | template<class T> |
1045 | BOOL LLStringBase<T>::containsNonprintable(const std::basic_string<T>& string) | 936 | BOOL 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 |
1061 | template<class T> | 952 | template<class T> |
1062 | void LLStringBase<T>::stripNonprintable(std::basic_string<T>& string) | 953 | void 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 | ||
1092 | template<class T> | 983 | template<class T> |
1093 | void LLStringBase<T>::_makeASCII(std::basic_string<T>& string) | 984 | void 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 |
1106 | template<class T> | 997 | template<class T> |
1107 | void LLStringBase<T>::copy( T* dst, const T* src, size_type dst_size ) | 998 | void 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 |
1122 | template<class T> | 1013 | template<class T> |
1123 | void LLStringBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset) | 1014 | void 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 |
1143 | template<class T> | 1034 | template<class T> |
1144 | BOOL LLStringBase<T>::isHead( const std::basic_string<T>& string, const T* s ) | 1035 | BOOL 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 | ||
1157 | template<class T> | 1048 | template<class T> |
1158 | BOOL LLStringBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& value) | 1049 | BOOL 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 | ||
1194 | template<class T> | 1085 | template<class T> |
1195 | BOOL LLStringBase<T>::convertToU8(const std::basic_string<T>& string, U8& value) | 1086 | BOOL 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 | ||
1207 | template<class T> | 1098 | template<class T> |
1208 | BOOL LLStringBase<T>::convertToS8(const std::basic_string<T>& string, S8& value) | 1099 | BOOL 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 | ||
1220 | template<class T> | 1111 | template<class T> |
1221 | BOOL LLStringBase<T>::convertToS16(const std::basic_string<T>& string, S16& value) | 1112 | BOOL 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 | ||
1233 | template<class T> | 1124 | template<class T> |
1234 | BOOL LLStringBase<T>::convertToU16(const std::basic_string<T>& string, U16& value) | 1125 | BOOL 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 | ||
1246 | template<class T> | 1137 | template<class T> |
1247 | BOOL LLStringBase<T>::convertToU32(const std::basic_string<T>& string, U32& value) | 1138 | BOOL 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 | ||
1273 | template<class T> | 1164 | template<class T> |
1274 | BOOL LLStringBase<T>::convertToS32(const std::basic_string<T>& string, S32& value) | 1165 | BOOL 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 | ||
1300 | template<class T> | 1191 | template<class T> |
1301 | BOOL LLStringBase<T>::convertToF32(const std::basic_string<T>& string, F32& value) | 1192 | BOOL 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 | ||
1313 | template<class T> | 1204 | template<class T> |
1314 | BOOL LLStringBase<T>::convertToF64(const std::basic_string<T>& string, F64& value) | 1205 | BOOL 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 | ||
1340 | template<class T> | 1231 | template<class T> |
1341 | void LLStringBase<T>::truncate(std::basic_string<T>& string, size_type count) | 1232 | void 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); |