diff options
author | Luboš Luňák <l.lunak@suse.cz> | 2012-04-06 13:45:47 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@suse.cz> | 2012-04-06 13:46:21 +0200 |
commit | 066dbfd1970b8ea58ba16b07b2a57f61c0cb8e36 (patch) | |
tree | 635b7cdbca8b31e82fedbead441dfd298b53718b /sal | |
parent | 7d82fb18fe6ae68f6eb6a33c6030105f9e2fe232 (diff) |
string literal O(U)StringBuffer ctors too, after all
Diffstat (limited to 'sal')
-rw-r--r-- | sal/inc/rtl/strbuf.hxx | 54 | ||||
-rw-r--r-- | sal/inc/rtl/string.h | 3 | ||||
-rw-r--r-- | sal/inc/rtl/string.hxx | 4 | ||||
-rw-r--r-- | sal/inc/rtl/ustrbuf.hxx | 69 | ||||
-rw-r--r-- | sal/inc/rtl/ustring.h | 15 | ||||
-rw-r--r-- | sal/inc/rtl/ustring.hxx | 12 | ||||
-rw-r--r-- | sal/qa/rtl/strings/test_ostring_stringliterals.cxx | 6 | ||||
-rw-r--r-- | sal/qa/rtl/strings/test_oustring_stringliterals.cxx | 21 | ||||
-rw-r--r-- | sal/rtl/source/strtmpl.cxx | 11 |
9 files changed, 162 insertions, 33 deletions
diff --git a/sal/inc/rtl/strbuf.hxx b/sal/inc/rtl/strbuf.hxx index 122eb4b099e6..4500cf0f8de8 100644 --- a/sal/inc/rtl/strbuf.hxx +++ b/sal/inc/rtl/strbuf.hxx @@ -155,6 +155,60 @@ public: } /** + @overload + @since LibreOffice 3.6 + */ +#ifdef HAVE_SFINAE_ANONYMOUS_BROKEN // see the OString ctors + OStringBuffer( const char* value ) + : pData(NULL) + { + sal_Int32 length = rtl_str_getLength( value ); + nCapacity = length + 16; + rtl_stringbuffer_newFromStr_WithLength( &pData, value, length ); + } +#else + template< typename T > + OStringBuffer( const T& value, typename internal::CharPtrDetector< T, internal::Dummy >::Type = internal::Dummy()) + : pData(NULL) + { + sal_Int32 length = rtl_str_getLength( value ); + nCapacity = length + 16; + rtl_stringbuffer_newFromStr_WithLength( &pData, value, length ); + } + + template< typename T > + OStringBuffer( T& value, typename internal::NonConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy()) + : pData(NULL) + { + sal_Int32 length = rtl_str_getLength( value ); + nCapacity = length + 16; + rtl_stringbuffer_newFromStr_WithLength( &pData, value, length ); + } + + /** + Constructs a string buffer so that it represents the same + sequence of characters as the string literal. + + If there are any embedded \0's in the string literal, the result is undefined. + Use the overload that explicitly accepts length. + + @since LibreOffice 3.6 + + @param literal a string literal + */ + template< typename T > + OStringBuffer( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy()) + : pData(NULL) + , nCapacity( internal::ConstCharArrayDetector< T, void >::size - 1 + 16 ) + { + rtl_string_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 16 ); +#ifdef RTL_STRING_UNITTEST + rtl_string_unittest_const_literal = true; +#endif + } +#endif // HAVE_SFINAE_ANONYMOUS_BROKEN + + /** Constructs a string buffer so that it represents the same sequence of characters as the string argument. diff --git a/sal/inc/rtl/string.h b/sal/inc/rtl/string.h index f695c1207021..f326abe3d7f9 100644 --- a/sal/inc/rtl/string.h +++ b/sal/inc/rtl/string.h @@ -888,8 +888,9 @@ SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromStr_WithLength( rtl_String ** newS /** @internal + @since LibreOffice 3.6 */ -SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromLiteral( rtl_String ** newStr, const sal_Char * value, sal_Int32 len ) SAL_THROW_EXTERN_C(); +SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromLiteral( rtl_String ** newStr, const sal_Char * value, sal_Int32 len, sal_Int32 allocExtra ) SAL_THROW_EXTERN_C(); /** Assign a new value to a string. diff --git a/sal/inc/rtl/string.hxx b/sal/inc/rtl/string.hxx index 0f6246b65d72..9791a8c70faa 100644 --- a/sal/inc/rtl/string.hxx +++ b/sal/inc/rtl/string.hxx @@ -206,7 +206,7 @@ public: OString( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy() ) SAL_THROW(()) { pData = 0; - rtl_string_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1 ); + rtl_string_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 0 ); #ifdef RTL_STRING_UNITTEST rtl_string_unittest_const_literal = true; #endif @@ -285,7 +285,7 @@ public: typename internal::ConstCharArrayDetector< T, OString& >::Type operator=( T& literal ) SAL_THROW(()) { RTL_STRING_CONST_FUNCTION - rtl_string_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1 ); + rtl_string_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 0 ); return *this; } diff --git a/sal/inc/rtl/ustrbuf.hxx b/sal/inc/rtl/ustrbuf.hxx index 02a507ce18cf..17deadd5de9e 100644 --- a/sal/inc/rtl/ustrbuf.hxx +++ b/sal/inc/rtl/ustrbuf.hxx @@ -149,6 +149,75 @@ public: rtl_uStringbuffer_newFromStr_WithLength( &pData, value.getStr(), value.getLength() ); } +#ifdef HAVE_SFINAE_ANONYMOUS_BROKEN // see OUString ctors + template< int N > + OUStringBuffer( const char (&literal)[ N ] ) + : pData(NULL) + , nCapacity( N - 1 + 16 ) + { + rtl_uStringbuffer_newFromStr_WithLength( &pData, literal, N - 1 ); +#ifdef RTL_STRING_UNITTEST + rtl_string_unittest_const_literal = true; +#endif + } + + /** + * It is an error to call this overload. Strings cannot directly use non-const char[]. + * @internal + */ + template< int N > + OUStringBuffer( char (&value)[ N ] ) +#ifndef RTL_STRING_UNITTEST + ; // intentionally not implemented +#else + { + (void) value; // unused + pData = 0; + nCapacity = 10; + rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage + rtl_string_unittest_invalid_conversion = true; + } +#endif +#else // HAVE_SFINAE_ANONYMOUS_BROKEN + template< typename T > + OUStringBuffer( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy() ) + : pData(NULL) + , nCapacity( internal::ConstCharArrayDetector< T, void >::size - 1 + 16 ) + { + rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 16 ); +#ifdef RTL_STRING_UNITTEST + rtl_string_unittest_const_literal = true; +#endif + } +#endif // HAVE_SFINAE_ANONYMOUS_BROKEN + +#ifdef RTL_STRING_UNITTEST + /** + * Only used by unittests to detect incorrect conversions. + * @internal + */ + template< typename T > + OUStringBuffer( T&, typename internal::ExceptConstCharArrayDetector< T >::Type = internal::Dummy() ) + { + pData = 0; + nCapacity = 10; + rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage + rtl_string_unittest_invalid_conversion = true; + } + /** + * Only used by unittests to detect incorrect conversions. + * @internal + */ + template< typename T > + OUStringBuffer( const T&, typename internal::ExceptCharArrayDetector< T >::Type = internal::Dummy() ) + { + pData = 0; + nCapacity = 10; + rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage + rtl_string_unittest_invalid_conversion = true; + } +#endif + /** Assign to this a copy of value. */ OUStringBuffer& operator = ( const OUStringBuffer& value ) diff --git a/sal/inc/rtl/ustring.h b/sal/inc/rtl/ustring.h index b9184e0c9cab..0e95c51a21d8 100644 --- a/sal/inc/rtl/ustring.h +++ b/sal/inc/rtl/ustring.h @@ -1243,16 +1243,13 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromStr_WithLength( SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromAscii( rtl_uString ** newStr, const sal_Char * value ) SAL_THROW_EXTERN_C(); -/** Allocate a new string that contains a copy of a string literal. - - This is similar to rtl_uString_newFromAscii(), except that - length of the string literal is explicitly passed to the function, - and embedded \0's are included in the string. - - @since LibreOffice 3.6 - */ +/** + @internal + @since LibreOffice 3.6 +*/ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromLiteral( - rtl_uString ** newStr, const sal_Char * value, sal_Int32 len ) SAL_THROW_EXTERN_C(); + rtl_uString ** newStr, const sal_Char * value, sal_Int32 len, + sal_Int32 allocExtra ) SAL_THROW_EXTERN_C(); /** Allocate a new string from an array of Unicode code points. diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx index 093b6c953fa4..883fb93e5881 100644 --- a/sal/inc/rtl/ustring.hxx +++ b/sal/inc/rtl/ustring.hxx @@ -204,7 +204,7 @@ public: OUString( const char (&literal)[ N ] ) { pData = 0; - rtl_uString_newFromLiteral( &pData, literal, N - 1 ); + rtl_uString_newFromLiteral( &pData, literal, N - 1, 0 ); #ifdef RTL_STRING_UNITTEST rtl_string_unittest_const_literal = true; #endif @@ -222,7 +222,7 @@ public: { (void) value; // unused pData = 0; - rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10 ); // set to garbage + rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage rtl_string_unittest_invalid_conversion = true; } #endif @@ -231,7 +231,7 @@ public: OUString( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy() ) { pData = 0; - rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1 ); + rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 0 ); #ifdef RTL_STRING_UNITTEST rtl_string_unittest_const_literal = true; #endif @@ -249,7 +249,7 @@ public: OUString( T&, typename internal::ExceptConstCharArrayDetector< T >::Type = internal::Dummy() ) { pData = 0; - rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10 ); // set to garbage + rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage rtl_string_unittest_invalid_conversion = true; } /** @@ -260,7 +260,7 @@ public: OUString( const T&, typename internal::ExceptCharArrayDetector< T >::Type = internal::Dummy() ) { pData = 0; - rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10 ); // set to garbage + rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage rtl_string_unittest_invalid_conversion = true; } #endif @@ -372,7 +372,7 @@ public: template< typename T > typename internal::ConstCharArrayDetector< T, OUString& >::Type operator=( T& literal ) { - rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1 ); + rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 0 ); return *this; } diff --git a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx index d7e3cf5be7c4..2baac11c742b 100644 --- a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx +++ b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx @@ -83,12 +83,15 @@ CPPUNIT_TEST_SUITE_END(); ( \ rtl_string_unittest_const_literal = false, \ ( void ) rtl::OString( argument ), \ - rtl_string_unittest_const_literal ) + result_tmp = rtl_string_unittest_const_literal, \ + ( void ) rtl::OStringBuffer( argument ), \ + rtl_string_unittest_const_literal && result_tmp ) void test::ostring::StringLiterals::checkCtors() { // string literal ctors do not work with SFINAE broken and are disabled #ifndef HAVE_SFINAE_ANONYMOUS_BROKEN + bool result_tmp; CPPUNIT_ASSERT( CONST_CTOR_USED( "test" )); const char good1[] = "test"; CPPUNIT_ASSERT( CONST_CTOR_USED( good1 )); @@ -144,6 +147,7 @@ char test::ostring::StringLiterals::bad6[] = "test"; void test::ostring::StringLiterals::testcall( const char str[] ) { #ifndef _MSC_VER + bool result_tmp; CPPUNIT_ASSERT( !CONST_CTOR_USED( str )); #else // MSVC just errors out on this for some reason, which is fine as well diff --git a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx index 631647858927..82e76ea14b70 100644 --- a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx +++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx @@ -70,32 +70,33 @@ CPPUNIT_TEST_SUITE_END(); #define VALID_CONVERSION( expression ) \ ( \ rtl_string_unittest_invalid_conversion = false, \ - ( void ) ( expression ), \ + ( void ) rtl::OUString( expression ), \ + ( void ) rtl::OUStringBuffer( expression ), \ !rtl_string_unittest_invalid_conversion ) void test::oustring::StringLiterals::checkCtors() { - CPPUNIT_ASSERT( VALID_CONVERSION( rtl::OUString( "test" ))); + CPPUNIT_ASSERT( VALID_CONVERSION( "test" )); const char good1[] = "test"; - CPPUNIT_ASSERT( VALID_CONVERSION( rtl::OUString( good1 ))); + CPPUNIT_ASSERT( VALID_CONVERSION( good1 )); - CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( (const char*) "test" ))); + CPPUNIT_ASSERT( !VALID_CONVERSION( (const char*) "test" )); const char* bad1 = good1; - CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( bad1 ))); + CPPUNIT_ASSERT( !VALID_CONVERSION( bad1 )); char bad2[] = "test"; - CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( bad2 ))); + CPPUNIT_ASSERT( !VALID_CONVERSION( bad2 )); char* bad3 = bad2; - CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( bad3 ))); + CPPUNIT_ASSERT( !VALID_CONVERSION( bad3 )); const char* bad4[] = { "test1" }; - CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( bad4[ 0 ] ))); + CPPUNIT_ASSERT( !VALID_CONVERSION( bad4[ 0 ] )); 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). // RTL_CONSTASCII_USTRINGPARAM() has the same flaw. const char bad5[][ 6 ] = { "test", "test2" }; -// CPPUNIT_ASSERT( VALID_CONVERSION( rtl::OUString( bad5[ 0 ] ))); - CPPUNIT_ASSERT( VALID_CONVERSION( rtl::OUString( bad5[ 1 ] ))); +// 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. diff --git a/sal/rtl/source/strtmpl.cxx b/sal/rtl/source/strtmpl.cxx index be86ab305d7a..a6cfa18a2410 100644 --- a/sal/rtl/source/strtmpl.cxx +++ b/sal/rtl/source/strtmpl.cxx @@ -1195,9 +1195,10 @@ void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA* /* ----------------------------------------------------------------------- */ // Used when creating from string literals. -void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral)( IMPL_RTL_STRINGDATA** ppThis, - const sal_Char* pCharStr, - sal_Int32 nLen ) +void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral )( IMPL_RTL_STRINGDATA** ppThis, + const sal_Char* pCharStr, + sal_Int32 nLen, + sal_Int32 allocExtra ) SAL_THROW_EXTERN_C() { if ( !nLen ) @@ -1209,10 +1210,12 @@ void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral)( IMPL_RTL_STRINGDATA** ppThis if ( *ppThis ) IMPL_RTL_STRINGNAME( release )( *ppThis ); - *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); + *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen + allocExtra ); assert( *ppThis != NULL ); if ( (*ppThis) ) { + (*ppThis)->length = nLen; // fix after possible allocExtra != 0 + (*ppThis)->buffer[nLen] = 0; IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer; sal_Int32 nCount; for( nCount = nLen; nCount > 0; --nCount ) |