00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _RTL_USTRING_HXX_
00021 #define _RTL_USTRING_HXX_
00022
00023 #include "sal/config.h"
00024
00025 #include <cassert>
00026 #include <ostream>
00027 #include <string.h>
00028
00029 #include "osl/diagnose.h"
00030 #include <rtl/ustring.h>
00031 #include <rtl/string.hxx>
00032 #include <rtl/stringutils.hxx>
00033 #include <rtl/textenc.h>
00034 #include "sal/log.hxx"
00035
00036 #ifdef RTL_FAST_STRING
00037 #include <rtl/stringconcat.hxx>
00038 #endif
00039
00040 #if defined EXCEPTIONS_OFF
00041 #include <stdlib.h>
00042 #else
00043 #include <new>
00044 #endif
00045
00046
00047
00048
00049
00050
00051 #ifdef RTL_STRING_UNITTEST
00052 #define rtl rtlunittest
00053 #endif
00054
00055 namespace rtl
00056 {
00057
00058 #ifdef RTL_STRING_UNITTEST
00059 #undef rtl
00060 #endif
00061
00062
00063
00087 class SAL_WARN_UNUSED OUString
00088 {
00089 public:
00091 rtl_uString * pData;
00093
00094 private:
00095 class DO_NOT_ACQUIRE{};
00096
00097 OUString( rtl_uString * value, SAL_UNUSED_PARAMETER DO_NOT_ACQUIRE * )
00098 {
00099 pData = value;
00100 }
00101
00102 public:
00106 OUString() SAL_THROW(())
00107 {
00108 pData = 0;
00109 rtl_uString_new( &pData );
00110 }
00111
00117 OUString( const OUString & str ) SAL_THROW(())
00118 {
00119 pData = str.pData;
00120 rtl_uString_acquire( pData );
00121 }
00122
00128 OUString( rtl_uString * str ) SAL_THROW(())
00129 {
00130 pData = str;
00131 rtl_uString_acquire( pData );
00132 }
00133
00142 inline OUString( rtl_uString * str, __sal_NoAcquire ) SAL_THROW(())
00143 { pData = str; }
00144
00150 explicit OUString( sal_Unicode value ) SAL_THROW(())
00151 : pData (0)
00152 {
00153 rtl_uString_newFromStr_WithLength( &pData, &value, 1 );
00154 }
00155
00161 OUString( const sal_Unicode * value ) SAL_THROW(())
00162 {
00163 pData = 0;
00164 rtl_uString_newFromStr( &pData, value );
00165 }
00166
00175 OUString( const sal_Unicode * value, sal_Int32 length ) SAL_THROW(())
00176 {
00177 pData = 0;
00178 rtl_uString_newFromStr_WithLength( &pData, value, length );
00179 }
00180
00196 #ifdef HAVE_SFINAE_ANONYMOUS_BROKEN
00197
00198
00199 template< int N >
00200 OUString( const char (&literal)[ N ] )
00201 {
00202
00203
00204 assert( strlen( literal ) == N - 1 );
00205 pData = 0;
00206 rtl_uString_newFromLiteral( &pData, literal, N - 1, 0 );
00207 #ifdef RTL_STRING_UNITTEST
00208 rtl_string_unittest_const_literal = true;
00209 #endif
00210 }
00211
00216 template< int N >
00217 OUString( char (&value)[ N ] )
00218 #ifndef RTL_STRING_UNITTEST
00219 ;
00220 #else
00221 {
00222 (void) value;
00223 pData = 0;
00224 rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 );
00225 rtl_string_unittest_invalid_conversion = true;
00226 }
00227 #endif
00228 #else // HAVE_SFINAE_ANONYMOUS_BROKEN
00229 template< typename T >
00230 OUString( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy() )
00231 {
00232 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
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 );
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 );
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
00327 #ifdef RTL_FAST_STRING
00328 template< typename T1, typename T2 >
00329 OUString( const OUStringConcat< T1, T2 >& c )
00330 {
00331 const sal_Int32 l = c.length();
00332 rtl_uString* buffer = NULL;
00333 rtl_uString_new_WithLength( &buffer, l );
00334 if (l != 0)
00335 {
00336 sal_Unicode* end = c.addData( buffer->buffer );
00337 buffer->length = end - buffer->buffer;
00338
00339 }
00340 pData = buffer;
00341 }
00342 #endif
00343
00347 ~OUString() SAL_THROW(())
00348 {
00349 rtl_uString_release( pData );
00350 }
00351
00363 static inline OUString const & unacquired( rtl_uString * const * ppHandle )
00364 { return * reinterpret_cast< OUString const * >( ppHandle ); }
00365
00371 OUString & operator=( const OUString & str ) SAL_THROW(())
00372 {
00373 rtl_uString_assign( &pData, str.pData );
00374 return *this;
00375 }
00376
00389 template< typename T >
00390 typename internal::ConstCharArrayDetector< T, OUString& >::Type operator=( T& literal )
00391 {
00392 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00393 rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 0 );
00394 return *this;
00395 }
00396
00402 OUString & operator+=( const OUString & str ) SAL_THROW(())
00403 {
00404 rtl_uString_newConcat( &pData, pData, str.pData );
00405 return *this;
00406 }
00407
00416 sal_Int32 getLength() const SAL_THROW(()) { return pData->length; }
00417
00426 bool isEmpty() const SAL_THROW(())
00427 {
00428 return pData->length == 0;
00429 }
00430
00438 const sal_Unicode * getStr() const SAL_THROW(()) { return pData->buffer; }
00439
00449 sal_Unicode operator [](sal_Int32 index) const { return getStr()[index]; }
00450
00463 sal_Int32 compareTo( const OUString & str ) const SAL_THROW(())
00464 {
00465 return rtl_ustr_compare_WithLength( pData->buffer, pData->length,
00466 str.pData->buffer, str.pData->length );
00467 }
00468
00484 sal_Int32 compareTo( const OUString & str, sal_Int32 maxLength ) const SAL_THROW(())
00485 {
00486 return rtl_ustr_shortenedCompare_WithLength( pData->buffer, pData->length,
00487 str.pData->buffer, str.pData->length, maxLength );
00488 }
00489
00502 sal_Int32 reverseCompareTo( const OUString & str ) const SAL_THROW(())
00503 {
00504 return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length,
00505 str.pData->buffer, str.pData->length );
00506 }
00507
00519 sal_Bool equals( const OUString & str ) const SAL_THROW(())
00520 {
00521 if ( pData->length != str.pData->length )
00522 return sal_False;
00523 if ( pData == str.pData )
00524 return sal_True;
00525 return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length,
00526 str.pData->buffer, str.pData->length ) == 0;
00527 }
00528
00543 sal_Bool equalsIgnoreAsciiCase( const OUString & str ) const SAL_THROW(())
00544 {
00545 if ( pData->length != str.pData->length )
00546 return sal_False;
00547 if ( pData == str.pData )
00548 return sal_True;
00549 return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
00550 str.pData->buffer, str.pData->length ) == 0;
00551 }
00552
00568 sal_Int32 compareToIgnoreAsciiCase( const OUString & str ) const SAL_THROW(())
00569 {
00570 return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
00571 str.pData->buffer, str.pData->length );
00572 }
00573
00574
00580 template< typename T >
00581 typename internal::ConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& literal ) const SAL_THROW(())
00582 {
00583 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00584 if ( pData->length != internal::ConstCharArrayDetector< T, void >::size - 1 )
00585 return sal_False;
00586
00587 return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, literal ) == 0;
00588 }
00589
00605 sal_Bool match( const OUString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
00606 {
00607 return rtl_ustr_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
00608 str.pData->buffer, str.pData->length, str.pData->length ) == 0;
00609 }
00610
00616 template< typename T >
00617 typename internal::ConstCharArrayDetector< T, bool >::Type match( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
00618 {
00619 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00620 return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
00621 literal, internal::ConstCharArrayDetector< T, void >::size - 1 ) == 0;
00622 }
00623
00642 sal_Bool matchIgnoreAsciiCase( const OUString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
00643 {
00644 return rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
00645 str.pData->buffer, str.pData->length,
00646 str.pData->length ) == 0;
00647 }
00648
00654 template< typename T >
00655 typename internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
00656 {
00657 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00658 return rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
00659 literal, internal::ConstCharArrayDetector< T, void >::size - 1 ) == 0;
00660 }
00661
00678 sal_Int32 compareToAscii( const sal_Char* asciiStr ) const SAL_THROW(())
00679 {
00680 return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length, asciiStr );
00681 }
00682
00700 sal_Int32 compareToAscii( const sal_Char * asciiStr, sal_Int32 maxLength ) const SAL_THROW(())
00701 {
00702 return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer, pData->length,
00703 asciiStr, maxLength );
00704 }
00705
00725 sal_Int32 reverseCompareToAsciiL( const sal_Char * asciiStr, sal_Int32 asciiStrLength ) const SAL_THROW(())
00726 {
00727 return rtl_ustr_asciil_reverseCompare_WithLength( pData->buffer, pData->length,
00728 asciiStr, asciiStrLength );
00729 }
00730
00746 sal_Bool equalsAscii( const sal_Char* asciiStr ) const SAL_THROW(())
00747 {
00748 return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length,
00749 asciiStr ) == 0;
00750 }
00751
00769 sal_Bool equalsAsciiL( const sal_Char* asciiStr, sal_Int32 asciiStrLength ) const SAL_THROW(())
00770 {
00771 if ( pData->length != asciiStrLength )
00772 return sal_False;
00773
00774 return rtl_ustr_asciil_reverseEquals_WithLength(
00775 pData->buffer, asciiStr, asciiStrLength );
00776 }
00777
00796 sal_Bool equalsIgnoreAsciiCaseAscii( const sal_Char * asciiStr ) const SAL_THROW(())
00797 {
00798 return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0;
00799 }
00800
00819 sal_Int32 compareToIgnoreAsciiCaseAscii( const sal_Char * asciiStr ) const SAL_THROW(())
00820 {
00821 return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr );
00822 }
00823
00844 sal_Bool equalsIgnoreAsciiCaseAsciiL( const sal_Char * asciiStr, sal_Int32 asciiStrLength ) const SAL_THROW(())
00845 {
00846 if ( pData->length != asciiStrLength )
00847 return sal_False;
00848
00849 return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0;
00850 }
00851
00873 sal_Bool matchAsciiL( const sal_Char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
00874 {
00875 return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
00876 asciiStr, asciiStrLength ) == 0;
00877 }
00878
00879
00880
00881
00882
00883 #if SAL_TYPES_SIZEOFLONG == 8
00884 void matchAsciiL(char const *, sal_Int32, rtl_TextEncoding) const;
00885 #endif
00886
00911 sal_Bool matchIgnoreAsciiCaseAsciiL( const sal_Char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
00912 {
00913 return rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
00914 asciiStr, asciiStrLength ) == 0;
00915 }
00916
00917
00918
00919
00920
00921 #if SAL_TYPES_SIZEOFLONG == 8
00922 void matchIgnoreAsciiCaseAsciiL(char const *, sal_Int32, rtl_TextEncoding)
00923 const;
00924 #endif
00925
00936 bool startsWith(OUString const & str) const {
00937 return match(str, 0);
00938 }
00939
00945 template< typename T >
00946 typename internal::ConstCharArrayDetector< T, bool >::Type startsWith( T& literal ) const
00947 {
00948 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00949 return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length
00950 && rtl_ustr_asciil_reverseEquals_WithLength( pData->buffer, literal,
00951 internal::ConstCharArrayDetector< T, void >::size - 1);
00952 }
00953
00967 sal_Bool startsWithIgnoreAsciiCase( const OUString & str ) const SAL_THROW(())
00968 {
00969 return matchIgnoreAsciiCase(str, 0);
00970 }
00971
00977 template< typename T >
00978 typename internal::ConstCharArrayDetector< T, bool >::Type startsWithIgnoreAsciiCase( T& literal ) const SAL_THROW(())
00979 {
00980 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00981 return (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
00982 pData->buffer,
00983 internal::ConstCharArrayDetector< T, void >::size - 1, literal,
00984 internal::ConstCharArrayDetector< T, void >::size - 1)
00985 == 0);
00986 }
00987
00998 bool endsWith(OUString const & str) const {
00999 return str.getLength() <= getLength()
01000 && match(str, getLength() - str.getLength());
01001 }
01002
01008 template< typename T >
01009 typename internal::ConstCharArrayDetector< T, bool >::Type endsWith( T& literal ) const
01010 {
01011 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
01012 return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length
01013 && rtl_ustr_asciil_reverseEquals_WithLength(
01014 pData->buffer + pData->length - ( internal::ConstCharArrayDetector< T, void >::size - 1 ), literal,
01015 internal::ConstCharArrayDetector< T, void >::size - 1);
01016 }
01017
01029 inline bool endsWithAsciiL(char const * asciiStr, sal_Int32 asciiStrLength)
01030 const
01031 {
01032 return asciiStrLength <= pData->length
01033 && rtl_ustr_asciil_reverseEquals_WithLength(
01034 pData->buffer + pData->length - asciiStrLength, asciiStr,
01035 asciiStrLength);
01036 }
01037
01051 sal_Bool endsWithIgnoreAsciiCase( const OUString & str ) const SAL_THROW(())
01052 {
01053 return str.getLength() <= getLength()
01054 && matchIgnoreAsciiCase(str, getLength() - str.getLength());
01055 }
01056
01062 template< typename T >
01063 typename internal::ConstCharArrayDetector< T, bool >::Type endsWithIgnoreAsciiCase( T& literal ) const SAL_THROW(())
01064 {
01065 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
01066 return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length
01067 && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
01068 pData->buffer + pData->length - ( internal::ConstCharArrayDetector< T, void >::size - 1 ),
01069 internal::ConstCharArrayDetector< T, void >::size - 1, literal,
01070 internal::ConstCharArrayDetector< T, void >::size - 1)
01071 == 0);
01072 }
01073
01084 inline bool endsWithIgnoreAsciiCaseAsciiL(
01085 char const * asciiStr, sal_Int32 asciiStrLength) const
01086 {
01087 return asciiStrLength <= pData->length
01088 && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
01089 pData->buffer + pData->length - asciiStrLength,
01090 asciiStrLength, asciiStr, asciiStrLength)
01091 == 0);
01092 }
01093
01094 friend sal_Bool operator == ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
01095 { return rStr1.equals(rStr2); }
01096 friend sal_Bool operator == ( const OUString& rStr1, const sal_Unicode * pStr2 ) SAL_THROW(())
01097 { return rStr1.compareTo( pStr2 ) == 0; }
01098 friend sal_Bool operator == ( const sal_Unicode * pStr1, const OUString& rStr2 ) SAL_THROW(())
01099 { return OUString( pStr1 ).compareTo( rStr2 ) == 0; }
01100
01101 friend sal_Bool operator != ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
01102 { return !(operator == ( rStr1, rStr2 )); }
01103 friend sal_Bool operator != ( const OUString& rStr1, const sal_Unicode * pStr2 ) SAL_THROW(())
01104 { return !(operator == ( rStr1, pStr2 )); }
01105 friend sal_Bool operator != ( const sal_Unicode * pStr1, const OUString& rStr2 ) SAL_THROW(())
01106 { return !(operator == ( pStr1, rStr2 )); }
01107
01108 friend sal_Bool operator < ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
01109 { return rStr1.compareTo( rStr2 ) < 0; }
01110 friend sal_Bool operator > ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
01111 { return rStr1.compareTo( rStr2 ) > 0; }
01112 friend sal_Bool operator <= ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
01113 { return rStr1.compareTo( rStr2 ) <= 0; }
01114 friend sal_Bool operator >= ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
01115 { return rStr1.compareTo( rStr2 ) >= 0; }
01116
01124 template< typename T >
01125 friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator==( const OUString& string, T& literal )
01126 {
01127 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
01128 return string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
01129 }
01137 template< typename T >
01138 friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OUString& string )
01139 {
01140 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
01141 return string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
01142 }
01150 template< typename T >
01151 friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OUString& string, T& literal )
01152 {
01153 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
01154 return !string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
01155 }
01163 template< typename T >
01164 friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OUString& string )
01165 {
01166 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
01167 return !string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
01168 }
01169
01177 sal_Int32 hashCode() const SAL_THROW(())
01178 {
01179 return rtl_ustr_hashCode_WithLength( pData->buffer, pData->length );
01180 }
01181
01195 sal_Int32 indexOf( sal_Unicode ch, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
01196 {
01197 sal_Int32 ret = rtl_ustr_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
01198 return (ret < 0 ? ret : ret+fromIndex);
01199 }
01200
01210 sal_Int32 lastIndexOf( sal_Unicode ch ) const SAL_THROW(())
01211 {
01212 return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
01213 }
01214
01227 sal_Int32 lastIndexOf( sal_Unicode ch, sal_Int32 fromIndex ) const SAL_THROW(())
01228 {
01229 return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
01230 }
01231
01247 sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
01248 {
01249 sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
01250 str.pData->buffer, str.pData->length );
01251 return (ret < 0 ? ret : ret+fromIndex);
01252 }
01253
01259 template< typename T >
01260 typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
01261 {
01262 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
01263 sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength(
01264 pData->buffer + fromIndex, pData->length - fromIndex, literal,
01265 internal::ConstCharArrayDetector< T, void >::size - 1);
01266 return ret < 0 ? ret : ret + fromIndex;
01267 }
01268
01292 sal_Int32 indexOfAsciiL(
01293 char const * str, sal_Int32 len, sal_Int32 fromIndex = 0) const
01294 SAL_THROW(())
01295 {
01296 sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength(
01297 pData->buffer + fromIndex, pData->length - fromIndex, str, len);
01298 return ret < 0 ? ret : ret + fromIndex;
01299 }
01300
01301
01302
01303
01304
01305 #if SAL_TYPES_SIZEOFLONG == 8
01306 void indexOfAsciiL(char const *, sal_Int32 len, rtl_TextEncoding) const;
01307 #endif
01308
01324 sal_Int32 lastIndexOf( const OUString & str ) const SAL_THROW(())
01325 {
01326 return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length,
01327 str.pData->buffer, str.pData->length );
01328 }
01329
01347 sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const SAL_THROW(())
01348 {
01349 return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
01350 str.pData->buffer, str.pData->length );
01351 }
01352
01358 template< typename T >
01359 typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const SAL_THROW(())
01360 {
01361 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
01362 return rtl_ustr_lastIndexOfAscii_WithLength(
01363 pData->buffer, pData->length, literal, internal::ConstCharArrayDetector< T, void >::size - 1);
01364 }
01365
01385 sal_Int32 lastIndexOfAsciiL(char const * str, sal_Int32 len) const
01386 SAL_THROW(())
01387 {
01388 return rtl_ustr_lastIndexOfAscii_WithLength(
01389 pData->buffer, pData->length, str, len);
01390 }
01391
01402 OUString copy( sal_Int32 beginIndex ) const SAL_THROW(())
01403 {
01404 rtl_uString *pNew = 0;
01405 rtl_uString_newFromSubString( &pNew, pData, beginIndex, getLength() - beginIndex );
01406 return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
01407 }
01408
01421 OUString copy( sal_Int32 beginIndex, sal_Int32 count ) const SAL_THROW(())
01422 {
01423 rtl_uString *pNew = 0;
01424 rtl_uString_newFromSubString( &pNew, pData, beginIndex, count );
01425 return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
01426 }
01427
01436 SAL_WARN_UNUSED_RESULT OUString concat( const OUString & str ) const SAL_THROW(())
01437 {
01438 rtl_uString* pNew = 0;
01439 rtl_uString_newConcat( &pNew, pData, str.pData );
01440 return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
01441 }
01442
01443 #ifndef RTL_FAST_STRING
01444 friend OUString operator+( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
01445 {
01446 return rStr1.concat( rStr2 );
01447 }
01448 #endif
01449
01463 SAL_WARN_UNUSED_RESULT OUString replaceAt( sal_Int32 index, sal_Int32 count, const OUString& newStr ) const SAL_THROW(())
01464 {
01465 rtl_uString* pNew = 0;
01466 rtl_uString_newReplaceStrAt( &pNew, pData, index, count, newStr.pData );
01467 return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
01468 }
01469
01483 SAL_WARN_UNUSED_RESULT OUString replace( sal_Unicode oldChar, sal_Unicode newChar ) const SAL_THROW(())
01484 {
01485 rtl_uString* pNew = 0;
01486 rtl_uString_newReplace( &pNew, pData, oldChar, newChar );
01487 return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
01488 }
01489
01508 SAL_WARN_UNUSED_RESULT OUString replaceFirst(
01509 OUString const & from, OUString const & to, sal_Int32 * index = 0) const
01510 {
01511 rtl_uString * s = 0;
01512 sal_Int32 i = 0;
01513 rtl_uString_newReplaceFirst(
01514 &s, pData, from.pData, to.pData, index == 0 ? &i : index);
01515 return OUString(s, SAL_NO_ACQUIRE);
01516 }
01517
01536 template< typename T >
01537 SAL_WARN_UNUSED_RESULT typename internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( T& from, OUString const & to,
01538 sal_Int32 * index = 0) const
01539 {
01540 rtl_uString * s = 0;
01541 sal_Int32 i = 0;
01542 assert( strlen( from ) == internal::ConstCharArrayDetector< T >::size - 1 );
01543 rtl_uString_newReplaceFirstAsciiL(
01544 &s, pData, from, internal::ConstCharArrayDetector< T, void >::size - 1, to.pData, index == 0 ? &i : index);
01545 return OUString(s, SAL_NO_ACQUIRE);
01546 }
01547
01566 template< typename T1, typename T2 >
01567 SAL_WARN_UNUSED_RESULT typename internal::ConstCharArrayDetector< T1, typename internal::ConstCharArrayDetector< T2, OUString >::Type >::Type
01568 replaceFirst( T1& from, T2& to, sal_Int32 * index = 0) const
01569 {
01570 rtl_uString * s = 0;
01571 sal_Int32 i = 0;
01572 assert( strlen( from ) == internal::ConstCharArrayDetector< T1 >::size - 1 );
01573 assert( strlen( to ) == internal::ConstCharArrayDetector< T2 >::size - 1 );
01574 rtl_uString_newReplaceFirstAsciiLAsciiL(
01575 &s, pData, from, internal::ConstCharArrayDetector< T1, void >::size - 1, to,
01576 internal::ConstCharArrayDetector< T2, void >::size - 1, index == 0 ? &i : index);
01577 return OUString(s, SAL_NO_ACQUIRE);
01578 }
01579
01595 OUString replaceAll(OUString const & from, OUString const & to, sal_Int32 fromIndex = 0) const {
01596 rtl_uString * s = 0;
01597 rtl_uString_newReplaceAllFromIndex(&s, pData, from.pData, to.pData, fromIndex);
01598 return OUString(s, SAL_NO_ACQUIRE);
01599 }
01600
01614 template< typename T >
01615 typename internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( T& from, OUString const & to) const
01616 {
01617 rtl_uString * s = 0;
01618 assert( strlen( from ) == internal::ConstCharArrayDetector< T >::size - 1 );
01619 rtl_uString_newReplaceAllAsciiL(&s, pData, from, internal::ConstCharArrayDetector< T, void >::size - 1, to.pData);
01620 return OUString(s, SAL_NO_ACQUIRE);
01621 }
01622
01636 template< typename T1, typename T2 >
01637 typename internal::ConstCharArrayDetector< T1, typename internal::ConstCharArrayDetector< T2, OUString >::Type >::Type
01638 replaceAll( T1& from, T2& to ) const
01639 {
01640 rtl_uString * s = 0;
01641 assert( strlen( from ) == internal::ConstCharArrayDetector< T1 >::size - 1 );
01642 assert( strlen( to ) == internal::ConstCharArrayDetector< T2 >::size - 1 );
01643 rtl_uString_newReplaceAllAsciiLAsciiL(
01644 &s, pData, from, internal::ConstCharArrayDetector< T1, void >::size - 1,
01645 to, internal::ConstCharArrayDetector< T2, void >::size - 1);
01646 return OUString(s, SAL_NO_ACQUIRE);
01647 }
01648
01659 SAL_WARN_UNUSED_RESULT OUString toAsciiLowerCase() const SAL_THROW(())
01660 {
01661 rtl_uString* pNew = 0;
01662 rtl_uString_newToAsciiLowerCase( &pNew, pData );
01663 return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
01664 }
01665
01676 SAL_WARN_UNUSED_RESULT OUString toAsciiUpperCase() const SAL_THROW(())
01677 {
01678 rtl_uString* pNew = 0;
01679 rtl_uString_newToAsciiUpperCase( &pNew, pData );
01680 return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
01681 }
01682
01694 SAL_WARN_UNUSED_RESULT OUString trim() const SAL_THROW(())
01695 {
01696 rtl_uString* pNew = 0;
01697 rtl_uString_newTrim( &pNew, pData );
01698 return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
01699 }
01700
01725 OUString getToken( sal_Int32 token, sal_Unicode cTok, sal_Int32& index ) const SAL_THROW(())
01726 {
01727 rtl_uString * pNew = 0;
01728 index = rtl_uString_getToken( &pNew, pData, token, cTok, index );
01729 return OUString( pNew, (DO_NOT_ACQUIRE *)0 );
01730 }
01731
01745 OUString getToken(sal_Int32 count, sal_Unicode separator) const {
01746 sal_Int32 n = 0;
01747 return getToken(count, separator, n);
01748 }
01749
01758 sal_Bool toBoolean() const SAL_THROW(())
01759 {
01760 return rtl_ustr_toBoolean( pData->buffer );
01761 }
01762
01769 sal_Unicode toChar() const SAL_THROW(())
01770 {
01771 return pData->buffer[0];
01772 }
01773
01783 sal_Int32 toInt32( sal_Int16 radix = 10 ) const SAL_THROW(())
01784 {
01785 return rtl_ustr_toInt32( pData->buffer, radix );
01786 }
01787
01797 sal_Int64 toInt64( sal_Int16 radix = 10 ) const SAL_THROW(())
01798 {
01799 return rtl_ustr_toInt64( pData->buffer, radix );
01800 }
01801
01810 float toFloat() const SAL_THROW(())
01811 {
01812 return rtl_ustr_toFloat( pData->buffer );
01813 }
01814
01823 double toDouble() const SAL_THROW(())
01824 {
01825 return rtl_ustr_toDouble( pData->buffer );
01826 }
01827
01828
01844 OUString intern() const
01845 {
01846 rtl_uString * pNew = 0;
01847 rtl_uString_intern( &pNew, pData );
01848 if (pNew == 0) {
01849 #if defined EXCEPTIONS_OFF
01850 abort();
01851 #else
01852 throw std::bad_alloc();
01853 #endif
01854 }
01855 return OUString( pNew, (DO_NOT_ACQUIRE *)0 );
01856 }
01857
01883 static OUString intern( const sal_Char * value, sal_Int32 length,
01884 rtl_TextEncoding encoding,
01885 sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS,
01886 sal_uInt32 *pInfo = NULL )
01887 {
01888 rtl_uString * pNew = 0;
01889 rtl_uString_internConvert( &pNew, value, length, encoding,
01890 convertFlags, pInfo );
01891 if (pNew == 0) {
01892 #if defined EXCEPTIONS_OFF
01893 abort();
01894 #else
01895 throw std::bad_alloc();
01896 #endif
01897 }
01898 return OUString( pNew, (DO_NOT_ACQUIRE *)0 );
01899 }
01900
01925 inline bool convertToString(OString * pTarget, rtl_TextEncoding nEncoding,
01926 sal_uInt32 nFlags) const
01927 {
01928 return rtl_convertUStringToString(&pTarget->pData, pData->buffer,
01929 pData->length, nEncoding, nFlags);
01930 }
01931
01983 inline sal_uInt32 iterateCodePoints(
01984 sal_Int32 * indexUtf16, sal_Int32 incrementCodePoints = 1) const
01985 {
01986 return rtl_uString_iterateCodePoints(
01987 pData, indexUtf16, incrementCodePoints);
01988 }
01989
02000 static OUString valueOf( sal_Bool b ) SAL_THROW(())
02001 {
02002 sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFBOOLEAN];
02003 rtl_uString* pNewData = 0;
02004 rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfBoolean( aBuf, b ) );
02005 return OUString( pNewData, (DO_NOT_ACQUIRE*)0 );
02006 }
02007
02014 static OUString valueOf( sal_Unicode c ) SAL_THROW(())
02015 {
02016 return OUString( &c, 1 );
02017 }
02018
02028 static OUString valueOf( sal_Int32 i, sal_Int16 radix = 10 ) SAL_THROW(())
02029 {
02030 sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT32];
02031 rtl_uString* pNewData = 0;
02032 rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfInt32( aBuf, i, radix ) );
02033 return OUString( pNewData, (DO_NOT_ACQUIRE*)0 );
02034 }
02035
02045 static OUString valueOf( sal_Int64 ll, sal_Int16 radix = 10 ) SAL_THROW(())
02046 {
02047 sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT64];
02048 rtl_uString* pNewData = 0;
02049 rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfInt64( aBuf, ll, radix ) );
02050 return OUString( pNewData, (DO_NOT_ACQUIRE*)0 );
02051 }
02052
02061 static OUString valueOf( float f ) SAL_THROW(())
02062 {
02063 sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFFLOAT];
02064 rtl_uString* pNewData = 0;
02065 rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfFloat( aBuf, f ) );
02066 return OUString( pNewData, (DO_NOT_ACQUIRE*)0 );
02067 }
02068
02077 static OUString valueOf( double d ) SAL_THROW(())
02078 {
02079 sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFDOUBLE];
02080 rtl_uString* pNewData = 0;
02081 rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfDouble( aBuf, d ) );
02082 return OUString( pNewData, (DO_NOT_ACQUIRE*)0 );
02083 }
02084
02100 static OUString createFromAscii( const sal_Char * value ) SAL_THROW(())
02101 {
02102 rtl_uString* pNew = 0;
02103 rtl_uString_newFromAscii( &pNew, value );
02104 return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
02105 }
02106
02107 template< typename T1, typename T2 >
02108 friend struct OUStringConcat;
02109 };
02110
02111
02112
02113 #ifdef RTL_FAST_STRING
02114
02122 struct SAL_WARN_UNUSED OUStringLiteral
02123 {
02124 template< int N >
02125 OUStringLiteral( const char (&str)[ N ] ) : size( N - 1 ), data( str ) { assert( strlen( str ) == N - 1 ); }
02126 int size;
02127 const char* data;
02128 };
02129
02130 template<>
02131 struct ToStringHelper< OUString >
02132 {
02133 static int length( const OUString& s ) { return s.getLength(); }
02134 static sal_Unicode* addData( sal_Unicode* buffer, const OUString& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); }
02135 static const bool allowOStringConcat = false;
02136 static const bool allowOUStringConcat = true;
02137 };
02138
02139 template<>
02140 struct ToStringHelper< OUStringLiteral >
02141 {
02142 static int length( const OUStringLiteral& str ) { return str.size; }
02143 static sal_Unicode* addData( sal_Unicode* buffer, const OUStringLiteral& str ) { return addDataLiteral( buffer, str.data, str.size ); }
02144 static const bool allowOStringConcat = false;
02145 static const bool allowOUStringConcat = true;
02146 };
02147
02148 template< typename charT, typename traits, typename T1, typename T2 >
02149 inline std::basic_ostream<charT, traits> & operator <<(
02150 std::basic_ostream<charT, traits> & stream, const OUStringConcat< T1, T2 >& concat)
02151 {
02152 return stream << OUString( concat );
02153 }
02154 #else
02155
02156 typedef OUString OUStringLiteral;
02157 #endif
02158
02159 }
02160
02161 #ifdef RTL_STRING_UNITTEST
02162 namespace rtl
02163 {
02164 typedef rtlunittest::OUString OUString;
02165 }
02166 #endif
02167
02168 namespace rtl
02169 {
02170
02176 struct OUStringHash
02177 {
02187 size_t operator()(const OUString& rString) const
02188 { return (size_t)rString.hashCode(); }
02189 };
02190
02191
02192
02210 inline OUString OStringToOUString( const OString & rStr,
02211 rtl_TextEncoding encoding,
02212 sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS )
02213 {
02214 return OUString( rStr.getStr(), rStr.getLength(), encoding, convertFlags );
02215 }
02216
02234 inline OString OUStringToOString( const OUString & rUnicode,
02235 rtl_TextEncoding encoding,
02236 sal_uInt32 convertFlags = OUSTRING_TO_OSTRING_CVTFLAGS )
02237 {
02238 return OString( rUnicode.getStr(), rUnicode.getLength(), encoding, convertFlags );
02239 }
02240
02241
02242
02243 }
02244
02245 #ifdef RTL_STRING_UNITTEST
02246 #define rtl rtlunittest
02247 #endif
02248 namespace rtl
02249 {
02250 #ifdef RTL_STRING_UNITTEST
02251 #undef rtl
02252 #endif
02253
02262 template< typename charT, typename traits >
02263 inline std::basic_ostream<charT, traits> & operator <<(
02264 std::basic_ostream<charT, traits> & stream, OUString const & string)
02265 {
02266 return stream <<
02267 rtl::OUStringToOString(string, RTL_TEXTENCODING_UTF8).getStr();
02268
02269
02270 }
02271
02272 }
02273
02274
02275
02276
02277
02278 #ifdef RTL_USING
02279 using ::rtl::OUString;
02280 using ::rtl::OUStringHash;
02281 using ::rtl::OStringToOUString;
02282 using ::rtl::OUStringToOString;
02283 using ::rtl::OUStringLiteral;
02284 #endif
02285
02286 #endif
02287
02288