00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _RTL_STRBUF_HXX_
00021 #define _RTL_STRBUF_HXX_
00022
00023 #include "sal/config.h"
00024
00025 #include <cassert>
00026 #include <string.h>
00027
00028 #include <rtl/strbuf.h>
00029 #include <rtl/string.hxx>
00030 #include <rtl/stringutils.hxx>
00031
00032 #ifdef RTL_FAST_STRING
00033 #include <rtl/stringconcat.hxx>
00034 #endif
00035
00036 #ifdef __cplusplus
00037
00038
00039
00040
00041
00042
00043 #ifdef RTL_STRING_UNITTEST
00044 #define rtl rtlunittest
00045 #endif
00046
00047 namespace rtl
00048 {
00049
00050 #ifdef RTL_STRING_UNITTEST
00051 #undef rtl
00052
00053 #define RTL_STRING_CONST_FUNCTION rtl_string_unittest_const_literal_function = true;
00054 #else
00055 #define RTL_STRING_CONST_FUNCTION
00056 #endif
00057
00096 class SAL_WARN_UNUSED OStringBuffer
00097 {
00098 public:
00103 OStringBuffer()
00104 : pData(NULL)
00105 , nCapacity( 16 )
00106 {
00107 rtl_string_new_WithLength( &pData, nCapacity );
00108 }
00109
00116 OStringBuffer( const OStringBuffer & value )
00117 : pData(NULL)
00118 , nCapacity( value.nCapacity )
00119 {
00120 rtl_stringbuffer_newFromStringBuffer( &pData, value.nCapacity, value.pData );
00121 }
00122
00129 explicit OStringBuffer(int length)
00130 : pData(NULL)
00131 , nCapacity( length )
00132 {
00133 rtl_string_new_WithLength( &pData, length );
00134 }
00135
00146 OStringBuffer(OString value)
00147 : pData(NULL)
00148 , nCapacity( value.getLength() + 16 )
00149 {
00150 rtl_stringbuffer_newFromStr_WithLength( &pData, value.getStr(), value.getLength() );
00151 }
00152
00157 #ifdef HAVE_SFINAE_ANONYMOUS_BROKEN // see the OString ctors
00158 OStringBuffer( const char* value )
00159 : pData(NULL)
00160 {
00161 sal_Int32 length = rtl_str_getLength( value );
00162 nCapacity = length + 16;
00163 rtl_stringbuffer_newFromStr_WithLength( &pData, value, length );
00164 }
00165 #else
00166 template< typename T >
00167 OStringBuffer( const T& value, typename internal::CharPtrDetector< T, internal::Dummy >::Type = internal::Dummy())
00168 : pData(NULL)
00169 {
00170 sal_Int32 length = rtl_str_getLength( value );
00171 nCapacity = length + 16;
00172 rtl_stringbuffer_newFromStr_WithLength( &pData, value, length );
00173 }
00174
00175 template< typename T >
00176 OStringBuffer( T& value, typename internal::NonConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy())
00177 : pData(NULL)
00178 {
00179 sal_Int32 length = rtl_str_getLength( value );
00180 nCapacity = length + 16;
00181 rtl_stringbuffer_newFromStr_WithLength( &pData, value, length );
00182 }
00183
00195 template< typename T >
00196 OStringBuffer( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy())
00197 : pData(NULL)
00198 , nCapacity( internal::ConstCharArrayDetector< T, void >::size - 1 + 16 )
00199 {
00200 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00201 rtl_string_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 16 );
00202 #ifdef RTL_STRING_UNITTEST
00203 rtl_string_unittest_const_literal = true;
00204 #endif
00205 }
00206 #endif // HAVE_SFINAE_ANONYMOUS_BROKEN
00207
00220 OStringBuffer(const sal_Char * value, sal_Int32 length)
00221 : pData(NULL)
00222 , nCapacity( length + 16 )
00223 {
00224 rtl_stringbuffer_newFromStr_WithLength( &pData, value, length );
00225 }
00226
00227 #ifdef RTL_FAST_STRING
00228 template< typename T1, typename T2 >
00229 OStringBuffer( const OStringConcat< T1, T2 >& c )
00230 {
00231 const sal_Int32 l = c.length();
00232 rtl_String* buffer = NULL;
00233 nCapacity = l + 16;
00234 rtl_string_new_WithLength( &buffer, nCapacity );
00235 char* end = c.addData( buffer->buffer );
00236 *end = '\0';
00237 buffer->length = end - buffer->buffer;
00238 pData = buffer;
00239 }
00240 #endif
00241
00244 OStringBuffer& operator = ( const OStringBuffer& value )
00245 {
00246 if (this != &value)
00247 {
00248 rtl_stringbuffer_newFromStringBuffer(&pData,
00249 value.nCapacity,
00250 value.pData);
00251 nCapacity = value.nCapacity;
00252 }
00253 return *this;
00254 }
00255
00259 ~OStringBuffer()
00260 {
00261 rtl_string_release( pData );
00262 }
00263
00272 OString makeStringAndClear()
00273 {
00274 OString aRet( pData );
00275 rtl_string_new(&pData);
00276 nCapacity = 0;
00277 return aRet;
00278 }
00279
00285 sal_Int32 getLength() const
00286 {
00287 return pData->length;
00288 }
00289
00300 sal_Int32 getCapacity() const
00301 {
00302 return nCapacity;
00303 }
00304
00316 void ensureCapacity(sal_Int32 minimumCapacity)
00317 {
00318 rtl_stringbuffer_ensureCapacity( &pData, &nCapacity, minimumCapacity );
00319 }
00320
00339 void setLength(sal_Int32 newLength)
00340 {
00341 assert(newLength >= 0);
00342
00343 if( newLength != pData->length )
00344 {
00345 if( newLength > nCapacity )
00346 rtl_stringbuffer_ensureCapacity(&pData, &nCapacity, newLength);
00347 else
00348 pData->buffer[newLength] = '\0';
00349 pData->length = newLength;
00350 }
00351 }
00352
00366 SAL_DEPRECATED("use rtl::OStringBuffer::operator [] instead")
00367 sal_Char charAt( sal_Int32 index )
00368 {
00369 assert(index >= 0 && index < pData->length);
00370 return pData->buffer[ index ];
00371 }
00372
00383 SAL_DEPRECATED("use rtl::OStringBuffer::operator [] instead")
00384 OStringBuffer & setCharAt(sal_Int32 index, sal_Char ch)
00385 {
00386 assert(index >= 0 && index < pData->length);
00387 pData->buffer[ index ] = ch;
00388 return *this;
00389 }
00390
00394 const sal_Char* getStr() const { return pData->buffer; }
00395
00405 sal_Char & operator [](sal_Int32 index) { return pData->buffer[index]; }
00406
00411 const OString toString() const
00412 {
00413 return OString(pData->buffer, pData->length);
00414 }
00415
00426 OStringBuffer & append(const OString &str)
00427 {
00428 return append( str.getStr(), str.getLength() );
00429 }
00430
00442 #ifdef HAVE_SFINAE_ANONYMOUS_BROKEN
00443 OStringBuffer & append( const sal_Char * str )
00444 {
00445 return append( str, rtl_str_getLength( str ) );
00446 }
00447 #else
00448 template< typename T >
00449 typename internal::CharPtrDetector< T, OStringBuffer& >::Type append( const T& str )
00450 {
00451 return append( str, rtl_str_getLength( str ) );
00452 }
00453
00454 template< typename T >
00455 typename internal::NonConstCharArrayDetector< T, OStringBuffer& >::Type append( T& str )
00456 {
00457 return append( str, rtl_str_getLength( str ) );
00458 }
00459
00465 template< typename T >
00466 typename internal::ConstCharArrayDetector< T, OStringBuffer& >::Type append( T& literal )
00467 {
00468 RTL_STRING_CONST_FUNCTION
00469 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00470 rtl_stringbuffer_insert( &pData, &nCapacity, getLength(), literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
00471 return *this;
00472 }
00473 #endif
00474
00488 OStringBuffer & append( const sal_Char * str, sal_Int32 len)
00489 {
00490
00491 rtl_stringbuffer_insert( &pData, &nCapacity, getLength(), str, len );
00492 return *this;
00493 }
00494
00506 OStringBuffer & append(sal_Bool b)
00507 {
00508 sal_Char sz[RTL_STR_MAX_VALUEOFBOOLEAN];
00509 return append( sz, rtl_str_valueOfBoolean( sz, b ) );
00510 }
00511
00522 OStringBuffer & append(sal_Char c)
00523 {
00524 return append( &c, 1 );
00525 }
00526
00538 OStringBuffer & append(sal_Int32 i, sal_Int16 radix = 10 )
00539 {
00540 sal_Char sz[RTL_STR_MAX_VALUEOFINT32];
00541 return append( sz, rtl_str_valueOfInt32( sz, i, radix ) );
00542 }
00543
00555 OStringBuffer & append(sal_Int64 l, sal_Int16 radix = 10 )
00556 {
00557 sal_Char sz[RTL_STR_MAX_VALUEOFINT64];
00558 return append( sz, rtl_str_valueOfInt64( sz, l, radix ) );
00559 }
00560
00572 OStringBuffer & append(float f)
00573 {
00574 sal_Char sz[RTL_STR_MAX_VALUEOFFLOAT];
00575 return append( sz, rtl_str_valueOfFloat( sz, f ) );
00576 }
00577
00589 OStringBuffer & append(double d)
00590 {
00591 sal_Char sz[RTL_STR_MAX_VALUEOFDOUBLE];
00592 return append( sz, rtl_str_valueOfDouble( sz, d ) );
00593 }
00594
00610 OStringBuffer & insert(sal_Int32 offset, const OString & str)
00611 {
00612 return insert( offset, str.getStr(), str.getLength() );
00613 }
00614
00632 #ifdef HAVE_SFINAE_ANONYMOUS_BROKEN
00633 OStringBuffer & insert( sal_Int32 offset, const sal_Char * str )
00634 {
00635 return insert( offset, str, rtl_str_getLength( str ) );
00636 }
00637 #else
00638 template< typename T >
00639 typename internal::CharPtrDetector< T, OStringBuffer& >::Type insert( sal_Int32 offset, const T& str )
00640 {
00641 return insert( offset, str, rtl_str_getLength( str ) );
00642 }
00643
00644 template< typename T >
00645 typename internal::NonConstCharArrayDetector< T, OStringBuffer& >::Type insert( sal_Int32 offset, T& str )
00646 {
00647 return insert( offset, str, rtl_str_getLength( str ) );
00648 }
00649
00655 template< typename T >
00656 typename internal::ConstCharArrayDetector< T, OStringBuffer& >::Type insert( sal_Int32 offset, T& literal )
00657 {
00658 RTL_STRING_CONST_FUNCTION
00659 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
00660 rtl_stringbuffer_insert( &pData, &nCapacity, offset, literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
00661 return *this;
00662 }
00663 #endif
00664
00683 OStringBuffer & insert( sal_Int32 offset, const sal_Char * str, sal_Int32 len)
00684 {
00685
00686 rtl_stringbuffer_insert( &pData, &nCapacity, offset, str, len );
00687 return *this;
00688 }
00689
00707 OStringBuffer & insert(sal_Int32 offset, sal_Bool b)
00708 {
00709 sal_Char sz[RTL_STR_MAX_VALUEOFBOOLEAN];
00710 return insert( offset, sz, rtl_str_valueOfBoolean( sz, b ) );
00711 }
00712
00729 OStringBuffer & insert(sal_Int32 offset, sal_Char c)
00730 {
00731 return insert( offset, &c, 1 );
00732 }
00733
00751 OStringBuffer & insert(sal_Int32 offset, sal_Int32 i, sal_Int16 radix = 10 )
00752 {
00753 sal_Char sz[RTL_STR_MAX_VALUEOFINT32];
00754 return insert( offset, sz, rtl_str_valueOfInt32( sz, i, radix ) );
00755 }
00756
00774 OStringBuffer & insert(sal_Int32 offset, sal_Int64 l, sal_Int16 radix = 10 )
00775 {
00776 sal_Char sz[RTL_STR_MAX_VALUEOFINT64];
00777 return insert( offset, sz, rtl_str_valueOfInt64( sz, l, radix ) );
00778 }
00779
00797 OStringBuffer insert(sal_Int32 offset, float f)
00798 {
00799 sal_Char sz[RTL_STR_MAX_VALUEOFFLOAT];
00800 return insert( offset, sz, rtl_str_valueOfFloat( sz, f ) );
00801 }
00802
00820 OStringBuffer & insert(sal_Int32 offset, double d)
00821 {
00822 sal_Char sz[RTL_STR_MAX_VALUEOFDOUBLE];
00823 return insert( offset, sz, rtl_str_valueOfDouble( sz, d ) );
00824 }
00825
00838 OStringBuffer & remove( sal_Int32 start, sal_Int32 len )
00839 {
00840 rtl_stringbuffer_remove( &pData, start, len );
00841 return *this;
00842 }
00843
00844 private:
00848 rtl_String * pData;
00849
00853 sal_Int32 nCapacity;
00854 };
00855
00856 #ifdef RTL_FAST_STRING
00857 template<>
00858 struct ToStringHelper< OStringBuffer >
00859 {
00860 static int length( const OStringBuffer& s ) { return s.getLength(); }
00861 static char* addData( char* buffer, const OStringBuffer& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); }
00862 static const bool allowOStringConcat = true;
00863 static const bool allowOUStringConcat = false;
00864 };
00865 #endif
00866
00867
00868 }
00869
00870 #ifdef RTL_STRING_UNITTEST
00871 namespace rtl
00872 {
00873 typedef rtlunittest::OStringBuffer OStringBuffer;
00874 }
00875 #undef RTL_STRING_CONST_FUNCTION
00876 #endif
00877
00878 #ifdef RTL_USING
00879 using ::rtl::OStringBuffer;
00880 #endif
00881
00882 #endif
00883 #endif
00884
00885
00886