summaryrefslogtreecommitdiff
path: root/sal
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2012-02-22 15:35:41 +0100
committerLuboš Luňák <l.lunak@suse.cz>2012-02-22 16:21:37 +0100
commitf150ed241ff796a25bd1a797155104198b415f18 (patch)
treebce5481ac1cd29b781ad73c2eb5a7606c49f5da2 /sal
parent768da511046f22346874734da2418117f71dcd11 (diff)
OUString ctor for string literals without RTL_CONSTASCII stuff
http://lists.freedesktop.org/archives/libreoffice/2012-February/025662.html
Diffstat (limited to 'sal')
-rw-r--r--sal/CppunitTest_sal_rtl_strings.mk1
-rw-r--r--sal/inc/rtl/ustring.hxx62
-rw-r--r--sal/inc/sal/log-areas.dox4
-rw-r--r--sal/qa/rtl/strings/test_oustring_stringliterals.cxx91
-rw-r--r--sal/rtl/source/ustring.cxx3
5 files changed, 160 insertions, 1 deletions
diff --git a/sal/CppunitTest_sal_rtl_strings.mk b/sal/CppunitTest_sal_rtl_strings.mk
index f43e7fd3a73d..8bc537010701 100644
--- a/sal/CppunitTest_sal_rtl_strings.mk
+++ b/sal/CppunitTest_sal_rtl_strings.mk
@@ -33,6 +33,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,sal_rtl_strings,\
sal/qa/rtl/strings/test_oustring_convert \
sal/qa/rtl/strings/test_oustring_endswith \
sal/qa/rtl/strings/test_oustring_noadditional \
+ sal/qa/rtl/strings/test_oustring_stringliterals \
))
$(eval $(call gb_CppunitTest_add_linked_libs,sal_rtl_strings,\
diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx
index faff676dcedb..f55fb7d6fdaf 100644
--- a/sal/inc/rtl/ustring.hxx
+++ b/sal/inc/rtl/ustring.hxx
@@ -168,6 +168,65 @@ public:
}
/**
+ New string from an 8-Bit string literal that is expected to be in UTF-8
+ (or its subset, ASCII). All string literals in the codebase are
+ assumed to be only UTF-8/ASCII, so this constructor allows an efficient
+ and convenient way to create OUString instances from literals.
+
+ @param value the 8-bit string literal
+
+ @exception std::bad_alloc is thrown if an out-of-memory condition occurs
+ */
+ template< int N >
+ OUString( const char (&literal)[ N ] )
+ {
+ pData = 0;
+ rtl_string2UString( &pData, literal, N - 1, RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS );
+ if (pData == 0) {
+#if defined EXCEPTIONS_OFF
+ SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
+#else
+ throw std::bad_alloc();
+#endif
+ }
+ }
+
+ /**
+ * This overload exists only to avoid creating instances directly from (non-const) char[],
+ * which would otherwise be picked up by the optimized const char[] constructor.
+ * Since the non-const array cannot be guaranteed to contain characters in the expected
+ * UTF-8/ASCII encoding, this needs to be prevented.
+ *
+ * It is an error to try to call this overload.
+ *
+ * @internal
+ */
+ template< int N >
+ OUString( char (&value)[ N ] )
+#ifndef RTL_STRING_UNITTEST
+ ; // intentionally not implemented
+#else
+ {
+ (void) value; // unused
+ pData = 0; // for the unittest create an empty string
+ rtl_uString_new( &pData );
+ }
+#endif
+
+#ifdef RTL_STRING_UNITTEST
+ /**
+ * Only used by unittests to detect incorrect conversions.
+ * @internal
+ */
+ template< typename T >
+ OUString( T )
+ {
+ pData = 0;
+ rtl_uString_new( &pData );
+ }
+#endif
+
+ /**
New string from a 8-Bit character buffer array.
@param value a 8-Bit character array.
@@ -1722,6 +1781,9 @@ public:
all ASCII characters are in the allowed range between 0 and
127. The ASCII string must be NULL-terminated.
+ Note that for string literals it is simpler and more efficient
+ to directly use the OUString constructor.
+
@param value the 8-Bit ASCII character string
@return a string with the string representation of the argument.
*/
diff --git a/sal/inc/sal/log-areas.dox b/sal/inc/sal/log-areas.dox
index d89bbdc886ba..7c2d8cea568c 100644
--- a/sal/inc/sal/log-areas.dox
+++ b/sal/inc/sal/log-areas.dox
@@ -25,6 +25,10 @@ certain functionality.
@li oox.xmlstream - XmlStream class
+@section SAL/RTL
+
+@li rtl.string - rtl::OString, rtl::OUString and related functionality
+
@section VCL
@li vcl.gdi - the GDI part of VCL: devices, bitmaps, etc.
diff --git a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
new file mode 100644
index 000000000000..142f53d9a8cf
--- /dev/null
+++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// activate the extra needed ctor
+#define RTL_STRING_UNITTEST
+
+#include "sal/config.h"
+#include "sal/precppunit.hxx"
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "rtl/string.h"
+#include "rtl/ustring.hxx"
+
+namespace test { namespace oustring {
+
+class StringLiterals: public CppUnit::TestFixture
+{
+private:
+ void checkCtors();
+
+ void testcall( const char str[] );
+ // invalid conversions will trigger templated OUString ctor that creates an empty string
+ // (see RTL_STRING_UNITTEST)
+ bool validConversion( const rtl::OUString& str ) { return !str.isEmpty(); }
+
+CPPUNIT_TEST_SUITE(StringLiterals);
+CPPUNIT_TEST(checkCtors);
+CPPUNIT_TEST_SUITE_END();
+};
+
+void test::oustring::StringLiterals::checkCtors()
+{
+ CPPUNIT_ASSERT( validConversion( rtl::OUString( "test" )));
+ const char good1[] = "test";
+ CPPUNIT_ASSERT( validConversion( rtl::OUString( good1 )));
+
+ CPPUNIT_ASSERT( !validConversion( rtl::OUString( (const char*) "test" )));
+ const char* bad1 = good1;
+ CPPUNIT_ASSERT( !validConversion( rtl::OUString( bad1 )));
+ char bad2[] = "test";
+ CPPUNIT_ASSERT( !validConversion( rtl::OUString( bad2 )));
+ char* bad3 = bad2;
+ CPPUNIT_ASSERT( !validConversion( rtl::OUString( bad3 )));
+ const char* bad4[] = { "test1" };
+ CPPUNIT_ASSERT( !validConversion( rtl::OUString( 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( validConversion( rtl::OUString( bad5[ 0 ] )));
+ CPPUNIT_ASSERT( validConversion( rtl::OUString( bad5[ 1 ] )));
+}
+
+void test::oustring::StringLiterals::testcall( const char str[] )
+{
+ CPPUNIT_ASSERT( !validConversion( rtl::OUString( str )));
+}
+
+}} // namespace
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::oustring::StringLiterals);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/rtl/source/ustring.cxx b/sal/rtl/source/ustring.cxx
index 0156ceae9a08..d7f8a96971ec 100644
--- a/sal/rtl/source/ustring.cxx
+++ b/sal/rtl/source/ustring.cxx
@@ -45,6 +45,7 @@
#include <string.h>
#include <sal/alloca.h>
+#include <sal/log.hxx>
#include "hash.hxx"
#include "strimp.hxx"
@@ -600,7 +601,7 @@ static void rtl_string2UString_status( rtl_uString** ppThis,
do
{
/* Check ASCII range */
- OSL_ENSURE( ((unsigned char)*pStr) <= 127,
+ SAL_WARN_IF( ((unsigned char)*pStr) > 127, "rtl.string",
"rtl_string2UString_status() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
*pBuffer = *pStr;