00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _RTL_USTRBUF_HXX_
00021 #define _RTL_USTRBUF_HXX_
00022
00023 #include "sal/config.h"
00024
00025 #include <cassert>
00026 #include <string.h>
00027
00028 #include <osl/diagnose.h>
00029 #include <rtl/ustrbuf.h>
00030 #include <rtl/ustring.hxx>
00031 #include <rtl/stringutils.hxx>
00032
00033 #ifdef RTL_FAST_STRING
00034 #include <rtl/stringconcat.hxx>
00035 #endif
00036
00037
00038
00039
00040
00041
00042 #ifdef RTL_STRING_UNITTEST
00043 #define rtl rtlunittest
00044 #endif
00045
00046 namespace rtl
00047 {
00048
00049 #ifdef RTL_STRING_UNITTEST
00050 #undef rtl
00051 #endif
00052
00091 class SAL_WARN_UNUSED OUStringBuffer
00092 {
00093 public:
00098 OUStringBuffer()
00099 : pData(NULL)
00100 , nCapacity( 16 )
00101 {
00102 rtl_uString_new_WithLength( &pData, nCapacity );
00103 }
00104
00111 OUStringBuffer( const OUStringBuffer & value )
00112 : pData(NULL)
00113 , nCapacity( value.nCapacity )
00114 {
00115 rtl_uStringbuffer_newFromStringBuffer( &pData, value.nCapacity, value.pData );
00116 }
00117
00124 explicit OUStringBuffer(int length)
00125 : pData(NULL)
00126 , nCapacity( length )
00127 {
00128 rtl_uString_new_WithLength( &pData, length );
00129 }
00130
00141 OUStringBuffer(OUString value)
00142 : pData(NULL)
00143 , nCapacity( value.getLength() + 16 )
00144 {
00145 rtl_uStringbuffer_newFromStr_WithLength( &pData, value.getStr(), value.getLength() );
00146 }
00147
00148 #ifdef HAVE_SFINAE_ANONYMOUS_BROKEN // see OUString ctors
00149 template< int N >
00150 OUStringBuffer( const char (&literal)[ N ] )
00151 : pData(NULL)
00152 , nCapacity( N - 1 + 16 )
00153 {
00154 assert( strlen( literal ) == N - 1 );
00155 rtl_uString_newFromLiteral( &pData, literal, N - 1, 16 );
00156 #ifdef RTL_STRING_UNITTEST
00157 rtl_string_unittest_const_literal = true;
00158 #endif
00159 }
00160
00165 template< int N >
00166 OUStringBuffer( char (&value)[ N ] )
00167 #ifndef RTL_STRING_UNITTEST
00168 ;
00169 #else
00170 {
00171 (void) value;
00172 pData = 0;
00173 nCapacity = 10;
00174 rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 );
00175 rtl_string_unittest_invalid_conversion = true;
00176 }
00177 #endif
00178 #else // HAVE_SFINAE_ANONYMOUS_BROKEN
00179 template< typename T >
00180 OUStringBuffer( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy() )
00181 : pData(NULL)
00182 , nCapacity( internal::ConstCharArrayDetector< T, void >::size - 1 + 16 )
00183 {
00184 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00185 rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 16 );
00186 #ifdef RTL_STRING_UNITTEST
00187 rtl_string_unittest_const_literal = true;
00188 #endif
00189 }
00190 #endif // HAVE_SFINAE_ANONYMOUS_BROKEN
00191
00192 #ifdef RTL_STRING_UNITTEST
00193
00197 template< typename T >
00198 OUStringBuffer( T&, typename internal::ExceptConstCharArrayDetector< T >::Type = internal::Dummy() )
00199 {
00200 pData = 0;
00201 nCapacity = 10;
00202 rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 );
00203 rtl_string_unittest_invalid_conversion = true;
00204 }
00209 template< typename T >
00210 OUStringBuffer( const T&, typename internal::ExceptCharArrayDetector< T >::Type = internal::Dummy() )
00211 {
00212 pData = 0;
00213 nCapacity = 10;
00214 rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 );
00215 rtl_string_unittest_invalid_conversion = true;
00216 }
00217 #endif
00218
00219 #ifdef RTL_FAST_STRING
00220 template< typename T1, typename T2 >
00221 OUStringBuffer( const OUStringConcat< T1, T2 >& c )
00222 {
00223 const sal_Int32 l = c.length();
00224 rtl_uString* buffer = NULL;
00225 nCapacity = l + 16;
00226 rtl_uString_new_WithLength( &buffer, nCapacity );
00227 sal_Unicode* end = c.addData( buffer->buffer );
00228 *end = '\0';
00229 buffer->length = end - buffer->buffer;
00230
00231 pData = buffer;
00232 }
00233 #endif
00234
00236 OUStringBuffer& operator = ( const OUStringBuffer& value )
00237 {
00238 if (this != &value)
00239 {
00240 rtl_uStringbuffer_newFromStringBuffer(&pData,
00241 value.nCapacity,
00242 value.pData);
00243 nCapacity = value.nCapacity;
00244 }
00245 return *this;
00246 }
00247
00251 ~OUStringBuffer()
00252 {
00253 rtl_uString_release( pData );
00254 }
00255
00264 OUString makeStringAndClear()
00265 {
00266 return OUString(
00267 rtl_uStringBuffer_makeStringAndClear( &pData, &nCapacity ),
00268 SAL_NO_ACQUIRE );
00269 }
00270
00276 sal_Int32 getLength() const
00277 {
00278 return pData->length;
00279 }
00280
00291 sal_Int32 getCapacity() const
00292 {
00293 return nCapacity;
00294 }
00295
00307 void ensureCapacity(sal_Int32 minimumCapacity)
00308 {
00309 rtl_uStringbuffer_ensureCapacity( &pData, &nCapacity, minimumCapacity );
00310 }
00311
00330 void setLength(sal_Int32 newLength)
00331 {
00332 assert(newLength >= 0);
00333
00334 if( newLength != pData->length )
00335 {
00336 if( newLength > nCapacity )
00337 rtl_uStringbuffer_ensureCapacity(&pData, &nCapacity, newLength);
00338 else
00339 pData->buffer[newLength] = 0;
00340 pData->length = newLength;
00341 }
00342 }
00343
00357 SAL_DEPRECATED("use rtl::OUStringBuffer::operator [] instead")
00358 sal_Unicode charAt( sal_Int32 index ) const
00359 {
00360 assert(index >= 0 && index < pData->length);
00361 return pData->buffer[ index ];
00362 }
00363
00374 SAL_DEPRECATED("use rtl::OUStringBuffer::operator [] instead")
00375 OUStringBuffer & setCharAt(sal_Int32 index, sal_Unicode ch)
00376 {
00377 assert(index >= 0 && index < pData->length);
00378 pData->buffer[ index ] = ch;
00379 return *this;
00380 }
00381
00385 const sal_Unicode* getStr() const { return pData->buffer; }
00386
00396 sal_Unicode & operator [](sal_Int32 index) { return pData->buffer[index]; }
00397
00402 const OUString toString() const
00403 {
00404 return OUString(pData->buffer, pData->length);
00405 }
00406
00417 OUStringBuffer & append(const OUString &str)
00418 {
00419 return append( str.getStr(), str.getLength() );
00420 }
00421
00434 OUStringBuffer & append(const OUStringBuffer &str)
00435 {
00436 if(str.getLength() > 0)
00437 {
00438 append( str.getStr(), str.getLength() );
00439 }
00440 return *this;
00441 }
00442
00454 OUStringBuffer & append( const sal_Unicode * str )
00455 {
00456 return append( str, rtl_ustr_getLength( str ) );
00457 }
00458
00472 OUStringBuffer & append( const sal_Unicode * str, sal_Int32 len)
00473 {
00474
00475 rtl_uStringbuffer_insert( &pData, &nCapacity, getLength(), str, len );
00476 return *this;
00477 }
00478
00484 template< typename T >
00485 typename internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type append( T& literal )
00486 {
00487 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00488 rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), literal,
00489 internal::ConstCharArrayDetector< T, void >::size - 1 );
00490 return *this;
00491 }
00492
00509 OUStringBuffer & appendAscii( const sal_Char * str )
00510 {
00511 return appendAscii( str, rtl_str_getLength( str ) );
00512 }
00513
00532 OUStringBuffer & appendAscii( const sal_Char * str, sal_Int32 len)
00533 {
00534 rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), str, len );
00535 return *this;
00536 }
00537
00549 OUStringBuffer & append(sal_Bool b)
00550 {
00551 sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
00552 return append( sz, rtl_ustr_valueOfBoolean( sz, b ) );
00553 }
00554
00567 OUStringBuffer & append(char c)
00568 {
00569 assert(static_cast< unsigned char >(c) <= 0x7F);
00570 return append(sal_Unicode(c));
00571 }
00572
00583 OUStringBuffer & append(sal_Unicode c)
00584 {
00585 return append( &c, 1 );
00586 }
00587
00599 OUStringBuffer & append(sal_Int32 i, sal_Int16 radix = 10 )
00600 {
00601 sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT32];
00602 return append( sz, rtl_ustr_valueOfInt32( sz, i, radix ) );
00603 }
00604
00616 OUStringBuffer & append(sal_Int64 l, sal_Int16 radix = 10 )
00617 {
00618 sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT64];
00619 return append( sz, rtl_ustr_valueOfInt64( sz, l, radix ) );
00620 }
00621
00633 OUStringBuffer & append(float f)
00634 {
00635 sal_Unicode sz[RTL_USTR_MAX_VALUEOFFLOAT];
00636 return append( sz, rtl_ustr_valueOfFloat( sz, f ) );
00637 }
00638
00650 OUStringBuffer & append(double d)
00651 {
00652 sal_Unicode sz[RTL_USTR_MAX_VALUEOFDOUBLE];
00653 return append( sz, rtl_ustr_valueOfDouble( sz, d ) );
00654 }
00655
00669 OUStringBuffer & appendUtf32(sal_uInt32 c) {
00670 return insertUtf32(getLength(), c);
00671 }
00672
00688 OUStringBuffer & insert(sal_Int32 offset, const OUString & str)
00689 {
00690 return insert( offset, str.getStr(), str.getLength() );
00691 }
00692
00710 OUStringBuffer & insert( sal_Int32 offset, const sal_Unicode * str )
00711 {
00712 return insert( offset, str, rtl_ustr_getLength( str ) );
00713 }
00714
00733 OUStringBuffer & insert( sal_Int32 offset, const sal_Unicode * str, sal_Int32 len)
00734 {
00735
00736 rtl_uStringbuffer_insert( &pData, &nCapacity, offset, str, len );
00737 return *this;
00738 }
00739
00745 template< typename T >
00746 typename internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type insert( sal_Int32 offset, T& literal )
00747 {
00748 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00749 rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, offset, literal,
00750 internal::ConstCharArrayDetector< T, void >::size - 1 );
00751 return *this;
00752 }
00753
00771 OUStringBuffer & insert(sal_Int32 offset, sal_Bool b)
00772 {
00773 sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
00774 return insert( offset, sz, rtl_ustr_valueOfBoolean( sz, b ) );
00775 }
00776
00795 OUStringBuffer & insert(sal_Int32 offset, char c)
00796 {
00797 sal_Unicode u = c;
00798 return insert( offset, &u, 1 );
00799 }
00800
00817 OUStringBuffer & insert(sal_Int32 offset, sal_Unicode c)
00818 {
00819 return insert( offset, &c, 1 );
00820 }
00821
00841 OUStringBuffer & insert(sal_Int32 offset, sal_Int32 i, sal_Int16 radix = 10 )
00842 {
00843 sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT32];
00844 return insert( offset, sz, rtl_ustr_valueOfInt32( sz, i, radix ) );
00845 }
00846
00866 OUStringBuffer & insert(sal_Int32 offset, sal_Int64 l, sal_Int16 radix = 10 )
00867 {
00868 sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT64];
00869 return insert( offset, sz, rtl_ustr_valueOfInt64( sz, l, radix ) );
00870 }
00871
00890 OUStringBuffer insert(sal_Int32 offset, float f)
00891 {
00892 sal_Unicode sz[RTL_USTR_MAX_VALUEOFFLOAT];
00893 return insert( offset, sz, rtl_ustr_valueOfFloat( sz, f ) );
00894 }
00895
00914 OUStringBuffer & insert(sal_Int32 offset, double d)
00915 {
00916 sal_Unicode sz[RTL_USTR_MAX_VALUEOFDOUBLE];
00917 return insert( offset, sz, rtl_ustr_valueOfDouble( sz, d ) );
00918 }
00919
00935 OUStringBuffer & insertUtf32(sal_Int32 offset, sal_uInt32 c) {
00936 rtl_uStringbuffer_insertUtf32(&pData, &nCapacity, offset, c);
00937 return *this;
00938 }
00939
00952 OUStringBuffer & remove( sal_Int32 start, sal_Int32 len )
00953 {
00954 rtl_uStringbuffer_remove( &pData, start, len );
00955 return *this;
00956 }
00957
00968 OUStringBuffer & truncate( sal_Int32 start = 0 )
00969 {
00970 rtl_uStringbuffer_remove( &pData, start, getLength() - start );
00971 return *this;
00972 }
00973
00984 OUStringBuffer& replace( sal_Unicode oldChar, sal_Unicode newChar )
00985 {
00986 sal_Int32 index = 0;
00987 while((index = indexOf(oldChar, index)) >= 0)
00988 {
00989 pData->buffer[ index ] = newChar;
00990 }
00991 return *this;
00992 }
00993
01009 inline void accessInternals(rtl_uString *** pInternalData,
01010 sal_Int32 ** pInternalCapacity)
01011 {
01012 *pInternalData = &pData;
01013 *pInternalCapacity = &nCapacity;
01014 }
01015
01016
01032 sal_Int32 indexOf( sal_Unicode ch, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
01033 {
01034 sal_Int32 ret = rtl_ustr_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
01035 return (ret < 0 ? ret : ret+fromIndex);
01036 }
01037
01049 sal_Int32 lastIndexOf( sal_Unicode ch ) const SAL_THROW(())
01050 {
01051 return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
01052 }
01053
01068 sal_Int32 lastIndexOf( sal_Unicode ch, sal_Int32 fromIndex ) const SAL_THROW(())
01069 {
01070 return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
01071 }
01072
01090 sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
01091 {
01092 sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
01093 str.pData->buffer, str.pData->length );
01094 return (ret < 0 ? ret : ret+fromIndex);
01095 }
01096
01103 template< typename T >
01104 typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
01105 {
01106 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
01107 sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength(
01108 pData->buffer + fromIndex, pData->length - fromIndex, literal,
01109 internal::ConstCharArrayDetector< T, void >::size - 1);
01110 return ret < 0 ? ret : ret + fromIndex;
01111 }
01112
01130 sal_Int32 lastIndexOf( const OUString & str ) const SAL_THROW(())
01131 {
01132 return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length,
01133 str.pData->buffer, str.pData->length );
01134 }
01135
01155 sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const SAL_THROW(())
01156 {
01157 return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
01158 str.pData->buffer, str.pData->length );
01159 }
01160
01166 template< typename T >
01167 typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const SAL_THROW(())
01168 {
01169 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
01170 return rtl_ustr_lastIndexOfAscii_WithLength(
01171 pData->buffer, pData->length, literal, internal::ConstCharArrayDetector< T, void >::size - 1);
01172 }
01173
01183 sal_Int32 stripStart(sal_Unicode c = (sal_Unicode)' ')
01184 {
01185 sal_Int32 index;
01186 for(index = 0; index < getLength() ; index++)
01187 {
01188 if(pData->buffer[ index ] != c)
01189 {
01190 break;
01191 }
01192 }
01193 if(index)
01194 {
01195 remove(0, index);
01196 }
01197 return index;
01198 }
01199
01209 sal_Int32 stripEnd(sal_Unicode c = (sal_Unicode)' ')
01210 {
01211 sal_Int32 result = getLength();
01212 sal_Int32 index;
01213 for(index = getLength(); index > 0 ; index--)
01214 {
01215 if(pData->buffer[ index - 1 ] != c)
01216 {
01217 break;
01218 }
01219 }
01220 if(index < getLength())
01221 {
01222 truncate(index);
01223 }
01224 return result - getLength();
01225 }
01235 sal_Int32 strip(sal_Unicode c = (sal_Unicode)' ')
01236 {
01237 return stripStart(c) + stripEnd(c);
01238 }
01239
01240 private:
01244 rtl_uString * pData;
01245
01249 sal_Int32 nCapacity;
01250 };
01251
01252 #ifdef RTL_FAST_STRING
01253 template<>
01254 struct ToStringHelper< OUStringBuffer >
01255 {
01256 static int length( const OUStringBuffer& s ) { return s.getLength(); }
01257 static sal_Unicode* addData( sal_Unicode* buffer, const OUStringBuffer& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); }
01258 static const bool allowOStringConcat = false;
01259 static const bool allowOUStringConcat = true;
01260 };
01261 #endif
01262
01263 }
01264
01265 #ifdef RTL_STRING_UNITTEST
01266 namespace rtl
01267 {
01268 typedef rtlunittest::OUStringBuffer OUStringBuffer;
01269 }
01270 #endif
01271
01272 #ifdef RTL_USING
01273 using ::rtl::OUStringBuffer;
01274 #endif
01275
01276 #endif
01277
01278