diff options
author | Luboš Luňák <l.lunak@suse.cz> | 2012-02-22 15:35:41 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@suse.cz> | 2012-02-22 16:21:37 +0100 |
commit | f150ed241ff796a25bd1a797155104198b415f18 (patch) | |
tree | bce5481ac1cd29b781ad73c2eb5a7606c49f5da2 /sal | |
parent | 768da511046f22346874734da2418117f71dcd11 (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.mk | 1 | ||||
-rw-r--r-- | sal/inc/rtl/ustring.hxx | 62 | ||||
-rw-r--r-- | sal/inc/sal/log-areas.dox | 4 | ||||
-rw-r--r-- | sal/qa/rtl/strings/test_oustring_stringliterals.cxx | 91 | ||||
-rw-r--r-- | sal/rtl/source/ustring.cxx | 3 |
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; |