UDK 3.2.7 C/C++ API Reference
|
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 00002 /************************************************************************* 00003 * 00004 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 00005 * 00006 * Copyright 2000, 2010 Oracle and/or its affiliates. 00007 * 00008 * OpenOffice.org - a multi-platform office productivity suite 00009 * 00010 * This file is part of OpenOffice.org. 00011 * 00012 * OpenOffice.org is free software: you can redistribute it and/or modify 00013 * it under the terms of the GNU Lesser General Public License version 3 00014 * only, as published by the Free Software Foundation. 00015 * 00016 * OpenOffice.org is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Lesser General Public License version 3 for more details 00020 * (a copy is included in the LICENSE file that accompanied this code). 00021 * 00022 * You should have received a copy of the GNU Lesser General Public License 00023 * version 3 along with OpenOffice.org. If not, see 00024 * <http://www.openoffice.org/license.html> 00025 * for a copy of the LGPLv3 License. 00026 * 00027 ************************************************************************/ 00028 00029 #ifndef _RTL_USTRING_HXX_ 00030 #define _RTL_USTRING_HXX_ 00031 00032 #include "sal/config.h" 00033 00034 #include <cassert> 00035 00036 #include "osl/diagnose.h" 00037 #include <rtl/ustring.h> 00038 #include <rtl/string.hxx> 00039 #include <rtl/stringutils.hxx> 00040 #include <rtl/memory.h> 00041 #include "sal/log.hxx" 00042 00043 #if defined EXCEPTIONS_OFF 00044 #include <stdlib.h> 00045 #else 00046 #include <new> 00047 #endif 00048 00049 // The unittest uses slightly different code to help check that the proper 00050 // calls are made. The class is put into a different namespace to make 00051 // sure the compiler generates a different (if generating also non-inline) 00052 // copy of the function and does not merge them together. The class 00053 // is "brought" into the proper rtl namespace by a typedef below. 00054 #ifdef RTL_STRING_UNITTEST 00055 #define rtl rtlunittest 00056 #endif 00057 00058 namespace rtl 00059 { 00060 00061 #ifdef RTL_STRING_UNITTEST 00062 #undef rtl 00063 #endif 00064 00065 /* ======================================================================= */ 00066 00091 class OUString 00092 { 00093 public: 00095 rtl_uString * pData; 00097 00098 private: 00099 class DO_NOT_ACQUIRE{}; 00100 00101 OUString( rtl_uString * value, SAL_UNUSED_PARAMETER DO_NOT_ACQUIRE * ) 00102 { 00103 pData = value; 00104 } 00105 00106 public: 00110 OUString() SAL_THROW(()) 00111 { 00112 pData = 0; 00113 rtl_uString_new( &pData ); 00114 } 00115 00121 OUString( const OUString & str ) SAL_THROW(()) 00122 { 00123 pData = str.pData; 00124 rtl_uString_acquire( pData ); 00125 } 00126 00132 OUString( rtl_uString * str ) SAL_THROW(()) 00133 { 00134 pData = str; 00135 rtl_uString_acquire( pData ); 00136 } 00137 00146 inline OUString( rtl_uString * str, __sal_NoAcquire ) SAL_THROW(()) 00147 { pData = str; } 00148 00154 explicit OUString( sal_Unicode value ) SAL_THROW(()) 00155 : pData (0) 00156 { 00157 rtl_uString_newFromStr_WithLength( &pData, &value, 1 ); 00158 } 00159 00165 OUString( const sal_Unicode * value ) SAL_THROW(()) 00166 { 00167 pData = 0; 00168 rtl_uString_newFromStr( &pData, value ); 00169 } 00170 00179 OUString( const sal_Unicode * value, sal_Int32 length ) SAL_THROW(()) 00180 { 00181 pData = 0; 00182 rtl_uString_newFromStr_WithLength( &pData, value, length ); 00183 } 00184 00200 #ifdef HAVE_SFINAE_ANONYMOUS_BROKEN 00201 // Old gcc can try to convert anonymous enums to OUString and give compile error. 00202 // So instead have a variant for const and non-const char[]. 00203 template< int N > 00204 OUString( const char (&literal)[ N ] ) 00205 { 00206 pData = 0; 00207 rtl_uString_newFromLiteral( &pData, literal, N - 1, 0 ); 00208 #ifdef RTL_STRING_UNITTEST 00209 rtl_string_unittest_const_literal = true; 00210 #endif 00211 } 00212 00217 template< int N > 00218 OUString( char (&value)[ N ] ) 00219 #ifndef RTL_STRING_UNITTEST 00220 ; // intentionally not implemented 00221 #else 00222 { 00223 (void) value; // unused 00224 pData = 0; 00225 rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage 00226 rtl_string_unittest_invalid_conversion = true; 00227 } 00228 #endif 00229 #else // HAVE_SFINAE_ANONYMOUS_BROKEN 00230 template< typename T > 00231 OUString( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy() ) 00232 { 00233 pData = 0; 00234 rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 0 ); 00235 #ifdef RTL_STRING_UNITTEST 00236 rtl_string_unittest_const_literal = true; 00237 #endif 00238 } 00239 00240 #endif // HAVE_SFINAE_ANONYMOUS_BROKEN 00241 00242 00243 #ifdef RTL_STRING_UNITTEST 00244 00248 template< typename T > 00249 OUString( T&, typename internal::ExceptConstCharArrayDetector< T >::Type = internal::Dummy() ) 00250 { 00251 pData = 0; 00252 rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage 00253 rtl_string_unittest_invalid_conversion = true; 00254 } 00259 template< typename T > 00260 OUString( const T&, typename internal::ExceptCharArrayDetector< T >::Type = internal::Dummy() ) 00261 { 00262 pData = 0; 00263 rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage 00264 rtl_string_unittest_invalid_conversion = true; 00265 } 00266 #endif 00267 00282 OUString( const sal_Char * value, sal_Int32 length, 00283 rtl_TextEncoding encoding, 00284 sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS ) 00285 { 00286 pData = 0; 00287 rtl_string2UString( &pData, value, length, encoding, convertFlags ); 00288 if (pData == 0) { 00289 #if defined EXCEPTIONS_OFF 00290 abort(); 00291 #else 00292 throw std::bad_alloc(); 00293 #endif 00294 } 00295 } 00296 00313 inline explicit OUString( 00314 sal_uInt32 const * codePoints, sal_Int32 codePointCount): 00315 pData(NULL) 00316 { 00317 rtl_uString_newFromCodePoints(&pData, codePoints, codePointCount); 00318 if (pData == NULL) { 00319 #if defined EXCEPTIONS_OFF 00320 abort(); 00321 #else 00322 throw std::bad_alloc(); 00323 #endif 00324 } 00325 } 00326 00330 ~OUString() SAL_THROW(()) 00331 { 00332 rtl_uString_release( pData ); 00333 } 00334 00346 static inline OUString const & unacquired( rtl_uString * const * ppHandle ) 00347 { return * reinterpret_cast< OUString const * >( ppHandle ); } 00348 00354 OUString & operator=( const OUString & str ) SAL_THROW(()) 00355 { 00356 rtl_uString_assign( &pData, str.pData ); 00357 return *this; 00358 } 00359 00372 template< typename T > 00373 typename internal::ConstCharArrayDetector< T, OUString& >::Type operator=( T& literal ) 00374 { 00375 rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 0 ); 00376 return *this; 00377 } 00378 00384 OUString & operator+=( const OUString & str ) SAL_THROW(()) 00385 { 00386 rtl_uString_newConcat( &pData, pData, str.pData ); 00387 return *this; 00388 } 00389 00398 sal_Int32 getLength() const SAL_THROW(()) { return pData->length; } 00399 00408 bool isEmpty() const SAL_THROW(()) 00409 { 00410 return pData->length == 0; 00411 } 00412 00420 const sal_Unicode * getStr() const SAL_THROW(()) { return pData->buffer; } 00421 00431 sal_Unicode operator [](sal_Int32 index) const { return getStr()[index]; } 00432 00445 sal_Int32 compareTo( const OUString & str ) const SAL_THROW(()) 00446 { 00447 return rtl_ustr_compare_WithLength( pData->buffer, pData->length, 00448 str.pData->buffer, str.pData->length ); 00449 } 00450 00466 sal_Int32 compareTo( const OUString & str, sal_Int32 maxLength ) const SAL_THROW(()) 00467 { 00468 return rtl_ustr_shortenedCompare_WithLength( pData->buffer, pData->length, 00469 str.pData->buffer, str.pData->length, maxLength ); 00470 } 00471 00484 sal_Int32 reverseCompareTo( const OUString & str ) const SAL_THROW(()) 00485 { 00486 return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length, 00487 str.pData->buffer, str.pData->length ); 00488 } 00489 00501 sal_Bool equals( const OUString & str ) const SAL_THROW(()) 00502 { 00503 if ( pData->length != str.pData->length ) 00504 return sal_False; 00505 if ( pData == str.pData ) 00506 return sal_True; 00507 return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length, 00508 str.pData->buffer, str.pData->length ) == 0; 00509 } 00510 00525 sal_Bool equalsIgnoreAsciiCase( const OUString & str ) const SAL_THROW(()) 00526 { 00527 if ( pData->length != str.pData->length ) 00528 return sal_False; 00529 if ( pData == str.pData ) 00530 return sal_True; 00531 return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, 00532 str.pData->buffer, str.pData->length ) == 0; 00533 } 00534 00540 template< typename T > 00541 typename internal::ConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& literal ) const SAL_THROW(()) 00542 { 00543 if ( pData->length != internal::ConstCharArrayDetector< T, void >::size - 1 ) 00544 return sal_False; 00545 00546 return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, literal ) == 0; 00547 } 00548 00564 sal_Bool match( const OUString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(()) 00565 { 00566 return rtl_ustr_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, 00567 str.pData->buffer, str.pData->length, str.pData->length ) == 0; 00568 } 00569 00575 template< typename T > 00576 typename internal::ConstCharArrayDetector< T, bool >::Type match( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(()) 00577 { 00578 return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, 00579 literal, internal::ConstCharArrayDetector< T, void >::size - 1 ) == 0; 00580 } 00581 00600 sal_Bool matchIgnoreAsciiCase( const OUString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(()) 00601 { 00602 return rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, 00603 str.pData->buffer, str.pData->length, 00604 str.pData->length ) == 0; 00605 } 00606 00612 template< typename T > 00613 typename internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(()) 00614 { 00615 return rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, 00616 literal, internal::ConstCharArrayDetector< T, void >::size - 1 ) == 0; 00617 } 00618 00635 sal_Int32 compareToAscii( const sal_Char* asciiStr ) const SAL_THROW(()) 00636 { 00637 return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length, asciiStr ); 00638 } 00639 00657 sal_Int32 compareToAscii( const sal_Char * asciiStr, sal_Int32 maxLength ) const SAL_THROW(()) 00658 { 00659 return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer, pData->length, 00660 asciiStr, maxLength ); 00661 } 00662 00682 sal_Int32 reverseCompareToAsciiL( const sal_Char * asciiStr, sal_Int32 asciiStrLength ) const SAL_THROW(()) 00683 { 00684 return rtl_ustr_asciil_reverseCompare_WithLength( pData->buffer, pData->length, 00685 asciiStr, asciiStrLength ); 00686 } 00687 00703 sal_Bool equalsAscii( const sal_Char* asciiStr ) const SAL_THROW(()) 00704 { 00705 return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length, 00706 asciiStr ) == 0; 00707 } 00708 00726 sal_Bool equalsAsciiL( const sal_Char* asciiStr, sal_Int32 asciiStrLength ) const SAL_THROW(()) 00727 { 00728 if ( pData->length != asciiStrLength ) 00729 return sal_False; 00730 00731 return rtl_ustr_asciil_reverseEquals_WithLength( 00732 pData->buffer, asciiStr, asciiStrLength ); 00733 } 00734 00753 sal_Bool equalsIgnoreAsciiCaseAscii( const sal_Char * asciiStr ) const SAL_THROW(()) 00754 { 00755 return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0; 00756 } 00757 00776 sal_Int32 compareToIgnoreAsciiCaseAscii( const sal_Char * asciiStr ) const SAL_THROW(()) 00777 { 00778 return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ); 00779 } 00780 00801 sal_Bool equalsIgnoreAsciiCaseAsciiL( const sal_Char * asciiStr, sal_Int32 asciiStrLength ) const SAL_THROW(()) 00802 { 00803 if ( pData->length != asciiStrLength ) 00804 return sal_False; 00805 00806 return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0; 00807 } 00808 00830 sal_Bool matchAsciiL( const sal_Char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const SAL_THROW(()) 00831 { 00832 return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, 00833 asciiStr, asciiStrLength ) == 0; 00834 } 00835 00836 // This overload is left undefined, to detect calls of matchAsciiL that 00837 // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of 00838 // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit 00839 // platforms): 00840 #if SAL_TYPES_SIZEOFLONG == 8 00841 void matchAsciiL(char const *, sal_Int32, rtl_TextEncoding) const; 00842 #endif 00843 00868 sal_Bool matchIgnoreAsciiCaseAsciiL( const sal_Char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const SAL_THROW(()) 00869 { 00870 return rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, 00871 asciiStr, asciiStrLength ) == 0; 00872 } 00873 00874 // This overload is left undefined, to detect calls of 00875 // matchIgnoreAsciiCaseAsciiL that erroneously use 00876 // RTL_CONSTASCII_USTRINGPARAM instead of RTL_CONSTASCII_STRINGPARAM (but 00877 // would lead to ambiguities on 32 bit platforms): 00878 #if SAL_TYPES_SIZEOFLONG == 8 00879 void matchIgnoreAsciiCaseAsciiL(char const *, sal_Int32, rtl_TextEncoding) 00880 const; 00881 #endif 00882 00893 bool endsWith(OUString const & str) const { 00894 return str.getLength() <= getLength() 00895 && match(str, getLength() - str.getLength()); 00896 } 00897 00903 template< typename T > 00904 typename internal::ConstCharArrayDetector< T, bool >::Type endsWith( T& literal ) const 00905 { 00906 return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length 00907 && rtl_ustr_asciil_reverseEquals_WithLength( 00908 pData->buffer + pData->length - ( internal::ConstCharArrayDetector< T, void >::size - 1 ), literal, 00909 internal::ConstCharArrayDetector< T, void >::size - 1); 00910 } 00911 00923 inline bool endsWithAsciiL(char const * asciiStr, sal_Int32 asciiStrLength) 00924 const 00925 { 00926 return asciiStrLength <= pData->length 00927 && rtl_ustr_asciil_reverseEquals_WithLength( 00928 pData->buffer + pData->length - asciiStrLength, asciiStr, 00929 asciiStrLength); 00930 } 00931 00945 sal_Bool endsWithIgnoreAsciiCase( const OUString & str ) const SAL_THROW(()) 00946 { 00947 return str.getLength() <= getLength() 00948 && matchIgnoreAsciiCase(str, getLength() - str.getLength()); 00949 } 00950 00956 template< typename T > 00957 typename internal::ConstCharArrayDetector< T, bool >::Type endsWithIgnoreAsciiCase( T& literal ) const SAL_THROW(()) 00958 { 00959 return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length 00960 && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( 00961 pData->buffer + pData->length - ( internal::ConstCharArrayDetector< T, void >::size - 1 ), 00962 internal::ConstCharArrayDetector< T, void >::size - 1, literal, 00963 internal::ConstCharArrayDetector< T, void >::size - 1) 00964 == 0); 00965 } 00966 00977 inline bool endsWithIgnoreAsciiCaseAsciiL( 00978 char const * asciiStr, sal_Int32 asciiStrLength) const 00979 { 00980 return asciiStrLength <= pData->length 00981 && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( 00982 pData->buffer + pData->length - asciiStrLength, 00983 asciiStrLength, asciiStr, asciiStrLength) 00984 == 0); 00985 } 00986 00987 friend sal_Bool operator == ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(()) 00988 { return rStr1.equals(rStr2); } 00989 friend sal_Bool operator == ( const OUString& rStr1, const sal_Unicode * pStr2 ) SAL_THROW(()) 00990 { return rStr1.compareTo( pStr2 ) == 0; } 00991 friend sal_Bool operator == ( const sal_Unicode * pStr1, const OUString& rStr2 ) SAL_THROW(()) 00992 { return OUString( pStr1 ).compareTo( rStr2 ) == 0; } 00993 00994 friend sal_Bool operator != ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(()) 00995 { return !(operator == ( rStr1, rStr2 )); } 00996 friend sal_Bool operator != ( const OUString& rStr1, const sal_Unicode * pStr2 ) SAL_THROW(()) 00997 { return !(operator == ( rStr1, pStr2 )); } 00998 friend sal_Bool operator != ( const sal_Unicode * pStr1, const OUString& rStr2 ) SAL_THROW(()) 00999 { return !(operator == ( pStr1, rStr2 )); } 01000 01001 friend sal_Bool operator < ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(()) 01002 { return rStr1.compareTo( rStr2 ) < 0; } 01003 friend sal_Bool operator > ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(()) 01004 { return rStr1.compareTo( rStr2 ) > 0; } 01005 friend sal_Bool operator <= ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(()) 01006 { return rStr1.compareTo( rStr2 ) <= 0; } 01007 friend sal_Bool operator >= ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(()) 01008 { return rStr1.compareTo( rStr2 ) >= 0; } 01009 01017 template< typename T > 01018 friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator==( const OUString& string, T& literal ) 01019 { 01020 return string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 ); 01021 } 01029 template< typename T > 01030 friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OUString& string ) 01031 { 01032 return string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 ); 01033 } 01041 template< typename T > 01042 friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OUString& string, T& literal ) 01043 { 01044 return !string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 ); 01045 } 01053 template< typename T > 01054 friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OUString& string ) 01055 { 01056 return !string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 ); 01057 } 01058 01066 sal_Int32 hashCode() const SAL_THROW(()) 01067 { 01068 return rtl_ustr_hashCode_WithLength( pData->buffer, pData->length ); 01069 } 01070 01084 sal_Int32 indexOf( sal_Unicode ch, sal_Int32 fromIndex = 0 ) const SAL_THROW(()) 01085 { 01086 sal_Int32 ret = rtl_ustr_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch ); 01087 return (ret < 0 ? ret : ret+fromIndex); 01088 } 01089 01099 sal_Int32 lastIndexOf( sal_Unicode ch ) const SAL_THROW(()) 01100 { 01101 return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch ); 01102 } 01103 01116 sal_Int32 lastIndexOf( sal_Unicode ch, sal_Int32 fromIndex ) const SAL_THROW(()) 01117 { 01118 return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch ); 01119 } 01120 01136 sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(()) 01137 { 01138 sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, 01139 str.pData->buffer, str.pData->length ); 01140 return (ret < 0 ? ret : ret+fromIndex); 01141 } 01142 01148 template< typename T > 01149 typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(()) 01150 { 01151 sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength( 01152 pData->buffer + fromIndex, pData->length - fromIndex, literal, 01153 internal::ConstCharArrayDetector< T, void >::size - 1); 01154 return ret < 0 ? ret : ret + fromIndex; 01155 } 01156 01180 sal_Int32 indexOfAsciiL( 01181 char const * str, sal_Int32 len, sal_Int32 fromIndex = 0) const 01182 SAL_THROW(()) 01183 { 01184 sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength( 01185 pData->buffer + fromIndex, pData->length - fromIndex, str, len); 01186 return ret < 0 ? ret : ret + fromIndex; 01187 } 01188 01189 // This overload is left undefined, to detect calls of indexOfAsciiL that 01190 // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of 01191 // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit 01192 // platforms): 01193 #if SAL_TYPES_SIZEOFLONG == 8 01194 void indexOfAsciiL(char const *, sal_Int32 len, rtl_TextEncoding) const; 01195 #endif 01196 01212 sal_Int32 lastIndexOf( const OUString & str ) const SAL_THROW(()) 01213 { 01214 return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length, 01215 str.pData->buffer, str.pData->length ); 01216 } 01217 01235 sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const SAL_THROW(()) 01236 { 01237 return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex, 01238 str.pData->buffer, str.pData->length ); 01239 } 01240 01246 template< typename T > 01247 typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const SAL_THROW(()) 01248 { 01249 return rtl_ustr_lastIndexOfAscii_WithLength( 01250 pData->buffer, pData->length, literal, internal::ConstCharArrayDetector< T, void >::size - 1); 01251 } 01252 01272 sal_Int32 lastIndexOfAsciiL(char const * str, sal_Int32 len) const 01273 SAL_THROW(()) 01274 { 01275 return rtl_ustr_lastIndexOfAscii_WithLength( 01276 pData->buffer, pData->length, str, len); 01277 } 01278 01288 OUString copy( sal_Int32 beginIndex ) const SAL_THROW(()) 01289 { 01290 assert(beginIndex >= 0 && beginIndex <= getLength()); 01291 if ( beginIndex == 0 ) 01292 return *this; 01293 else 01294 { 01295 rtl_uString* pNew = 0; 01296 rtl_uString_newFromStr_WithLength( &pNew, pData->buffer+beginIndex, getLength()-beginIndex ); 01297 return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); 01298 } 01299 } 01300 01312 OUString copy( sal_Int32 beginIndex, sal_Int32 count ) const SAL_THROW(()) 01313 { 01314 assert(beginIndex >= 0 && beginIndex <= getLength() && count >= 0); 01315 if ( (beginIndex == 0) && (count == getLength()) ) 01316 return *this; 01317 else 01318 { 01319 rtl_uString* pNew = 0; 01320 rtl_uString_newFromStr_WithLength( &pNew, pData->buffer+beginIndex, count ); 01321 return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); 01322 } 01323 } 01324 01333 OUString concat( const OUString & str ) const SAL_THROW(()) 01334 { 01335 rtl_uString* pNew = 0; 01336 rtl_uString_newConcat( &pNew, pData, str.pData ); 01337 return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); 01338 } 01339 01340 friend OUString operator+( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(()) 01341 { 01342 return rStr1.concat( rStr2 ); 01343 } 01344 01358 OUString replaceAt( sal_Int32 index, sal_Int32 count, const OUString& newStr ) const SAL_THROW(()) 01359 { 01360 rtl_uString* pNew = 0; 01361 rtl_uString_newReplaceStrAt( &pNew, pData, index, count, newStr.pData ); 01362 return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); 01363 } 01364 01378 OUString replace( sal_Unicode oldChar, sal_Unicode newChar ) const SAL_THROW(()) 01379 { 01380 rtl_uString* pNew = 0; 01381 rtl_uString_newReplace( &pNew, pData, oldChar, newChar ); 01382 return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); 01383 } 01384 01403 OUString replaceFirst( 01404 OUString const & from, OUString const & to, sal_Int32 * index = 0) const 01405 { 01406 rtl_uString * s = 0; 01407 sal_Int32 i = 0; 01408 rtl_uString_newReplaceFirst( 01409 &s, pData, from.pData, to.pData, index == 0 ? &i : index); 01410 return OUString(s, SAL_NO_ACQUIRE); 01411 } 01412 01431 template< typename T > 01432 typename internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( T& from, OUString const & to, 01433 sal_Int32 * index = 0) const 01434 { 01435 rtl_uString * s = 0; 01436 sal_Int32 i = 0; 01437 rtl_uString_newReplaceFirstAsciiL( 01438 &s, pData, from, internal::ConstCharArrayDetector< T, void >::size - 1, to.pData, index == 0 ? &i : index); 01439 return OUString(s, SAL_NO_ACQUIRE); 01440 } 01441 01460 template< typename T1, typename T2 > 01461 typename internal::ConstCharArrayDetector< T1, typename internal::ConstCharArrayDetector< T2, OUString >::Type >::Type 01462 replaceFirst( T1& from, T2& to, sal_Int32 * index = 0) const 01463 { 01464 rtl_uString * s = 0; 01465 sal_Int32 i = 0; 01466 rtl_uString_newReplaceFirstAsciiLAsciiL( 01467 &s, pData, from, internal::ConstCharArrayDetector< T1, void >::size - 1, to, 01468 internal::ConstCharArrayDetector< T2, void >::size - 1, index == 0 ? &i : index); 01469 return OUString(s, SAL_NO_ACQUIRE); 01470 } 01471 01485 OUString replaceAll(OUString const & from, OUString const & to) const { 01486 rtl_uString * s = 0; 01487 rtl_uString_newReplaceAll(&s, pData, from.pData, to.pData); 01488 return OUString(s, SAL_NO_ACQUIRE); 01489 } 01490 01504 template< typename T > 01505 typename internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( T& from, OUString const & to) const 01506 { 01507 rtl_uString * s = 0; 01508 rtl_uString_newReplaceAllAsciiL(&s, pData, from, internal::ConstCharArrayDetector< T, void >::size - 1, to.pData); 01509 return OUString(s, SAL_NO_ACQUIRE); 01510 } 01511 01525 template< typename T1, typename T2 > 01526 typename internal::ConstCharArrayDetector< T1, typename internal::ConstCharArrayDetector< T2, OUString >::Type >::Type 01527 replaceAll( T1& from, T2& to ) const 01528 { 01529 rtl_uString * s = 0; 01530 rtl_uString_newReplaceAllAsciiLAsciiL( 01531 &s, pData, from, internal::ConstCharArrayDetector< T1, void >::size - 1, 01532 to, internal::ConstCharArrayDetector< T2, void >::size - 1); 01533 return OUString(s, SAL_NO_ACQUIRE); 01534 } 01535 01546 OUString toAsciiLowerCase() const SAL_THROW(()) 01547 { 01548 rtl_uString* pNew = 0; 01549 rtl_uString_newToAsciiLowerCase( &pNew, pData ); 01550 return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); 01551 } 01552 01563 OUString toAsciiUpperCase() const SAL_THROW(()) 01564 { 01565 rtl_uString* pNew = 0; 01566 rtl_uString_newToAsciiUpperCase( &pNew, pData ); 01567 return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); 01568 } 01569 01581 OUString trim() const SAL_THROW(()) 01582 { 01583 rtl_uString* pNew = 0; 01584 rtl_uString_newTrim( &pNew, pData ); 01585 return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); 01586 } 01587 01612 OUString getToken( sal_Int32 token, sal_Unicode cTok, sal_Int32& index ) const SAL_THROW(()) 01613 { 01614 rtl_uString * pNew = 0; 01615 index = rtl_uString_getToken( &pNew, pData, token, cTok, index ); 01616 return OUString( pNew, (DO_NOT_ACQUIRE *)0 ); 01617 } 01618 01632 OUString getToken(sal_Int32 count, sal_Unicode separator) const { 01633 sal_Int32 n = 0; 01634 return getToken(count, separator, n); 01635 } 01636 01645 sal_Bool toBoolean() const SAL_THROW(()) 01646 { 01647 return rtl_ustr_toBoolean( pData->buffer ); 01648 } 01649 01656 sal_Unicode toChar() const SAL_THROW(()) 01657 { 01658 return pData->buffer[0]; 01659 } 01660 01670 sal_Int32 toInt32( sal_Int16 radix = 10 ) const SAL_THROW(()) 01671 { 01672 return rtl_ustr_toInt32( pData->buffer, radix ); 01673 } 01674 01684 sal_Int64 toInt64( sal_Int16 radix = 10 ) const SAL_THROW(()) 01685 { 01686 return rtl_ustr_toInt64( pData->buffer, radix ); 01687 } 01688 01697 float toFloat() const SAL_THROW(()) 01698 { 01699 return rtl_ustr_toFloat( pData->buffer ); 01700 } 01701 01710 double toDouble() const SAL_THROW(()) 01711 { 01712 return rtl_ustr_toDouble( pData->buffer ); 01713 } 01714 01715 01731 OUString intern() const 01732 { 01733 rtl_uString * pNew = 0; 01734 rtl_uString_intern( &pNew, pData ); 01735 if (pNew == 0) { 01736 #if defined EXCEPTIONS_OFF 01737 abort(); 01738 #else 01739 throw std::bad_alloc(); 01740 #endif 01741 } 01742 return OUString( pNew, (DO_NOT_ACQUIRE *)0 ); 01743 } 01744 01770 static OUString intern( const sal_Char * value, sal_Int32 length, 01771 rtl_TextEncoding encoding, 01772 sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS, 01773 sal_uInt32 *pInfo = NULL ) 01774 { 01775 rtl_uString * pNew = 0; 01776 rtl_uString_internConvert( &pNew, value, length, encoding, 01777 convertFlags, pInfo ); 01778 if (pNew == 0) { 01779 #if defined EXCEPTIONS_OFF 01780 abort(); 01781 #else 01782 throw std::bad_alloc(); 01783 #endif 01784 } 01785 return OUString( pNew, (DO_NOT_ACQUIRE *)0 ); 01786 } 01787 01812 inline bool convertToString(OString * pTarget, rtl_TextEncoding nEncoding, 01813 sal_uInt32 nFlags) const 01814 { 01815 return rtl_convertUStringToString(&pTarget->pData, pData->buffer, 01816 pData->length, nEncoding, nFlags); 01817 } 01818 01870 inline sal_uInt32 iterateCodePoints( 01871 sal_Int32 * indexUtf16, sal_Int32 incrementCodePoints = 1) const 01872 { 01873 return rtl_uString_iterateCodePoints( 01874 pData, indexUtf16, incrementCodePoints); 01875 } 01876 01887 static OUString valueOf( sal_Bool b ) SAL_THROW(()) 01888 { 01889 sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFBOOLEAN]; 01890 rtl_uString* pNewData = 0; 01891 rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfBoolean( aBuf, b ) ); 01892 return OUString( pNewData, (DO_NOT_ACQUIRE*)0 ); 01893 } 01894 01901 static OUString valueOf( sal_Unicode c ) SAL_THROW(()) 01902 { 01903 return OUString( &c, 1 ); 01904 } 01905 01915 static OUString valueOf( sal_Int32 i, sal_Int16 radix = 10 ) SAL_THROW(()) 01916 { 01917 sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT32]; 01918 rtl_uString* pNewData = 0; 01919 rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfInt32( aBuf, i, radix ) ); 01920 return OUString( pNewData, (DO_NOT_ACQUIRE*)0 ); 01921 } 01922 01932 static OUString valueOf( sal_Int64 ll, sal_Int16 radix = 10 ) SAL_THROW(()) 01933 { 01934 sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT64]; 01935 rtl_uString* pNewData = 0; 01936 rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfInt64( aBuf, ll, radix ) ); 01937 return OUString( pNewData, (DO_NOT_ACQUIRE*)0 ); 01938 } 01939 01948 static OUString valueOf( float f ) SAL_THROW(()) 01949 { 01950 sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFFLOAT]; 01951 rtl_uString* pNewData = 0; 01952 rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfFloat( aBuf, f ) ); 01953 return OUString( pNewData, (DO_NOT_ACQUIRE*)0 ); 01954 } 01955 01964 static OUString valueOf( double d ) SAL_THROW(()) 01965 { 01966 sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFDOUBLE]; 01967 rtl_uString* pNewData = 0; 01968 rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfDouble( aBuf, d ) ); 01969 return OUString( pNewData, (DO_NOT_ACQUIRE*)0 ); 01970 } 01971 01987 static OUString createFromAscii( const sal_Char * value ) SAL_THROW(()) 01988 { 01989 rtl_uString* pNew = 0; 01990 rtl_uString_newFromAscii( &pNew, value ); 01991 return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); 01992 } 01993 }; 01994 01995 /* ======================================================================= */ 01996 01997 } /* Namespace */ 01998 01999 #ifdef RTL_STRING_UNITTEST 02000 namespace rtl 02001 { 02002 typedef rtlunittest::OUString OUString; 02003 } 02004 #endif 02005 02006 namespace rtl 02007 { 02008 02014 struct OUStringHash 02015 { 02025 size_t operator()(const OUString& rString) const 02026 { return (size_t)rString.hashCode(); } 02027 }; 02028 02029 /* ======================================================================= */ 02030 02048 inline OUString OStringToOUString( const OString & rStr, 02049 rtl_TextEncoding encoding, 02050 sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS ) 02051 { 02052 return OUString( rStr.getStr(), rStr.getLength(), encoding, convertFlags ); 02053 } 02054 02072 inline OString OUStringToOString( const OUString & rUnicode, 02073 rtl_TextEncoding encoding, 02074 sal_uInt32 convertFlags = OUSTRING_TO_OSTRING_CVTFLAGS ) 02075 { 02076 return OString( rUnicode.getStr(), rUnicode.getLength(), encoding, convertFlags ); 02077 } 02078 02079 /* ======================================================================= */ 02080 02081 } /* Namespace */ 02082 02083 #endif /* _RTL_USTRING_HXX */ 02084 02085 // Include the ostream << operator directly here, so that it's always available 02086 // for SAL_INFO etc. Make sure it's outside of #ifdef _RTL_USTRING_HXX, because 02087 // includes ustring.hxx back. 02088 #include <rtl/oustringostreaminserter.hxx> 02089 02090 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */