UDK 3.2.7 C/C++ API Reference
rtl/ustring.hxx
Go to the documentation of this file.
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: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines