[Libreoffice-commits] .: 10 commits - chart2/source comphelper/inc cppuhelper/source cppu/inc cui/source extensions/source i18npool/source l10ntools/source oox/source sal/CppunitTest_sal_rtl_strings.mk sal/inc sal/Package_inc.mk sal/qa sc/source sdext/source sd/source solenv/gbuild stoc/source svx/source sw/source tools/inc tools/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Dec 3 09:04:48 PST 2012


 chart2/source/controller/main/ChartController.cxx       |    2 
 comphelper/inc/comphelper/string.hxx                    |   16 
 cppu/inc/com/sun/star/uno/Any.hxx                       |   22 +
 cppuhelper/source/bootstrap.cxx                         |    2 
 cui/source/dialogs/scriptdlg.cxx                        |    4 
 extensions/source/update/check/updatecheckconfig.cxx    |    2 
 extensions/source/update/check/updatehdl.cxx            |   20 -
 i18npool/source/collator/collator_unicode.cxx           |    4 
 i18npool/source/indexentry/indexentrysupplier_asian.cxx |    4 
 l10ntools/source/po.cxx                                 |    6 
 l10ntools/source/propmerge.cxx                          |    2 
 oox/source/export/drawingml.cxx                         |    4 
 oox/source/export/shapes.cxx                            |    4 
 oox/source/ppt/presentationfragmenthandler.cxx          |    2 
 oox/source/ppt/slidefragmenthandler.cxx                 |    2 
 sal/CppunitTest_sal_rtl_strings.mk                      |    2 
 sal/Package_inc.mk                                      |    1 
 sal/inc/rtl/strbuf.hxx                                  |   34 ++
 sal/inc/rtl/string.hxx                                  |   75 ++++
 sal/inc/rtl/stringconcat.hxx                            |  261 ++++++++++++++++
 sal/inc/rtl/stringutils.hxx                             |   30 +
 sal/inc/rtl/ustrbuf.hxx                                 |   36 ++
 sal/inc/rtl/ustring.hxx                                 |   94 +++++
 sal/inc/sal/log-areas.dox                               |    1 
 sal/qa/rtl/strings/test_ostring_concat.cxx              |   79 ++++
 sal/qa/rtl/strings/test_ostring_stringliterals.cxx      |    4 
 sal/qa/rtl/strings/test_oustring_concat.cxx             |   68 ++++
 sal/qa/rtl/strings/test_oustring_stringliterals.cxx     |    9 
 sc/source/ui/vba/vbaname.cxx                            |    8 
 sd/source/core/CustomAnimationCloner.cxx                |    6 
 sd/source/filter/eppt/pptx-epptooxml.cxx                |    2 
 sd/source/filter/html/htmlex.cxx                        |    4 
 sd/source/ui/slideshow/slideshowimpl.cxx                |   44 +-
 sd/source/ui/unoidl/DrawController.cxx                  |    2 
 sd/source/ui/view/drviews1.cxx                          |    2 
 sdext/source/presenter/PresenterTheme.cxx               |    4 
 solenv/gbuild/gbuild.mk                                 |    5 
 stoc/source/inspect/introspection.cxx                   |    2 
 svx/source/svdraw/svdoole2.cxx                          |   16 
 sw/source/filter/ww8/docxattributeoutput.cxx            |    6 
 tools/inc/tools/string.hxx                              |   27 +
 tools/source/string/strucvt.cxx                         |    3 
 42 files changed, 833 insertions(+), 88 deletions(-)

New commits:
commit 13d277b5504a47ae2e2320685669b27b5ed3a3ba
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Mon Dec 3 17:36:21 2012 +0100

    fix capacity in stringbuffers
    
    rtl_stringbuffer_* functions silently allocate +16 extra for capacity,
    but rtl_string_* functions do not. As intuitive and obvious as ever.
    
    Change-Id: Ia0bb63dedf31f6ad5c687187221d7385043b5456

diff --git a/sal/inc/rtl/strbuf.hxx b/sal/inc/rtl/strbuf.hxx
index 5efd055..7a28298 100644
--- a/sal/inc/rtl/strbuf.hxx
+++ b/sal/inc/rtl/strbuf.hxx
@@ -229,11 +229,12 @@ public:
     {
         const int l = c.length();
         rtl_String* buffer = NULL;
-        rtl_string_new_WithLength( &buffer, l );
+        nCapacity = l + 16;
+        rtl_string_new_WithLength( &buffer, nCapacity );
         char* end = c.addData( buffer->buffer );
+        *end = '\0';
         buffer->length = end - buffer->buffer;
         pData = buffer;
-        nCapacity = l + 16;
     }
 #endif
 
diff --git a/sal/inc/rtl/ustrbuf.hxx b/sal/inc/rtl/ustrbuf.hxx
index 06d906e..5f133bf 100644
--- a/sal/inc/rtl/ustrbuf.hxx
+++ b/sal/inc/rtl/ustrbuf.hxx
@@ -221,12 +221,13 @@ public:
     {
         const int l = c.length();
         rtl_uString* buffer = NULL;
-        rtl_uString_new_WithLength( &buffer, l ); // TODO this clears, not necessary
+        nCapacity = l + 16;
+        rtl_uString_new_WithLength( &buffer, nCapacity ); // TODO this clears, not necessary
         sal_Unicode* end = c.addData( buffer->buffer );
+        *end = '\0';
         buffer->length = end - buffer->buffer;
         // TODO realloc in case buffer->length is noticeably smaller than l ?
         pData = buffer;
-        nCapacity = l + 16;
     }
 #endif
     /** Assign to this a copy of value.
commit 371443a8045a8f777323472f9cb702f00084b0dc
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Mon Dec 3 17:02:47 2012 +0100

    avoid unused warning in non-debug mode
    
    Change-Id: I9687f5388a8c01075ee6e359ff9350edff296f4d

diff --git a/sal/inc/rtl/stringconcat.hxx b/sal/inc/rtl/stringconcat.hxx
index 9fb9568..bf0244a 100644
--- a/sal/inc/rtl/stringconcat.hxx
+++ b/sal/inc/rtl/stringconcat.hxx
@@ -128,7 +128,7 @@ struct ToStringHelper< char[ N ] >
 template< int N >
 struct ToStringHelper< const char[ N ] >
     {
-    static int length( const char str[ N ] ) { assert( strlen( str ) == N - 1 ); return N - 1; }
+    static int length( const char str[ N ] ) { (void)str; assert( strlen( str ) == N - 1 ); return N - 1; }
     static char* addData( char* buffer, const char str[ N ] ) { return addDataHelper( buffer, str, N - 1 ); }
     static sal_Unicode* addData( sal_Unicode* buffer, const char str[ N ] ) { return addDataLiteral( buffer, str, N - 1 ); }
     static const bool allowOStringConcat = true;
commit 7b57e37c68f2c4cece3b0e0db61f4878277dd1bc
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Mon Dec 3 16:08:30 2012 +0100

    there should be no support for OString in Any
    
    Change-Id: I53d047381a89d52c43378dd304ba6e0774f59968

diff --git a/cppu/inc/com/sun/star/uno/Any.hxx b/cppu/inc/com/sun/star/uno/Any.hxx
index 8f6dfc6..6f3bda9 100644
--- a/cppu/inc/com/sun/star/uno/Any.hxx
+++ b/cppu/inc/com/sun/star/uno/Any.hxx
@@ -190,14 +190,6 @@ inline Any SAL_CALL makeAny( bool const & value ) SAL_THROW(())
 //__________________________________________________________________________________________________
 #ifdef RTL_FAST_STRING
 template< class C1, class C2 >
-inline Any SAL_CALL makeAny( const rtl::OStringConcat< C1, C2 >& value ) SAL_THROW(())
-{
-    const rtl::OString str( value );
-    return Any( &str, ::cppu::getTypeFavourUnsigned(&str) );
-}
-
-//__________________________________________________________________________________________________
-template< class C1, class C2 >
 inline Any SAL_CALL makeAny( const rtl::OUStringConcat< C1, C2 >& value ) SAL_THROW(())
 {
     const rtl::OUString str( value );
@@ -228,18 +220,6 @@ inline void SAL_CALL operator <<= ( Any & rAny, bool const & value )
 //______________________________________________________________________________
 #ifdef RTL_FAST_STRING
 template< class C1, class C2 >
-inline void SAL_CALL operator <<= ( Any & rAny, const rtl::OStringConcat< C1, C2 >& value )
-    SAL_THROW(())
-{
-    const rtl::OString str( value );
-    const Type & rType = ::cppu::getTypeFavourUnsigned(&str);
-    ::uno_type_any_assign(
-        &rAny, const_cast< rtl::OString * >( &str ), rType.getTypeLibType(),
-        (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release );
-}
-
-//______________________________________________________________________________
-template< class C1, class C2 >
 inline void SAL_CALL operator <<= ( Any & rAny, const rtl::OUStringConcat< C1, C2 >& value )
     SAL_THROW(())
 {
commit 5db72152fe67c7f538f67c284b6767a52c12aa69
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Mon Dec 3 16:06:16 2012 +0100

    assert on strange lengths of string literals
    
    It's better to detect corner cases this way rather than get possibly
    incorrect results. And strlen() should be easy to optimize out
    for string literals.
    
    Change-Id: Id762e256207668a0cbefe4e13d5f2067f373e783

diff --git a/sal/inc/rtl/strbuf.hxx b/sal/inc/rtl/strbuf.hxx
index 945d1d2..5efd055 100644
--- a/sal/inc/rtl/strbuf.hxx
+++ b/sal/inc/rtl/strbuf.hxx
@@ -196,6 +196,7 @@ public:
         : pData(NULL)
         , nCapacity( internal::ConstCharArrayDetector< T, void >::size - 1 + 16 )
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         rtl_string_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 16 );
 #ifdef RTL_STRING_UNITTEST
         rtl_string_unittest_const_literal = true;
@@ -463,6 +464,7 @@ public:
     typename internal::ConstCharArrayDetector< T, OStringBuffer& >::Type append( T& literal )
     {
         RTL_STRING_CONST_FUNCTION
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         rtl_stringbuffer_insert( &pData, &nCapacity, getLength(), literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
         return *this;
     }
@@ -652,6 +654,7 @@ public:
     typename internal::ConstCharArrayDetector< T, OStringBuffer& >::Type insert( sal_Int32 offset, T& literal )
     {
         RTL_STRING_CONST_FUNCTION
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         rtl_stringbuffer_insert( &pData, &nCapacity, offset, literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
         return *this;
     }
diff --git a/sal/inc/rtl/string.hxx b/sal/inc/rtl/string.hxx
index a2cee51..2c7a43d 100644
--- a/sal/inc/rtl/string.hxx
+++ b/sal/inc/rtl/string.hxx
@@ -202,6 +202,7 @@ public:
     template< typename T >
     OString( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy() ) SAL_THROW(())
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         pData = 0;
         rtl_string_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 0 );
 #ifdef RTL_STRING_UNITTEST
@@ -295,6 +296,7 @@ public:
     typename internal::ConstCharArrayDetector< T, OString& >::Type operator=( T& literal ) SAL_THROW(())
     {
         RTL_STRING_CONST_FUNCTION
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         rtl_string_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 0 );
         return *this;
     }
@@ -529,6 +531,7 @@ public:
     typename internal::ConstCharArrayDetector< T, bool >::Type  equalsIgnoreAsciiCase( T& literal ) const SAL_THROW(())
     {
         RTL_STRING_CONST_FUNCTION
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         if ( pData->length != internal::ConstCharArrayDetector< T, void >::size - 1 )
             return false;
         return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
@@ -594,6 +597,7 @@ public:
     typename internal::ConstCharArrayDetector< T, bool >::Type  match( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
     {
         RTL_STRING_CONST_FUNCTION
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return rtl_str_shortenedCompare_WithLength(
             pData->buffer + fromIndex, pData->length - fromIndex,
             literal, internal::ConstCharArrayDetector< T, void >::size - 1, internal::ConstCharArrayDetector< T, void >::size - 1) == 0;
@@ -666,6 +670,7 @@ public:
     typename internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const
     {
         RTL_STRING_CONST_FUNCTION
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
             literal, internal::ConstCharArrayDetector< T, void >::size - 1, internal::ConstCharArrayDetector< T, void >::size - 1 ) == 0;
     }
@@ -720,6 +725,7 @@ public:
     typename internal::ConstCharArrayDetector< T, bool >::Type endsWith( T& literal ) const
     {
         RTL_STRING_CONST_FUNCTION
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return internal::ConstCharArrayDetector< T, void >::size - 1 <= getLength()
             && match(literal, getLength() - ( internal::ConstCharArrayDetector< T, void >::size - 1 ));
     }
@@ -788,6 +794,7 @@ public:
     friend typename internal::ConstCharArrayDetector< T, bool >::Type operator==( const OString& rStr, T& literal ) SAL_THROW(())
     {
         RTL_STRING_CONST_FUNCTION
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return rStr.getLength() == internal::ConstCharArrayDetector< T, void >::size - 1
             && rtl_str_compare_WithLength( rStr.pData->buffer, rStr.pData->length, literal,
                 internal::ConstCharArrayDetector< T, void >::size - 1 ) == 0;
@@ -802,6 +809,7 @@ public:
     friend typename internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OString& rStr ) SAL_THROW(())
     {
         RTL_STRING_CONST_FUNCTION
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return rStr.getLength() == internal::ConstCharArrayDetector< T, void >::size - 1
             && rtl_str_compare_WithLength( rStr.pData->buffer, rStr.pData->length, literal,
                 internal::ConstCharArrayDetector< T, void >::size - 1 ) == 0;
@@ -946,6 +954,7 @@ public:
     typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
     {
         RTL_STRING_CONST_FUNCTION
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         sal_Int32 n = rtl_str_indexOfStr_WithLength(
             pData->buffer + fromIndex, pData->length - fromIndex, literal, internal::ConstCharArrayDetector< T, void >::size - 1);
         return n < 0 ? n : n + fromIndex;
@@ -1466,7 +1475,7 @@ This class is not part of public API and is meant to be used only in LibreOffice
 struct SAL_WARN_UNUSED OStringLiteral
 {
     template< int N >
-    OStringLiteral( const char (&str)[ N ] ) : size( N - 1 ), data( str ) {}
+    OStringLiteral( const char (&str)[ N ] ) : size( N - 1 ), data( str ) { assert( strlen( str ) == N - 1 ); }
     int size;
     const char* data;
 };
diff --git a/sal/inc/rtl/stringconcat.hxx b/sal/inc/rtl/stringconcat.hxx
index fddf6ed..9fb9568 100644
--- a/sal/inc/rtl/stringconcat.hxx
+++ b/sal/inc/rtl/stringconcat.hxx
@@ -128,7 +128,7 @@ struct ToStringHelper< char[ N ] >
 template< int N >
 struct ToStringHelper< const char[ N ] >
     {
-    static int length( const char[ N ] ) { return N - 1; }
+    static int length( const char str[ N ] ) { assert( strlen( str ) == N - 1 ); return N - 1; }
     static char* addData( char* buffer, const char str[ N ] ) { return addDataHelper( buffer, str, N - 1 ); }
     static sal_Unicode* addData( sal_Unicode* buffer, const char str[ N ] ) { return addDataLiteral( buffer, str, N - 1 ); }
     static const bool allowOStringConcat = true;
diff --git a/sal/inc/rtl/stringutils.hxx b/sal/inc/rtl/stringutils.hxx
index b1e19e5..c6e44b6 100644
--- a/sal/inc/rtl/stringutils.hxx
+++ b/sal/inc/rtl/stringutils.hxx
@@ -124,7 +124,7 @@ struct NonConstCharArrayDetector< const char[], T >
 };
 #endif
 
-template< typename T1, typename T2 >
+template< typename T1, typename T2 = void >
 struct ConstCharArrayDetector
 {
     static const bool ok = false;
diff --git a/sal/inc/rtl/ustrbuf.hxx b/sal/inc/rtl/ustrbuf.hxx
index 7d36356..06d906e 100644
--- a/sal/inc/rtl/ustrbuf.hxx
+++ b/sal/inc/rtl/ustrbuf.hxx
@@ -150,6 +150,7 @@ public:
         : pData(NULL)
         , nCapacity( N - 1 + 16 )
     {
+        assert( strlen( literal ) == N - 1 );
         rtl_uString_newFromLiteral( &pData, literal, N - 1, 16 );
 #ifdef RTL_STRING_UNITTEST
         rtl_string_unittest_const_literal = true;
@@ -179,6 +180,7 @@ public:
         : pData(NULL)
         , nCapacity( internal::ConstCharArrayDetector< T, void >::size - 1 + 16 )
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 16 );
 #ifdef RTL_STRING_UNITTEST
         rtl_string_unittest_const_literal = true;
@@ -480,6 +482,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type append( T& literal )
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), literal,
             internal::ConstCharArrayDetector< T, void >::size - 1 );
         return *this;
@@ -740,6 +743,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type insert( sal_Int32 offset, T& literal )
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, offset, literal,
             internal::ConstCharArrayDetector< T, void >::size - 1 );
         return *this;
@@ -1097,6 +1101,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength(
             pData->buffer + fromIndex, pData->length - fromIndex, literal,
             internal::ConstCharArrayDetector< T, void >::size - 1);
@@ -1159,6 +1164,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const SAL_THROW(())
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return rtl_ustr_lastIndexOfAscii_WithLength(
             pData->buffer, pData->length, literal, internal::ConstCharArrayDetector< T, void >::size - 1);
     }
diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx
index ec7c290..534bd88 100644
--- a/sal/inc/rtl/ustring.hxx
+++ b/sal/inc/rtl/ustring.hxx
@@ -198,6 +198,9 @@ public:
     template< int N >
     OUString( const char (&literal)[ N ] )
     {
+        // Check that the string literal is in fact N - 1 long (no embedded \0's),
+        // any decent compiler should optimize out calls to strlen with literals.
+        assert( strlen( literal ) == N - 1 );
         pData = 0;
         rtl_uString_newFromLiteral( &pData, literal, N - 1, 0 );
 #ifdef RTL_STRING_UNITTEST
@@ -225,6 +228,7 @@ public:
     template< typename T >
     OUString( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy() )
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         pData = 0;
         rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 0 );
 #ifdef RTL_STRING_UNITTEST
@@ -381,6 +385,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, OUString& >::Type operator=( T& literal )
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 0 );
         return *this;
     }
@@ -571,6 +576,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& literal ) const SAL_THROW(())
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         if ( pData->length != internal::ConstCharArrayDetector< T, void >::size - 1 )
             return sal_False;
 
@@ -606,6 +612,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, bool >::Type match( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
             literal, internal::ConstCharArrayDetector< T, void >::size - 1 ) == 0;
     }
@@ -643,6 +650,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
             literal, internal::ConstCharArrayDetector< T, void >::size - 1 ) == 0;
     }
@@ -933,6 +941,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, bool >::Type startsWith( T& literal ) const
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length
             && rtl_ustr_asciil_reverseEquals_WithLength( pData->buffer, literal,
                 internal::ConstCharArrayDetector< T, void >::size - 1);
@@ -964,6 +973,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, bool >::Type startsWithIgnoreAsciiCase( T& literal ) const SAL_THROW(())
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
                     pData->buffer,
                     internal::ConstCharArrayDetector< T, void >::size - 1, literal,
@@ -994,6 +1004,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, bool >::Type endsWith( T& literal ) const
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length
             && rtl_ustr_asciil_reverseEquals_WithLength(
                 pData->buffer + pData->length - ( internal::ConstCharArrayDetector< T, void >::size - 1 ), literal,
@@ -1047,6 +1058,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, bool >::Type endsWithIgnoreAsciiCase( T& literal ) const SAL_THROW(())
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length
             && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
                     pData->buffer + pData->length - ( internal::ConstCharArrayDetector< T, void >::size - 1 ),
@@ -1108,6 +1120,7 @@ public:
     template< typename T >
     friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator==( const OUString& string, T& literal )
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
     }
     /**
@@ -1120,6 +1133,7 @@ public:
     template< typename T >
     friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OUString& string )
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
     }
     /**
@@ -1132,6 +1146,7 @@ public:
     template< typename T >
     friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OUString& string, T& literal )
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return !string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
     }
     /**
@@ -1144,6 +1159,7 @@ public:
     template< typename T >
     friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OUString& string )
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return !string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
     }
 
@@ -1239,6 +1255,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength(
             pData->buffer + fromIndex, pData->length - fromIndex, literal,
             internal::ConstCharArrayDetector< T, void >::size - 1);
@@ -1337,6 +1354,7 @@ public:
     template< typename T >
     typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const SAL_THROW(())
     {
+        assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
         return rtl_ustr_lastIndexOfAscii_WithLength(
             pData->buffer, pData->length, literal, internal::ConstCharArrayDetector< T, void >::size - 1);
     }
@@ -1517,6 +1535,7 @@ public:
     {
         rtl_uString * s = 0;
         sal_Int32 i = 0;
+        assert( strlen( from ) == internal::ConstCharArrayDetector< T >::size - 1 );
         rtl_uString_newReplaceFirstAsciiL(
             &s, pData, from, internal::ConstCharArrayDetector< T, void >::size - 1, to.pData, index == 0 ? &i : index);
         return OUString(s, SAL_NO_ACQUIRE);
@@ -1546,6 +1565,8 @@ public:
     {
         rtl_uString * s = 0;
         sal_Int32 i = 0;
+        assert( strlen( from ) == internal::ConstCharArrayDetector< T1 >::size - 1 );
+        assert( strlen( to ) == internal::ConstCharArrayDetector< T2 >::size - 1 );
         rtl_uString_newReplaceFirstAsciiLAsciiL(
             &s, pData, from, internal::ConstCharArrayDetector< T1, void >::size - 1, to,
             internal::ConstCharArrayDetector< T2, void >::size - 1, index == 0 ? &i : index);
@@ -1590,6 +1611,7 @@ public:
     typename internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( T& from, OUString const & to) const
     {
         rtl_uString * s = 0;
+        assert( strlen( from ) == internal::ConstCharArrayDetector< T >::size - 1 );
         rtl_uString_newReplaceAllAsciiL(&s, pData, from, internal::ConstCharArrayDetector< T, void >::size - 1, to.pData);
         return OUString(s, SAL_NO_ACQUIRE);
     }
@@ -1612,6 +1634,8 @@ public:
         replaceAll( T1& from, T2& to ) const
     {
         rtl_uString * s = 0;
+        assert( strlen( from ) == internal::ConstCharArrayDetector< T1 >::size - 1 );
+        assert( strlen( to ) == internal::ConstCharArrayDetector< T2 >::size - 1 );
         rtl_uString_newReplaceAllAsciiLAsciiL(
             &s, pData, from, internal::ConstCharArrayDetector< T1, void >::size - 1,
             to, internal::ConstCharArrayDetector< T2, void >::size - 1);
@@ -2094,7 +2118,7 @@ This class is not part of public API and is meant to be used only in LibreOffice
 struct SAL_WARN_UNUSED OUStringLiteral
 {
     template< int N >
-    OUStringLiteral( const char (&str)[ N ] ) : size( N - 1 ), data( str ) {}
+    OUStringLiteral( const char (&str)[ N ] ) : size( N - 1 ), data( str ) { assert( strlen( str ) == N - 1 ); }
     int size;
     const char* data;
 };
diff --git a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
index 8a78b89..9276e99 100644
--- a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
+++ b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
@@ -114,10 +114,10 @@ void test::ostring::StringLiterals::checkCtors()
 #endif
 
 // This one is technically broken, since the first element is 6 characters test\0\0,
-// but there does not appear a way to detect this by compile time (runtime will complain).
+// but there does not appear a way to detect this by compile time (runtime will assert()).
 // RTL_CONSTASCII_USTRINGPARAM() has the same flaw.
     const char bad7[][ 6 ] = { "test", "test2" };
-    CPPUNIT_ASSERT( CONST_CTOR_USED( bad7[ 0 ] ));
+//    CPPUNIT_ASSERT( CONST_CTOR_USED( bad7[ 0 ] ));
     CPPUNIT_ASSERT( CONST_CTOR_USED( bad7[ 1 ] ));
 
 // Check that contents are correct and equal to the case when const char* ctor is used.
diff --git a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
index 8d82543..a6d7145 100644
--- a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
+++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
@@ -89,18 +89,21 @@ void test::oustring::StringLiterals::checkCtors()
     testcall( good1 );
 
 // This one is technically broken, since the first element is 6 characters test\0\0,
-// but there does not appear a way to detect this by compile time (runtime will complain).
+// but there does not appear a way to detect this by compile time (runtime will assert()).
 // RTL_CONSTASCII_USTRINGPARAM() has the same flaw.
     const char bad5[][ 6 ] = { "test", "test2" };
 //    CPPUNIT_ASSERT( VALID_CONVERSION( bad5[ 0 ] ));
     CPPUNIT_ASSERT( VALID_CONVERSION( bad5[ 1 ] ));
 
 // Check that contents are correct and equal to the case when RTL_CONSTASCII_USTRINGPARAM is used.
-// Also check that embedded \0 is included.
     CPPUNIT_ASSERT_EQUAL( rtl::OUString( "" ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "" )));
-    CPPUNIT_ASSERT_EQUAL( rtl::OUString( "\0" ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\0" )));
     CPPUNIT_ASSERT_EQUAL( rtl::OUString( "ab" ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ab" )));
+#if 0
+// Also check that embedded \0 is included.
+// In fact, allowing this is probably just trouble, so this now asserts.
+    CPPUNIT_ASSERT_EQUAL( rtl::OUString( "\0" ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\0" )));
     CPPUNIT_ASSERT_EQUAL( rtl::OUString( "a\0b" ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "a\0b" )));
+#endif
 }
 
 void test::oustring::StringLiterals::testcall( const char str[] )
commit 084a2c52c27a095bf32815512340b485c5b05eaf
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Mon Dec 3 14:54:39 2012 +0100

    make sure fast string operator+ is used only by LO code
    
    Change-Id: Iaa8fc379e4d032931c0f60a3e3525783d8d28964

diff --git a/sal/inc/rtl/stringutils.hxx b/sal/inc/rtl/stringutils.hxx
index f0ad4f8..b1e19e5 100644
--- a/sal/inc/rtl/stringutils.hxx
+++ b/sal/inc/rtl/stringutils.hxx
@@ -35,11 +35,13 @@
 // (e.g. for debugging).
 #ifndef RTL_DISABLE_FAST_STRING
 #ifndef HAVE_SFINAE_ANONYMOUS_BROKEN
-// Enable fast string concatenation.
 // This feature is not part of public API and is meant to be used only internally by LibreOffice.
+#ifdef LIBO_INTERNAL_ONLY
+// Enable fast string concatenation.
 #define RTL_FAST_STRING
 #endif
 #endif
+#endif
 
 // The unittest uses slightly different code to help check that the proper
 // calls are made. The class is put into a different namespace to make
diff --git a/solenv/gbuild/gbuild.mk b/solenv/gbuild/gbuild.mk
index 23b580a..d0440b4 100644
--- a/solenv/gbuild/gbuild.mk
+++ b/solenv/gbuild/gbuild.mk
@@ -197,9 +197,10 @@ gb_GLOBALDEFS := \
 	$(gb_COMPILERDEFS) \
 	$(gb_CPUDEFS) \
 
-# This is used to tag deprecation for API we want to
+# This is used to detect whether LibreOffice is being built (as opposed to building
+# 3rd-party code). Used for tag deprecation for API we want to
 # ensure is not used at all externally while we clean
-# out our internal usage.
+# out our internal usage, for code in sal/ that should be used only internally, etc.
 gb_GLOBALDEFS += \
 	-DLIBO_INTERNAL_ONLY \
 
commit ce90f99a2d66c2b998ad3f9f028e2ea623a757f5
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Sun Dec 2 22:35:57 2012 +0100

    fixes for where fast string operator+ is not perfectly source compatible
    
    Change-Id: I80af0399037e4f68113338139e7f2ad2400e65ab

diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx
index 6eb90ae..a00d529 100644
--- a/chart2/source/controller/main/ChartController.cxx
+++ b/chart2/source/controller/main/ChartController.cxx
@@ -249,7 +249,7 @@ void ChartController::TheModel::tryTermination()
     catch(const uno::Exception& ex)
     {
         (void)(ex); // no warning in non-debug builds
-        OSL_FAIL( ( OString("Termination of model failed: ")
+        OSL_FAIL( OString( OString("Termination of model failed: ")
             + OUStringToOString( ex.Message, RTL_TEXTENCODING_ASCII_US ) ).getStr() );
     }
 }
diff --git a/cppuhelper/source/bootstrap.cxx b/cppuhelper/source/bootstrap.cxx
index 87e58de..2728890 100644
--- a/cppuhelper/source/bootstrap.cxx
+++ b/cppuhelper/source/bootstrap.cxx
@@ -180,7 +180,7 @@ Reference< XComponentContext > SAL_CALL bootstrap()
         // start office process
         oslProcess hProcess = 0;
         oslProcessError rc = osl_executeProcess(
-            (path + OUSTR("soffice")).pData, ar_args, ARLEN( ar_args ),
+            OUString(path + "soffice").pData, ar_args, ARLEN( ar_args ),
             osl_Process_DETACHED,
             sec.getHandle(),
             0, // => current working dir
diff --git a/cui/source/dialogs/scriptdlg.cxx b/cui/source/dialogs/scriptdlg.cxx
index 3505102..f149a59 100644
--- a/cui/source/dialogs/scriptdlg.cxx
+++ b/cui/source/dialogs/scriptdlg.cxx
@@ -914,7 +914,7 @@ void SvxScriptOrgDialog::createEntry( SvTreeListEntry* pEntry )
             }
             for( sal_Int32 index = 0; index < childNodes.getLength(); index++ )
             {
-                if ( (aNewName+extn).equals( childNodes[index]->getName() ) )
+                if ( (aNewName+extn) == childNodes[index]->getName() )
                 {
                     bFound = sal_True;
                     break;
@@ -943,7 +943,7 @@ void SvxScriptOrgDialog::createEntry( SvTreeListEntry* pEntry )
                 bValid = sal_True;
                 for( sal_Int32 index = 0; index < childNodes.getLength(); index++ )
                 {
-                    if ( (aUserSuppliedName+extn).equals( childNodes[index]->getName() ) )
+                    if ( (aUserSuppliedName+extn) == childNodes[index]->getName() )
                     {
                         bValid = sal_False;
                         String aError( m_createErrStr );
diff --git a/extensions/source/update/check/updatecheckconfig.cxx b/extensions/source/update/check/updatecheckconfig.cxx
index c569c71..9ad538b 100644
--- a/extensions/source/update/check/updatecheckconfig.cxx
+++ b/extensions/source/update/check/updatecheckconfig.cxx
@@ -176,7 +176,7 @@ UpdateCheckROModel::getUpdateEntry(UpdateInfo& rInfo) const
     for(sal_Int32 n=1; n < 6; ++n )
     {
         rtl::OUString aUStr = getStringValue(
-            (aStr + rtl::OString::valueOf(n)).getStr());
+            OString(aStr + rtl::OString::valueOf(n)).getStr());
         if( !aUStr.isEmpty() )
             rInfo.ReleaseNotes.push_back(ReleaseNote((sal_Int8) n, aUStr));
     }
diff --git a/extensions/source/update/check/updatehdl.cxx b/extensions/source/update/check/updatehdl.cxx
index 67e1589..ff04abc 100644
--- a/extensions/source/update/check/updatehdl.cxx
+++ b/extensions/source/update/check/updatehdl.cxx
@@ -152,7 +152,7 @@ void UpdateHandler::setDownloadBtnLabel( bool bAppendDots )
             aLabel += UNISTRING( "..." );
 
         setControlProperty( msButtonIDs[DOWNLOAD_BUTTON], UNISTRING("Label"), uno::Any( aLabel ) );
-        setControlProperty( msButtonIDs[DOWNLOAD_BUTTON], UNISTRING("HelpURL"), uno::Any( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_DOWNLOAD2 ) ) );
+        setControlProperty( msButtonIDs[DOWNLOAD_BUTTON], UNISTRING("HelpURL"), uno::makeAny( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_DOWNLOAD2 ) ) );
 
         mbDownloadBtnHasDots = bAppendDots;
     }
@@ -1116,7 +1116,7 @@ void UpdateHandler::createDialog()
         xPropSet->setPropertyValue( UNISTRING("PositionY"), uno::Any(sal_Int32( 100 )) );
         xPropSet->setPropertyValue( UNISTRING("Width"), uno::Any(sal_Int32( DIALOG_WIDTH )) );
         xPropSet->setPropertyValue( UNISTRING("Height"), uno::Any(sal_Int32( DIALOG_HEIGHT )) );
-        xPropSet->setPropertyValue( UNISTRING("HelpURL"), uno::Any( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_DLG ) ) );
+        xPropSet->setPropertyValue( UNISTRING("HelpURL"), uno::makeAny( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_DLG ) ) );
     }
     {   // Label (fixed text) <status>
         uno::Sequence< beans::NamedValue > aProps(1);
@@ -1143,7 +1143,7 @@ void UpdateHandler::createDialog()
         setProperty( aProps, 3, UNISTRING("MultiLine"), uno::Any( true ) );
         setProperty( aProps, 4, UNISTRING("ReadOnly"), uno::Any( true ) );
         setProperty( aProps, 5, UNISTRING("AutoVScroll"), uno::Any( true ) );
-        setProperty( aProps, 6, UNISTRING("HelpURL"), uno::Any( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_STATUS ) ) );
+        setProperty( aProps, 6, UNISTRING("HelpURL"), uno::makeAny( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_STATUS ) ) );
 
         insertControlModel( xControlModel, EDIT_FIELD_MODEL, TEXT_STATUS,
                             awt::Rectangle( DIALOG_BORDER + TEXT_OFFSET,
@@ -1174,7 +1174,7 @@ void UpdateHandler::createDialog()
         setProperty( aProps, 1, UNISTRING("Enabled"), uno::Any( true ) );
         setProperty( aProps, 2, UNISTRING("PushButtonType"), uno::Any( sal_Int16(awt::PushButtonType_STANDARD) ) );
         setProperty( aProps, 3, UNISTRING("Label"), uno::Any( msPauseBtn ) );
-        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::Any( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_PAUSE ) ) );
+        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::makeAny( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_PAUSE ) ) );
 
         insertControlModel ( xControlModel, BUTTON_MODEL, msButtonIDs[PAUSE_BUTTON],
                              awt::Rectangle( BOX1_BTN_X, BOX1_BTN_Y, BUTTON_WIDTH, BUTTON_HEIGHT ),
@@ -1187,7 +1187,7 @@ void UpdateHandler::createDialog()
         setProperty( aProps, 1, UNISTRING("Enabled"), uno::Any( true ) );
         setProperty( aProps, 2, UNISTRING("PushButtonType"), uno::Any( sal_Int16(awt::PushButtonType_STANDARD) ) );
         setProperty( aProps, 3, UNISTRING("Label"), uno::Any( msResumeBtn ) );
-        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::Any( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_RESUME ) ) );
+        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::makeAny( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_RESUME ) ) );
 
         insertControlModel ( xControlModel, BUTTON_MODEL, msButtonIDs[RESUME_BUTTON],
                              awt::Rectangle( BOX1_BTN_X,
@@ -1203,7 +1203,7 @@ void UpdateHandler::createDialog()
         setProperty( aProps, 1, UNISTRING("Enabled"), uno::Any( true ) );
         setProperty( aProps, 2, UNISTRING("PushButtonType"), uno::Any( sal_Int16(awt::PushButtonType_STANDARD) ) );
         setProperty( aProps, 3, UNISTRING("Label"), uno::Any( msCancelBtn ) );
-        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::Any( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_CANCEL ) ) );
+        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::makeAny( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_CANCEL ) ) );
 
         insertControlModel ( xControlModel, BUTTON_MODEL, msButtonIDs[CANCEL_BUTTON],
                              awt::Rectangle( BOX1_BTN_X,
@@ -1237,7 +1237,7 @@ void UpdateHandler::createDialog()
         setProperty( aProps, 3, UNISTRING("MultiLine"), uno::Any( true ) );
         setProperty( aProps, 4, UNISTRING("ReadOnly"), uno::Any( true ) );
         setProperty( aProps, 5, UNISTRING("AutoVScroll"), uno::Any( true ) );
-        setProperty( aProps, 6, UNISTRING("HelpURL"), uno::Any( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_DESCRIPTION ) ) );
+        setProperty( aProps, 6, UNISTRING("HelpURL"), uno::makeAny( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_DESCRIPTION ) ) );
 
         insertControlModel( xControlModel, EDIT_FIELD_MODEL, TEXT_DESCRIPTION,
                             awt::Rectangle( DIALOG_BORDER + TEXT_OFFSET,
@@ -1267,7 +1267,7 @@ void UpdateHandler::createDialog()
         // setProperty( aProps, 2, UNISTRING("PushButtonType"), uno::Any( sal_Int16(awt::PushButtonType_CANCEL) ) );
         // [property] string Label // only if PushButtonType_STANDARD
         setProperty( aProps, 3, UNISTRING("Label"), uno::Any( msClose ) );
-        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::Any( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_CLOSE ) ) );
+        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::makeAny( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_CLOSE ) ) );
 
         insertControlModel ( xControlModel, BUTTON_MODEL, msButtonIDs[ CLOSE_BUTTON ],
                              awt::Rectangle( CLOSE_BTN_X, BUTTON_Y_POS, BUTTON_WIDTH, BUTTON_HEIGHT ),
@@ -1280,7 +1280,7 @@ void UpdateHandler::createDialog()
         setProperty( aProps, 1, UNISTRING("Enabled"), uno::Any( true ) );
         setProperty( aProps, 2, UNISTRING("PushButtonType"), uno::Any( sal_Int16(awt::PushButtonType_STANDARD) ) );
         setProperty( aProps, 3, UNISTRING("Label"), uno::Any( msInstall ) );
-        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::Any( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_INSTALL ) ) );
+        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::makeAny( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_INSTALL ) ) );
 
         insertControlModel ( xControlModel, BUTTON_MODEL, msButtonIDs[INSTALL_BUTTON],
                              awt::Rectangle( INSTALL_BTN_X, BUTTON_Y_POS, BUTTON_WIDTH, BUTTON_HEIGHT ),
@@ -1293,7 +1293,7 @@ void UpdateHandler::createDialog()
         setProperty( aProps, 1, UNISTRING("Enabled"), uno::Any( true ) );
         setProperty( aProps, 2, UNISTRING("PushButtonType"), uno::Any( sal_Int16(awt::PushButtonType_STANDARD) ) );
         setProperty( aProps, 3, UNISTRING("Label"), uno::Any( msDownload ) );
-        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::Any( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_DOWNLOAD ) ) );
+        setProperty( aProps, 4, UNISTRING("HelpURL"), uno::makeAny( UNISTRING( INET_HID_SCHEME ) + rtl::OUString::createFromAscii( HID_CHECK_FOR_UPD_DOWNLOAD ) ) );
 
         insertControlModel ( xControlModel, BUTTON_MODEL, msButtonIDs[DOWNLOAD_BUTTON],
                              awt::Rectangle( DOWNLOAD_BTN_X, BUTTON_Y_POS, BUTTON_WIDTH, BUTTON_HEIGHT ),
diff --git a/i18npool/source/collator/collator_unicode.cxx b/i18npool/source/collator/collator_unicode.cxx
index c705ee9..2ba089a 100644
--- a/i18npool/source/collator/collator_unicode.cxx
+++ b/i18npool/source/collator/collator_unicode.cxx
@@ -131,9 +131,9 @@ Collator_Unicode::loadCollatorAlgorithm(const OUString& rAlgorithm, const lang::
                     OUString func_base = aBuf.makeStringAndClear();
                     if (OUString("TW HK MO").indexOf(rLocale.Country) >= 0)
                         func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule,
-                                    (func_base + OUString("TW_") + rAlgorithm).pData);
+                                    OUString(func_base + "TW_" + rAlgorithm).pData);
                     if (!func)
-                        func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule, (func_base + rAlgorithm).pData);
+                        func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule, OUString(func_base + rAlgorithm).pData);
                 } else {
                     if ( rLocale.Language == "ja" ) {
                         // replace algrithm name to implementation name.
diff --git a/i18npool/source/indexentry/indexentrysupplier_asian.cxx b/i18npool/source/indexentry/indexentrysupplier_asian.cxx
index f77bc7d..4df4d24 100644
--- a/i18npool/source/indexentry/indexentrysupplier_asian.cxx
+++ b/i18npool/source/indexentry/indexentrysupplier_asian.cxx
@@ -88,9 +88,9 @@ IndexEntrySupplier_asian::getIndexCharacter( const OUString& rIndexEntry,
     if (hModule) {
         OUString get("get_indexdata_");
         if ( rLocale.Language == "zh" && OUString( "TW HK MO" ).indexOf(rLocale.Country) >= 0 )
-            func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString("_TW_")+rAlgorithm).pData);
+            func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, OUString(get+rLocale.Language+"_TW_"+rAlgorithm).pData);
         if (!func)
-            func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString('_')+rAlgorithm).pData);
+            func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, OUString(get+rLocale.Language+OUString('_')+rAlgorithm).pData);
     }
 #else
     if ( rLocale.Language == "zh" && OUString( "TW HK MO" ).indexOf(rLocale.Country) >= 0 ) {
diff --git a/l10ntools/source/po.cxx b/l10ntools/source/po.cxx
index d767db3..c59a4f8 100644
--- a/l10ntools/source/po.cxx
+++ b/l10ntools/source/po.cxx
@@ -420,7 +420,7 @@ PoEntry::PoEntry(const OString& rSDFLine, const TYPE eType)
 
     OString sMsgCtxt =
         vParts[GROUPID] + "\n" +
-        (vParts[LOCALID].isEmpty() ? "" : vParts[LOCALID] + "\n") +
+        (vParts[LOCALID].isEmpty() ? OString( "" ) : vParts[LOCALID] + "\n") +
         vParts[RESOURCETYPE];
     switch(eType){
     case TTEXT:
@@ -433,7 +433,7 @@ PoEntry::PoEntry(const OString& rSDFLine, const TYPE eType)
       only three element*/
     }
     m_pGenPo->setExtractCom(
-        ( !vParts[HELPTEXT].isEmpty() ?  vParts[HELPTEXT] + "\n" : "" ) +
+        ( !vParts[HELPTEXT].isEmpty() ?  vParts[HELPTEXT] + "\n" : OString( "" )) +
         lcl_GenKeyId(
             vParts[SOURCEFILE] + sMsgCtxt + vParts[eType] ) );
     m_pGenPo->setMsgCtxt(sMsgCtxt);
@@ -827,7 +827,7 @@ void PoIfstream::readEntry( PoEntry& rPoEntry )
                     sExtractCom.indexOf("\n") == -1 ) )
             {
                 aGenPo.setExtractCom(
-                    ( !sExtractCom.isEmpty() ? sExtractCom + "\n" : "" ) +
+                    ( !sExtractCom.isEmpty() ? sExtractCom + "\n" : OString( "" )) +
                     lcl_GenKeyId(
                         aGenPo.getReference() + sMsgCtxt +
                         aGenPo.getMsgId() ) );
diff --git a/l10ntools/source/propmerge.cxx b/l10ntools/source/propmerge.cxx
index 79c737e..3bd44fb 100644
--- a/l10ntools/source/propmerge.cxx
+++ b/l10ntools/source/propmerge.cxx
@@ -210,7 +210,7 @@ void PropParser::Merge( const OString &rMergeSrc, const OString &rDestinationFil
             {
                 OString sNewText;
                 pEntrys->GetText( sNewText, STRING_TYP_TEXT, m_sLang );
-                aDestination << (sID + OString("=")).getStr();
+                aDestination << OString(sID + "=").getStr();
                 lcl_PrintJavaStyle( sNewText, aDestination );
                 aDestination << std::endl;
             }
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index ae9f1b3..bc48e60 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1349,8 +1349,8 @@ void DrawingML::WritePresetShape( const char* pShape, MSO_SPT eShapeType, sal_Bo
         for( sal_Int32 i=0; i < nLength; i++ )
             if( EscherPropertyContainer::GetAdjustmentValue( aAdjustmentSeq[ i ], i, nAdjustmentsWhichNeedsToBeConverted, nValue ) )
                 mpFS->singleElementNS( XML_a, XML_gd,
-                                       XML_name, aAdjustmentSeq[ i ].Name.getLength() > 0 ? USS(aAdjustmentSeq[ i ].Name) : (nLength > 1 ? ( OString( "adj" ) + OString::valueOf( i + 1 ) ).getStr() : "adj"),
-                                       XML_fmla, (OString("val ") + OString::valueOf( nValue )).getStr(),
+                                       XML_name, aAdjustmentSeq[ i ].Name.getLength() > 0 ? USS(aAdjustmentSeq[ i ].Name) : (nLength > 1 ? OString( "adj" + OString::valueOf( i + 1 ) ).getStr() : "adj"),
+                                       XML_fmla, OString("val " + OString::valueOf( nValue )).getStr(),
                                        FSEND );
     }
 
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 191f27f..87b8e55 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -112,7 +112,7 @@ using ::rtl::OUString;
 using ::rtl::OUStringBuffer;
 using ::sax_fastparser::FSHelperPtr;
 
-#define IDS(x) (OString(#x " ") + OString::valueOf( mnShapeIdMax++ )).getStr()
+#define IDS(x) OString(OStringLiteral(#x " ") + OString::valueOf( mnShapeIdMax++ )).getStr()
 
 struct CustomShapeTypeTranslationTable
 {
@@ -859,7 +859,7 @@ void ShapeExport::WriteGraphicObjectShapePart( Reference< XShape > xShape, Graph
 
     pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
                           XML_id,     I32S( GetNewShapeID( xShape ) ),
-                          XML_name,   bHaveName ? USS( sName ) : (OString("Picture ") + OString::valueOf( mnPictureIdMax++ )).getStr(),
+                          XML_name,   bHaveName ? USS( sName ) : OString( "Picture " + OString::valueOf( mnPictureIdMax++ )).getStr(),
                           XML_descr,  bHaveDesc ? USS( sDescr ) : NULL,
                           FSEND );
     // OOXTODO: //cNvPr children: XML_extLst, XML_hlinkClick, XML_hlinkHover
diff --git a/oox/source/ppt/presentationfragmenthandler.cxx b/oox/source/ppt/presentationfragmenthandler.cxx
index 5973885..4ae067c 100644
--- a/oox/source/ppt/presentationfragmenthandler.cxx
+++ b/oox/source/ppt/presentationfragmenthandler.cxx
@@ -286,7 +286,7 @@ void PresentationFragmentHandler::finalizeImport()
     }
     catch( uno::Exception& )
     {
-        OSL_FAIL( (rtl::OString("oox::ppt::PresentationFragmentHandler::EndDocument(), "
+        OSL_FAIL( OString(rtl::OString("oox::ppt::PresentationFragmentHandler::EndDocument(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
diff --git a/oox/source/ppt/slidefragmenthandler.cxx b/oox/source/ppt/slidefragmenthandler.cxx
index 789821b..a59f2e1 100644
--- a/oox/source/ppt/slidefragmenthandler.cxx
+++ b/oox/source/ppt/slidefragmenthandler.cxx
@@ -214,7 +214,7 @@ void SlideFragmentHandler::finalizeImport()
     }
     catch( uno::Exception& )
     {
-        OSL_FAIL( (rtl::OString("oox::ppt::SlideFragmentHandler::EndElement(), "
+        OSL_FAIL( OString(rtl::OString("oox::ppt::SlideFragmentHandler::EndElement(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
diff --git a/sal/inc/sal/log-areas.dox b/sal/inc/sal/log-areas.dox
index a474a2b..c167267 100644
--- a/sal/inc/sal/log-areas.dox
+++ b/sal/inc/sal/log-areas.dox
@@ -64,6 +64,7 @@ certain functionality.
 @li @c sd.sls
 @li @c sd.tools
 @li @c sd.view
+ at li @c sd.slideshow
 @li @c sdremote
 @li @c sdremote.bluetooth
 
diff --git a/sc/source/ui/vba/vbaname.cxx b/sc/source/ui/vba/vbaname.cxx
index 4c5f5f5..484eba3 100644
--- a/sc/source/ui/vba/vbaname.cxx
+++ b/sc/source/ui/vba/vbaname.cxx
@@ -120,7 +120,7 @@ ScVbaName::getValue() throw (css::uno::RuntimeException)
         if ( sTmpValue.toChar() == '$' )
         {
             ::rtl::OUString sTmp = sTmpValue.copy( 1 );
-            sTmp = sTmp.replaceAt(0, (sSheetName + ::rtl::OUString::createFromAscii(".")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("!"));
+            sTmp = sTmp.replaceAt(0, OUString(sSheetName + ::rtl::OUString::createFromAscii(".")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("!"));
             sResult += sTmp;
             sResult += sNewSegmentation;
         }
@@ -131,7 +131,7 @@ ScVbaName::getValue() throw (css::uno::RuntimeException)
     if ( sTmpValue.toChar() == '$' )
     {
         ::rtl::OUString sTmp = sTmpValue.copy(1);
-        sTmp = sTmp.replaceAt(0, (sSheetName + ::rtl::OUString::createFromAscii(".")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("!"));
+        sTmp = sTmp.replaceAt(0, OUString(sSheetName + ::rtl::OUString::createFromAscii(".")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("!"));
         sResult += sTmp;
     }
     if (sResult.indexOf('=') != 0)
@@ -160,7 +160,7 @@ ScVbaName::setValue( const ::rtl::OUString & rValue ) throw (css::uno::RuntimeEx
     while ( nTo != -1 )
     {
         ::rtl::OUString sTmpValue = sValue.copy( nFrom, nTo - nFrom );
-        sTmpValue = sTmpValue.replaceAt(0, (sSheetName + ::rtl::OUString::createFromAscii("!")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("."));
+        sTmpValue = sTmpValue.replaceAt(0, OUString(sSheetName + ::rtl::OUString::createFromAscii("!")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("."));
         if (sTmpValue.copy(0, sSheetName.getLength()).equals(sSheetName))
         {
             sTmpValue = ::rtl::OUString::createFromAscii("$") + sTmpValue;
@@ -171,7 +171,7 @@ ScVbaName::setValue( const ::rtl::OUString & rValue ) throw (css::uno::RuntimeEx
         nTo = sValue.indexOf( sSegmentation, nFrom );
     }
     ::rtl::OUString sTmpValue = sValue.copy( nFrom );
-    sTmpValue = sTmpValue.replaceAt(0, (sSheetName + ::rtl::OUString::createFromAscii("!")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("."));
+    sTmpValue = sTmpValue.replaceAt(0, OUString(sSheetName + ::rtl::OUString::createFromAscii("!")).getLength(), sSheetName + ::rtl::OUString::createFromAscii("."));
     if (sTmpValue.copy(0, sSheetName.getLength()).equals(sSheetName))
     {
         sTmpValue = ::rtl::OUString::createFromAscii("$") + sTmpValue;
diff --git a/sd/source/core/CustomAnimationCloner.cxx b/sd/source/core/CustomAnimationCloner.cxx
index aacdc1a..3ea6f70 100644
--- a/sd/source/core/CustomAnimationCloner.cxx
+++ b/sd/source/core/CustomAnimationCloner.cxx
@@ -129,7 +129,7 @@ namespace sd
         catch( Exception& )
         {
             OSL_FAIL(
-                (OString("sd::CustomAnimationClonerImpl::Clone(), "
+                OString(OString("sd::CustomAnimationClonerImpl::Clone(), "
                         "exception caught: ") +
                 rtl::OUStringToOString(
                     comphelper::anyToString( cppu::getCaughtException() ),
@@ -213,7 +213,7 @@ namespace sd
         catch( Exception& )
         {
             OSL_FAIL(
-                (OString("sd::CustomAnimationClonerImpl::transformNode(), "
+                OString(OString("sd::CustomAnimationClonerImpl::transformNode(), "
                         "exception caught: ") +
                 rtl::OUStringToOString(
                     comphelper::anyToString( cppu::getCaughtException() ),
@@ -287,7 +287,7 @@ namespace sd
         catch( Exception& )
         {
             OSL_FAIL(
-                (OString("sd::CustomAnimationClonerImpl::transformValue(), "
+                OString(OString("sd::CustomAnimationClonerImpl::transformValue(), "
                         "exception caught: ") +
                 rtl::OUStringToOString(
                     comphelper::anyToString( cppu::getCaughtException() ),
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx
index c08d80f..873f1d1 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -98,7 +98,7 @@ using ::sax_fastparser::FSHelperPtr;
 
 void dump_pset(Reference< XPropertySet > rXPropSet);
 
-#define IDS(x) (OString(#x " ") + OString::valueOf( mnShapeIdMax++ )).getStr()
+#define IDS(x) OString(OStringLiteral(#x " ") + OString::valueOf( mnShapeIdMax++ )).getStr()
 
 namespace oox {
     using namespace drawingml;
diff --git a/sd/source/filter/html/htmlex.cxx b/sd/source/filter/html/htmlex.cxx
index 785d203..b2d7afa 100644
--- a/sd/source/filter/html/htmlex.cxx
+++ b/sd/source/filter/html/htmlex.cxx
@@ -3100,7 +3100,7 @@ bool HtmlExport::checkFileExists( Reference< ::com::sun::star::ucb::XSimpleFileA
     }
     catch( com::sun::star::uno::Exception& )
     {
-        OSL_FAIL((OString("sd::HtmlExport::checkFileExists(), exception caught: ") +
+        OSL_FAIL(OString(OString("sd::HtmlExport::checkFileExists(), exception caught: ") +
              rtl::OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 )).getStr() );
     }
 
@@ -3162,7 +3162,7 @@ bool HtmlExport::checkForExistingFiles()
     }
     catch( Exception& )
     {
-        OSL_FAIL((OString("sd::HtmlExport::checkForExistingFiles(), exception caught: ") +
+        OSL_FAIL(OString(OString("sd::HtmlExport::checkForExistingFiles(), exception caught: ") +
              rtl::OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 )).getStr() );
         bFound = false;
     }
diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx
index 5c5c10e..8c71842 100644
--- a/sd/source/ui/slideshow/slideshowimpl.cxx
+++ b/sd/source/ui/slideshow/slideshowimpl.cxx
@@ -332,7 +332,7 @@ bool AnimationSlideController::getSlideAPI( sal_Int32 nSlideNumber, Reference< X
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::AnimationSlideController::getSlideAPI(), "
+            OString(OString("sd::AnimationSlideController::getSlideAPI(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -656,7 +656,7 @@ void SAL_CALL SlideshowImpl::disposing()
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::stop(), "
+            OString(OString("sd::SlideshowImpl::stop(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -884,7 +884,7 @@ bool SlideshowImpl::startPreview(
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::startPreview(), "
+            OString(OString("sd::SlideshowImpl::startPreview(), "
                      "exception caught: ") +
              rtl::OUStringToOString(
                  comphelper::anyToString( cppu::getCaughtException() ),
@@ -1127,7 +1127,7 @@ bool SlideshowImpl::startShow( PresentationSettingsEx* pPresSettings )
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::startShow(), "
+            OString(OString("sd::SlideshowImpl::startShow(), "
                      "exception caught: ") +
              rtl::OUStringToOString(
                  comphelper::anyToString( cppu::getCaughtException() ),
@@ -1188,7 +1188,7 @@ bool SlideshowImpl::startShowImpl( const Sequence< beans::PropertyValue >& aProp
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::startShowImpl(), "
+            OString(OString("sd::SlideshowImpl::startShowImpl(), "
                      "exception caught: ") +
              rtl::OUStringToOString(
                  comphelper::anyToString( cppu::getCaughtException() ),
@@ -1226,7 +1226,7 @@ void SlideshowImpl::paint( const Rectangle& /* rRect */ )
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::paint(), "
+            OString(OString("sd::SlideshowImpl::paint(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -1280,7 +1280,7 @@ void SlideshowImpl::removeShapeEvents()
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::removeShapeEvents(), "
+            OString(OString("sd::SlideshowImpl::removeShapeEvents(), "
                      "exception caught: ") +
              rtl::OUStringToOString(
                  comphelper::anyToString( cppu::getCaughtException() ),
@@ -1315,7 +1315,7 @@ void SlideshowImpl::registerShapeEvents(sal_Int32 nSlideNumber)
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::registerShapeEvents(), "
+            OString(OString("sd::SlideshowImpl::registerShapeEvents(), "
                      "exception caught: ") +
              rtl::OUStringToOString(
                  comphelper::anyToString( cppu::getCaughtException() ),
@@ -1393,7 +1393,7 @@ void SlideshowImpl::registerShapeEvents( Reference< XShapes >& xShapes ) throw(
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::registerShapeEvents(), "
+            OString(OString("sd::SlideshowImpl::registerShapeEvents(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -1464,7 +1464,7 @@ void SAL_CALL SlideshowImpl::pause() throw (RuntimeException)
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::pause(), "
+            OString(OString("sd::SlideshowImpl::pause(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -1500,7 +1500,7 @@ void SAL_CALL SlideshowImpl::resume() throw (RuntimeException)
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::resume(), "
+            OString(OString("sd::SlideshowImpl::resume(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -1925,7 +1925,7 @@ sal_Int32 SlideshowImpl::updateSlideShow (void)
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::updateSlideShow(), exception caught: ")
+            OString(OString("sd::SlideshowImpl::updateSlideShow(), exception caught: ")
                 + rtl::OUStringToOString(
                     comphelper::anyToString( cppu::getCaughtException() ),
                     RTL_TEXTENCODING_UTF8 )).getStr() );
@@ -2056,7 +2056,7 @@ bool SlideshowImpl::keyInput(const KeyEvent& rKEvt)
     {
         bRet = false;
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::keyInput(), "
+            OString(OString("sd::SlideshowImpl::keyInput(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -2448,7 +2448,7 @@ Reference< XSlideShow > SlideshowImpl::createSlideShow() const
     catch( uno::Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::createSlideShow(), "
+            OString(OString("sd::SlideshowImpl::createSlideShow(), "
                      "exception caught: ") +
              rtl::OUStringToOString(
                  comphelper::anyToString( cppu::getCaughtException() ),
@@ -2658,7 +2658,7 @@ void SlideshowImpl::resize( const Size& rSize )
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::resize(), "
+            OString(OString("sd::SlideshowImpl::resize(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -3014,7 +3014,7 @@ void SAL_CALL SlideshowImpl::setUsePen( sal_Bool bMouseAsPen ) throw (RuntimeExc
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::setUsePen(), "
+            OString(OString("sd::SlideshowImpl::setUsePen(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -3087,12 +3087,8 @@ void SAL_CALL SlideshowImpl::setEraseAllInk(bool bEraseAllInk) throw (RuntimeExc
         }
         catch( Exception& )
         {
-            OSL_TRACE(
-                (OString("sd::SlideshowImpl::setEraseAllInk(), "
-                        "exception caught: ") +
-                rtl::OUStringToOString(
-                    comphelper::anyToString( cppu::getCaughtException() ),
-                    RTL_TEXTENCODING_UTF8 )).getStr() );
+            SAL_WARN( "sd.slideshow", "sd::SlideshowImpl::setEraseAllInk(), "
+                "exception caught: " << comphelper::anyToString( cppu::getCaughtException() ));
         }
     }
 }
@@ -3308,7 +3304,7 @@ void SlideshowImpl::gotoPreviousSlide (const bool bSkipAllMainSequenceEffects)
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::gotoPreviousSlide(), "
+            OString(OString("sd::SlideshowImpl::gotoPreviousSlide(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -3408,7 +3404,7 @@ void SAL_CALL SlideshowImpl::stopSound(  ) throw (RuntimeException)
     catch( Exception& )
     {
         OSL_FAIL(
-            (OString("sd::SlideshowImpl::stopSound(), "
+            OString(OString("sd::SlideshowImpl::stopSound(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
diff --git a/sd/source/ui/unoidl/DrawController.cxx b/sd/source/ui/unoidl/DrawController.cxx
index 6d39b0b..b7fd00f 100644
--- a/sd/source/ui/unoidl/DrawController.cxx
+++ b/sd/source/ui/unoidl/DrawController.cxx
@@ -515,7 +515,7 @@ void DrawController::FireSwitchCurrentPage (SdPage* pNewCurrentPage) throw()
         catch (const uno::Exception&)
         {
             OSL_FAIL(
-                ("sd::SdUnoDrawView::FireSwitchCurrentPage(), exception caught: " +
+                OString("sd::SdUnoDrawView::FireSwitchCurrentPage(), exception caught: " +
                     ::rtl::OUStringToOString(
                         comphelper::anyToString( cppu::getCaughtException() ),
                         RTL_TEXTENCODING_UTF8 )).getStr() );
diff --git a/sd/source/ui/view/drviews1.cxx b/sd/source/ui/view/drviews1.cxx
index c41aa8d..db12ef4 100644
--- a/sd/source/ui/view/drviews1.cxx
+++ b/sd/source/ui/view/drviews1.cxx
@@ -241,7 +241,7 @@ void DrawViewShell::SelectionHasChanged (void)
     catch( ::com::sun::star::uno::Exception& )
     {
         OSL_FAIL(
-            (rtl::OString("sd::DrawViewShell::SelectionHasChanged(), "
+            OString(rtl::OString("sd::DrawViewShell::SelectionHasChanged(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
diff --git a/sdext/source/presenter/PresenterTheme.cxx b/sdext/source/presenter/PresenterTheme.cxx
index 1fc2f85..5decc57 100644
--- a/sdext/source/presenter/PresenterTheme.cxx
+++ b/sdext/source/presenter/PresenterTheme.cxx
@@ -382,8 +382,8 @@ bool PresenterTheme::ConvertToColor (
 
     // Get configuration node for the view style container of the current
     // theme.
-    if (pConfiguration->GoToChild(
-        A2S("Presenter/Themes/") + mpTheme->msConfigurationNodeName + A2S("/ViewStyles")))
+    if (pConfiguration->GoToChild( OUString(
+        "Presenter/Themes/" + mpTheme->msConfigurationNodeName + "/ViewStyles")))
     {
         pConfiguration->GoToChild(
             ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual,
diff --git a/stoc/source/inspect/introspection.cxx b/stoc/source/inspect/introspection.cxx
index cdb285d..b8d73d4 100644
--- a/stoc/source/inspect/introspection.cxx
+++ b/stoc/source/inspect/introspection.cxx
@@ -2155,7 +2155,7 @@ rtl::Reference< IntrospectionAccessStatic_Impl > ImplIntrospection::implInspect(
                 else
                 {
                     OSL_FAIL(
-                        ( ::rtl::OString( "Introspection: Property \"" ) +
+                        OString( ::rtl::OString( "Introspection: Property \"" ) +
                         ::rtl::OUStringToOString( aPropName, RTL_TEXTENCODING_UTF8 ) +
                         ::rtl::OString( "\" found more than once in PropertySet" ) ).getStr() );
                 }
diff --git a/svx/source/svdraw/svdoole2.cxx b/svx/source/svdraw/svdoole2.cxx
index 019f4a5..5eef368 100644
--- a/svx/source/svdraw/svdoole2.cxx
+++ b/svx/source/svdraw/svdoole2.cxx
@@ -931,7 +931,7 @@ sal_Bool SdrOle2Obj::UpdateLinkURL_Impl()
                     catch( ::com::sun::star::uno::Exception& )
                     {
                         OSL_FAIL(
-                            (OString("SdrOle2Obj::UpdateLinkURL_Impl(), "
+                            OString(OString("SdrOle2Obj::UpdateLinkURL_Impl(), "
                                     "exception caught: ") +
                             rtl::OUStringToOString(
                                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -973,7 +973,7 @@ void SdrOle2Obj::BreakFileLink_Impl()
             catch( ::com::sun::star::uno::Exception& )
             {
                 OSL_FAIL(
-                    (OString("SdrOle2Obj::BreakFileLink_Impl(), "
+                    OString(OString("SdrOle2Obj::BreakFileLink_Impl(), "
                             "exception caught: ") +
                     rtl::OUStringToOString(
                         comphelper::anyToString( cppu::getCaughtException() ),
@@ -1024,7 +1024,7 @@ void SdrOle2Obj::CheckFileLink_Impl()
         catch( ::com::sun::star::uno::Exception& )
         {
             OSL_FAIL(
-                (OString("SdrOle2Obj::CheckFileLink_Impl(), "
+                OString(OString("SdrOle2Obj::CheckFileLink_Impl(), "
                         "exception caught: ") +
                 rtl::OUStringToOString(
                     comphelper::anyToString( cppu::getCaughtException() ),
@@ -1108,7 +1108,7 @@ void SdrOle2Obj::Connect_Impl()
         catch( ::com::sun::star::uno::Exception& )
         {
             OSL_FAIL(
-                (OString("SdrOle2Obj::Connect_Impl(), "
+                OString(OString("SdrOle2Obj::Connect_Impl(), "
                         "exception caught: ") +
                 rtl::OUStringToOString(
                     comphelper::anyToString( cppu::getCaughtException() ),
@@ -1195,7 +1195,7 @@ void SdrOle2Obj::RemoveListeners_Impl()
         catch( ::com::sun::star::uno::Exception& )
         {
             OSL_FAIL(
-                (OString("SdrOle2Obj::RemoveListeners_Impl(), "
+                OString(OString("SdrOle2Obj::RemoveListeners_Impl(), "
                         "exception caught: ") +
                 rtl::OUStringToOString(
                     comphelper::anyToString( cppu::getCaughtException() ),
@@ -1277,7 +1277,7 @@ void SdrOle2Obj::Disconnect_Impl()
     catch( ::com::sun::star::uno::Exception& )
     {
         OSL_FAIL(
-            (OString("SdrOle2Obj::Disconnect_Impl(), "
+            OString(OString("SdrOle2Obj::Disconnect_Impl(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
@@ -1412,7 +1412,7 @@ void SdrOle2Obj::SetModel(SdrModel* pNewModel)
         catch( ::com::sun::star::uno::Exception& )
         {
             OSL_FAIL(
-                (OString("SdrOle2Obj::SetModel(), "
+                OString(OString("SdrOle2Obj::SetModel(), "
                         "exception caught: ") +
                 rtl::OUStringToOString(
                     comphelper::anyToString( cppu::getCaughtException() ),
@@ -1935,7 +1935,7 @@ sal_Bool SdrOle2Obj::Unload( const uno::Reference< embed::XEmbeddedObject >& xOb
         catch( ::com::sun::star::uno::Exception& )
         {
             OSL_FAIL(
-                (OString("SdrOle2Obj::Unload=(), "
+                OString(OString("SdrOle2Obj::Unload=(), "
                         "exception caught: ") +
                 rtl::OUStringToOString(
                     comphelper::anyToString( cppu::getCaughtException() ),
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 87425bd..b55daeb 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -2526,7 +2526,7 @@ void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt,
 
     m_pSerializer->startElementNS( XML_w, XML_style,
             FSNS( XML_w, XML_type ), bPapFmt? "paragraph": "character", // FIXME is this correct?
-            FSNS( XML_w, XML_styleId ), ( aStyle + OString::valueOf( sal_Int32( nId ) ) ).getStr(),
+            FSNS( XML_w, XML_styleId ), OString( aStyle + OString::valueOf( sal_Int32( nId ) ) ).getStr(),
             FSEND );
 
     m_pSerializer->singleElementNS( XML_w, XML_name,
@@ -2536,12 +2536,12 @@ void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt,
     if ( nBase != 0x0FFF )
     {
         m_pSerializer->singleElementNS( XML_w, XML_basedOn,
-                FSNS( XML_w, XML_val ), ( aStyle + OString::valueOf( sal_Int32( nBase ) ) ).getStr(),
+                FSNS( XML_w, XML_val ), OString( aStyle + OString::valueOf( sal_Int32( nBase ) ) ).getStr(),
                 FSEND );
     }
 
     m_pSerializer->singleElementNS( XML_w, XML_next,
-            FSNS( XML_w, XML_val ), ( aStyle + OString::valueOf( sal_Int32( nNext ) ) ).getStr(),
+            FSNS( XML_w, XML_val ), OString( aStyle + OString::valueOf( sal_Int32( nNext ) ) ).getStr(),
             FSEND );
 
     if ( bAutoUpdate )
commit 249f09885bc06f580ec3aea5ccd7a09d8e91541d
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Sun Dec 2 22:33:47 2012 +0100

    make sure uno::Any works with fast operator+
    
    The result of the operation needs to be first converted to O(U)String.
    
    Change-Id: I24dafeaebf68a0eff3edf1d1cf713bfc10bbd8f4

diff --git a/cppu/inc/com/sun/star/uno/Any.hxx b/cppu/inc/com/sun/star/uno/Any.hxx
index beeed81..8f6dfc6 100644
--- a/cppu/inc/com/sun/star/uno/Any.hxx
+++ b/cppu/inc/com/sun/star/uno/Any.hxx
@@ -188,6 +188,23 @@ inline Any SAL_CALL makeAny( bool const & value ) SAL_THROW(())
 }
 
 //__________________________________________________________________________________________________
+#ifdef RTL_FAST_STRING
+template< class C1, class C2 >
+inline Any SAL_CALL makeAny( const rtl::OStringConcat< C1, C2 >& value ) SAL_THROW(())
+{
+    const rtl::OString str( value );
+    return Any( &str, ::cppu::getTypeFavourUnsigned(&str) );
+}
+
+//__________________________________________________________________________________________________
+template< class C1, class C2 >
+inline Any SAL_CALL makeAny( const rtl::OUStringConcat< C1, C2 >& value ) SAL_THROW(())
+{
+    const rtl::OUString str( value );
+    return Any( &str, ::cppu::getTypeFavourUnsigned(&str) );
+}
+#endif
+//__________________________________________________________________________________________________
 template< class C >
 inline void SAL_CALL operator <<= ( Any & rAny, const C & value ) SAL_THROW(())
 {
@@ -208,6 +225,31 @@ inline void SAL_CALL operator <<= ( Any & rAny, bool const & value )
         (uno_AcquireFunc) cpp_acquire, (uno_ReleaseFunc) cpp_release );
 }
 
+//______________________________________________________________________________
+#ifdef RTL_FAST_STRING
+template< class C1, class C2 >
+inline void SAL_CALL operator <<= ( Any & rAny, const rtl::OStringConcat< C1, C2 >& value )
+    SAL_THROW(())
+{
+    const rtl::OString str( value );
+    const Type & rType = ::cppu::getTypeFavourUnsigned(&str);
+    ::uno_type_any_assign(
+        &rAny, const_cast< rtl::OString * >( &str ), rType.getTypeLibType(),
+        (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release );
+}
+
+//______________________________________________________________________________
+template< class C1, class C2 >
+inline void SAL_CALL operator <<= ( Any & rAny, const rtl::OUStringConcat< C1, C2 >& value )
+    SAL_THROW(())
+{
+    const rtl::OUString str( value );
+    const Type & rType = ::cppu::getTypeFavourUnsigned(&str);
+    ::uno_type_any_assign(
+        &rAny, const_cast< rtl::OUString * >( &str ), rType.getTypeLibType(),
+        (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release );
+}
+#endif
 //__________________________________________________________________________________________________
 template< class C >
 inline sal_Bool SAL_CALL operator >>= ( const Any & rAny, C & value ) SAL_THROW(())
commit c94b9c48664062396e9f8a12176970f6c90c0003
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Sun Dec 2 22:32:41 2012 +0100

    tools String support for fast operator+
    
    Change-Id: I13f49a49f86a7097fce115d62271ad82609036f1

diff --git a/tools/inc/tools/string.hxx b/tools/inc/tools/string.hxx
index 3aeb7e9..b98899e 100644
--- a/tools/inc/tools/string.hxx
+++ b/tools/inc/tools/string.hxx
@@ -154,6 +154,18 @@ public:
                                 reinterpret_cast<rtl_uString*>(mpData)), SAL_NO_ACQUIRE );
     }
 
+#ifdef RTL_FAST_STRING
+    template< typename T1, typename T2 >
+    UniString( const rtl::OUStringConcat< T1, T2 >& concat )
+        : mpData(NULL) { Assign( rtl::OUString( concat )); }
+    template< typename T1, typename T2 >
+    UniString&          operator =( const rtl::OUStringConcat< T1, T2 >& concat )
+                            { return Assign( rtl::OUString( concat )); }
+    template< typename T1, typename T2 >
+    UniString&          operator +=( const rtl::OUStringConcat< T1, T2 >& concat )
+                            { return Append( UniString( concat ) ); }
+#endif
+
     static UniString    CreateFromInt32( sal_Int32 n, sal_Int16 nRadix = 10 );
     static const UniString& EmptyString();
     sal_Int32           ToInt32() const;
@@ -308,6 +320,21 @@ operator <<(
         // (stray surrogate halves) and embedded null characters
 }
 
+#ifdef RTL_FAST_STRING
+namespace rtl
+{
+template<>
+struct ToStringHelper< UniString >
+    {
+    static int length( const UniString& s ) { return s.Len(); }
+    static sal_Unicode* addData( sal_Unicode* buffer, const UniString& s ) { return addDataHelper( buffer, s.GetBuffer(), s.Len()); }
+    static const bool allowOStringConcat = false;
+    static const bool allowOUStringConcat = true;
+    };
+}
+
+#endif
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/string/strucvt.cxx b/tools/source/string/strucvt.cxx
index 759da63..b01e3e2 100644
--- a/tools/source/string/strucvt.cxx
+++ b/tools/source/string/strucvt.cxx
@@ -73,7 +73,8 @@ UniString& UniString::Assign( const rtl::OUString& rStr )
 
     if (rStr.pData->length < STRING_MAXLEN)
     {
-        STRING_RELEASE((STRING_TYPE *)mpData);
+        if( mpData != NULL )
+            STRING_RELEASE((STRING_TYPE *)mpData);
         mpData = reinterpret_cast< UniStringData * >(const_cast< rtl::OUString & >(rStr).pData);
         STRING_ACQUIRE((STRING_TYPE *)mpData);
     }
commit d3e763d65c44d1838eeebbc5a581bcdd18040d8e
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Sun Dec 2 22:31:45 2012 +0100

    comphelper::string::ConstAsciiString support for fast operator+
    
    Although an ever better option seems to be replace this overblown
    const char[] wannabe with the real const char[] thing.
    
    Change-Id: Ibdf5e498585d9e2fb589a49800f7ceee1545fc30

diff --git a/comphelper/inc/comphelper/string.hxx b/comphelper/inc/comphelper/string.hxx
index 170d50f..693703d 100644
--- a/comphelper/inc/comphelper/string.hxx
+++ b/comphelper/inc/comphelper/string.hxx
@@ -479,6 +479,22 @@ struct COMPHELPER_DLLPUBLIC ConstAsciiString
 
 } }
 
+#ifdef RTL_FAST_STRING
+// TODO The whole ConstAsciiString class should probably be dumped
+// and replaced with plain 'const char[]'.
+namespace rtl
+{
+template<>
+struct ToStringHelper< comphelper::string::ConstAsciiString >
+    {
+    static int length( const comphelper::string::ConstAsciiString& str ) { return str.length; }
+    static sal_Unicode* addData( sal_Unicode* buffer, const comphelper::string::ConstAsciiString& str ) { return addDataLiteral( buffer, str.ascii, str.length ); }
+    static const bool allowOStringConcat = false;
+    static const bool allowOUStringConcat = true;
+    };
+}
+#endif
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit d87f5d30879aca73fff271c254589fc41a91fdd0
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Sun Dec 2 22:29:21 2012 +0100

    support for fast O(U)String concatenation using operator+
    
    Operator+ now, instead of requiring O(U)String operands and returning
    another O(U)String object, keeps a track of the whole concatenation
    operation using temporary O(U)StringConcat objects and performs
    the whole operation only at the very end.
    
    Change-Id: I94b3348300a137498514d26e96459c1698328520

diff --git a/sal/CppunitTest_sal_rtl_strings.mk b/sal/CppunitTest_sal_rtl_strings.mk
index 4d4f598..a30bf70 100644
--- a/sal/CppunitTest_sal_rtl_strings.mk
+++ b/sal/CppunitTest_sal_rtl_strings.mk
@@ -29,8 +29,10 @@ $(eval $(call gb_CppunitTest_CppunitTest,sal_rtl_strings))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,sal_rtl_strings,\
     sal/qa/rtl/strings/test_strings_replace \
+    sal/qa/rtl/strings/test_ostring_concat \
     sal/qa/rtl/strings/test_ostring_stringliterals \
     sal/qa/rtl/strings/test_oustring_compare \
+    sal/qa/rtl/strings/test_oustring_concat \
     sal/qa/rtl/strings/test_oustring_convert \
     sal/qa/rtl/strings/test_oustring_endswith \
     sal/qa/rtl/strings/test_oustring_noadditional \
diff --git a/sal/Package_inc.mk b/sal/Package_inc.mk
index dff0229..bf17e5f 100644
--- a/sal/Package_inc.mk
+++ b/sal/Package_inc.mk
@@ -91,6 +91,7 @@ $(eval $(call gb_Package_add_file,sal_inc,inc/rtl/strbuf.h,rtl/strbuf.h))
 $(eval $(call gb_Package_add_file,sal_inc,inc/rtl/strbuf.hxx,rtl/strbuf.hxx))
 $(eval $(call gb_Package_add_file,sal_inc,inc/rtl/string.h,rtl/string.h))
 $(eval $(call gb_Package_add_file,sal_inc,inc/rtl/string.hxx,rtl/string.hxx))
+$(eval $(call gb_Package_add_file,sal_inc,inc/rtl/stringconcat.hxx,rtl/stringconcat.hxx))
 $(eval $(call gb_Package_add_file,sal_inc,inc/rtl/stringutils.hxx,rtl/stringutils.hxx))
 $(eval $(call gb_Package_add_file,sal_inc,inc/rtl/tencinfo.h,rtl/tencinfo.h))
 $(eval $(call gb_Package_add_file,sal_inc,inc/rtl/textcvt.h,rtl/textcvt.h))
diff --git a/sal/inc/rtl/strbuf.hxx b/sal/inc/rtl/strbuf.hxx
index 7bde9e7..945d1d2 100644
--- a/sal/inc/rtl/strbuf.hxx
+++ b/sal/inc/rtl/strbuf.hxx
@@ -28,6 +28,10 @@
 #include <rtl/string.hxx>
 #include <rtl/stringutils.hxx>
 
+#ifdef RTL_FAST_STRING
+#include <rtl/stringconcat.hxx>
+#endif
+
 #ifdef __cplusplus
 
 // The unittest uses slightly different code to help check that the proper
@@ -218,6 +222,20 @@ public:
         rtl_stringbuffer_newFromStr_WithLength( &pData, value, length );
     }
 
+#ifdef RTL_FAST_STRING
+    template< typename T1, typename T2 >
+    OStringBuffer( const OStringConcat< T1, T2 >& c )
+    {
+        const int l = c.length();
+        rtl_String* buffer = NULL;
+        rtl_string_new_WithLength( &buffer, l );
+        char* end = c.addData( buffer->buffer );
+        buffer->length = end - buffer->buffer;
+        pData = buffer;
+        nCapacity = l + 16;
+    }
+#endif
+
     /** Assign to this a copy of value.
      */
     OStringBuffer& operator = ( const OStringBuffer& value )
@@ -830,6 +848,18 @@ private:
     sal_Int32       nCapacity;
 };
 
+#ifdef RTL_FAST_STRING
+template<>
+struct ToStringHelper< OStringBuffer >
+    {
+    static int length( const OStringBuffer& s ) { return s.getLength(); }
+    static char* addData( char* buffer, const OStringBuffer& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); }
+    static const bool allowOStringConcat = true;
+    static const bool allowOUStringConcat = false;
+    };
+#endif
+
+
 }
 
 #ifdef RTL_STRING_UNITTEST
diff --git a/sal/inc/rtl/string.hxx b/sal/inc/rtl/string.hxx
index 4e55020..a2cee51 100644
--- a/sal/inc/rtl/string.hxx
+++ b/sal/inc/rtl/string.hxx
@@ -30,6 +30,10 @@
 #include <rtl/string.h>
 #include <rtl/stringutils.hxx>
 
+#ifdef RTL_FAST_STRING
+#include <rtl/stringconcat.hxx>
+#endif
+
 #include "sal/log.hxx"
 
 #if !defined EXCEPTIONS_OFF
@@ -250,6 +254,19 @@ public:
         }
     }
 
+#ifdef RTL_FAST_STRING
+    template< typename T1, typename T2 >
+    OString( const OStringConcat< T1, T2 >& c )
+    {
+        const int l = c.length();
+        rtl_String* buffer = NULL;
+        rtl_string_new_WithLength( &buffer, l );
+        char* end = c.addData( buffer->buffer );
+        buffer->length = end - buffer->buffer;
+        pData = buffer;
+    }
+#endif
+
     /**
       Release the string data.
     */
@@ -1063,10 +1080,12 @@ public:
         return OString( pNew, (DO_NOT_ACQUIRE*)0 );
     }
 
+#ifndef RTL_FAST_STRING
     friend OString operator+( const OString & str1, const OString & str2  ) SAL_THROW(())
     {
         return str1.concat( str2 );
     }
+#endif
 
     /**
       Returns a new string resulting from replacing n = count characters
@@ -1435,6 +1454,52 @@ public:
 
 /* ======================================================================= */
 
+#ifdef RTL_FAST_STRING
+/**
+A simple wrapper around string literal. It is usually not necessary to use, can
+be mostly used to force OString operator+ working with operands that otherwise would
+not trigger it.
+
+This class is not part of public API and is meant to be used only in LibreOffice code.
+ at since LibreOffice 4.0
+*/
+struct SAL_WARN_UNUSED OStringLiteral
+{
+    template< int N >
+    OStringLiteral( const char (&str)[ N ] ) : size( N - 1 ), data( str ) {}
+    int size;
+    const char* data;
+};
+
+template<>
+struct ToStringHelper< OString >
+    {
+    static int length( const OString& s ) { return s.getLength(); }
+    static char* addData( char* buffer, const OString& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); }
+    static const bool allowOStringConcat = true;
+    static const bool allowOUStringConcat = false;
+    };
+
+template<>
+struct ToStringHelper< OStringLiteral >
+    {
+    static int length( const OStringLiteral& str ) { return str.size; }
+    static char* addData( char* buffer, const OStringLiteral& str ) { return addDataHelper( buffer, str.data, str.size ); }
+    static const bool allowOStringConcat = true;
+    static const bool allowOUStringConcat = false;
+    };
+
+template< typename charT, typename traits, typename T1, typename T2 >
+inline std::basic_ostream<charT, traits> & operator <<(
+    std::basic_ostream<charT, traits> & stream, const OStringConcat< T1, T2 >& concat)
+{
+    return stream << OString( concat );
+}
+#else
+// non-RTL_FAST_CODE needs this to compile
+typedef OString OStringLiteral;
+#endif
+
 } /* Namespace */
 
 #ifdef RTL_STRING_UNITTEST
@@ -1489,6 +1554,7 @@ operator <<(
 #ifdef RTL_USING
 using ::rtl::OString;
 using ::rtl::OStringHash;
+using ::rtl::OStringLiteral;
 #endif
 
 #endif /* _RTL_STRING_HXX_ */
diff --git a/sal/inc/rtl/stringconcat.hxx b/sal/inc/rtl/stringconcat.hxx
new file mode 100644
index 0000000..fddf6ed
--- /dev/null
+++ b/sal/inc/rtl/stringconcat.hxx
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef RTL_STRINGCONCAT_HXX
+#define RTL_STRINGCONCAT_HXX
+
+#include <rtl/stringutils.hxx>
+
+#include <string.h>
+
+#ifdef RTL_FAST_STRING
+
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
+namespace rtl
+{
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+#endif
+
+/*
+Implementation of efficient string concatenation.
+
+The whole system is built around two basic template classes:
+- ToStringHelper< T > - for each T it can give the length of the resulting string representation and can write
+    this string representation to a buffer
+- O(U)StringConcat< T1, T2 > - operator+ now, instead of creating O(U)String object, returns only this helper object,
+    that keeps a reference to both operator+ operands; only when converted to O(U)String it will actually create
+    the resulting string object using ToStringHelper, creating directly the resulting object without any string
+    intermediate objects
+As all the code is inline methods, it allows for extensive optimization and will usually result in very effective code
+(even surpassing strlen/strcat and equalling handwritten), while allowing for very easy and intuitive syntax.
+*/
+
+/**
+ at internal
+
+Helper class for converting a given type to a string representation.
+*/
+template< typename T >
+struct ToStringHelper
+    {
+    /// Return length of the string representation of the given object (if not known exactly, it needs to be the maximum).
+    static int length( const T& );
+    /// Add 8-bit representation of the given object to the given buffer and return position right after the added data.
+    static char* addData( char* buffer, const T& );
+    /// Add Unicode representation of the given object to the given buffer and return position right after the added data.
+    static sal_Unicode* addData( sal_Unicode* buffer, const T& );
+    /// If true, T can be used in concatenation resulting in OString.
+    static const bool allowOStringConcat = false;
+    /// If true, T can be used in concatenation resulting in OUString.
+    static const bool allowOUStringConcat = false;
+    };
+
+inline
+char* addDataHelper( char* buffer, const char* data, int length )
+    {
+    memcpy( buffer, data, length );
+    return buffer + length;
+    }
+
+inline
+sal_Unicode* addDataHelper( sal_Unicode* buffer, const sal_Unicode* data, int length )
+    {
+    memcpy( buffer, data, length * sizeof( sal_Unicode ));
+    return buffer + length;
+    }
+
+inline
+sal_Unicode* addDataLiteral( sal_Unicode* buffer, const char* data, int length )
+    {
+    while( length-- > 0 )
+        *buffer++ = *data++;
+    return buffer;
+    }
+
+inline
+char* addDataCString( char* buffer, const char* str )
+    {
+    while( *str != '\0' )
+        *buffer++ = *str++;
+    return buffer;
+    }
+
+inline
+sal_Unicode* addDataUString( sal_Unicode* buffer, const sal_Unicode* str )
+    {
+    while( *str != '\0' )
+        *buffer++ = *str++;
+    return buffer;
+    }
+
+template<>
+struct ToStringHelper< const char* >
+    {
+    static int length( const char* str ) { return strlen( str ); }
+    static char* addData( char* buffer, const char* str ) { return addDataCString( buffer, str ); }
+    static const bool allowOStringConcat = true;
+    static const bool allowOUStringConcat = false;
+    };
+
+template<>
+struct ToStringHelper< char* >
+    {
+    static int length( const char* str ) { return strlen( str ); }
+    static char* addData( char* buffer, const char* str ) { return addDataCString( buffer, str ); }
+    static const bool allowOStringConcat = true;
+    static const bool allowOUStringConcat = false;
+    };
+
+template< int N >
+struct ToStringHelper< char[ N ] >
+    {
+    static int length( const char str[ N ] ) { return strlen( str ); }
+    static char* addData( char* buffer, const char str[ N ] ) { return addDataCString( buffer, str ); }
+    static sal_Unicode* addData( sal_Unicode* buffer, const char str[ N ] ) { return addDataLiteral( buffer, str, N - 1 ); }
+    static const bool allowOStringConcat = true;
+    static const bool allowOUStringConcat = false;
+    };
+
+template< int N >
+struct ToStringHelper< const char[ N ] >
+    {
+    static int length( const char[ N ] ) { return N - 1; }
+    static char* addData( char* buffer, const char str[ N ] ) { return addDataHelper( buffer, str, N - 1 ); }
+    static sal_Unicode* addData( sal_Unicode* buffer, const char str[ N ] ) { return addDataLiteral( buffer, str, N - 1 ); }
+    static const bool allowOStringConcat = true;
+    static const bool allowOUStringConcat = true;
+    };
+
+/**
+ at internal
+
+Objects returned by operator+, instead of OString. These objects (possibly recursively) keep a representation of the whole
+concatenation operation.
+*/
+template< typename T1, typename T2 >
+struct OStringConcat
+    {
+    public:
+        OStringConcat( const T1& left_, const T2& right_ ) : left( left_ ), right( right_ ) {}
+        int length() const { return ToStringHelper< T1 >::length( left ) + ToStringHelper< T2 >::length( right ); }
+        char* addData( char* buffer ) const { return ToStringHelper< T2 >::addData( ToStringHelper< T1 >::addData( buffer, left ), right ); }
+        // NOTE here could be functions that would forward to the "real" temporary OString. Note however that e.g. getStr()
+        // is not so simple, as the OString temporary must live long enough (i.e. can't be created here in a function, a wrapper
+        // temporary object containing it must be returned instead).
+    private:
+        const T1& left;
+        const T2& right;
+    };
+
+/**
+ at internal
+
+Objects returned by operator+, instead of OUString. These objects (possibly recursively) keep a representation of the whole
+concatenation operation.
+*/
+template< typename T1, typename T2 >
+struct OUStringConcat
+    {
+    public:
+        OUStringConcat( const T1& left_, const T2& right_ ) : left( left_ ), right( right_ ) {}
+        int length() const { return ToStringHelper< T1 >::length( left ) + ToStringHelper< T2 >::length( right ); }
+        sal_Unicode* addData( sal_Unicode* buffer ) const { return ToStringHelper< T2 >::addData( ToStringHelper< T1 >::addData( buffer, left ), right ); }
+    private:
+        const T1& left;
+        const T2& right;
+    };
+
+template< typename T1, typename T2 >
+struct ToStringHelper< OStringConcat< T1, T2 > >
+    {
+    static int length( const OStringConcat< T1, T2 >& c ) { return c.length(); }
+    static char* addData( char* buffer, const OStringConcat< T1, T2 >& c ) { return c.addData( buffer ); }
+    static const bool allowOStringConcat = ToStringHelper< T1 >::allowOStringConcat && ToStringHelper< T2 >::allowOStringConcat;
+    static const bool allowOUStringConcat = false;
+    };
+
+template< typename T1, typename T2 >
+struct ToStringHelper< OUStringConcat< T1, T2 > >
+    {
+    static int length( const OUStringConcat< T1, T2 >& c ) { return c.length(); }
+    static sal_Unicode* addData( sal_Unicode* buffer, const OUStringConcat< T1, T2 >& c ) { return c.addData( buffer ); }
+    static const bool allowOStringConcat = false;
+    static const bool allowOUStringConcat = ToStringHelper< T1 >::allowOUStringConcat && ToStringHelper< T2 >::allowOUStringConcat;
+    };
+
+template< typename T1, typename T2 >
+inline
+SAL_WARN_UNUSED_RESULT
+typename internal::Enable< OStringConcat< T1, T2 >, ToStringHelper< T1 >::allowOStringConcat && ToStringHelper< T2 >::allowOStringConcat >::Type operator+( const T1& left, const T2& right )
+    {
+    return OStringConcat< T1, T2 >( left, right );
+    }
+
+// char[N] and const char[N] need to be done explicitly, otherwise the compiler likes to treat them the same way for some reason
+template< typename T, int N >
+inline
+SAL_WARN_UNUSED_RESULT
+typename internal::Enable< OStringConcat< T, const char[ N ] >, ToStringHelper< T >::allowOStringConcat >::Type operator+( const T& left, const char (&right)[ N ] )
+    {
+    return OStringConcat< T, const char[ N ] >( left, right );
+    }
+
+template< typename T, int N >
+inline
+SAL_WARN_UNUSED_RESULT
+typename internal::Enable< OStringConcat< const char[ N ], T >, ToStringHelper< T >::allowOStringConcat >::Type operator+( const char (&left)[ N ], const T& right )
+    {
+    return OStringConcat< const char[ N ], T >( left, right );
+    }
+
+template< typename T, int N >
+inline
+SAL_WARN_UNUSED_RESULT
+typename internal::Enable< OStringConcat< T, char[ N ] >, ToStringHelper< T >::allowOStringConcat >::Type operator+( const T& left, char (&right)[ N ] )
+    {
+    return OStringConcat< T, char[ N ] >( left, right );
+    }
+
+template< typename T, int N >
+inline
+SAL_WARN_UNUSED_RESULT
+typename internal::Enable< OStringConcat< char[ N ], T >, ToStringHelper< T >::allowOStringConcat >::Type operator+( char (&left)[ N ], const T& right )
+    {
+    return OStringConcat< char[ N ], T >( left, right );
+    }
+
+template< typename T1, typename T2 >
+inline
+typename internal::Enable< OUStringConcat< T1, T2 >, ToStringHelper< T1 >::allowOUStringConcat && ToStringHelper< T2 >::allowOUStringConcat >::Type operator+( const T1& left, const T2& right )
+    {
+    return OUStringConcat< T1, T2 >( left, right );
+    }
+
+template< typename T1, typename T2 >
+inline
+typename internal::Enable< OUStringConcat< T1, T2 >, ToStringHelper< T1 >::allowOUStringConcat && ToStringHelper< T2 >::allowOUStringConcat && internal::ConstCharArrayDetector< T1, void >::ok >::Type operator+( T1& left, const T2& right )
+    {
+    return OUStringConcat< T1, T2 >( left, right );
+    }
+
+template< typename T1, typename T2 >
+inline
+typename internal::Enable< OUStringConcat< T1, T2 >, ToStringHelper< T1 >::allowOUStringConcat && ToStringHelper< T2 >::allowOUStringConcat && internal::ConstCharArrayDetector< T2, void >::ok >::Type operator+( const T1& left, T2& right )
+    {
+    return OUStringConcat< T1, T2 >( left, right );
+    }
+
+} // namespace
+
+#endif
+
+#endif
diff --git a/sal/inc/rtl/stringutils.hxx b/sal/inc/rtl/stringutils.hxx
index 3ed36a7..f0ad4f8 100644
--- a/sal/inc/rtl/stringutils.hxx
+++ b/sal/inc/rtl/stringutils.hxx
@@ -31,6 +31,16 @@
 
 #include "sal/config.h"
 
+// Manually defining RTL_DISABLE_FAST_STRING allows to force turning fast string concatenation off
+// (e.g. for debugging).
+#ifndef RTL_DISABLE_FAST_STRING
+#ifndef HAVE_SFINAE_ANONYMOUS_BROKEN
+// Enable fast string concatenation.
+// This feature is not part of public API and is meant to be used only internally by LibreOffice.
+#define RTL_FAST_STRING
+#endif
+#endif
+
 // The unittest uses slightly different code to help check that the proper
 // calls are made. The class is put into a different namespace to make
 // sure the compiler generates a different (if generating also non-inline)
@@ -46,6 +56,7 @@ namespace rtl
 #ifdef RTL_STRING_UNITTEST
 #undef rtl
 #endif
+
 namespace internal
 {
 /*
@@ -114,12 +125,14 @@ struct NonConstCharArrayDetector< const char[], T >
 template< typename T1, typename T2 >
 struct ConstCharArrayDetector
 {
+    static const bool ok = false;
 };
 template< int N, typename T >
 struct ConstCharArrayDetector< const char[ N ], T >
 {
     typedef T Type;
     static const int size = N;
+    static const bool ok = true;
 };
 
 // this one is used to rule out only const char[N]
@@ -150,6 +163,19 @@ struct ExceptCharArrayDetector< const char[ N ] >
 {
 };
 
+// SFINAE helper class
+template< typename T, bool >
+struct Enable
+    {
+    };
+
+template< typename T >
+struct Enable< T, true >
+    {
+    typedef T Type;
+    };
+
+
 } /* Namespace */
 
 } /* Namespace */
diff --git a/sal/inc/rtl/ustrbuf.hxx b/sal/inc/rtl/ustrbuf.hxx
index 6338dd1..7d36356 100644
--- a/sal/inc/rtl/ustrbuf.hxx
+++ b/sal/inc/rtl/ustrbuf.hxx
@@ -29,6 +29,10 @@
 #include <rtl/ustring.hxx>
 #include <rtl/stringutils.hxx>
 
+#ifdef RTL_FAST_STRING
+#include <rtl/stringconcat.hxx>
+#endif
+
 // The unittest uses slightly different code to help check that the proper
 // calls are made. The class is put into a different namespace to make
 // sure the compiler generates a different (if generating also non-inline)
@@ -209,6 +213,20 @@ public:
     }
 #endif
 
+#ifdef RTL_FAST_STRING
+    template< typename T1, typename T2 >
+    OUStringBuffer( const OUStringConcat< T1, T2 >& c )
+    {
+        const int l = c.length();
+        rtl_uString* buffer = NULL;
+        rtl_uString_new_WithLength( &buffer, l ); // TODO this clears, not necessary
+        sal_Unicode* end = c.addData( buffer->buffer );
+        buffer->length = end - buffer->buffer;
+        // TODO realloc in case buffer->length is noticeably smaller than l ?
+        pData = buffer;
+        nCapacity = l + 16;
+    }
+#endif
     /** Assign to this a copy of value.
      */
     OUStringBuffer& operator = ( const OUStringBuffer& value )
@@ -1223,6 +1241,17 @@ private:
     sal_Int32       nCapacity;
 };
 
+#ifdef RTL_FAST_STRING
+template<>
+struct ToStringHelper< OUStringBuffer >
+    {
+    static int length( const OUStringBuffer& s ) { return s.getLength(); }
+    static sal_Unicode* addData( sal_Unicode* buffer, const OUStringBuffer& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); }
+    static const bool allowOStringConcat = false;
+    static const bool allowOUStringConcat = true;
+    };
+#endif
+
 }
 
 #ifdef RTL_STRING_UNITTEST
diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx
index c5cfcc3..ec7c290 100644
--- a/sal/inc/rtl/ustring.hxx
+++ b/sal/inc/rtl/ustring.hxx
@@ -32,6 +32,10 @@
 #include <rtl/textenc.h>
 #include "sal/log.hxx"
 
+#ifdef RTL_FAST_STRING
+#include <rtl/stringconcat.hxx>
+#endif
+
 #if defined EXCEPTIONS_OFF
 #include <stdlib.h>
 #else
@@ -315,6 +319,20 @@ public:
         }
     }
 
+#ifdef RTL_FAST_STRING
+    template< typename T1, typename T2 >
+    OUString( const OUStringConcat< T1, T2 >& c )
+    {
+        const int l = c.length();
+        rtl_uString* buffer = NULL;
+        rtl_uString_new_WithLength( &buffer, l ); // TODO this clears, not necessary

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list