summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2012-04-06 13:45:47 +0200
committerLuboš Luňák <l.lunak@suse.cz>2012-04-06 13:46:21 +0200
commit066dbfd1970b8ea58ba16b07b2a57f61c0cb8e36 (patch)
tree635b7cdbca8b31e82fedbead441dfd298b53718b
parent7d82fb18fe6ae68f6eb6a33c6030105f9e2fe232 (diff)
string literal O(U)StringBuffer ctors too, after all
-rw-r--r--sal/inc/rtl/strbuf.hxx54
-rw-r--r--sal/inc/rtl/string.h3
-rw-r--r--sal/inc/rtl/string.hxx4
-rw-r--r--sal/inc/rtl/ustrbuf.hxx69
-rw-r--r--sal/inc/rtl/ustring.h15
-rw-r--r--sal/inc/rtl/ustring.hxx12
-rw-r--r--sal/qa/rtl/strings/test_ostring_stringliterals.cxx6
-rw-r--r--sal/qa/rtl/strings/test_oustring_stringliterals.cxx21
-rw-r--r--sal/rtl/source/strtmpl.cxx11
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 )